/[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.35 Revision 1.38
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/Attic/scanelf.c,v 1.35 2005/04/14 00:17:30 solar Exp $ 5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.38 2005/04/19 22:19:26 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
33#include <getopt.h> 33#include <getopt.h>
34#include <assert.h> 34#include <assert.h>
35 35
36#include "paxelf.h" 36#include "paxelf.h"
37 37
38static const char *rcsid = "$Id: scanelf.c,v 1.35 2005/04/14 00:17:30 solar Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.38 2005/04/19 22:19:26 vapier Exp $";
39 39#define argv0 "scanelf"
40
41/* helper functions for showing errors */
42#define argv0 "scanelf" /*((*argv != NULL) ? argv[0] : __FILE__ "\b\b")*/
43#define warn(fmt, args...) \
44 fprintf(stderr, "%s: " fmt "\n", argv0, ## args)
45#define warnf(fmt, args...) warn("%s(): " fmt, __FUNCTION__, ## args)
46#define err(fmt, args...) \
47 do { \
48 warn(fmt, ## args); \
49 exit(EXIT_FAILURE); \
50 } while (0)
51 40
52 41
53 42
54/* prototypes */ 43/* prototypes */
55static void scanelf_file(const char *filename); 44static void scanelf_file(const char *filename);
60static void parseargs(int argc, char *argv[]); 49static void parseargs(int argc, char *argv[]);
61 50
62/* variables to control behavior */ 51/* variables to control behavior */
63static char scan_ldpath = 0; 52static char scan_ldpath = 0;
64static char scan_envpath = 0; 53static char scan_envpath = 0;
54static char scan_symlink = 1;
65static char dir_recurse = 0; 55static char dir_recurse = 0;
66static char dir_crossmount = 1; 56static char dir_crossmount = 1;
67static char show_pax = 0; 57static char show_pax = 0;
68static char show_stack = 0; 58static char show_stack = 0;
69static char show_textrel = 0; 59static char show_textrel = 0;
70static char show_rpath = 0; 60static char show_rpath = 0;
71static char show_needed = 0; 61static char show_needed = 0;
62static char show_interp = 0;
72static char show_banner = 1; 63static char show_banner = 1;
73static char be_quiet = 0; 64static char be_quiet = 0;
74static char be_verbose = 0; 65static char be_verbose = 0;
75static char *find_sym = NULL; 66static char *find_sym = NULL;
76 67
79/* scan an elf file and show all the fun stuff */ 70/* scan an elf file and show all the fun stuff */
80static void scanelf_file(const char *filename) 71static void scanelf_file(const char *filename)
81{ 72{
82 int i; 73 int i;
83 char found_pax, found_stack, found_relro, found_textrel, 74 char found_pax, found_stack, found_relro, found_textrel,
84 found_rpath, found_needed, found_sym; 75 found_rpath, found_needed, found_interp, found_sym;
85 elfobj *elf; 76 elfobj *elf;
86 struct stat st; 77 struct stat st;
87 78
88 /* make sure path exists */ 79 /* make sure 'filename' exists */
89 if (lstat(filename, &st) == -1) 80 if (lstat(filename, &st) == -1)
90 return; 81 return;
91 if (!S_ISREG(st.st_mode)) 82 /* always handle regular files and handle symlinked files if no -y */
83 if (!(S_ISREG(st.st_mode) || (S_ISLNK(st.st_mode) && scan_symlink)))
92 return; 84 return;
85
93 found_pax = found_stack = found_relro = found_textrel = \ 86 found_pax = found_stack = found_relro = found_textrel = \
94 found_rpath = found_needed = found_sym = 0; 87 found_rpath = found_needed = found_interp = found_sym = 0;
95 88
96 /* verify this is real ELF */ 89 /* verify this is real ELF */
97 if ((elf = readelf(filename)) == NULL) { 90 if ((elf = readelf(filename)) == NULL) {
98 if (be_verbose > 2) printf("%s: not an ELF\n", filename); 91 if (be_verbose > 2) printf("%s: not an ELF\n", filename);
99 return; 92 return;
112 if (show_pax) printf(" PAX "); 105 if (show_pax) printf(" PAX ");
113 if (show_stack) printf("STK/REL "); 106 if (show_stack) printf("STK/REL ");
114 if (show_textrel) printf("TEXTREL "); 107 if (show_textrel) printf("TEXTREL ");
115 if (show_rpath) printf("RPATH "); 108 if (show_rpath) printf("RPATH ");
116 if (show_needed) printf("NEEDED "); 109 if (show_needed) printf("NEEDED ");
110 if (show_interp) printf("INTERP ");
117 printf(" FILE\n"); 111 printf(" FILE\n");
118 show_banner = 0; 112 show_banner = 0;
119 } 113 }
120 114
121 /* dump all the good stuff */ 115 /* dump all the good stuff */
259 printf(" - "); 253 printf(" - ");
260 else if (found_needed) 254 else if (found_needed)
261 printf(" "); 255 printf(" ");
262 } 256 }
263 257
258 /* print out all the INTERP info (i.e. glibc is /lib/ld-linux.so.2) */
259 if (show_interp) {
260 void *strtbl_void = elf_findsecbyname(elf, ".interp");
261
262 if (strtbl_void) {
263#define SHOW_INTERP(B) \
264 if (elf->elf_class == ELFCLASS ## B) { \
265 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
266 printf("%s ", elf->data + EGET(strtbl->sh_offset)); \
267 found_interp = 1; \
268 }
269 SHOW_INTERP(32)
270 SHOW_INTERP(64)
271 }
272 if (!be_quiet && !found_interp)
273 printf(" - ");
274 else if (found_interp)
275 printf(" ");
276 }
277
264 /* search the symbol table for a specified symbol */ 278 /* search the symbol table for a specified symbol */
265 if (find_sym) { 279 if (find_sym) {
266 void *symtab_void, *strtab_void; 280 void *symtab_void, *strtab_void;
267 char *versioned_symname; 281 char *versioned_symname;
268 size_t len; 282 size_t len;
426} 440}
427 441
428 442
429 443
430/* usage / invocation handling functions */ 444/* usage / invocation handling functions */
431#define PARSE_FLAGS "plRmxetrns:aqvo:BhV" 445#define PARSE_FLAGS "plRmyxetrnis:aqvo:BhV"
432#define a_argument required_argument 446#define a_argument required_argument
433static struct option const long_opts[] = { 447static struct option const long_opts[] = {
434 {"path", no_argument, NULL, 'p'}, 448 {"path", no_argument, NULL, 'p'},
435 {"ldpath", no_argument, NULL, 'l'}, 449 {"ldpath", no_argument, NULL, 'l'},
436 {"recursive", no_argument, NULL, 'R'}, 450 {"recursive", no_argument, NULL, 'R'},
437 {"mount", no_argument, NULL, 'm'}, 451 {"mount", no_argument, NULL, 'm'},
452 {"symlink", no_argument, NULL, 'y'},
438 {"pax", no_argument, NULL, 'x'}, 453 {"pax", no_argument, NULL, 'x'},
439 {"header", no_argument, NULL, 'e'}, 454 {"header", no_argument, NULL, 'e'},
440 {"textrel", no_argument, NULL, 't'}, 455 {"textrel", no_argument, NULL, 't'},
441 {"rpath", no_argument, NULL, 'r'}, 456 {"rpath", no_argument, NULL, 'r'},
442 {"needed", no_argument, NULL, 'n'}, 457 {"needed", no_argument, NULL, 'n'},
458 {"interp", no_argument, NULL, 'i'},
443 {"symbol", a_argument, NULL, 's'}, 459 {"symbol", a_argument, NULL, 's'},
444 {"all", no_argument, NULL, 'a'}, 460 {"all", no_argument, NULL, 'a'},
445 {"quiet", no_argument, NULL, 'q'}, 461 {"quiet", no_argument, NULL, 'q'},
446 {"verbose", no_argument, NULL, 'v'}, 462 {"verbose", no_argument, NULL, 'v'},
447 {"file", a_argument, NULL, 'o'}, 463 {"file", a_argument, NULL, 'o'},
452}; 468};
453static char *opts_help[] = { 469static char *opts_help[] = {
454 "Scan all directories in PATH environment", 470 "Scan all directories in PATH environment",
455 "Scan all directories in /etc/ld.so.conf", 471 "Scan all directories in /etc/ld.so.conf",
456 "Scan directories recursively", 472 "Scan directories recursively",
457 "Don't recursively cross mount points\n", 473 "Don't recursively cross mount points",
474 "Don't scan symlinks\n",
458 "Print PaX markings", 475 "Print PaX markings",
459 "Print GNU_STACK markings", 476 "Print GNU_STACK markings",
460 "Print TEXTREL information", 477 "Print TEXTREL information",
461 "Print RPATH information", 478 "Print RPATH information",
462 "Print NEEDED information", 479 "Print NEEDED information",
480 "Print INTERP information",
463 "Find a specified symbol", 481 "Find a specified symbol",
464 "Print all scanned info (-x -e -t -r)\n", 482 "Print all scanned info (-x -e -t -r)\n",
465 "Only output 'bad' things", 483 "Only output 'bad' things",
466 "Be verbose (can be specified more than once)", 484 "Be verbose (can be specified more than once)",
467 "Write output stream to a filename", 485 "Write output stream to a filename",
473 491
474/* display usage and exit */ 492/* display usage and exit */
475static void usage(int status) 493static void usage(int status)
476{ 494{
477 int i; 495 int i;
478 printf(" Scan ELF binaries for stuff\n" 496 printf(" Scan ELF binaries for stuff\n\n"
479 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); 497 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0);
480 printf("Options: -[%s]\n", PARSE_FLAGS); 498 printf("Options: -[%s]\n", PARSE_FLAGS);
481 for (i = 0; long_opts[i].name; ++i) 499 for (i = 0; long_opts[i].name; ++i)
482 if (long_opts[i].has_arg == no_argument) 500 if (long_opts[i].has_arg == no_argument)
483 printf(" -%c, --%-13s %s\n", long_opts[i].val, 501 printf(" -%c, --%-13s %s\n", long_opts[i].val,
514 break; 532 break;
515 } 533 }
516 534
517 case 's': find_sym = strdup(optarg); break; 535 case 's': find_sym = strdup(optarg); break;
518 536
537 case 'y': scan_symlink = 0; break;
519 case 'B': show_banner = 0; break; 538 case 'B': show_banner = 0; break;
520 case 'l': scan_ldpath = 1; break; 539 case 'l': scan_ldpath = 1; break;
521 case 'p': scan_envpath = 1; break; 540 case 'p': scan_envpath = 1; break;
522 case 'R': dir_recurse = 1; break; 541 case 'R': dir_recurse = 1; break;
523 case 'm': dir_crossmount = 0; break; 542 case 'm': dir_crossmount = 0; break;
524 case 'x': show_pax = 1; break; 543 case 'x': show_pax = 1; break;
525 case 'e': show_stack = 1; break; 544 case 'e': show_stack = 1; break;
526 case 't': show_textrel = 1; break; 545 case 't': show_textrel = 1; break;
527 case 'r': show_rpath = 1; break; 546 case 'r': show_rpath = 1; break;
528 case 'n': show_needed = 1; break; 547 case 'n': show_needed = 1; break;
548 case 'i': show_interp = 1; break;
529 case 'q': be_quiet = 1; break; 549 case 'q': be_quiet = 1; break;
530 case 'v': be_verbose = (be_verbose % 20) + 1; break; 550 case 'v': be_verbose = (be_verbose % 20) + 1; break;
531 case 'a': show_pax = show_stack = show_textrel = show_needed = show_rpath = 1; break; 551 case 'a': show_pax = show_stack = show_textrel = show_rpath = show_needed = show_interp = 1; break;
532 552
533 case ':': 553 case ':':
534 warn("Option missing parameter"); 554 warn("Option missing parameter");
535 usage(EXIT_FAILURE); 555 usage(EXIT_FAILURE);
536 break; 556 break;

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.38

  ViewVC Help
Powered by ViewVC 1.1.20