1 |
vapier 09/12/01 10:19:42 |
2 |
|
3 |
Modified: porting.h scanelf.c |
4 |
Log: |
5 |
extend symbol lookup syntax to allow matching of symbols based on more fields |
6 |
|
7 |
Revision Changes Path |
8 |
1.38 pax-utils/porting.h |
9 |
|
10 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-projects/pax-utils/porting.h?rev=1.38&view=markup |
11 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-projects/pax-utils/porting.h?rev=1.38&content-type=text/plain |
12 |
diff : http://sources.gentoo.org/viewcvs.py/gentoo-projects/pax-utils/porting.h?r1=1.37&r2=1.38 |
13 |
|
14 |
Index: porting.h |
15 |
=================================================================== |
16 |
RCS file: /var/cvsroot/gentoo-projects/pax-utils/porting.h,v |
17 |
retrieving revision 1.37 |
18 |
retrieving revision 1.38 |
19 |
diff -u -r1.37 -r1.38 |
20 |
--- porting.h 25 Oct 2009 20:42:34 -0000 1.37 |
21 |
+++ porting.h 1 Dec 2009 10:19:42 -0000 1.38 |
22 |
@@ -1,7 +1,7 @@ |
23 |
/* |
24 |
* Copyright 2005-2007 Gentoo Foundation |
25 |
* Distributed under the terms of the GNU General Public License v2 |
26 |
- * $Header: /var/cvsroot/gentoo-projects/pax-utils/porting.h,v 1.37 2009/10/25 20:42:34 grobian Exp $ |
27 |
+ * $Header: /var/cvsroot/gentoo-projects/pax-utils/porting.h,v 1.38 2009/12/01 10:19:42 vapier Exp $ |
28 |
* |
29 |
* Copyright 2005-2007 Ned Ludd - <solar@g.o> |
30 |
* Copyright 2005-2007 Mike Frysinger - <vapier@g.o> |
31 |
@@ -27,6 +27,7 @@ |
32 |
#include <limits.h> |
33 |
#include <pwd.h> |
34 |
#include <regex.h> |
35 |
+#include <stdbool.h> |
36 |
#include <stdio.h> |
37 |
#include <stdlib.h> |
38 |
#include <string.h> |
39 |
|
40 |
|
41 |
|
42 |
1.214 pax-utils/scanelf.c |
43 |
|
44 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-projects/pax-utils/scanelf.c?rev=1.214&view=markup |
45 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-projects/pax-utils/scanelf.c?rev=1.214&content-type=text/plain |
46 |
diff : http://sources.gentoo.org/viewcvs.py/gentoo-projects/pax-utils/scanelf.c?r1=1.213&r2=1.214 |
47 |
|
48 |
Index: scanelf.c |
49 |
=================================================================== |
50 |
RCS file: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v |
51 |
retrieving revision 1.213 |
52 |
retrieving revision 1.214 |
53 |
diff -u -r1.213 -r1.214 |
54 |
--- scanelf.c 1 Dec 2009 10:18:58 -0000 1.213 |
55 |
+++ scanelf.c 1 Dec 2009 10:19:42 -0000 1.214 |
56 |
@@ -1,13 +1,13 @@ |
57 |
/* |
58 |
* Copyright 2003-2007 Gentoo Foundation |
59 |
* Distributed under the terms of the GNU General Public License v2 |
60 |
- * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.213 2009/12/01 10:18:58 vapier Exp $ |
61 |
+ * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.214 2009/12/01 10:19:42 vapier Exp $ |
62 |
* |
63 |
* Copyright 2003-2007 Ned Ludd - <solar@g.o> |
64 |
* Copyright 2004-2007 Mike Frysinger - <vapier@g.o> |
65 |
*/ |
66 |
|
67 |
-static const char *rcsid = "$Id: scanelf.c,v 1.213 2009/12/01 10:18:58 vapier Exp $"; |
68 |
+static const char *rcsid = "$Id: scanelf.c,v 1.214 2009/12/01 10:19:42 vapier Exp $"; |
69 |
const char * const argv0 = "scanelf"; |
70 |
|
71 |
#include "paxinc.h" |
72 |
@@ -979,7 +979,8 @@ |
73 |
return NULL; |
74 |
} |
75 |
|
76 |
-static int scanelf_match_symname(const char *symname, const char *tomatch) { |
77 |
+static int scanelf_match_symname(const char *symname, const char *tomatch) |
78 |
+{ |
79 |
/* We do things differently when checking with regexp */ |
80 |
if (g_match) { |
81 |
return rematch(symname, tomatch, REG_EXTENDED) == 0; |
82 |
@@ -998,7 +999,7 @@ |
83 |
void *symtab_void, *strtab_void; |
84 |
|
85 |
if (!find_sym) return NULL; |
86 |
- ret = find_sym; |
87 |
+ ret = NULL; |
88 |
|
89 |
scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void); |
90 |
|
91 |
@@ -1010,6 +1011,7 @@ |
92 |
Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ |
93 |
unsigned long cnt = EGET(symtab->sh_entsize); \ |
94 |
char *symname; \ |
95 |
+ size_t ret_len = 0; \ |
96 |
if (cnt) \ |
97 |
cnt = EGET(symtab->sh_size) / cnt; \ |
98 |
for (i = 0; i < cnt; ++i) { \ |
99 |
@@ -1018,6 +1020,8 @@ |
100 |
goto break_out; \ |
101 |
} \ |
102 |
if (sym->st_name) { \ |
103 |
+ char *this_sym, *next_sym; \ |
104 |
+ bool all_syms; \ |
105 |
/* make sure the symbol name is in acceptable memory range */ \ |
106 |
symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ |
107 |
if ((void*)symname > (void*)elf->data_end) { \ |
108 |
@@ -1025,51 +1029,118 @@ |
109 |
++sym; \ |
110 |
continue; \ |
111 |
} \ |
112 |
- /* debug display ... show all symbols and some extra info */ \ |
113 |
- if (0 && g_match ? rematch(ret, symname, REG_EXTENDED) == 0 : *ret == '*') { \ |
114 |
- printf("%s(%s) %5lX %15s %s %s\n", \ |
115 |
- ((*found_sym == 0) ? "\n\t" : "\t"), \ |
116 |
- elf->base_filename, \ |
117 |
- (unsigned long)sym->st_size, \ |
118 |
- get_elfstttype(sym->st_info), \ |
119 |
- sym->st_shndx == SHN_UNDEF ? "U" : "D", symname); \ |
120 |
- *found_sym = 1; \ |
121 |
- } else { \ |
122 |
- /* allow the user to specify a comma delimited list of symbols to search for */ \ |
123 |
- char *this_sym, *next_sym; \ |
124 |
- next_sym = ret; \ |
125 |
- while (next_sym) { \ |
126 |
+ /* allow the user to specify a comma delimited list of symbols to search for */ \ |
127 |
+ all_syms = false; \ |
128 |
+ next_sym = NULL; \ |
129 |
+ do { \ |
130 |
+ bool inc_notype, inc_object, inc_func, inc_file, \ |
131 |
+ inc_local, inc_global, inc_weak, \ |
132 |
+ inc_def, inc_undef, inc_abs, inc_common; \ |
133 |
+ unsigned int stt, stb, shn; \ |
134 |
+ char saved = saved; /* shut gcc up */ \ |
135 |
+ if (next_sym) { \ |
136 |
+ next_sym[-1] = saved; \ |
137 |
this_sym = next_sym; \ |
138 |
- if ((next_sym = strchr(this_sym, ','))) \ |
139 |
- next_sym += 1; /* Skip the comma */ \ |
140 |
- /* do we want a defined symbol ? */ \ |
141 |
- if (*this_sym == '+') { \ |
142 |
- if (sym->st_shndx == SHN_UNDEF) \ |
143 |
- continue; \ |
144 |
- ++this_sym; \ |
145 |
- /* do we want an undefined symbol ? */ \ |
146 |
- } else if (*this_sym == '-') { \ |
147 |
- if (sym->st_shndx != SHN_UNDEF) \ |
148 |
- continue; \ |
149 |
- ++this_sym; \ |
150 |
+ } else \ |
151 |
+ this_sym = find_sym; \ |
152 |
+ if ((next_sym = strchr(this_sym, ','))) { \ |
153 |
+ saved = *next_sym; \ |
154 |
+ *next_sym = '\0'; /* make parsing easier */ \ |
155 |
+ next_sym += 1; /* Skip the comma */ \ |
156 |
+ } \ |
157 |
+ /* symbol selection! */ \ |
158 |
+ inc_notype = inc_object = inc_func = inc_file = \ |
159 |
+ inc_local = inc_global = inc_weak = \ |
160 |
+ inc_def = inc_undef = inc_abs = inc_common = \ |
161 |
+ (*this_sym != '%'); \ |
162 |
+ if (!inc_notype) { \ |
163 |
+ if (this_sym[1] == '%') \ |
164 |
+ all_syms = true; /* %% hack */ \ |
165 |
+ while (*(this_sym++)) { \ |
166 |
+ if (*this_sym == '%') { \ |
167 |
+ ++this_sym; \ |
168 |
+ break; \ |
169 |
+ } \ |
170 |
+ switch (*this_sym) { \ |
171 |
+ case 'n': inc_notype = true; break; \ |
172 |
+ case 'o': inc_object = true; break; \ |
173 |
+ case 'f': inc_func = true; break; \ |
174 |
+ case 'F': inc_file = true; break; \ |
175 |
+ case 'l': inc_local = true; break; \ |
176 |
+ case 'g': inc_global = true; break; \ |
177 |
+ case 'w': inc_weak = true; break; \ |
178 |
+ case 'd': inc_def = true; break; \ |
179 |
+ case 'u': inc_undef = true; break; \ |
180 |
+ case 'a': inc_abs = true; break; \ |
181 |
+ case 'c': inc_common = true; break; \ |
182 |
+ default: err("invalid symbol selector '%c'", *this_sym); \ |
183 |
+ } \ |
184 |
} \ |
185 |
- if (next_sym) /* Copy it so that we don't have to worry about the final , */ \ |
186 |
- this_sym = xstrndup(this_sym, next_sym-this_sym); \ |
187 |
- /* ok, lets compare the name now */ \ |
188 |
- if (scanelf_match_symname(this_sym, symname)) { \ |
189 |
- if (be_semi_verbose) { \ |
190 |
- char buf[126]; \ |
191 |
- snprintf(buf, sizeof(buf), "%lX %s %s", \ |
192 |
- (unsigned long)sym->st_size, get_elfstttype(sym->st_info), this_sym); \ |
193 |
- ret = buf; \ |
194 |
- } else \ |
195 |
- ret = symname; \ |
196 |
- (*found_sym)++; \ |
197 |
- goto break_out; \ |
198 |
+ if (!inc_notype && !inc_object && !inc_func && !inc_file) \ |
199 |
+ inc_notype = inc_object = inc_func = inc_file = true; \ |
200 |
+ if (!inc_local && !inc_global && !inc_weak) \ |
201 |
+ inc_local = inc_global = inc_weak = true; \ |
202 |
+ if (!inc_def && !inc_undef && !inc_abs && !inc_common) \ |
203 |
+ inc_def = inc_undef = inc_abs = inc_common = true; \ |
204 |
+ } else if (*this_sym == '+') { \ |
205 |
+ inc_undef = false; \ |
206 |
+ ++this_sym; \ |
207 |
+ } else if (*this_sym == '-') { \ |
208 |
+ inc_def = inc_abs = inc_common = false; \ |
209 |
+ ++this_sym; \ |
210 |
+ } \ |
211 |
+ /* filter symbols */ \ |
212 |
+ stt = ELF##B##_ST_TYPE(EGET(sym->st_info)); \ |
213 |
+ stb = ELF##B##_ST_BIND(EGET(sym->st_info)); \ |
214 |
+ shn = EGET(sym->st_shndx); \ |
215 |
+ if ((!inc_notype && stt == STT_NOTYPE) || \ |
216 |
+ (!inc_object && stt == STT_OBJECT) || \ |
217 |
+ (!inc_func && stt == STT_FUNC ) || \ |
218 |
+ (!inc_file && stt == STT_FILE ) || \ |
219 |
+ (!inc_local && stb == STB_LOCAL ) || \ |
220 |
+ (!inc_global && stb == STB_GLOBAL) || \ |
221 |
+ (!inc_weak && stb == STB_WEAK ) || \ |
222 |
+ (!inc_def && shn && shn < SHN_LORESERVE) || \ |
223 |
+ (!inc_undef && shn == SHN_UNDEF ) || \ |
224 |
+ (!inc_abs && shn == SHN_ABS ) || \ |
225 |
+ (!inc_common && shn == SHN_COMMON)) \ |
226 |
+ continue; \ |
227 |
+ /* still here !? */ \ |
228 |
+ if (*this_sym == '*' || !*this_sym) { \ |
229 |
+ if (*this_sym == '*') \ |
230 |
+ printf("%s(%s) %5lX %15s %15s %15s %s\n", \ |
231 |
+ ((*found_sym == 0) ? "\n\t" : "\t"), \ |
232 |
+ elf->base_filename, \ |
233 |
+ (unsigned long)EGET(sym->st_size), \ |
234 |
+ get_elfstttype(stt), \ |
235 |
+ get_elfstbtype(stb), \ |
236 |
+ get_elfshntype(shn), \ |
237 |
+ symname); \ |
238 |
+ else \ |
239 |
+ printf("%s%s", ((*found_sym == 0) ? "" : ","), symname); \ |
240 |
+ *found_sym = 1; \ |
241 |
+ if (next_sym) next_sym[-1] = saved; \ |
242 |
+ break; \ |
243 |
+ } else if (scanelf_match_symname(this_sym, symname)) { \ |
244 |
+ *found_sym = 1; \ |
245 |
+ if (be_semi_verbose) { \ |
246 |
+ char buf[1024]; \ |
247 |
+ snprintf(buf, sizeof(buf), "%lX %s %s", \ |
248 |
+ (unsigned long)EGET(sym->st_size), \ |
249 |
+ get_elfstttype(stt), \ |
250 |
+ this_sym); \ |
251 |
+ ret = xstrdup(buf); \ |
252 |
+ } else { \ |
253 |
+ if (ret) xchrcat(&ret, ',', &ret_len); \ |
254 |
+ xstrcat(&ret, symname, &ret_len); \ |
255 |
} \ |
256 |
- if (next_sym) free(this_sym); \ |
257 |
+ if (next_sym) next_sym[-1] = saved; \ |
258 |
+ if (all_syms) \ |
259 |
+ break; \ |
260 |
+ else \ |
261 |
+ goto break_out; \ |
262 |
} \ |
263 |
- } \ |
264 |
+ } while (next_sym); \ |
265 |
} \ |
266 |
++sym; \ |
267 |
} } |
268 |
@@ -1253,13 +1324,8 @@ |
269 |
case 'Z': snprintf(ubuf, sizeof(ubuf), "%lu", (unsigned long)elf->len); out = ubuf; break;; |
270 |
default: warnf("'%c' has no scan code?", out_format[i]); |
271 |
} |
272 |
- if (out) { |
273 |
- /* hack for comma delimited output like `scanelf -s sym1,sym2,sym3` */ |
274 |
- if (out_format[i] == 's' && (tmp=strchr(out,',')) != NULL) |
275 |
- xstrncat(&out_buffer, out, &out_len, (tmp-out)); |
276 |
- else |
277 |
- xstrcat(&out_buffer, out, &out_len); |
278 |
- } |
279 |
+ if (out) |
280 |
+ xstrcat(&out_buffer, out, &out_len); |
281 |
} |
282 |
|
283 |
#define FOUND_SOMETHING() \ |