/[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.71 Revision 1.72
1/* 1/*
2 * Copyright 2003-2005 Gentoo Foundation 2 * Copyright 2003-2005 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.71 2005/06/04 02:50:50 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.72 2005/06/04 06:23:06 vapier Exp $
5 * 5 *
6 ******************************************************************** 6 ********************************************************************
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the 9 * published by the Free Software Foundation; either version 2 of the
33#include <dirent.h> 33#include <dirent.h>
34#include <getopt.h> 34#include <getopt.h>
35#include <assert.h> 35#include <assert.h>
36#include "paxelf.h" 36#include "paxelf.h"
37 37
38static const char *rcsid = "$Id: scanelf.c,v 1.71 2005/06/04 02:50:50 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.72 2005/06/04 06:23:06 vapier Exp $";
39#define argv0 "scanelf" 39#define argv0 "scanelf"
40 40
41#define IS_MODIFIER(c) (c == '%' || c == '#') 41#define IS_MODIFIER(c) (c == '%' || c == '#')
42 42
43 43
71static char show_banner = 1; 71static char show_banner = 1;
72static char be_quiet = 0; 72static char be_quiet = 0;
73static char be_verbose = 0; 73static char be_verbose = 0;
74static char be_wewy_wewy_quiet = 0; 74static char be_wewy_wewy_quiet = 0;
75static char *find_sym = NULL, *versioned_symname = NULL; 75static char *find_sym = NULL, *versioned_symname = NULL;
76static char *find_lib = NULL;
76static char *out_format = NULL; 77static char *out_format = NULL;
77static char *search_path = NULL; 78static char *search_path = NULL;
78 79
79 80
80 81
304 } else if (rpath || runpath) 305 } else if (rpath || runpath)
305 xstrcat(ret, (runpath ? runpath : rpath), ret_len); 306 xstrcat(ret, (runpath ? runpath : rpath), ret_len);
306 else if (!be_quiet) 307 else if (!be_quiet)
307 xstrcat(ret, " - ", ret_len); 308 xstrcat(ret, " - ", ret_len);
308} 309}
309static void scanelf_file_needed(elfobj *elf, char *found_needed, char **ret, size_t *ret_len) 310static char *scanelf_file_needed_lib(elfobj *elf, char *found_needed, char *found_lib, int op, char **ret, size_t *ret_len)
310{ 311{
311 unsigned long i; 312 unsigned long i;
312 char *needed; 313 char *needed;
313 void *strtbl_void; 314 void *strtbl_void;
314 315
315 if (!show_needed) return; 316 if ((op==0 && !show_needed) || (op==1 && !find_lib)) return NULL;
316 317
317 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 318 strtbl_void = elf_findsecbyname(elf, ".dynstr");
318 319
319 if (elf->phdr && strtbl_void) { 320 if (elf->phdr && strtbl_void) {
320#define SHOW_NEEDED(B) \ 321#define SHOW_NEEDED(B) \
335 if (offset >= (Elf ## B ## _Off)elf->len) { \ 336 if (offset >= (Elf ## B ## _Off)elf->len) { \
336 ++dyn; \ 337 ++dyn; \
337 continue; \ 338 continue; \
338 } \ 339 } \
339 needed = (char*)(elf->data + offset); \ 340 needed = (char*)(elf->data + offset); \
341 if (op == 0) { \
342 if (!be_wewy_wewy_quiet) { \
340 if (*found_needed) xchrcat(ret, ',', ret_len); \ 343 if (*found_needed) xchrcat(ret, ',', ret_len); \
341 if (!be_wewy_wewy_quiet) xstrcat(ret, needed, ret_len); \ 344 xstrcat(ret, needed, ret_len); \
345 } \
342 *found_needed = 1; \ 346 *found_needed = 1; \
347 } else { \
348 if (strcmp(find_lib, needed)) return NULL; \
349 *found_lib = 1; \
350 return (be_wewy_wewy_quiet ? NULL : find_lib); \
351 } \
343 } \ 352 } \
344 ++dyn; \ 353 ++dyn; \
345 } \ 354 } \
346 } } 355 } }
347 SHOW_NEEDED(32) 356 SHOW_NEEDED(32)
348 SHOW_NEEDED(64) 357 SHOW_NEEDED(64)
349 } 358 }
359
360 return NULL;
350} 361}
351static char *scanelf_file_interp(elfobj *elf, char *found_interp) 362static char *scanelf_file_interp(elfobj *elf, char *found_interp)
352{ 363{
353 void *strtbl_void; 364 void *strtbl_void;
354 365
409 } else { 420 } else {
410 *found_bind = 1; 421 *found_bind = 1;
411 return (char *) "LAZY"; 422 return (char *) "LAZY";
412 } 423 }
413} 424}
414static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename) 425static char *scanelf_file_sym(elfobj *elf, char *found_sym)
415{ 426{
416 unsigned long i; 427 unsigned long i;
417 void *symtab_void, *strtab_void; 428 void *symtab_void, *strtab_void;
418 429
419 if (!find_sym) return NULL; 430 if (!find_sym) return NULL;
427 strtab_void = elf_findsecbyname(elf, ".dynstr"); 438 strtab_void = elf_findsecbyname(elf, ".dynstr");
428 } 439 }
429 440
430 if (symtab_void && strtab_void) { 441 if (symtab_void && strtab_void) {
431 char *base, *basemem; 442 char *base, *basemem;
432 basemem = xstrdup(filename); 443 basemem = xstrdup(elf->filename);
433 base = basename(basemem); 444 base = basename(basemem);
434#define FIND_SYM(B) \ 445#define FIND_SYM(B) \
435 if (elf->elf_class == ELFCLASS ## B) { \ 446 if (elf->elf_class == ELFCLASS ## B) { \
436 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 447 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
437 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 448 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
474static void scanelf_file(const char *filename) 485static void scanelf_file(const char *filename)
475{ 486{
476 unsigned long i; 487 unsigned long i;
477 char found_pax, found_stack, found_relro, found_load, found_textrel, 488 char found_pax, found_stack, found_relro, found_load, found_textrel,
478 found_rpath, found_needed, found_interp, found_bind, 489 found_rpath, found_needed, found_interp, found_bind,
479 found_sym, found_file; 490 found_sym, found_lib, found_file;
480 elfobj *elf; 491 elfobj *elf;
481 struct stat st; 492 struct stat st;
482 static char *out_buffer = NULL; 493 static char *out_buffer = NULL;
483 static size_t out_len; 494 static size_t out_len;
484 495
497 return; 508 return;
498 } 509 }
499 510
500 found_pax = found_stack = found_relro = found_load = \ 511 found_pax = found_stack = found_relro = found_load = \
501 found_textrel = found_rpath = found_needed = found_interp = \ 512 found_textrel = found_rpath = found_needed = found_interp = \
502 found_bind = found_sym = found_file = 0; 513 found_bind = found_sym = found_lib = found_file = 0;
503 514
504 /* verify this is real ELF */ 515 /* verify this is real ELF */
505 if ((elf = readelf(filename)) == NULL) { 516 if ((elf = readelf(filename)) == NULL) {
506 if (be_verbose > 2) printf("%s: not an ELF\n", filename); 517 if (be_verbose > 2) printf("%s: not an ELF\n", filename);
507 return; 518 return;
539 case 'r': prints("RPATH "); break; 550 case 'r': prints("RPATH "); break;
540 case 'n': prints("NEEDED "); break; 551 case 'n': prints("NEEDED "); break;
541 case 'i': prints("INTERP "); break; 552 case 'i': prints("INTERP "); break;
542 case 'b': prints("BIND "); break; 553 case 'b': prints("BIND "); break;
543 case 's': prints("SYM "); break; 554 case 's': prints("SYM "); break;
555 case 'N': prints("LIB "); break;
544 } 556 }
545 } 557 }
546 if (!found_file) prints("FILE "); 558 if (!found_file) prints("FILE ");
547 prints("\n"); 559 prints("\n");
548 found_file = 0; 560 found_file = 0;
598 case 'o': out = get_elfetype(elf); break; 610 case 'o': out = get_elfetype(elf); break;
599 case 'x': out = scanelf_file_pax(elf, &found_pax); break; 611 case 'x': out = scanelf_file_pax(elf, &found_pax); break;
600 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro, &found_load); break; 612 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro, &found_load); break;
601 case 't': out = scanelf_file_textrel(elf, &found_textrel); break; 613 case 't': out = scanelf_file_textrel(elf, &found_textrel); break;
602 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break; 614 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break;
615 case 'n':
603 case 'n': scanelf_file_needed(elf, &found_needed, &out_buffer, &out_len); break; 616 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break;
604 case 'i': out = scanelf_file_interp(elf, &found_interp); break; 617 case 'i': out = scanelf_file_interp(elf, &found_interp); break;
605 case 'b': out = scanelf_file_bind(elf, &found_bind); break; 618 case 'b': out = scanelf_file_bind(elf, &found_bind); break;
606 case 's': out = scanelf_file_sym(elf, &found_sym, filename); break; 619 case 's': out = scanelf_file_sym(elf, &found_sym); break;
607 } 620 }
608 if (out) xstrcat(&out_buffer, out, &out_len); 621 if (out) xstrcat(&out_buffer, out, &out_len);
609 } 622 }
610 623
611#define FOUND_SOMETHING() \ 624#define FOUND_SOMETHING() \
612 (found_pax || found_stack || found_relro || found_load || found_textrel || \ 625 (found_pax || found_stack || found_relro || found_load || found_textrel || \
613 found_rpath || found_needed || found_interp || found_bind || found_sym) 626 found_rpath || found_needed || found_interp || found_bind || found_sym || found_lib)
614 627
615 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) { 628 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) {
616 xchrcat(&out_buffer, ' ', &out_len); 629 xchrcat(&out_buffer, ' ', &out_len);
617 xstrcat(&out_buffer, filename, &out_len); 630 xstrcat(&out_buffer, filename, &out_len);
618 } 631 }
766} 779}
767 780
768 781
769 782
770/* usage / invocation handling functions */ 783/* usage / invocation handling functions */
771#define PARSE_FLAGS "plRmyxetrnibs:aqvF:f:o:BhV" 784#define PARSE_FLAGS "plRmyxetrnibs:N:aqvF:f:o:BhV"
772#define a_argument required_argument 785#define a_argument required_argument
773static struct option const long_opts[] = { 786static struct option const long_opts[] = {
774 {"path", no_argument, NULL, 'p'}, 787 {"path", no_argument, NULL, 'p'},
775 {"ldpath", no_argument, NULL, 'l'}, 788 {"ldpath", no_argument, NULL, 'l'},
776 {"recursive", no_argument, NULL, 'R'}, 789 {"recursive", no_argument, NULL, 'R'},
782 {"rpath", no_argument, NULL, 'r'}, 795 {"rpath", no_argument, NULL, 'r'},
783 {"needed", no_argument, NULL, 'n'}, 796 {"needed", no_argument, NULL, 'n'},
784 {"interp", no_argument, NULL, 'i'}, 797 {"interp", no_argument, NULL, 'i'},
785 {"bind", no_argument, NULL, 'b'}, 798 {"bind", no_argument, NULL, 'b'},
786 {"symbol", a_argument, NULL, 's'}, 799 {"symbol", a_argument, NULL, 's'},
800 {"lib", a_argument, NULL, 'N'},
787 {"all", no_argument, NULL, 'a'}, 801 {"all", no_argument, NULL, 'a'},
788 {"quiet", no_argument, NULL, 'q'}, 802 {"quiet", no_argument, NULL, 'q'},
789 {"verbose", no_argument, NULL, 'v'}, 803 {"verbose", no_argument, NULL, 'v'},
790 {"format", a_argument, NULL, 'F'}, 804 {"format", a_argument, NULL, 'F'},
791 {"from", a_argument, NULL, 'f'}, 805 {"from", a_argument, NULL, 'f'},
808 "Print RPATH information", 822 "Print RPATH information",
809 "Print NEEDED information", 823 "Print NEEDED information",
810 "Print INTERP information", 824 "Print INTERP information",
811 "Print BIND information", 825 "Print BIND information",
812 "Find a specified symbol", 826 "Find a specified symbol",
827 "Find a specified library",
813 "Print all scanned info (-x -e -t -r -n -i -b)\n", 828 "Print all scanned info (-x -e -t -r -n -i -b)\n",
814 "Only output 'bad' things", 829 "Only output 'bad' things",
815 "Be verbose (can be specified more than once)", 830 "Be verbose (can be specified more than once)",
816 "Use specified format for output", 831 "Use specified format for output",
817 "Read input stream from a filename", 832 "Read input stream from a filename",
842 857
843 puts("\nThe format modifiers for the -F option are:"); 858 puts("\nThe format modifiers for the -F option are:");
844 puts(" F Filename \tx PaX Flags \te STACK/RELRO"); 859 puts(" F Filename \tx PaX Flags \te STACK/RELRO");
845 puts(" t TEXTREL \tr RPATH \tn NEEDED"); 860 puts(" t TEXTREL \tr RPATH \tn NEEDED");
846 puts(" i INTERP \tb BIND \ts symbol"); 861 puts(" i INTERP \tb BIND \ts symbol");
862 puts(" N library \to Type");
847 puts(" p filename (with search path removed)"); 863 puts(" p filename (with search path removed)");
848 puts(" f base filename"); 864 puts(" f base filename");
849 puts("Prefix each modifier with '%' (verbose) or '#' (silent)"); 865 puts("Prefix each modifier with '%' (verbose) or '#' (silent)");
850 866
851 exit(status); 867 exit(status);
887 len = strlen(find_sym) + 1; 903 len = strlen(find_sym) + 1;
888 versioned_symname = (char*)xmalloc(sizeof(char) * (len+1)); 904 versioned_symname = (char*)xmalloc(sizeof(char) * (len+1));
889 sprintf(versioned_symname, "%s@", find_sym); 905 sprintf(versioned_symname, "%s@", find_sym);
890 break; 906 break;
891 } 907 }
908 case 'N': {
909 if (find_lib) err("Don't specify -N twice");
910 find_lib = xstrdup(optarg);
911 break;
912 }
892 913
893 case 'F': { 914 case 'F': {
894 if (out_format) err("Don't specify -F twice"); 915 if (out_format) err("Don't specify -F twice");
895 out_format = xstrdup(optarg); 916 out_format = xstrdup(optarg);
896 break; 917 break;
935 case '#': break; 956 case '#': break;
936 case 'F': break; 957 case 'F': break;
937 case 'p': break; 958 case 'p': break;
938 case 'f': break; 959 case 'f': break;
939 case 's': break; 960 case 's': break;
961 case 'N': break;
940 case 'o': break; 962 case 'o': break;
941 case 'x': show_pax = 1; break; 963 case 'x': show_pax = 1; break;
942 case 'e': show_stack = 1; break; 964 case 'e': show_stack = 1; break;
943 case 't': show_textrel = 1; break; 965 case 't': show_textrel = 1; break;
944 case 'r': show_rpath = 1; break; 966 case 'r': show_rpath = 1; break;
962 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); 984 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len);
963 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); 985 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len);
964 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); 986 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);
965 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len); 987 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len);
966 if (find_sym) xstrcat(&out_format, "%s ", &fmt_len); 988 if (find_sym) xstrcat(&out_format, "%s ", &fmt_len);
989 if (find_lib) xstrcat(&out_format, "%N ", &fmt_len);
967 if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len); 990 if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len);
968 } 991 }
969 if (be_verbose > 2) printf("Format: %s\n", out_format); 992 if (be_verbose > 2) printf("Format: %s\n", out_format);
970 993
971 /* now lets actually do the scanning */ 994 /* now lets actually do the scanning */
988 /* clean up */ 1011 /* clean up */
989 if (find_sym) { 1012 if (find_sym) {
990 free(find_sym); 1013 free(find_sym);
991 free(versioned_symname); 1014 free(versioned_symname);
992 } 1015 }
1016 if (find_lib) free(find_lib);
993 if (out_format) free(out_format); 1017 if (out_format) free(out_format);
994 for (i = 0; ldpaths[i]; ++i) 1018 for (i = 0; ldpaths[i]; ++i)
995 free(ldpaths[i]); 1019 free(ldpaths[i]);
996} 1020}
997 1021
1032 static char my_app[2]; 1056 static char my_app[2];
1033 my_app[0] = append; 1057 my_app[0] = append;
1034 my_app[1] = '\0'; 1058 my_app[1] = '\0';
1035 xstrcat(dst, my_app, curr_len); 1059 xstrcat(dst, my_app, curr_len);
1036} 1060}
1061
1037 1062
1038 1063
1039int main(int argc, char *argv[]) 1064int main(int argc, char *argv[])
1040{ 1065{
1041 if (argc < 2) 1066 if (argc < 2)

Legend:
Removed from v.1.71  
changed lines
  Added in v.1.72

  ViewVC Help
Powered by ViewVC 1.1.20