/[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.188 Revision 1.203
1/* 1/*
2 * Copyright 2003-2007 Gentoo Foundation 2 * Copyright 2003-2007 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/Attic/scanelf.c,v 1.188 2007/08/31 17:45:24 solar Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.203 2008/12/30 12:39:53 vapier Exp $
5 * 5 *
6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
10static const char *rcsid = "$Id: scanelf.c,v 1.188 2007/08/31 17:45:24 solar Exp $"; 10static const char *rcsid = "$Id: scanelf.c,v 1.203 2008/12/30 12:39:53 vapier Exp $";
11const char * const argv0 = "scanelf"; 11const char * const argv0 = "scanelf";
12 12
13#include "paxinc.h" 13#include "paxinc.h"
14 14
15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+') 15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+')
38static char scan_archives = 0; 38static char scan_archives = 0;
39static char dir_recurse = 0; 39static char dir_recurse = 0;
40static char dir_crossmount = 1; 40static char dir_crossmount = 1;
41static char show_pax = 0; 41static char show_pax = 0;
42static char show_perms = 0; 42static char show_perms = 0;
43static char show_size = 0;
43static char show_phdr = 0; 44static char show_phdr = 0;
44static char show_textrel = 0; 45static char show_textrel = 0;
45static char show_rpath = 0; 46static char show_rpath = 0;
46static char show_needed = 0; 47static char show_needed = 0;
47static char show_interp = 0; 48static char show_interp = 0;
48static char show_bind = 0; 49static char show_bind = 0;
49static char show_soname = 0; 50static char show_soname = 0;
50static char show_textrels = 0; 51static char show_textrels = 0;
51static char show_banner = 1; 52static char show_banner = 1;
52static char show_endian = 0; 53static char show_endian = 0;
54static char show_osabi = 0;
55static char show_eabi = 0;
53static char be_quiet = 0; 56static char be_quiet = 0;
54static char be_verbose = 0; 57static char be_verbose = 0;
55static char be_wewy_wewy_quiet = 0; 58static char be_wewy_wewy_quiet = 0;
56static char be_semi_verbose = 0; 59static char be_semi_verbose = 0;
57static char *find_sym = NULL, *versioned_symname = NULL; 60static char *find_sym = NULL;
58static char *find_lib = NULL; 61static char *find_lib = NULL;
59static char *find_section = NULL; 62static char *find_section = NULL;
60static char *out_format = NULL; 63static char *out_format = NULL;
61static char *search_path = NULL; 64static char *search_path = NULL;
62static char fix_elf = 0; 65static char fix_elf = 0;
65 68
66static char **qa_textrels = NULL; 69static char **qa_textrels = NULL;
67static char **qa_execstack = NULL; 70static char **qa_execstack = NULL;
68static char **qa_wx_load = NULL; 71static char **qa_wx_load = NULL;
69 72
70int match_bits = 0; 73static int match_bits = 0;
71unsigned int match_perms = 0; 74static unsigned int match_perms = 0;
72caddr_t ldcache = 0; 75static caddr_t ldcache = 0;
73size_t ldcache_size = 0; 76static size_t ldcache_size = 0;
74unsigned long setpax = 0UL; 77static unsigned long setpax = 0UL;
75 78
76int has_objdump = 0; 79static int has_objdump = 0;
77 80
78static char *getstr_perms(const char *fname); 81static char *getstr_perms(const char *fname);
79static char *getstr_perms(const char *fname) 82static char *getstr_perms(const char *fname)
80{ 83{
81 struct stat st; 84 struct stat st;
118 regex_t preg; 121 regex_t preg;
119 int ret; 122 int ret;
120 123
121 if ((match == NULL) || (regex == NULL)) 124 if ((match == NULL) || (regex == NULL))
122 return EXIT_FAILURE; 125 return EXIT_FAILURE;
123
124 126
125 if ((ret = regcomp(&preg, regex, cflags))) { 127 if ((ret = regcomp(&preg, regex, cflags))) {
126 char err[256]; 128 char err[256];
127 129
128 if (regerror(ret, &preg, err, sizeof(err))) 130 if (regerror(ret, &preg, err, sizeof(err)))
197 } \ 199 } \
198 } 200 }
199 SHOW_PAX(32) 201 SHOW_PAX(32)
200 SHOW_PAX(64) 202 SHOW_PAX(64)
201 } 203 }
202
203 204
204 if (fix_elf && setpax) { 205 if (fix_elf && setpax) {
205 /* set the chpax settings */ 206 /* set the chpax settings */
206 if (elf->elf_class == ELFCLASS32) { 207 if (elf->elf_class == ELFCLASS32) {
207 if (EHDR32(elf->ehdr)->e_type == ET_DYN || EHDR32(elf->ehdr)->e_type == ET_EXEC) 208 if (EHDR32(elf->ehdr)->e_type == ET_DYN || EHDR32(elf->ehdr)->e_type == ET_EXEC)
737 ldcache_size = st.st_size; 738 ldcache_size = st.st_size;
738 ldcache = mmap(0, ldcache_size, PROT_READ, MAP_SHARED, fd, 0); 739 ldcache = mmap(0, ldcache_size, PROT_READ, MAP_SHARED, fd, 0);
739 740
740 close(fd); 741 close(fd);
741 742
742 if (ldcache == (caddr_t)-1) { 743 if (ldcache == MAP_FAILED) {
743 ldcache = 0; 744 ldcache = 0;
744 return NULL; 745 return NULL;
745 } 746 }
746 747
747 if (memcmp(((header_t *) ldcache)->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)) 748 if (memcmp(((header_t *) ldcache)->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN))
793 794
794 /* not found in any path */ 795 /* not found in any path */
795 return NULL; 796 return NULL;
796} 797}
797#else 798#else
799#ifdef __ELF__
798#warning Cache support not implemented for your target 800#warning Cache support not implemented for your target
801#endif
799static char *lookup_cache_lib(elfobj *elf, char *fname) 802static char *lookup_cache_lib(elfobj *elf, char *fname)
800{ 803{
801 return NULL; 804 return NULL;
802} 805}
803#endif 806#endif
972 } 975 }
973 976
974 return NULL; 977 return NULL;
975} 978}
976 979
980static int scanelf_match_symname(const char *symname, const char *tomatch) {
981 /* We do things differently when checking with regexp */
982 if (g_match) {
983 return rematch(symname, tomatch, REG_EXTENDED) == 0;
984 } else {
985 const size_t symname_len = strlen(symname);
986 return (strncmp(symname, tomatch, symname_len) == 0 &&
987 /* Accept unversioned symbol names */
988 (tomatch[symname_len] == '\0' || tomatch[symname_len] == '@'));
989 }
990}
991
977static char *scanelf_file_sym(elfobj *elf, char *found_sym) 992static char *scanelf_file_sym(elfobj *elf, char *found_sym)
978{ 993{
979 unsigned long i; 994 unsigned long i;
980 char *ret; 995 char *ret;
981 void *symtab_void, *strtab_void; 996 void *symtab_void, *strtab_void;
994 unsigned long cnt = EGET(symtab->sh_entsize); \ 1009 unsigned long cnt = EGET(symtab->sh_entsize); \
995 char *symname; \ 1010 char *symname; \
996 if (cnt) \ 1011 if (cnt) \
997 cnt = EGET(symtab->sh_size) / cnt; \ 1012 cnt = EGET(symtab->sh_size) / cnt; \
998 for (i = 0; i < cnt; ++i) { \ 1013 for (i = 0; i < cnt; ++i) { \
1014 if ((void*)sym > (void*)elf->data_end) { \
1015 warnf("%s: corrupt ELF symbols - aborting", elf->filename); \
1016 goto break_out; \
1017 } \
999 if (sym->st_name) { \ 1018 if (sym->st_name) { \
1000 /* make sure the symbol name is in acceptable memory range */ \ 1019 /* make sure the symbol name is in acceptable memory range */ \
1001 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ 1020 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
1002 if ((void*)symname > (void*)elf->data_end) { \ 1021 if ((void*)symname > (void*)elf->data_end) { \
1003 warnf("%s: corrupt ELF symbols", elf->filename); \ 1022 warnf("%s: corrupt ELF symbols", elf->filename); \
1004 ++sym; \ 1023 ++sym; \
1005 continue; \ 1024 continue; \
1006 } \ 1025 } \
1007 /* debug display ... show all symbols and some extra info */ \ 1026 /* debug display ... show all symbols and some extra info */ \
1008 if (g_match ? rematch(ret, symname, REG_EXTENDED) == 0 : *ret == '*') { \ 1027 if (0 && g_match ? rematch(ret, symname, REG_EXTENDED) == 0 : *ret == '*') { \
1009 printf("%s(%s) %5lX %15s %s %s\n", \ 1028 printf("%s(%s) %5lX %15s %s %s\n", \
1010 ((*found_sym == 0) ? "\n\t" : "\t"), \ 1029 ((*found_sym == 0) ? "\n\t" : "\t"), \
1011 elf->base_filename, \ 1030 elf->base_filename, \
1012 (unsigned long)sym->st_size, \ 1031 (unsigned long)sym->st_size, \
1013 get_elfstttype(sym->st_info), \ 1032 get_elfstttype(sym->st_info), \
1014 sym->st_shndx == SHN_UNDEF ? "U" : "D", symname); \ 1033 sym->st_shndx == SHN_UNDEF ? "U" : "D", symname); \
1015 *found_sym = 1; \ 1034 *found_sym = 1; \
1016 } else { \ 1035 } else { \
1017 /* allow the user to specify a comma delimited list of symbols to search for */ \ 1036 /* allow the user to specify a comma delimited list of symbols to search for */ \
1018 char *this_sym, *this_sym_ver, *next_sym; \ 1037 char *this_sym, *next_sym; \
1019 this_sym = ret; \ 1038 next_sym = ret; \
1020 this_sym_ver = versioned_symname; \ 1039 while (next_sym) { \
1021 do { \ 1040 this_sym = next_sym; \
1022 next_sym = strchr(this_sym, ','); \ 1041 if ((next_sym = strchr(this_sym, ','))) \
1023 if (next_sym == NULL) \ 1042 next_sym += 1; /* Skip the comma */ \
1024 next_sym = this_sym + strlen(this_sym); \
1025 /* do we want a defined symbol ? */ \ 1043 /* do we want a defined symbol ? */ \
1026 if (*this_sym == '+') { \ 1044 if (*this_sym == '+') { \
1027 if (sym->st_shndx == SHN_UNDEF) \ 1045 if (sym->st_shndx == SHN_UNDEF) \
1028 goto skip_this_sym##B; \ 1046 continue; \
1029 ++this_sym; \ 1047 ++this_sym; \
1030 ++this_sym_ver; \
1031 /* do we want an undefined symbol ? */ \ 1048 /* do we want an undefined symbol ? */ \
1032 } else if (*this_sym == '-') { \ 1049 } else if (*this_sym == '-') { \
1033 if (sym->st_shndx != SHN_UNDEF) \ 1050 if (sym->st_shndx != SHN_UNDEF) \
1034 goto skip_this_sym##B; \ 1051 continue; \
1035 ++this_sym; \ 1052 ++this_sym; \
1036 ++this_sym_ver; \
1037 } \ 1053 } \
1054 if (next_sym) /* Copy it so that we don't have to worry about the final , */ \
1055 this_sym = strndup(this_sym, next_sym-this_sym); \
1038 /* ok, lets compare the name now */ \ 1056 /* ok, lets compare the name now */ \
1039 if ((strncmp(this_sym, symname, (next_sym-this_sym)) == 0 && symname[next_sym-this_sym] == '\0') || \ 1057 if (scanelf_match_symname(this_sym, symname)) { \
1040 (strncmp(this_sym_ver, symname, strlen(this_sym_ver)) == 0)) { \
1041 if (be_semi_verbose) { \ 1058 if (be_semi_verbose) { \
1042 char buf[126]; \ 1059 char buf[126]; \
1043 snprintf(buf, sizeof(buf), "%lX %s %s", \ 1060 snprintf(buf, sizeof(buf), "%lX %s %s", \
1044 (unsigned long)sym->st_size, get_elfstttype(sym->st_info), this_sym); \ 1061 (unsigned long)sym->st_size, get_elfstttype(sym->st_info), this_sym); \
1045 ret = buf; \ 1062 ret = buf; \
1046 } else \ 1063 } else \
1047 ret = this_sym; \ 1064 ret = symname; \
1048 (*found_sym)++; \ 1065 (*found_sym)++; \
1049 goto break_out; \ 1066 goto break_out; \
1050 } \ 1067 } \
1051 skip_this_sym##B: this_sym = next_sym + 1; \ 1068 if (next_sym) free(this_sym); \
1052 } while (*next_sym != '\0'); \ 1069 } \
1053 } \ 1070 } \
1054 } \ 1071 } \
1055 ++sym; \ 1072 ++sym; \
1056 } } 1073 } }
1057 FIND_SYM(32) 1074 FIND_SYM(32)
1066 if (be_quiet) 1083 if (be_quiet)
1067 return NULL; 1084 return NULL;
1068 else 1085 else
1069 return (char *)" - "; 1086 return (char *)" - ";
1070} 1087}
1071
1072 1088
1073static char *scanelf_file_sections(elfobj *elf, char *found_section) 1089static char *scanelf_file_sections(elfobj *elf, char *found_section)
1074{ 1090{
1075 if (!find_section) 1091 if (!find_section)
1076 return NULL; 1092 return NULL;
1147 case 'r': prints("RPATH "); break; 1163 case 'r': prints("RPATH "); break;
1148 case 'M': prints("CLASS "); break; 1164 case 'M': prints("CLASS "); break;
1149 case 'n': prints("NEEDED "); break; 1165 case 'n': prints("NEEDED "); break;
1150 case 'i': prints("INTERP "); break; 1166 case 'i': prints("INTERP "); break;
1151 case 'b': prints("BIND "); break; 1167 case 'b': prints("BIND "); break;
1168 case 'Z': prints("SIZE "); break;
1152 case 'S': prints("SONAME "); break; 1169 case 'S': prints("SONAME "); break;
1153 case 's': prints("SYM "); break; 1170 case 's': prints("SYM "); break;
1154 case 'N': prints("LIB "); break; 1171 case 'N': prints("LIB "); break;
1155 case 'T': prints("TEXTRELS "); break; 1172 case 'T': prints("TEXTRELS "); break;
1156 case 'k': prints("SECTION "); break; 1173 case 'k': prints("SECTION "); break;
1157 case 'a': prints("ARCH "); break; 1174 case 'a': prints("ARCH "); break;
1175 case 'I': prints("OSABI "); break;
1176 case 'Y': prints("EABI "); break;
1158 case 'O': prints("PERM "); break; 1177 case 'O': prints("PERM "); break;
1159 case 'D': prints("ENDIAN "); break; 1178 case 'D': prints("ENDIAN "); break;
1160 default: warnf("'%c' has no title ?", out_format[i]); 1179 default: warnf("'%c' has no title ?", out_format[i]);
1161 } 1180 }
1162 } 1181 }
1168 1187
1169 /* dump all the good stuff */ 1188 /* dump all the good stuff */
1170 for (i = 0; out_format[i]; ++i) { 1189 for (i = 0; out_format[i]; ++i) {
1171 const char *out; 1190 const char *out;
1172 const char *tmp; 1191 const char *tmp;
1173 1192 static char ubuf[sizeof(unsigned long)*2];
1174 if (!IS_MODIFIER(out_format[i])) { 1193 if (!IS_MODIFIER(out_format[i])) {
1175 xchrcat(&out_buffer, out_format[i], &out_len); 1194 xchrcat(&out_buffer, out_format[i], &out_len);
1176 continue; 1195 continue;
1177 } 1196 }
1178 1197
1225 case 'b': out = scanelf_file_bind(elf, &found_bind); break; 1244 case 'b': out = scanelf_file_bind(elf, &found_bind); break;
1226 case 'S': out = scanelf_file_soname(elf, &found_soname); break; 1245 case 'S': out = scanelf_file_soname(elf, &found_soname); break;
1227 case 's': out = scanelf_file_sym(elf, &found_sym); break; 1246 case 's': out = scanelf_file_sym(elf, &found_sym); break;
1228 case 'k': out = scanelf_file_sections(elf, &found_section); break; 1247 case 'k': out = scanelf_file_sections(elf, &found_section); break;
1229 case 'a': out = get_elfemtype(elf); break; 1248 case 'a': out = get_elfemtype(elf); break;
1249 case 'I': out = get_elfosabi(elf); break;
1250 case 'Y': out = get_elf_eabi(elf); break;
1251 case 'Z': snprintf(ubuf, sizeof(ubuf), "%lu", (unsigned long)elf->len); out = ubuf; break;;
1230 default: warnf("'%c' has no scan code?", out_format[i]); 1252 default: warnf("'%c' has no scan code?", out_format[i]);
1231 } 1253 }
1232 if (out) { 1254 if (out) {
1233 /* hack for comma delimited output like `scanelf -s sym1,sym2,sym3` */ 1255 /* hack for comma delimited output like `scanelf -s sym1,sym2,sym3` */
1234 if (out_format[i] == 's' && (tmp=strchr(out,',')) != NULL) 1256 if (out_format[i] == 's' && (tmp=strchr(out,',')) != NULL)
1310 1332
1311 ar = ar_open_fd(filename, fd); 1333 ar = ar_open_fd(filename, fd);
1312 if (ar == NULL) 1334 if (ar == NULL)
1313 return 1; 1335 return 1;
1314 1336
1315 ar_buffer = (char*)mmap(0, len, PROT_READ | (fix_elf ? PROT_WRITE : 0), (fix_elf ? MAP_SHARED : MAP_PRIVATE), fd, 0); 1337 ar_buffer = mmap(0, len, PROT_READ | (fix_elf ? PROT_WRITE : 0), (fix_elf ? MAP_SHARED : MAP_PRIVATE), fd, 0);
1316 while ((m=ar_next(ar)) != NULL) { 1338 while ((m=ar_next(ar)) != NULL) {
1317 elf = readelf_buffer(m->name, ar_buffer+lseek(fd,0,SEEK_CUR), m->size); 1339 elf = readelf_buffer(m->name, ar_buffer+lseek(fd,0,SEEK_CUR), m->size);
1318 if (elf) { 1340 if (elf) {
1319 scanelf_elfobj(elf); 1341 scanelf_elfobj(elf);
1320 unreadelf(elf); 1342 unreadelf(elf);
1538 fclose(fp); 1560 fclose(fp);
1539 return i; 1561 return i;
1540} 1562}
1541 1563
1542#else 1564#else
1543 1565#ifdef __ELF__
1544#warning Cache config support not implemented for your target 1566#warning Cache config support not implemented for your target
1567#endif
1545static int load_ld_cache_config(int i, const char *fname) 1568static int load_ld_cache_config(int i, const char *fname)
1546{ 1569{
1547 memset(ldpaths, 0x00, sizeof(ldpaths)); 1570 memset(ldpaths, 0x00, sizeof(ldpaths));
1571 return 0;
1548} 1572}
1549
1550#endif 1573#endif
1551 1574
1552/* scan /etc/ld.so.conf for paths */ 1575/* scan /etc/ld.so.conf for paths */
1553static void scanelf_ldpath(void) 1576static void scanelf_ldpath(void)
1554{ 1577{
1589 } 1612 }
1590 1613
1591 free(path); 1614 free(path);
1592} 1615}
1593 1616
1594
1595/* usage / invocation handling functions */ /* Free Flags: c d j u w C G H I J K P Q U W Y Z */ 1617/* usage / invocation handling functions */ /* Free Flags: c d j u w C G H J K P Q U W */
1596#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DO:BhV" 1618#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DIYO:ZBhV"
1597#define a_argument required_argument 1619#define a_argument required_argument
1598static struct option const long_opts[] = { 1620static struct option const long_opts[] = {
1599 {"path", no_argument, NULL, 'p'}, 1621 {"path", no_argument, NULL, 'p'},
1600 {"ldpath", no_argument, NULL, 'l'}, 1622 {"ldpath", no_argument, NULL, 'l'},
1601 {"recursive", no_argument, NULL, 'R'}, 1623 {"recursive", no_argument, NULL, 'R'},
1619 {"gmatch", no_argument, NULL, 'g'}, 1641 {"gmatch", no_argument, NULL, 'g'},
1620 {"textrels", no_argument, NULL, 'T'}, 1642 {"textrels", no_argument, NULL, 'T'},
1621 {"etype", a_argument, NULL, 'E'}, 1643 {"etype", a_argument, NULL, 'E'},
1622 {"bits", a_argument, NULL, 'M'}, 1644 {"bits", a_argument, NULL, 'M'},
1623 {"endian", no_argument, NULL, 'D'}, 1645 {"endian", no_argument, NULL, 'D'},
1646 {"osabi", no_argument, NULL, 'I'},
1647 {"eabi", no_argument, NULL, 'Y'},
1624 {"perms", a_argument, NULL, 'O'}, 1648 {"perms", a_argument, NULL, 'O'},
1649 {"size", no_argument, NULL, 'Z'},
1625 {"all", no_argument, NULL, 'a'}, 1650 {"all", no_argument, NULL, 'a'},
1626 {"quiet", no_argument, NULL, 'q'}, 1651 {"quiet", no_argument, NULL, 'q'},
1627 {"verbose", no_argument, NULL, 'v'}, 1652 {"verbose", no_argument, NULL, 'v'},
1628 {"format", a_argument, NULL, 'F'}, 1653 {"format", a_argument, NULL, 'F'},
1629 {"from", a_argument, NULL, 'f'}, 1654 {"from", a_argument, NULL, 'f'},
1658 "Use strncmp to match libraries. (use with -N)", 1683 "Use strncmp to match libraries. (use with -N)",
1659 "Locate cause of TEXTREL", 1684 "Locate cause of TEXTREL",
1660 "Print only ELF files matching etype ET_DYN,ET_EXEC ...", 1685 "Print only ELF files matching etype ET_DYN,ET_EXEC ...",
1661 "Print only ELF files matching numeric bits", 1686 "Print only ELF files matching numeric bits",
1662 "Print Endianness", 1687 "Print Endianness",
1688 "Print OSABI",
1689 "Print EABI (EM_ARM Only)",
1663 "Print only ELF files matching octal permissions", 1690 "Print only ELF files matching octal permissions",
1691 "Print ELF file size",
1664 "Print all scanned info (-x -e -t -r -b)\n", 1692 "Print all scanned info (-x -e -t -r -b)\n",
1665 "Only output 'bad' things", 1693 "Only output 'bad' things",
1666 "Be verbose (can be specified more than once)", 1694 "Be verbose (can be specified more than once)",
1667 "Use specified format for output", 1695 "Use specified format for output",
1668 "Read input stream from a filename", 1696 "Read input stream from a filename",
1748 find_section = optarg; 1776 find_section = optarg;
1749 break; 1777 break;
1750 case 's': { 1778 case 's': {
1751 if (find_sym) warn("You prob don't want to specify -s twice"); 1779 if (find_sym) warn("You prob don't want to specify -s twice");
1752 find_sym = optarg; 1780 find_sym = optarg;
1753 versioned_symname = xmalloc(sizeof(char) * (strlen(find_sym)+1+1));
1754 sprintf(versioned_symname, "%s@", find_sym);
1755 break; 1781 break;
1756 } 1782 }
1757 case 'N': { 1783 case 'N': {
1758 if (find_lib) warn("You prob don't want to specify -N twice"); 1784 if (find_lib) warn("You prob don't want to specify -N twice");
1759 find_lib = optarg; 1785 find_lib = optarg;
1806 ((flags & PF_EMUTRAMP) && (flags & PF_NOEMUTRAMP)) || 1832 ((flags & PF_EMUTRAMP) && (flags & PF_NOEMUTRAMP)) ||
1807 ((flags & PF_RANDMMAP) && (flags & PF_NORANDMMAP)))) 1833 ((flags & PF_RANDMMAP) && (flags & PF_NORANDMMAP))))
1808 setpax = flags; 1834 setpax = flags;
1809 break; 1835 break;
1810 } 1836 }
1837 case 'Z': show_size = 1; break;
1811 case 'g': g_match = 1; break; 1838 case 'g': g_match = 1; break;
1812 case 'L': use_ldcache = 1; break; 1839 case 'L': use_ldcache = 1; break;
1813 case 'y': scan_symlink = 0; break; 1840 case 'y': scan_symlink = 0; break;
1814 case 'A': scan_archives = 1; break; 1841 case 'A': scan_archives = 1; break;
1815 case 'B': show_banner = 0; break; 1842 case 'B': show_banner = 0; break;
1829 case 'T': show_textrels = 1; break; 1856 case 'T': show_textrels = 1; break;
1830 case 'q': be_quiet = 1; break; 1857 case 'q': be_quiet = 1; break;
1831 case 'v': be_verbose = (be_verbose % 20) + 1; break; 1858 case 'v': be_verbose = (be_verbose % 20) + 1; break;
1832 case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = show_endian = 1; break; 1859 case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = show_endian = 1; break;
1833 case 'D': show_endian = 1; break; 1860 case 'D': show_endian = 1; break;
1861 case 'I': show_osabi = 1; break;
1862 case 'Y': show_eabi = 1; break;
1834 case ':': 1863 case ':':
1835 err("Option '%c' is missing parameter", optopt); 1864 err("Option '%c' is missing parameter", optopt);
1836 case '?': 1865 case '?':
1837 err("Unknown option '%c' or argument missing", optopt); 1866 err("Unknown option '%c' or argument missing", optopt);
1838 default: 1867 default:
1845 } 1874 }
1846 /* let the format option override all other options */ 1875 /* let the format option override all other options */
1847 if (out_format) { 1876 if (out_format) {
1848 show_pax = show_phdr = show_textrel = show_rpath = \ 1877 show_pax = show_phdr = show_textrel = show_rpath = \
1849 show_needed = show_interp = show_bind = show_soname = \ 1878 show_needed = show_interp = show_bind = show_soname = \
1850 show_textrels = show_perms = show_endian = 0; 1879 show_textrels = show_perms = show_endian = show_size = \
1880 show_osabi = show_eabi = 0;
1851 for (i = 0; out_format[i]; ++i) { 1881 for (i = 0; out_format[i]; ++i) {
1852 if (!IS_MODIFIER(out_format[i])) continue; 1882 if (!IS_MODIFIER(out_format[i])) continue;
1853 1883
1854 switch (out_format[++i]) { 1884 switch (out_format[++i]) {
1855 case '+': break; 1885 case '+': break;
1862 case 's': break; 1892 case 's': break;
1863 case 'N': break; 1893 case 'N': break;
1864 case 'o': break; 1894 case 'o': break;
1865 case 'a': break; 1895 case 'a': break;
1866 case 'M': break; 1896 case 'M': break;
1897 case 'Z': show_size = 1; break;
1867 case 'D': show_endian = 1; break; 1898 case 'D': show_endian = 1; break;
1899 case 'I': show_osabi = 1; break;
1900 case 'Y': show_eabi = 1; break;
1868 case 'O': show_perms = 1; break; 1901 case 'O': show_perms = 1; break;
1869 case 'x': show_pax = 1; break; 1902 case 'x': show_pax = 1; break;
1870 case 'e': show_phdr = 1; break; 1903 case 'e': show_phdr = 1; break;
1871 case 't': show_textrel = 1; break; 1904 case 't': show_textrel = 1; break;
1872 case 'r': show_rpath = 1; break; 1905 case 'r': show_rpath = 1; break;
1883 1916
1884 /* construct our default format */ 1917 /* construct our default format */
1885 } else { 1918 } else {
1886 size_t fmt_len = 30; 1919 size_t fmt_len = 30;
1887 out_format = xmalloc(sizeof(char) * fmt_len); 1920 out_format = xmalloc(sizeof(char) * fmt_len);
1921 *out_format = '\0';
1888 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); 1922 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len);
1889 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); 1923 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len);
1890 if (show_perms) xstrcat(&out_format, "%O ", &fmt_len); 1924 if (show_perms) xstrcat(&out_format, "%O ", &fmt_len);
1925 if (show_size) xstrcat(&out_format, "%Z ", &fmt_len);
1891 if (show_endian) xstrcat(&out_format, "%D ", &fmt_len); 1926 if (show_endian) xstrcat(&out_format, "%D ", &fmt_len);
1927 if (show_osabi) xstrcat(&out_format, "%I ", &fmt_len);
1928 if (show_eabi) xstrcat(&out_format, "%Y ", &fmt_len);
1892 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len); 1929 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len);
1893 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len); 1930 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len);
1894 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); 1931 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len);
1895 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); 1932 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len);
1896 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); 1933 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);
1921 search_path = argv[optind++]; 1958 search_path = argv[optind++];
1922 ret = scanelf_dir(search_path); 1959 ret = scanelf_dir(search_path);
1923 } 1960 }
1924 1961
1925 /* clean up */ 1962 /* clean up */
1926 free(versioned_symname);
1927 for (i = 0; ldpaths[i]; ++i) 1963 for (i = 0; ldpaths[i]; ++i)
1928 free(ldpaths[i]); 1964 free(ldpaths[i]);
1929 1965
1930 if (ldcache != 0) 1966 if (ldcache != 0)
1931 munmap(ldcache, ldcache_size); 1967 munmap(ldcache, ldcache_size);
1980 free(qa_textrels); 2016 free(qa_textrels);
1981 free(qa_execstack); 2017 free(qa_execstack);
1982 free(qa_wx_load); 2018 free(qa_wx_load);
1983} 2019}
1984#endif 2020#endif
1985
1986 2021
1987int main(int argc, char *argv[]) 2022int main(int argc, char *argv[])
1988{ 2023{
1989 int ret; 2024 int ret;
1990 if (argc < 2) 2025 if (argc < 2)
1999 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD"); 2034 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD");
2000#endif 2035#endif
2001 return ret; 2036 return ret;
2002} 2037}
2003 2038
2004
2005/* Match filename against entries in matchlist, return TRUE 2039/* Match filename against entries in matchlist, return TRUE
2006 * if the file is listed */ 2040 * if the file is listed */
2007static int file_matches_list(const char *filename, char **matchlist) 2041static int file_matches_list(const char *filename, char **matchlist)
2008{ 2042{
2009 char **file; 2043 char **file;

Legend:
Removed from v.1.188  
changed lines
  Added in v.1.203

  ViewVC Help
Powered by ViewVC 1.1.20