/[gentoo-projects]/pax-utils/scanelf.c
Gentoo

Diff of /pax-utils/scanelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.26 Revision 1.27
1/* 1/*
2 * Copyright 2003 Ned Ludd <solar@gentoo.org> 2 * Copyright 2003 Ned Ludd <solar@gentoo.org>
3 * Copyright 1999-2005 Gentoo Foundation 3 * Copyright 1999-2005 Gentoo Foundation
4 * Distributed under the terms of the GNU General Public License v2 4 * Distributed under the terms of the GNU General Public License v2
5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.26 2005/04/05 00:51:33 vapier Exp $ 5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.27 2005/04/05 01:44:08 vapier Exp $
6 * 6 *
7 ******************************************************************** 7 ********************************************************************
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the 10 * published by the Free Software Foundation; either version 2 of the
32#include <getopt.h> 32#include <getopt.h>
33#include <assert.h> 33#include <assert.h>
34 34
35#include "paxelf.h" 35#include "paxelf.h"
36 36
37static const char *rcsid = "$Id: scanelf.c,v 1.26 2005/04/05 00:51:33 vapier Exp $"; 37static const char *rcsid = "$Id: scanelf.c,v 1.27 2005/04/05 01:44:08 vapier Exp $";
38 38
39 39
40/* helper functions for showing errors */ 40/* helper functions for showing errors */
41#define argv0 "scanelf" /*((*argv != NULL) ? argv[0] : __FILE__ "\b\b")*/ 41#define argv0 "scanelf" /*((*argv != NULL) ? argv[0] : __FILE__ "\b\b")*/
42#define warn(fmt, args...) \ 42#define warn(fmt, args...) \
68static char show_textrel = 0; 68static char show_textrel = 0;
69static char show_rpath = 0; 69static char show_rpath = 0;
70static char show_banner = 1; 70static char show_banner = 1;
71static char be_quiet = 0; 71static char be_quiet = 0;
72static char be_verbose = 0; 72static char be_verbose = 0;
73static char *find_sym = NULL;
73 74
74 75
75 76
76/* scan an elf file and show all the fun stuff */ 77/* scan an elf file and show all the fun stuff */
77static void scanelf_file(const char *filename) 78static void scanelf_file(const char *filename)
78{ 79{
79 int i; 80 int i;
80 char found_pax, found_stack, found_relro, found_textrel, found_rpath; 81 char found_pax, found_stack, found_relro, found_textrel, found_rpath, found_sym;
81 elfobj *elf; 82 elfobj *elf;
82 83
83 found_pax = found_stack = found_relro = found_textrel = found_rpath = 0; 84 found_pax = found_stack = found_relro = found_textrel = found_rpath = found_sym = 0;
84 85
85 /* verify this is real ELF */ 86 /* verify this is real ELF */
86 if ((elf = readelf(filename)) == NULL) { 87 if ((elf = readelf(filename)) == NULL) {
87 if (be_verbose > 2) printf("%s: not an ELF\n", filename); 88 if (be_verbose > 2) printf("%s: not an ELF\n", filename);
88 return; 89 return;
209 else if (!be_quiet && !found_rpath) 210 else if (!be_quiet && !found_rpath)
210 printf(" - "); 211 printf(" - ");
211 } 212 }
212 213
213 if (!be_quiet || found_pax || found_stack || found_textrel || found_rpath) 214 if (!be_quiet || found_pax || found_stack || found_textrel || found_rpath)
214 puts(filename); 215 printf("%s\n", filename);
216
217 if (find_sym) {
218 void *symtab_void, *strtab_void;
219 symtab_void = elf_findsecbyname(elf, ".symtab");
220 strtab_void = elf_findsecbyname(elf, ".strtab");
221
222 if (symtab_void && strtab_void) {
223#define FIND_SYM(B) \
224 if (elf->elf_class == ELFCLASS ## B) { \
225 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
226 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
227 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
228 int cnt = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
229 char *symname; \
230 if (be_verbose > 1) \
231 printf("%s: .symtab has %i entries\n", filename, cnt); \
232 for (i = 0; i < cnt; ++i) { \
233 if (sym->st_name) { \
234 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
235 if (*find_sym == '*' || !strcmp(find_sym, symname)) \
236 printf("%s: %5lX %15s %s\n", \
237 filename, \
238 (long)sym->st_size, \
239 (char *)get_elfstttype(sym->st_info & 0xF), \
240 symname); \
241 } \
242 ++sym; \
243 } }
244 FIND_SYM(32)
245 FIND_SYM(64)
246 }
247 }
215 248
216 unreadelf(elf); 249 unreadelf(elf);
217} 250}
218 251
219/* scan a directory for ET_EXEC files and print when we find one */ 252/* scan a directory for ET_EXEC files and print when we find one */
317} 350}
318 351
319 352
320 353
321/* usage / invocation handling functions */ 354/* usage / invocation handling functions */
322#define PARSE_FLAGS "plRmxetraqvo:BhV" 355#define PARSE_FLAGS "plRmxetrs:aqvo:BhV"
356#define a_argument required_argument
323static struct option const long_opts[] = { 357static struct option const long_opts[] = {
324 {"path", no_argument, NULL, 'p'}, 358 {"path", no_argument, NULL, 'p'},
325 {"ldpath", no_argument, NULL, 'l'}, 359 {"ldpath", no_argument, NULL, 'l'},
326 {"recursive", no_argument, NULL, 'R'}, 360 {"recursive", no_argument, NULL, 'R'},
327 {"mount", no_argument, NULL, 'm'}, 361 {"mount", no_argument, NULL, 'm'},
328 {"pax", no_argument, NULL, 'x'}, 362 {"pax", no_argument, NULL, 'x'},
329 {"header", no_argument, NULL, 'e'}, 363 {"header", no_argument, NULL, 'e'},
330 {"textrel", no_argument, NULL, 't'}, 364 {"textrel", no_argument, NULL, 't'},
331 {"rpath", no_argument, NULL, 'r'}, 365 {"rpath", no_argument, NULL, 'r'},
366 {"symbol", a_argument, NULL, 's'},
332 {"all", no_argument, NULL, 'a'}, 367 {"all", no_argument, NULL, 'a'},
333 {"quiet", no_argument, NULL, 'q'}, 368 {"quiet", no_argument, NULL, 'q'},
334 {"verbose", no_argument, NULL, 'v'}, 369 {"verbose", no_argument, NULL, 'v'},
335 {"file",required_argument, NULL, 'o'}, 370 {"file", a_argument, NULL, 'o'},
336 {"nobanner", no_argument, NULL, 'B'}, 371 {"nobanner", no_argument, NULL, 'B'},
337 {"help", no_argument, NULL, 'h'}, 372 {"help", no_argument, NULL, 'h'},
338 {"version", no_argument, NULL, 'V'}, 373 {"version", no_argument, NULL, 'V'},
339 {NULL, no_argument, NULL, 0x0} 374 {NULL, no_argument, NULL, 0x0}
340}; 375};
345 "Don't recursively cross mount points\n", 380 "Don't recursively cross mount points\n",
346 "Print PaX markings", 381 "Print PaX markings",
347 "Print GNU_STACK markings", 382 "Print GNU_STACK markings",
348 "Print TEXTREL information", 383 "Print TEXTREL information",
349 "Print RPATH information", 384 "Print RPATH information",
385 "Find a specified symbol",
350 "Print all scanned info (-x -e -t -r)\n", 386 "Print all scanned info (-x -e -t -r)\n",
351 "Only output 'bad' things", 387 "Only output 'bad' things",
352 "Be verbose (can be specified more than once)", 388 "Be verbose (can be specified more than once)",
353 "Write output stream to a filename", 389 "Write output stream to a filename",
354 "Don't display the header", 390 "Don't display the header",
359 395
360/* display usage and exit */ 396/* display usage and exit */
361static void usage(int status) 397static void usage(int status)
362{ 398{
363 int i; 399 int i;
364 printf(" Scan ELF binaries for stuff\n\n" 400 printf(" Scan ELF binaries for stuff\n"
365 "Usage: %s [options] <dir1> [dir2 dirN ...]\n\n", argv0); 401 "Usage: %s [options] <dir1> [dir2 dirN ...]\n\n", argv0);
366 printf("Options:\n"); 402 printf("Options:\n");
367 for (i = 0; long_opts[i].name; ++i) 403 for (i = 0; long_opts[i].name; ++i)
404 if (long_opts[i].has_arg == no_argument)
368 printf(" -%c, --%-12s %s\n", long_opts[i].val, 405 printf(" -%c, --%-13s %s\n", long_opts[i].val,
369 long_opts[i].name, opts_help[i]); 406 long_opts[i].name, opts_help[i]);
370#ifdef MANLYPAGE 407 else
371 for (i = 0; long_opts[i].name; ++i) 408 printf(" -%c, --%-6s <arg> %s\n", long_opts[i].val,
372 printf(".TP\n\\fB\\-%c, \\-\\-%s\\fR\n%s\n", long_opts[i].val,
373 long_opts[i].name, opts_help[i]); 409 long_opts[i].name, opts_help[i]);
374#endif
375 exit(status); 410 exit(status);
376} 411}
377 412
378/* parse command line arguments and preform needed actions */ 413/* parse command line arguments and preform needed actions */
379static void parseargs(int argc, char *argv[]) 414static void parseargs(int argc, char *argv[])
388 printf("%s compiled %s\n%s\n" 423 printf("%s compiled %s\n%s\n"
389 "%s written for Gentoo Linux by <solar and vapier @ gentoo.org>\n", 424 "%s written for Gentoo Linux by <solar and vapier @ gentoo.org>\n",
390 __FILE__, __DATE__, rcsid, argv0); 425 __FILE__, __DATE__, rcsid, argv0);
391 exit(EXIT_SUCCESS); 426 exit(EXIT_SUCCESS);
392 break; 427 break;
393 case 's': /* reserved for -s, --symbol= */
394 case 'h': usage(EXIT_SUCCESS); break; 428 case 'h': usage(EXIT_SUCCESS); break;
395 429
396 case 'o': { 430 case 'o': {
397 FILE *fp = NULL; 431 FILE *fp = NULL;
398 fp = freopen(optarg, "w", stdout); 432 fp = freopen(optarg, "w", stdout);
399 if (fp == NULL) 433 if (fp == NULL)
400 err("Could not open output stream '%s': %s", optarg, strerror(errno)); 434 err("Could not open output stream '%s': %s", optarg, strerror(errno));
401 stdout = fp; 435 stdout = fp;
402 break; 436 break;
403 } 437 }
438
439 case 's': find_sym = strdup(optarg); break;
404 440
405 case 'B': show_banner = 0; break; 441 case 'B': show_banner = 0; break;
406 case 'l': scan_ldpath = 1; break; 442 case 'l': scan_ldpath = 1; break;
407 case 'p': scan_envpath = 1; break; 443 case 'p': scan_envpath = 1; break;
408 case 'R': dir_recurse = 1; break; 444 case 'R': dir_recurse = 1; break;
436 if (scan_envpath) scanelf_envpath(); 472 if (scan_envpath) scanelf_envpath();
437 if (optind == argc && !scan_ldpath && !scan_envpath) 473 if (optind == argc && !scan_ldpath && !scan_envpath)
438 err("Nothing to scan !?"); 474 err("Nothing to scan !?");
439 while (optind < argc) 475 while (optind < argc)
440 scanelf_dir(argv[optind++]); 476 scanelf_dir(argv[optind++]);
477
478 if (find_sym) free(find_sym);
441} 479}
442 480
443 481
444 482
445int main(int argc, char *argv[]) 483int main(int argc, char *argv[])

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27

  ViewVC Help
Powered by ViewVC 1.1.20