/[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.75 Revision 1.76
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.75 2005/06/06 23:32:38 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.76 2005/06/08 04:24:19 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.75 2005/06/06 23:32:38 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.76 2005/06/08 04:24:19 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
66static char show_textrel = 0; 66static char show_textrel = 0;
67static char show_rpath = 0; 67static char show_rpath = 0;
68static char show_needed = 0; 68static char show_needed = 0;
69static char show_interp = 0; 69static char show_interp = 0;
70static char show_bind = 0; 70static char show_bind = 0;
71static char show_textrels = 0;
71static char show_banner = 1; 72static char show_banner = 1;
72static char be_quiet = 0; 73static char be_quiet = 0;
73static char be_verbose = 0; 74static char be_verbose = 0;
74static char be_wewy_wewy_quiet = 0; 75static char be_wewy_wewy_quiet = 0;
75static char *find_sym = NULL, *versioned_symname = NULL; 76static char *find_sym = NULL, *versioned_symname = NULL;
217 218
218 if (be_quiet || be_wewy_wewy_quiet) 219 if (be_quiet || be_wewy_wewy_quiet)
219 return NULL; 220 return NULL;
220 else 221 else
221 return (char *)" - "; 222 return (char *)" - ";
223}
224static char *scanelf_file_textrels(elfobj *elf, char *found_textrels)
225{
226 /* To locate TEXTREL symbols:
227 * for each shdr of type SHT_REL:
228 * for each phdr of type PT_LOAD:
229 * if phdr is not writable (why?)
230 * if shdr offset is inside of load (shdr->offset, phdr->{vaddr,memsz}
231 * look up shdr's symbol name
232 */
233 unsigned long p, s, r, rmax;
234 char *symtab_void, *strtab_void;
235
236 if (!show_textrels) return NULL;
237
238 /* debug sections */
239 symtab_void = elf_findsecbyname(elf, ".symtab");
240 strtab_void = elf_findsecbyname(elf, ".strtab");
241 /* fall back to runtime sections */
242 if (!symtab_void || !strtab_void) {
243 symtab_void = elf_findsecbyname(elf, ".dynsym");
244 strtab_void = elf_findsecbyname(elf, ".dynstr");
245 }
246
247 if (elf->phdr && elf->shdr) {
248#define SHOW_TEXTRELS(B) \
249 if (elf->elf_class == ELFCLASS ## B) { \
250 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
251 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
252 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \
253 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
254 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
255 Elf ## B ## _Rel *rel; \
256 Elf ## B ## _Rela *rela; \
257 /* search the section headers for relocations */ \
258 for (s = 0; s < EGET(ehdr->e_shnum); ++s) { \
259 uint32_t sh_type = EGET(shdr[s].sh_type); \
260 if (sh_type == SHT_REL) { \
261 rel = REL ## B (elf->data + EGET(shdr[s].sh_offset)); \
262 rela = NULL; \
263 rmax = EGET(shdr[s].sh_size) / sizeof(*rel); \
264 } else if (sh_type == SHT_RELA) { \
265 rel = NULL; \
266 rela = RELA ## B (elf->data + EGET(shdr[s].sh_offset)); \
267 rmax = EGET(shdr[s].sh_size) / sizeof(*rela); \
268 } else \
269 continue; \
270 /* search the program headers for PT_LOAD headers */ \
271 for (p = 0; p < EGET(ehdr->e_phnum); ++p) { \
272 Elf ## B ## _Addr vaddr; \
273 uint ## B ## _t memsz; \
274 if (EGET(phdr[p].p_type) != PT_LOAD) continue; \
275 if (EGET(phdr[p].p_flags) & PF_W) continue; \
276 vaddr = EGET(phdr[p].p_vaddr); \
277 memsz = EGET(phdr[p].p_memsz); \
278 *found_textrels = 1; \
279 /* now see if any of the relocs are in the PT_LOAD */ \
280 for (r = 0; r < rmax; ++r) { \
281 unsigned long sym_max; \
282 Elf ## B ## _Addr offset_tmp; \
283 Elf ## B ## _Sym *func; \
284 Elf ## B ## _Sym *sym; \
285 Elf ## B ## _Addr r_offset; \
286 uint ## B ## _t r_info; \
287 if (sh_type == SHT_REL) { \
288 r_offset = EGET(rel[r].r_offset); \
289 r_info = EGET(rel[r].r_info); \
290 } else { \
291 r_offset = EGET(rela[r].r_offset); \
292 r_info = EGET(rela[r].r_info); \
293 } \
294 /* make sure this relocation is inside of the .text */ \
295 if (r_offset < vaddr || r_offset >= vaddr + memsz) continue; \
296 sym_max = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
297 /* locate this relocation symbol name */ \
298 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
299 sym += ELF ## B ## _R_SYM(r_info); \
300 /* show the raw details about this reloc */ \
301 printf("\tTEXTREL %s: ", elf->base_filename); \
302 if (sym->st_name) \
303 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name))); \
304 else \
305 printf("(NULL: fake?)"); \
306 printf(" [0x%lX]", (unsigned long)r_offset); \
307 /* now try to find the closest symbol that this rel is probably in */ \
308 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
309 func = NULL; \
310 offset_tmp = 0; \
311 while (sym_max--) { \
312 if (EGET(sym->st_value) < r_offset && EGET(sym->st_value) > offset_tmp) { \
313 func = sym; \
314 offset_tmp = EGET(sym->st_value); \
315 } \
316 ++sym; \
317 } \
318 printf(" in "); \
319 if (func && func->st_name) \
320 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(func->st_name))); \
321 else \
322 printf("(NULL: fake?)"); \
323 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
324 } \
325 } \
326 } }
327 SHOW_TEXTRELS(32)
328 SHOW_TEXTRELS(64)
329 }
330
331 return NULL;
222} 332}
223static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) 333static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len)
224{ 334{
225 unsigned long i, s; 335 unsigned long i, s;
226 char *rpath, *runpath, **r; 336 char *rpath, *runpath, **r;
442 symtab_void = elf_findsecbyname(elf, ".dynsym"); 552 symtab_void = elf_findsecbyname(elf, ".dynsym");
443 strtab_void = elf_findsecbyname(elf, ".dynstr"); 553 strtab_void = elf_findsecbyname(elf, ".dynstr");
444 } 554 }
445 555
446 if (symtab_void && strtab_void) { 556 if (symtab_void && strtab_void) {
447 char *base, *basemem;
448 basemem = xstrdup(elf->filename);
449 base = basename(basemem);
450#define FIND_SYM(B) \ 557#define FIND_SYM(B) \
451 if (elf->elf_class == ELFCLASS ## B) { \ 558 if (elf->elf_class == ELFCLASS ## B) { \
452 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 559 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
453 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 560 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
454 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ 561 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
458 if (sym->st_name) { \ 565 if (sym->st_name) { \
459 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ 566 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
460 if (*find_sym == '*') { \ 567 if (*find_sym == '*') { \
461 printf("%s(%s) %5lX %15s %s\n", \ 568 printf("%s(%s) %5lX %15s %s\n", \
462 ((*found_sym == 0) ? "\n\t" : "\t"), \ 569 ((*found_sym == 0) ? "\n\t" : "\t"), \
463 base, \ 570 elf->base_filename, \
464 (long)sym->st_size, \ 571 (long)sym->st_size, \
465 (char *)get_elfstttype(sym->st_info), \ 572 (char *)get_elfstttype(sym->st_info), \
466 symname); \ 573 symname); \
467 *found_sym = 1; \ 574 *found_sym = 1; \
468 } else if ((strcmp(find_sym, symname) == 0) || \ 575 } else if ((strcmp(find_sym, symname) == 0) || \
471 } \ 578 } \
472 ++sym; \ 579 ++sym; \
473 } } 580 } }
474 FIND_SYM(32) 581 FIND_SYM(32)
475 FIND_SYM(64) 582 FIND_SYM(64)
476 free(basemem);
477 } 583 }
478 584
479 if (be_wewy_wewy_quiet) return NULL; 585 if (be_wewy_wewy_quiet) return NULL;
480 586
481 if (*find_sym != '*' && *found_sym) 587 if (*find_sym != '*' && *found_sym)
490static void scanelf_file(const char *filename) 596static void scanelf_file(const char *filename)
491{ 597{
492 unsigned long i; 598 unsigned long i;
493 char found_pax, found_phdr, found_relro, found_load, found_textrel, 599 char found_pax, found_phdr, found_relro, found_load, found_textrel,
494 found_rpath, found_needed, found_interp, found_bind, 600 found_rpath, found_needed, found_interp, found_bind,
495 found_sym, found_lib, found_file; 601 found_sym, found_lib, found_file, found_textrels;
496 elfobj *elf; 602 elfobj *elf;
497 struct stat st; 603 struct stat st;
498 static char *out_buffer = NULL; 604 static char *out_buffer = NULL;
499 static size_t out_len; 605 static size_t out_len;
500 606
511 if (!S_ISREG(st.st_mode)) { 617 if (!S_ISREG(st.st_mode)) {
512 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 618 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
513 return; 619 return;
514 } 620 }
515 621
516 found_pax = found_phdr = found_relro = found_load = \ 622 found_pax = found_phdr = found_relro = found_load = found_textrel = \
517 found_textrel = found_rpath = found_needed = found_interp = \ 623 found_rpath = found_needed = found_interp = found_bind = \
518 found_bind = found_sym = found_lib = found_file = 0; 624 found_sym = found_lib = found_file = found_textrels = 0;
519 625
520 /* verify this is real ELF */ 626 /* verify this is real ELF */
521 if ((elf = readelf(filename)) == NULL) { 627 if ((elf = readelf(filename)) == NULL) {
522 if (be_verbose > 2) printf("%s: not an ELF\n", filename); 628 if (be_verbose > 2) printf("%s: not an ELF\n", filename);
523 return; 629 return;
556 case 'n': prints("NEEDED "); break; 662 case 'n': prints("NEEDED "); break;
557 case 'i': prints("INTERP "); break; 663 case 'i': prints("INTERP "); break;
558 case 'b': prints("BIND "); break; 664 case 'b': prints("BIND "); break;
559 case 's': prints("SYM "); break; 665 case 's': prints("SYM "); break;
560 case 'N': prints("LIB "); break; 666 case 'N': prints("LIB "); break;
667 case 'T': prints("TEXTRELS "); break;
668 default: warnf("'%c' has no title ?", out_format[i]);
561 } 669 }
562 } 670 }
563 if (!found_file) prints("FILE "); 671 if (!found_file) prints("FILE ");
564 prints("\n"); 672 prints("\n");
565 found_file = 0; 673 found_file = 0;
585 switch (out_format[++i]) { 693 switch (out_format[++i]) {
586 case '%': 694 case '%':
587 case '#': 695 case '#':
588 xchrcat(&out_buffer, out_format[i], &out_len); break; 696 xchrcat(&out_buffer, out_format[i], &out_len); break;
589 case 'F': 697 case 'F':
698 found_file = 1;
590 if (be_wewy_wewy_quiet) break; 699 if (be_wewy_wewy_quiet) break;
591 found_file = 1;
592 xstrcat(&out_buffer, filename, &out_len); 700 xstrcat(&out_buffer, filename, &out_len);
593 break; 701 break;
594 case 'p': 702 case 'p':
703 found_file = 1;
595 if (be_wewy_wewy_quiet) break; 704 if (be_wewy_wewy_quiet) break;
596 found_file = 1;
597 tmp = filename; 705 tmp = filename;
598 if (search_path) { 706 if (search_path) {
599 ssize_t len_search = strlen(search_path); 707 ssize_t len_search = strlen(search_path);
600 ssize_t len_file = strlen(filename); 708 ssize_t len_file = strlen(filename);
601 if (!strncmp(filename, search_path, len_search) && \ 709 if (!strncmp(filename, search_path, len_search) && \
604 if (*tmp == '/' && search_path[len_search-1] == '/') tmp++; 712 if (*tmp == '/' && search_path[len_search-1] == '/') tmp++;
605 } 713 }
606 xstrcat(&out_buffer, tmp, &out_len); 714 xstrcat(&out_buffer, tmp, &out_len);
607 break; 715 break;
608 case 'f': 716 case 'f':
717 found_file = 1;
609 if (be_wewy_wewy_quiet) break; 718 if (be_wewy_wewy_quiet) break;
610 found_file = 1;
611 tmp = strrchr(filename, '/'); 719 tmp = strrchr(filename, '/');
612 tmp = (tmp == NULL ? filename : tmp+1); 720 tmp = (tmp == NULL ? filename : tmp+1);
613 xstrcat(&out_buffer, tmp, &out_len); 721 xstrcat(&out_buffer, tmp, &out_len);
614 break; 722 break;
615 case 'o': out = get_elfetype(elf); break; 723 case 'o': out = get_elfetype(elf); break;
616 case 'x': out = scanelf_file_pax(elf, &found_pax); break; 724 case 'x': out = scanelf_file_pax(elf, &found_pax); break;
617 case 'e': out = scanelf_file_phdr(elf, &found_phdr, &found_relro, &found_load); break; 725 case 'e': out = scanelf_file_phdr(elf, &found_phdr, &found_relro, &found_load); break;
618 case 't': out = scanelf_file_textrel(elf, &found_textrel); break; 726 case 't': out = scanelf_file_textrel(elf, &found_textrel); break;
727 case 'T': out = scanelf_file_textrels(elf, &found_textrels); break;
619 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break; 728 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break;
620 case 'n': 729 case 'n':
621 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break; 730 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break;
622 case 'i': out = scanelf_file_interp(elf, &found_interp); break; 731 case 'i': out = scanelf_file_interp(elf, &found_interp); break;
623 case 'b': out = scanelf_file_bind(elf, &found_bind); break; 732 case 'b': out = scanelf_file_bind(elf, &found_bind); break;
624 case 's': out = scanelf_file_sym(elf, &found_sym); break; 733 case 's': out = scanelf_file_sym(elf, &found_sym); break;
734 default: warnf("'%c' has no scan code?", out_format[i]);
625 } 735 }
626 if (out) xstrcat(&out_buffer, out, &out_len); 736 if (out) xstrcat(&out_buffer, out, &out_len);
627 } 737 }
628 738
629#define FOUND_SOMETHING() \ 739#define FOUND_SOMETHING() \
630 (found_pax || found_phdr || found_relro || found_load || found_textrel || \ 740 (found_pax || found_phdr || found_relro || found_load || found_textrel || \
631 found_rpath || found_needed || found_interp || found_bind || found_sym || found_lib) 741 found_rpath || found_needed || found_interp || found_bind || \
742 found_sym || found_lib || found_textrels)
632 743
633 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) { 744 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) {
634 xchrcat(&out_buffer, ' ', &out_len); 745 xchrcat(&out_buffer, ' ', &out_len);
635 xstrcat(&out_buffer, filename, &out_len); 746 xstrcat(&out_buffer, filename, &out_len);
636 } 747 }
672 while ((dentry = readdir(dir))) { 783 while ((dentry = readdir(dir))) {
673 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) 784 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
674 continue; 785 continue;
675 len = (pathlen + 1 + strlen(dentry->d_name) + 1); 786 len = (pathlen + 1 + strlen(dentry->d_name) + 1);
676 if (len >= sizeof(buf)) { 787 if (len >= sizeof(buf)) {
677 warnf("Skipping '%s': len > sizeof(buf); %lu > %lu\n", path, len, sizeof(buf)); 788 warnf("Skipping '%s': len > sizeof(buf); %lu > %lu\n", path,
789 (unsigned long)len, (unsigned long)sizeof(buf));
678 continue; 790 continue;
679 } 791 }
680 sprintf(buf, "%s/%s", path, dentry->d_name); 792 sprintf(buf, "%s/%s", path, dentry->d_name);
681 if (lstat(buf, &st) != -1) { 793 if (lstat(buf, &st) != -1) {
682 if (S_ISREG(st.st_mode)) 794 if (S_ISREG(st.st_mode))
784} 896}
785 897
786 898
787 899
788/* usage / invocation handling functions */ 900/* usage / invocation handling functions */
789#define PARSE_FLAGS "plRmyxetrnibs:N:aqvF:f:o:BhV" 901#define PARSE_FLAGS "plRmyxetrnibs:N:TaqvF:f:o:BhV"
790#define a_argument required_argument 902#define a_argument required_argument
791static struct option const long_opts[] = { 903static struct option const long_opts[] = {
792 {"path", no_argument, NULL, 'p'}, 904 {"path", no_argument, NULL, 'p'},
793 {"ldpath", no_argument, NULL, 'l'}, 905 {"ldpath", no_argument, NULL, 'l'},
794 {"recursive", no_argument, NULL, 'R'}, 906 {"recursive", no_argument, NULL, 'R'},
799 {"textrel", no_argument, NULL, 't'}, 911 {"textrel", no_argument, NULL, 't'},
800 {"rpath", no_argument, NULL, 'r'}, 912 {"rpath", no_argument, NULL, 'r'},
801 {"needed", no_argument, NULL, 'n'}, 913 {"needed", no_argument, NULL, 'n'},
802 {"interp", no_argument, NULL, 'i'}, 914 {"interp", no_argument, NULL, 'i'},
803 {"bind", no_argument, NULL, 'b'}, 915 {"bind", no_argument, NULL, 'b'},
804 {"symbol", a_argument, NULL, 's'}, 916 {"symbol", a_argument, NULL, 's'},
805 {"lib", a_argument, NULL, 'N'}, 917 {"lib", a_argument, NULL, 'N'},
918 {"textrels", no_argument, NULL, 'T'},
806 {"all", no_argument, NULL, 'a'}, 919 {"all", no_argument, NULL, 'a'},
807 {"quiet", no_argument, NULL, 'q'}, 920 {"quiet", no_argument, NULL, 'q'},
808 {"verbose", no_argument, NULL, 'v'}, 921 {"verbose", no_argument, NULL, 'v'},
809 {"format", a_argument, NULL, 'F'}, 922 {"format", a_argument, NULL, 'F'},
810 {"from", a_argument, NULL, 'f'}, 923 {"from", a_argument, NULL, 'f'},
811 {"file", a_argument, NULL, 'o'}, 924 {"file", a_argument, NULL, 'o'},
812 {"nobanner", no_argument, NULL, 'B'}, 925 {"nobanner", no_argument, NULL, 'B'},
813 {"help", no_argument, NULL, 'h'}, 926 {"help", no_argument, NULL, 'h'},
814 {"version", no_argument, NULL, 'V'}, 927 {"version", no_argument, NULL, 'V'},
815 {NULL, no_argument, NULL, 0x0} 928 {NULL, no_argument, NULL, 0x0}
816}; 929};
828 "Print NEEDED information", 941 "Print NEEDED information",
829 "Print INTERP information", 942 "Print INTERP information",
830 "Print BIND information", 943 "Print BIND information",
831 "Find a specified symbol", 944 "Find a specified symbol",
832 "Find a specified library", 945 "Find a specified library",
946 "Locate cause of TEXTREL",
833 "Print all scanned info (-x -e -t -r -n -i -b)\n", 947 "Print all scanned info (-x -e -t -r -n -i -b)\n",
834 "Only output 'bad' things", 948 "Only output 'bad' things",
835 "Be verbose (can be specified more than once)", 949 "Be verbose (can be specified more than once)",
836 "Use specified format for output", 950 "Use specified format for output",
837 "Read input stream from a filename", 951 "Read input stream from a filename",
862 976
863 puts("\nThe format modifiers for the -F option are:"); 977 puts("\nThe format modifiers for the -F option are:");
864 puts(" F Filename \tx PaX Flags \te STACK/RELRO"); 978 puts(" F Filename \tx PaX Flags \te STACK/RELRO");
865 puts(" t TEXTREL \tr RPATH \tn NEEDED"); 979 puts(" t TEXTREL \tr RPATH \tn NEEDED");
866 puts(" i INTERP \tb BIND \ts symbol"); 980 puts(" i INTERP \tb BIND \ts symbol");
867 puts(" N library \to Type"); 981 puts(" N library \to Type \tT TEXTRELs");
868 puts(" p filename (with search path removed)"); 982 puts(" p filename (with search path removed)");
869 puts(" f base filename"); 983 puts(" f base filename");
870 puts("Prefix each modifier with '%' (verbose) or '#' (silent)"); 984 puts("Prefix each modifier with '%' (verbose) or '#' (silent)");
871 985
872 exit(status); 986 exit(status);
933 case 't': show_textrel = 1; break; 1047 case 't': show_textrel = 1; break;
934 case 'r': show_rpath = 1; break; 1048 case 'r': show_rpath = 1; break;
935 case 'n': show_needed = 1; break; 1049 case 'n': show_needed = 1; break;
936 case 'i': show_interp = 1; break; 1050 case 'i': show_interp = 1; break;
937 case 'b': show_bind = 1; break; 1051 case 'b': show_bind = 1; break;
1052 case 'T': show_textrels = 1; break;
938 case 'q': be_quiet = 1; break; 1053 case 'q': be_quiet = 1; break;
939 case 'v': be_verbose = (be_verbose % 20) + 1; break; 1054 case 'v': be_verbose = (be_verbose % 20) + 1; break;
940 case 'a': show_pax = show_phdr = show_textrel = show_rpath = \ 1055 case 'a': show_pax = show_phdr = show_textrel = show_rpath = \
941 show_needed = show_interp = show_bind = 1; break; 1056 show_needed = show_interp = show_bind = 1; break;
942 1057
950 } 1065 }
951 1066
952 /* let the format option override all other options */ 1067 /* let the format option override all other options */
953 if (out_format) { 1068 if (out_format) {
954 show_pax = show_phdr = show_textrel = show_rpath = \ 1069 show_pax = show_phdr = show_textrel = show_rpath = \
955 show_needed = show_interp = show_bind = 0; 1070 show_needed = show_interp = show_bind = show_textrels = 0;
956 for (i = 0; out_format[i]; ++i) { 1071 for (i = 0; out_format[i]; ++i) {
957 if (!IS_MODIFIER(out_format[i])) continue; 1072 if (!IS_MODIFIER(out_format[i])) continue;
958 1073
959 switch (out_format[++i]) { 1074 switch (out_format[++i]) {
960 case '%': break; 1075 case '%': break;
970 case 't': show_textrel = 1; break; 1085 case 't': show_textrel = 1; break;
971 case 'r': show_rpath = 1; break; 1086 case 'r': show_rpath = 1; break;
972 case 'n': show_needed = 1; break; 1087 case 'n': show_needed = 1; break;
973 case 'i': show_interp = 1; break; 1088 case 'i': show_interp = 1; break;
974 case 'b': show_bind = 1; break; 1089 case 'b': show_bind = 1; break;
1090 case 'T': show_textrels = 1; break;
975 default: 1091 default:
976 err("Invalid format specifier '%c' (byte %i)", 1092 err("Invalid format specifier '%c' (byte %i)",
977 out_format[i], i+1); 1093 out_format[i], i+1);
978 } 1094 }
979 } 1095 }
980 1096
981 /* construct our default format */ 1097 /* construct our default format */
982 } else { 1098 } else {
983 size_t fmt_len = 30; 1099 size_t fmt_len = 30;
984 out_format = (char*)xmalloc(sizeof(char) * fmt_len); 1100 out_format = (char*)xmalloc(sizeof(char) * fmt_len);
985 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); 1101 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len);
986 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); 1102 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len);
987 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len); 1103 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len);
988 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len); 1104 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len);
989 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); 1105 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len);
990 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); 1106 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len);
991 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); 1107 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);
992 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len); 1108 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len);
1109 if (show_textrels) xstrcat(&out_format, "%T ", &fmt_len);
993 if (find_sym) xstrcat(&out_format, "%s ", &fmt_len); 1110 if (find_sym) xstrcat(&out_format, "%s ", &fmt_len);
994 if (find_lib) xstrcat(&out_format, "%N ", &fmt_len); 1111 if (find_lib) xstrcat(&out_format, "%N ", &fmt_len);
995 if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len); 1112 if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len);
996 } 1113 }
997 if (be_verbose > 2) printf("Format: %s\n", out_format); 1114 if (be_verbose > 2) printf("Format: %s\n", out_format);
998 1115
999 /* now lets actually do the scanning */ 1116 /* now lets actually do the scanning */
1000 if (scan_ldpath || (show_rpath && be_quiet)) 1117 if (scan_ldpath || (show_rpath && be_quiet))

Legend:
Removed from v.1.75  
changed lines
  Added in v.1.76

  ViewVC Help
Powered by ViewVC 1.1.20