/[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.206 Revision 1.214
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.206 2008/12/30 13:34:46 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.214 2009/12/01 10:19:42 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.206 2008/12/30 13:34:46 vapier Exp $"; 10static const char *rcsid = "$Id: scanelf.c,v 1.214 2009/12/01 10:19:42 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 == '+')
70static char **qa_execstack = NULL; 70static char **qa_execstack = NULL;
71static char **qa_wx_load = NULL; 71static char **qa_wx_load = NULL;
72 72
73static int match_bits = 0; 73static int match_bits = 0;
74static unsigned int match_perms = 0; 74static unsigned int match_perms = 0;
75static caddr_t ldcache = 0; 75static void *ldcache = NULL;
76static size_t ldcache_size = 0; 76static size_t ldcache_size = 0;
77static unsigned long setpax = 0UL; 77static unsigned long setpax = 0UL;
78 78
79static int has_objdump = 0; 79static int has_objdump = 0;
80 80
81/* find the path to a file by name */ 81/* find the path to a file by name */
82static char *which(const char *fname) 82static char *which(const char *fname)
83{ 83{
84 static char fullpath[BUFSIZ]; 84 static char fullpath[__PAX_UTILS_PATH_MAX];
85 char *path, *p; 85 char *path, *p;
86 86
87 path = getenv("PATH"); 87 path = getenv("PATH");
88 if (!path) 88 if (!path)
89 return NULL; 89 return NULL;
128 128
129/* sub-funcs for scanelf_file() */ 129/* sub-funcs for scanelf_file() */
130static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) 130static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
131{ 131{
132 /* find the best SHT_DYNSYM and SHT_STRTAB sections */ 132 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
133
134 /* debug sections */
135 void *symtab = elf_findsecbyname(elf, ".symtab");
136 void *strtab = elf_findsecbyname(elf, ".strtab");
137 /* runtime sections */
138 void *dynsym = elf_findsecbyname(elf, ".dynsym");
139 void *dynstr = elf_findsecbyname(elf, ".dynstr");
140
133#define GET_SYMTABS(B) \ 141#define GET_SYMTABS(B) \
134 if (elf->elf_class == ELFCLASS ## B) { \ 142 if (elf->elf_class == ELFCLASS ## B) { \
135 Elf ## B ## _Shdr *symtab, *strtab, *dynsym, *dynstr; \
136 /* debug sections */ \
137 symtab = SHDR ## B (elf_findsecbyname(elf, ".symtab")); \
138 strtab = SHDR ## B (elf_findsecbyname(elf, ".strtab")); \
139 /* runtime sections */ \
140 dynsym = SHDR ## B (elf_findsecbyname(elf, ".dynsym")); \
141 dynstr = SHDR ## B (elf_findsecbyname(elf, ".dynstr")); \
142 if (symtab && dynsym) { \ 143 if (symtab && dynsym) { \
144 Elf ## B ## _Shdr *esymtab = symtab; \
145 Elf ## B ## _Shdr *edynsym = dynsym; \
143 *sym = (void*)((EGET(symtab->sh_size) > EGET(dynsym->sh_size)) ? symtab : dynsym); \ 146 *sym = (EGET(esymtab->sh_size) > EGET(edynsym->sh_size)) ? symtab : dynsym; \
144 } else { \ 147 } else \
145 *sym = (void*)(symtab ? symtab : dynsym); \ 148 *sym = symtab ? symtab : dynsym; \
146 } \
147 if (strtab && dynstr) { \ 149 if (strtab && dynstr) { \
150 Elf ## B ## _Shdr *estrtab = strtab; \
151 Elf ## B ## _Shdr *edynstr = dynstr; \
148 *tab = (void*)((EGET(strtab->sh_size) > EGET(dynstr->sh_size)) ? strtab : dynstr); \ 152 *tab = (EGET(estrtab->sh_size) > EGET(edynstr->sh_size)) ? strtab : dynstr; \
149 } else { \ 153 } else \
150 *tab = (void*)(strtab ? strtab : dynstr); \ 154 *tab = strtab ? strtab : dynstr; \
151 } \
152 } 155 }
153 GET_SYMTABS(32) 156 GET_SYMTABS(32)
154 GET_SYMTABS(64) 157 GET_SYMTABS(64)
155} 158}
156 159
473 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \ 476 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
474 if (be_verbose && has_objdump) { \ 477 if (be_verbose && has_objdump) { \
475 Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \ 478 Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \
476 char *sysbuf; \ 479 char *sysbuf; \
477 size_t syslen; \ 480 size_t syslen; \
481 int sysret; \
478 const char sysfmt[] = "objdump -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \ 482 const char sysfmt[] = "objdump -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \
479 syslen = sizeof(sysfmt) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \ 483 syslen = sizeof(sysfmt) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \
480 sysbuf = xmalloc(syslen); \ 484 sysbuf = xmalloc(syslen); \
481 if (end_addr < r_offset) \ 485 if (end_addr < r_offset) \
482 /* not uncommon when things are optimized out */ \ 486 /* not uncommon when things are optimized out */ \
485 (unsigned long)offset_tmp, \ 489 (unsigned long)offset_tmp, \
486 (unsigned long)end_addr, \ 490 (unsigned long)end_addr, \
487 elf->filename, \ 491 elf->filename, \
488 (unsigned long)r_offset); \ 492 (unsigned long)r_offset); \
489 fflush(stdout); \ 493 fflush(stdout); \
490 system(sysbuf); \ 494 sysret = system(sysbuf); \
491 fflush(stdout); \ 495 fflush(stdout); \
492 free(sysbuf); \ 496 free(sysbuf); \
493 } \ 497 } \
494 } \ 498 } \
495 } } 499 } }
691 695
692#if defined(__GLIBC__) || defined(__UCLIBC__) 696#if defined(__GLIBC__) || defined(__UCLIBC__)
693 697
694static char *lookup_cache_lib(elfobj *elf, char *fname) 698static char *lookup_cache_lib(elfobj *elf, char *fname)
695{ 699{
696 int fd = 0; 700 int fd;
697 char *strs; 701 char *strs;
698 static char buf[__PAX_UTILS_PATH_MAX] = ""; 702 static char buf[__PAX_UTILS_PATH_MAX] = "";
699 const char *cachefile = "/etc/ld.so.cache"; 703 const char cachefile[] = "/etc/ld.so.cache";
700 struct stat st; 704 struct stat st;
701 705
702 typedef struct { 706 typedef struct {
703 char magic[LDSO_CACHE_MAGIC_LEN]; 707 char magic[LDSO_CACHE_MAGIC_LEN];
704 char version[LDSO_CACHE_VER_LEN]; 708 char version[LDSO_CACHE_VER_LEN];
714 libentry_t *libent; 718 libentry_t *libent;
715 719
716 if (fname == NULL) 720 if (fname == NULL)
717 return NULL; 721 return NULL;
718 722
719 if (ldcache == 0) { 723 if (ldcache == NULL) {
720 if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY)) == -1) 724 if (stat(cachefile, &st))
725 return NULL;
726
727 fd = open(cachefile, O_RDONLY);
728 if (fd == -1)
721 return NULL; 729 return NULL;
722 730
723 /* cache these values so we only map/unmap the cache file once */ 731 /* cache these values so we only map/unmap the cache file once */
724 ldcache_size = st.st_size; 732 ldcache_size = st.st_size;
725 ldcache = mmap(0, ldcache_size, PROT_READ, MAP_SHARED, fd, 0); 733 header = ldcache = mmap(0, ldcache_size, PROT_READ, MAP_SHARED, fd, 0);
726
727 close(fd); 734 close(fd);
728 735
729 if (ldcache == MAP_FAILED) { 736 if (ldcache == MAP_FAILED) {
730 ldcache = 0; 737 ldcache = NULL;
731 return NULL; 738 return NULL;
732 } 739 }
733 740
734 if (memcmp(((header_t *) ldcache)->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)) 741 if (memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN) ||
742 memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN))
743 {
744 munmap(ldcache, ldcache_size);
745 ldcache = NULL;
735 return NULL; 746 return NULL;
736 if (memcmp (((header_t *) ldcache)->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN))
737 return NULL;
738 } 747 }
748 } else
749 header = ldcache;
739 750
740 header = (header_t *) ldcache;
741 libent = (libentry_t *) (ldcache + sizeof(header_t)); 751 libent = ldcache + sizeof(header_t);
742 strs = (char *) &libent[header->nlibs]; 752 strs = (char *) &libent[header->nlibs];
743 753
744 for (fd = 0; fd < header->nlibs; fd++) { 754 for (fd = 0; fd < header->nlibs; ++fd) {
745 /* this should be more fine grained, but for now we assume that 755 /* This should be more fine grained, but for now we assume that
746 * diff arches will not be cached together. and we ignore the 756 * diff arches will not be cached together, and we ignore the
747 * the different multilib mips cases. */ 757 * the different multilib mips cases.
758 */
748 if (elf->elf_class == ELFCLASS64 && !(libent[fd].flags & FLAG_REQUIRED_MASK)) 759 if (elf->elf_class == ELFCLASS64 && !(libent[fd].flags & FLAG_REQUIRED_MASK))
749 continue; 760 continue;
750 if (elf->elf_class == ELFCLASS32 && (libent[fd].flags & FLAG_REQUIRED_MASK)) 761 if (elf->elf_class == ELFCLASS32 && (libent[fd].flags & FLAG_REQUIRED_MASK))
751 continue; 762 continue;
752 763
753 if (strcmp(fname, strs + libent[fd].sooffset) != 0) 764 if (strcmp(fname, strs + libent[fd].sooffset) != 0)
754 continue; 765 continue;
766
767 /* Return first hit because that is how the ldso rolls */
755 strncpy(buf, strs + libent[fd].liboffset, sizeof(buf)); 768 strncpy(buf, strs + libent[fd].liboffset, sizeof(buf));
769 break;
756 } 770 }
771
757 return buf; 772 return buf;
758} 773}
774
759#elif defined(__NetBSD__) 775#elif defined(__NetBSD__)
760static char *lookup_cache_lib(elfobj *elf, char *fname) 776static char *lookup_cache_lib(elfobj *elf, char *fname)
761{ 777{
762 static char buf[__PAX_UTILS_PATH_MAX] = ""; 778 static char buf[__PAX_UTILS_PATH_MAX] = "";
763 static struct stat st; 779 static struct stat st;
961 } 977 }
962 978
963 return NULL; 979 return NULL;
964} 980}
965 981
966static int scanelf_match_symname(const char *symname, const char *tomatch) { 982static int scanelf_match_symname(const char *symname, const char *tomatch)
983{
967 /* We do things differently when checking with regexp */ 984 /* We do things differently when checking with regexp */
968 if (g_match) { 985 if (g_match) {
969 return rematch(symname, tomatch, REG_EXTENDED) == 0; 986 return rematch(symname, tomatch, REG_EXTENDED) == 0;
970 } else { 987 } else {
971 const size_t symname_len = strlen(symname); 988 const size_t symname_len = strlen(symname);
980 unsigned long i; 997 unsigned long i;
981 char *ret; 998 char *ret;
982 void *symtab_void, *strtab_void; 999 void *symtab_void, *strtab_void;
983 1000
984 if (!find_sym) return NULL; 1001 if (!find_sym) return NULL;
985 ret = find_sym; 1002 ret = NULL;
986 1003
987 scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void); 1004 scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void);
988 1005
989 if (symtab_void && strtab_void) { 1006 if (symtab_void && strtab_void) {
990#define FIND_SYM(B) \ 1007#define FIND_SYM(B) \
992 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 1009 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
993 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 1010 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
994 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ 1011 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
995 unsigned long cnt = EGET(symtab->sh_entsize); \ 1012 unsigned long cnt = EGET(symtab->sh_entsize); \
996 char *symname; \ 1013 char *symname; \
1014 size_t ret_len = 0; \
997 if (cnt) \ 1015 if (cnt) \
998 cnt = EGET(symtab->sh_size) / cnt; \ 1016 cnt = EGET(symtab->sh_size) / cnt; \
999 for (i = 0; i < cnt; ++i) { \ 1017 for (i = 0; i < cnt; ++i) { \
1000 if ((void*)sym > (void*)elf->data_end) { \ 1018 if ((void*)sym > (void*)elf->data_end) { \
1001 warnf("%s: corrupt ELF symbols - aborting", elf->filename); \ 1019 warnf("%s: corrupt ELF symbols - aborting", elf->filename); \
1002 goto break_out; \ 1020 goto break_out; \
1003 } \ 1021 } \
1004 if (sym->st_name) { \ 1022 if (sym->st_name) { \
1023 char *this_sym, *next_sym; \
1024 bool all_syms; \
1005 /* make sure the symbol name is in acceptable memory range */ \ 1025 /* make sure the symbol name is in acceptable memory range */ \
1006 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ 1026 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
1007 if ((void*)symname > (void*)elf->data_end) { \ 1027 if ((void*)symname > (void*)elf->data_end) { \
1008 warnf("%s: corrupt ELF symbols", elf->filename); \ 1028 warnf("%s: corrupt ELF symbols", elf->filename); \
1009 ++sym; \ 1029 ++sym; \
1010 continue; \ 1030 continue; \
1011 } \ 1031 } \
1012 /* debug display ... show all symbols and some extra info */ \
1013 if (0 && g_match ? rematch(ret, symname, REG_EXTENDED) == 0 : *ret == '*') { \
1014 printf("%s(%s) %5lX %15s %s %s\n", \
1015 ((*found_sym == 0) ? "\n\t" : "\t"), \
1016 elf->base_filename, \
1017 (unsigned long)sym->st_size, \
1018 get_elfstttype(sym->st_info), \
1019 sym->st_shndx == SHN_UNDEF ? "U" : "D", symname); \
1020 *found_sym = 1; \
1021 } else { \
1022 /* allow the user to specify a comma delimited list of symbols to search for */ \ 1032 /* allow the user to specify a comma delimited list of symbols to search for */ \
1023 char *this_sym, *next_sym; \ 1033 all_syms = false; \
1024 next_sym = ret; \ 1034 next_sym = NULL; \
1035 do { \
1036 bool inc_notype, inc_object, inc_func, inc_file, \
1037 inc_local, inc_global, inc_weak, \
1038 inc_def, inc_undef, inc_abs, inc_common; \
1039 unsigned int stt, stb, shn; \
1040 char saved = saved; /* shut gcc up */ \
1025 while (next_sym) { \ 1041 if (next_sym) { \
1042 next_sym[-1] = saved; \
1026 this_sym = next_sym; \ 1043 this_sym = next_sym; \
1044 } else \
1045 this_sym = find_sym; \
1027 if ((next_sym = strchr(this_sym, ','))) \ 1046 if ((next_sym = strchr(this_sym, ','))) { \
1047 saved = *next_sym; \
1048 *next_sym = '\0'; /* make parsing easier */ \
1028 next_sym += 1; /* Skip the comma */ \ 1049 next_sym += 1; /* Skip the comma */ \
1029 /* do we want a defined symbol ? */ \ 1050 } \
1051 /* symbol selection! */ \
1052 inc_notype = inc_object = inc_func = inc_file = \
1053 inc_local = inc_global = inc_weak = \
1054 inc_def = inc_undef = inc_abs = inc_common = \
1055 (*this_sym != '%'); \
1056 if (!inc_notype) { \
1057 if (this_sym[1] == '%') \
1058 all_syms = true; /* %% hack */ \
1059 while (*(this_sym++)) { \
1030 if (*this_sym == '+') { \ 1060 if (*this_sym == '%') { \
1031 if (sym->st_shndx == SHN_UNDEF) \
1032 continue; \
1033 ++this_sym; \ 1061 ++this_sym; \
1034 /* do we want an undefined symbol ? */ \ 1062 break; \
1035 } else if (*this_sym == '-') { \ 1063 } \
1036 if (sym->st_shndx != SHN_UNDEF) \ 1064 switch (*this_sym) { \
1037 continue; \ 1065 case 'n': inc_notype = true; break; \
1038 ++this_sym; \ 1066 case 'o': inc_object = true; break; \
1067 case 'f': inc_func = true; break; \
1068 case 'F': inc_file = true; break; \
1069 case 'l': inc_local = true; break; \
1070 case 'g': inc_global = true; break; \
1071 case 'w': inc_weak = true; break; \
1072 case 'd': inc_def = true; break; \
1073 case 'u': inc_undef = true; break; \
1074 case 'a': inc_abs = true; break; \
1075 case 'c': inc_common = true; break; \
1076 default: err("invalid symbol selector '%c'", *this_sym); \
1077 } \
1039 } \ 1078 } \
1040 if (next_sym) /* Copy it so that we don't have to worry about the final , */ \ 1079 if (!inc_notype && !inc_object && !inc_func && !inc_file) \
1041 this_sym = strndup(this_sym, next_sym-this_sym); \ 1080 inc_notype = inc_object = inc_func = inc_file = true; \
1042 /* ok, lets compare the name now */ \ 1081 if (!inc_local && !inc_global && !inc_weak) \
1082 inc_local = inc_global = inc_weak = true; \
1083 if (!inc_def && !inc_undef && !inc_abs && !inc_common) \
1084 inc_def = inc_undef = inc_abs = inc_common = true; \
1085 } else if (*this_sym == '+') { \
1086 inc_undef = false; \
1087 ++this_sym; \
1088 } else if (*this_sym == '-') { \
1089 inc_def = inc_abs = inc_common = false; \
1090 ++this_sym; \
1091 } \
1092 /* filter symbols */ \
1093 stt = ELF##B##_ST_TYPE(EGET(sym->st_info)); \
1094 stb = ELF##B##_ST_BIND(EGET(sym->st_info)); \
1095 shn = EGET(sym->st_shndx); \
1096 if ((!inc_notype && stt == STT_NOTYPE) || \
1097 (!inc_object && stt == STT_OBJECT) || \
1098 (!inc_func && stt == STT_FUNC ) || \
1099 (!inc_file && stt == STT_FILE ) || \
1100 (!inc_local && stb == STB_LOCAL ) || \
1101 (!inc_global && stb == STB_GLOBAL) || \
1102 (!inc_weak && stb == STB_WEAK ) || \
1103 (!inc_def && shn && shn < SHN_LORESERVE) || \
1104 (!inc_undef && shn == SHN_UNDEF ) || \
1105 (!inc_abs && shn == SHN_ABS ) || \
1106 (!inc_common && shn == SHN_COMMON)) \
1107 continue; \
1108 /* still here !? */ \
1109 if (*this_sym == '*' || !*this_sym) { \
1110 if (*this_sym == '*') \
1111 printf("%s(%s) %5lX %15s %15s %15s %s\n", \
1112 ((*found_sym == 0) ? "\n\t" : "\t"), \
1113 elf->base_filename, \
1114 (unsigned long)EGET(sym->st_size), \
1115 get_elfstttype(stt), \
1116 get_elfstbtype(stb), \
1117 get_elfshntype(shn), \
1118 symname); \
1119 else \
1120 printf("%s%s", ((*found_sym == 0) ? "" : ","), symname); \
1121 *found_sym = 1; \
1122 if (next_sym) next_sym[-1] = saved; \
1123 break; \
1043 if (scanelf_match_symname(this_sym, symname)) { \ 1124 } else if (scanelf_match_symname(this_sym, symname)) { \
1125 *found_sym = 1; \
1044 if (be_semi_verbose) { \ 1126 if (be_semi_verbose) { \
1045 char buf[126]; \ 1127 char buf[1024]; \
1046 snprintf(buf, sizeof(buf), "%lX %s %s", \ 1128 snprintf(buf, sizeof(buf), "%lX %s %s", \
1047 (unsigned long)sym->st_size, get_elfstttype(sym->st_info), this_sym); \ 1129 (unsigned long)EGET(sym->st_size), \
1130 get_elfstttype(stt), \
1131 this_sym); \
1048 ret = buf; \ 1132 ret = xstrdup(buf); \
1049 } else \ 1133 } else { \
1050 ret = symname; \ 1134 if (ret) xchrcat(&ret, ',', &ret_len); \
1051 (*found_sym)++; \ 1135 xstrcat(&ret, symname, &ret_len); \
1136 } \
1137 if (next_sym) next_sym[-1] = saved; \
1138 if (all_syms) \
1139 break; \
1140 else \
1052 goto break_out; \ 1141 goto break_out; \
1053 } \
1054 if (next_sym) free(this_sym); \
1055 } \ 1142 } \
1056 } \ 1143 } while (next_sym); \
1057 } \ 1144 } \
1058 ++sym; \ 1145 ++sym; \
1059 } } 1146 } }
1060 FIND_SYM(32) 1147 FIND_SYM(32)
1061 FIND_SYM(64) 1148 FIND_SYM(64)
1100 else 1187 else
1101 return (char *)" - "; 1188 return (char *)" - ";
1102} 1189}
1103 1190
1104/* scan an elf file and show all the fun stuff */ 1191/* scan an elf file and show all the fun stuff */
1105#define prints(str) write(fileno(stdout), str, strlen(str)) 1192#define prints(str) ({ ssize_t ret = write(fileno(stdout), str, strlen(str)); ret; })
1106static int scanelf_elfobj(elfobj *elf) 1193static int scanelf_elfobj(elfobj *elf)
1107{ 1194{
1108 unsigned long i; 1195 unsigned long i;
1109 char found_pax, found_phdr, found_relro, found_load, found_textrel, 1196 char found_pax, found_phdr, found_relro, found_load, found_textrel,
1110 found_rpath, found_needed, found_interp, found_bind, found_soname, 1197 found_rpath, found_needed, found_interp, found_bind, found_soname,
1235 case 'I': out = get_elfosabi(elf); break; 1322 case 'I': out = get_elfosabi(elf); break;
1236 case 'Y': out = get_elf_eabi(elf); break; 1323 case 'Y': out = get_elf_eabi(elf); break;
1237 case 'Z': snprintf(ubuf, sizeof(ubuf), "%lu", (unsigned long)elf->len); out = ubuf; break;; 1324 case 'Z': snprintf(ubuf, sizeof(ubuf), "%lu", (unsigned long)elf->len); out = ubuf; break;;
1238 default: warnf("'%c' has no scan code?", out_format[i]); 1325 default: warnf("'%c' has no scan code?", out_format[i]);
1239 } 1326 }
1240 if (out) { 1327 if (out)
1241 /* hack for comma delimited output like `scanelf -s sym1,sym2,sym3` */
1242 if (out_format[i] == 's' && (tmp=strchr(out,',')) != NULL)
1243 xstrncat(&out_buffer, out, &out_len, (tmp-out));
1244 else
1245 xstrcat(&out_buffer, out, &out_len); 1328 xstrcat(&out_buffer, out, &out_len);
1246 }
1247 } 1329 }
1248 1330
1249#define FOUND_SOMETHING() \ 1331#define FOUND_SOMETHING() \
1250 (found_pax || found_phdr || found_relro || found_load || found_textrel || \ 1332 (found_pax || found_phdr || found_relro || found_load || found_textrel || \
1251 found_rpath || found_needed || found_interp || found_bind || \ 1333 found_rpath || found_needed || found_interp || found_bind || \
1502 1584
1503 fclose(fp); 1585 fclose(fp);
1504 return i; 1586 return i;
1505} 1587}
1506 1588
1507#elif defined(__FreeBSD__) || (__DragonFly__) 1589#elif defined(__FreeBSD__) || defined(__DragonFly__)
1508 1590
1509static int load_ld_cache_config(int i, const char *fname) 1591static int load_ld_cache_config(int i, const char *fname)
1510{ 1592{
1511 FILE *fp = NULL; 1593 FILE *fp = NULL;
1512 char *b = NULL, *p; 1594 char *b = NULL, *p;
1568 err("Unable to load any paths from ld.so.conf"); 1650 err("Unable to load any paths from ld.so.conf");
1569 1651
1570 scan_l = scan_ul = scan_ull = 0; 1652 scan_l = scan_ul = scan_ull = 0;
1571 1653
1572 while (ldpaths[i]) { 1654 while (ldpaths[i]) {
1573 if (!scan_l && !strcmp(ldpaths[i], "/lib")) scan_l = 1; 1655 if (!scan_l && !strcmp(ldpaths[i], "/lib")) scan_l = 1;
1574 if (!scan_ul && !strcmp(ldpaths[i], "/usr/lib")) scan_ul = 1; 1656 if (!scan_ul && !strcmp(ldpaths[i], "/usr/lib")) scan_ul = 1;
1575 if (!scan_ull && !strcmp(ldpaths[i], "/usr/local/lib")) scan_ull = 1; 1657 if (!scan_ull && !strcmp(ldpaths[i], "/usr/local/lib")) scan_ull = 1;
1576 scanelf_dir(ldpaths[i]); 1658 scanelf_dir(ldpaths[i]);
1577 ++i; 1659 ++i;
1578 } 1660 }
1579 1661

Legend:
Removed from v.1.206  
changed lines
  Added in v.1.214

  ViewVC Help
Powered by ViewVC 1.1.20