1 |
vapier 13/01/02 18:27:04 |
2 |
|
3 |
Added: pyelftools-0.20-dyntags-1.patch |
4 |
pyelftools-0.20-dyntags-2.patch |
5 |
Log: |
6 |
Add dynamic tag support as pax-utils/lddtree uses it. |
7 |
|
8 |
(Portage version: 2.2.0_alpha144/cvs/Linux x86_64, signed Manifest commit with key FB7C4156) |
9 |
|
10 |
Revision Changes Path |
11 |
1.1 dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch |
12 |
|
13 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch?rev=1.1&view=markup |
14 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/pyelftools/files/pyelftools-0.20-dyntags-1.patch?rev=1.1&content-type=text/plain |
15 |
|
16 |
Index: pyelftools-0.20-dyntags-1.patch |
17 |
=================================================================== |
18 |
# HG changeset patch |
19 |
# User Mike Frysinger <vapier@g.o> |
20 |
# Date 1352755639 18000 |
21 |
# Node ID a9c9b2f9ec964e6750dd6f9a96767fe2e9201d85 |
22 |
# Parent f3408c7b954910aa3a58e88196efba4954c0cc55 |
23 |
add support for parsing of the dynamic section/segment and its tags |
24 |
|
25 |
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/dynamic.py |
26 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
27 |
+++ b/elftools/elf/dynamic.py Mon Nov 12 16:27:19 2012 -0500 |
28 |
@@ -0,0 +1,115 @@ |
29 |
+#------------------------------------------------------------------------------- |
30 |
+# elftools: elf/dynamic.py |
31 |
+# |
32 |
+# ELF Dynamic Tags |
33 |
+# |
34 |
+# Mike Frysinger (vapier@g.o) |
35 |
+# This code is in the public domain |
36 |
+#------------------------------------------------------------------------------- |
37 |
+from .sections import Section |
38 |
+from .segments import Segment |
39 |
+from ..common.utils import struct_parse |
40 |
+ |
41 |
+from enums import ENUM_D_TAG |
42 |
+ |
43 |
+ |
44 |
+class DynamicTag(object): |
45 |
+ """ Dynamic Tag object - representing a single dynamic tag entry from a |
46 |
+ dynamic section. |
47 |
+ |
48 |
+ Similarly to Section objects, allows dictionary-like access to the |
49 |
+ dynamic tag. |
50 |
+ """ |
51 |
+ def __init__(self, entry, elffile): |
52 |
+ self.entry = entry |
53 |
+ if entry.d_tag == 'DT_NEEDED' or \ |
54 |
+ entry.d_tag == 'DT_RPATH' or \ |
55 |
+ entry.d_tag == 'DT_RUNPATH': |
56 |
+ dynstr = elffile.get_section_by_name('.dynstr') |
57 |
+ setattr(self, entry.d_tag[3:].lower(), dynstr.get_string(self.entry.d_val)) |
58 |
+ |
59 |
+ def __getitem__(self, name): |
60 |
+ """ Implement dict-like access to entries |
61 |
+ """ |
62 |
+ return self.entry[name] |
63 |
+ |
64 |
+ def __repr__(self): |
65 |
+ return '<DynamicTag (%s): %r>' % (self.entry.d_tag, self.entry) |
66 |
+ |
67 |
+ def __str__(self): |
68 |
+ if self.entry.d_tag == 'DT_NEEDED' or \ |
69 |
+ self.entry.d_tag == 'DT_RPATH' or \ |
70 |
+ self.entry.d_tag == 'DT_RUNPATH': |
71 |
+ s = '"%s"' % getattr(self, self.entry.d_tag[3:].lower()) |
72 |
+ else: |
73 |
+ s = '%#x' % self.entry.d_ptr |
74 |
+ return '<DynamicTag (%s) %s>' % (self.entry.d_tag, s) |
75 |
+ |
76 |
+ |
77 |
+class Dynamic(object): |
78 |
+ def __init__(self, stream, elffile, position): |
79 |
+ self._stream = stream |
80 |
+ self._elffile = elffile |
81 |
+ self._elfstructs = elffile.structs |
82 |
+ self._num_tags = -1; |
83 |
+ self._offset = position |
84 |
+ self._tagsize = self._elfstructs.Elf_Dyn.sizeof() |
85 |
+ |
86 |
+ def iter_tags(self, type=None): |
87 |
+ """ Yield all tags (limit to |type| if specified) |
88 |
+ """ |
89 |
+ offset = self._offset - self._tagsize |
90 |
+ for i in range(self.num_tags): |
91 |
+ offset += self._tagsize |
92 |
+ entry = struct_parse( |
93 |
+ self._elfstructs.Elf_Dyn, |
94 |
+ self._stream, |
95 |
+ stream_pos=offset) |
96 |
+ if type is not None and entry.d_tag != type: |
97 |
+ continue |
98 |
+ yield DynamicTag(entry, self._elffile) |
99 |
+ |
100 |
+ def get_tag(self, n): |
101 |
+ """ Get the tag at index #n from the file (DynamicTag object) |
102 |
+ """ |
103 |
+ offset = self._offset + n * self._tagsize |
104 |
+ entry = struct_parse( |
105 |
+ self._elfstructs.Elf_Dyn, |
106 |
+ self._stream, |
107 |
+ stream_pos=offset) |
108 |
+ return DynamicTag(entry, self._elffile) |
109 |
+ |
110 |
+ @property |
111 |
+ def num_tags(self): |
112 |
+ """ Number of dynamic tags in the file |
113 |
+ """ |
114 |
+ if self._num_tags != -1: |
115 |
+ return self._num_tags |
116 |
+ |
117 |
+ offset = self._offset |
118 |
+ while True: |
119 |
+ entry = struct_parse( |
120 |
+ self._elfstructs.Elf_Dyn, |
121 |
+ self._stream, |
122 |
+ stream_pos=offset) |
123 |
+ if entry.d_tag == 'DT_NULL': |
124 |
+ self._num_tags = ((offset - self._offset) // self._tagsize) + 1 |
125 |
+ break |
126 |
+ offset += self._tagsize |
127 |
+ return self._num_tags |
128 |
+ |
129 |
+ |
130 |
+class DynamicSection(Section, Dynamic): |
131 |
+ """ ELF dynamic table section. Knows how to process the list of tags. |
132 |
+ """ |
133 |
+ def __init__(self, header, name, stream, elffile): |
134 |
+ Section.__init__(self, header, name, stream) |
135 |
+ Dynamic.__init__(self, stream, elffile, self['sh_offset']) |
136 |
+ |
137 |
+ |
138 |
+class DynamicSegment(Segment, Dynamic): |
139 |
+ """ ELF dynamic table segment. Knows how to process the list of tags. |
140 |
+ """ |
141 |
+ def __init__(self, header, stream, elffile): |
142 |
+ Segment.__init__(self, header, stream) |
143 |
+ Dynamic.__init__(self, stream, elffile, self['p_offset']) |
144 |
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/elffile.py |
145 |
--- a/elftools/elf/elffile.py Thu Jul 05 06:32:09 2012 +0300 |
146 |
+++ b/elftools/elf/elffile.py Mon Nov 12 16:27:19 2012 -0500 |
147 |
@@ -13,6 +13,7 @@ |
148 |
from .structs import ELFStructs |
149 |
from .sections import ( |
150 |
Section, StringTableSection, SymbolTableSection, NullSection) |
151 |
+from .dynamic import DynamicSection, DynamicSegment |
152 |
from .relocation import RelocationSection, RelocationHandler |
153 |
from .segments import Segment, InterpSegment |
154 |
from .enums import ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64 |
155 |
@@ -208,6 +209,8 @@ |
156 |
segtype = segment_header['p_type'] |
157 |
if segtype == 'PT_INTERP': |
158 |
return InterpSegment(segment_header, self.stream) |
159 |
+ elif segtype == 'PT_DYNAMIC': |
160 |
+ return DynamicSegment(segment_header, self.stream, self) |
161 |
else: |
162 |
return Segment(segment_header, self.stream) |
163 |
|
164 |
@@ -241,6 +244,8 @@ |
165 |
elif sectype in ('SHT_REL', 'SHT_RELA'): |
166 |
return RelocationSection( |
167 |
section_header, name, self.stream, self) |
168 |
+ elif sectype == 'SHT_DYNAMIC': |
169 |
+ return DynamicSection(section_header, name, self.stream, self) |
170 |
else: |
171 |
return Section(section_header, name, self.stream) |
172 |
|
173 |
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/enums.py |
174 |
--- a/elftools/elf/enums.py Thu Jul 05 06:32:09 2012 +0300 |
175 |
+++ b/elftools/elf/enums.py Mon Nov 12 16:27:19 2012 -0500 |
176 |
@@ -186,6 +186,82 @@ |
177 |
_default_=Pass, |
178 |
) |
179 |
|
180 |
+# d_tag |
181 |
+ENUM_D_TAG = dict( |
182 |
+ DT_NULL=0, |
183 |
+ DT_NEEDED=1, |
184 |
+ DT_PLTRELSZ=2, |
185 |
+ DT_PLTGOT=3, |
186 |
+ DT_HASH=4, |
187 |
+ DT_STRTAB=5, |
188 |
+ DT_SYMTAB=6, |
189 |
+ DT_RELA=7, |
190 |
+ DT_RELASZ=8, |
191 |
+ DT_RELAENT=9, |
192 |
+ DT_STRSZ=10, |
193 |
+ DT_SYMENT=11, |
194 |
+ DT_INIT=12, |
195 |
+ DT_FINI=13, |
196 |
+ DT_SONAME=14, |
197 |
+ DT_RPATH=15, |
198 |
+ DT_SYMBOLIC=16, |
199 |
+ DT_REL=17, |
200 |
+ DT_RELSZ=18, |
201 |
+ DT_RELENT=19, |
202 |
+ DT_PLTREL=20, |
203 |
+ DT_DEBUG=21, |
204 |
+ DT_TEXTREL=22, |
205 |
+ DT_JMPREL=23, |
206 |
+ DT_BIND_NOW=24, |
207 |
+ DT_INIT_ARRAY=25, |
208 |
+ DT_FINI_ARRAY=26, |
209 |
+ DT_INIT_ARRAYSZ=27, |
210 |
+ DT_FINI_ARRAYSZ=28, |
211 |
+ DT_RUNPATH=29, |
212 |
+ DT_FLAGS=30, |
213 |
+ DT_ENCODING=32, |
214 |
+ DT_PREINIT_ARRAY=32, |
215 |
+ DT_PREINIT_ARRAYSZ=33, |
216 |
+ DT_NUM=34, |
217 |
+ DT_LOOS=0x6000000d, |
218 |
+ DT_HIOS=0x6ffff000, |
219 |
+ DT_LOPROC=0x70000000, |
220 |
+ DT_HIPROC=0x7fffffff, |
221 |
+ DT_PROCNUM=0x35, |
222 |
+ DT_VALRNGLO=0x6ffffd00, |
223 |
+ DT_GNU_PRELINKED=0x6ffffdf5, |
224 |
+ DT_GNU_CONFLICTSZ=0x6ffffdf6, |
225 |
+ DT_GNU_LIBLISTSZ=0x6ffffdf7, |
226 |
+ DT_CHECKSUM=0x6ffffdf8, |
227 |
+ DT_PLTPADSZ=0x6ffffdf9, |
228 |
+ DT_MOVEENT=0x6ffffdfa, |
229 |
+ DT_MOVESZ=0x6ffffdfb, |
230 |
+ DT_SYMINSZ=0x6ffffdfe, |
231 |
+ DT_SYMINENT=0x6ffffdff, |
232 |
+ DT_GNU_HASH=0x6ffffef5, |
233 |
+ DT_TLSDESC_PLT=0x6ffffef6, |
234 |
+ DT_TLSDESC_GOT=0x6ffffef7, |
235 |
+ DT_GNU_CONFLICT=0x6ffffef8, |
236 |
+ DT_GNU_LIBLIST=0x6ffffef9, |
237 |
+ DT_CONFIG=0x6ffffefa, |
238 |
+ DT_DEPAUDIT=0x6ffffefb, |
239 |
+ DT_AUDIT=0x6ffffefc, |
240 |
+ DT_PLTPAD=0x6ffffefd, |
241 |
+ DT_MOVETAB=0x6ffffefe, |
242 |
+ DT_SYMINFO=0x6ffffeff, |
243 |
+ DT_VERSYM=0x6ffffff0, |
244 |
+ DT_RELACOUNT=0x6ffffff9, |
245 |
+ DT_RELCOUNT=0x6ffffffa, |
246 |
+ DT_FLAGS_1=0x6ffffffb, |
247 |
+ DT_VERDEF=0x6ffffffc, |
248 |
+ DT_VERDEFNUM=0x6ffffffd, |
249 |
+ DT_VERNEED=0x6ffffffe, |
250 |
+ DT_VERNEEDNUM=0x6fffffff, |
251 |
+ DT_AUXILIARY=0x7ffffffd, |
252 |
+ DT_FILTER=0x7fffffff, |
253 |
+ _default_=Pass, |
254 |
+) |
255 |
+ |
256 |
ENUM_RELOC_TYPE_i386 = dict( |
257 |
R_386_NONE=0, |
258 |
R_386_32=1, |
259 |
diff -r f3408c7b9549 -r a9c9b2f9ec96 elftools/elf/structs.py |
260 |
--- a/elftools/elf/structs.py Thu Jul 05 06:32:09 2012 +0300 |
261 |
+++ b/elftools/elf/structs.py Mon Nov 12 16:27:19 2012 -0500 |
262 |
@@ -72,6 +72,7 @@ |
263 |
self._create_shdr() |
264 |
self._create_sym() |
265 |
self._create_rel() |
266 |
+ self._create_dyn() |
267 |
|
268 |
def _create_ehdr(self): |
269 |
self.Elf_Ehdr = Struct('Elf_Ehdr', |
270 |
@@ -165,6 +166,13 @@ |
271 |
self.Elf_sxword('r_addend'), |
272 |
) |
273 |
|
274 |
+ def _create_dyn(self): |
275 |
+ self.Elf_Dyn = Struct('Elf_Dyn', |
276 |
+ Enum(self.Elf_sxword('d_tag'), **ENUM_D_TAG), |
277 |
+ self.Elf_xword('d_val'), |
278 |
+ Value('d_ptr', lambda ctx: ctx['d_val']), |
279 |
+ ) |
280 |
+ |
281 |
def _create_sym(self): |
282 |
# st_info is hierarchical. To access the type, use |
283 |
# container['st_info']['type'] |
284 |
|
285 |
|
286 |
|
287 |
1.1 dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch |
288 |
|
289 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch?rev=1.1&view=markup |
290 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/pyelftools/files/pyelftools-0.20-dyntags-2.patch?rev=1.1&content-type=text/plain |
291 |
|
292 |
Index: pyelftools-0.20-dyntags-2.patch |
293 |
=================================================================== |
294 |
# HG changeset patch |
295 |
# User Mike Frysinger <vapier@g.o> |
296 |
# Date 1354166686 18000 |
297 |
# Node ID 94901c23fe58ca227aacadcdc5d7ad3045171b24 |
298 |
# Parent a9c9b2f9ec964e6750dd6f9a96767fe2e9201d85 |
299 |
rework dynamic tag walking to avoid doing it twice on the first call to iter_tags |
300 |
|
301 |
Based on suggestions from David James |
302 |
|
303 |
diff -r a9c9b2f9ec96 -r 94901c23fe58 elftools/elf/dynamic.py |
304 |
--- a/elftools/elf/dynamic.py Mon Nov 12 16:27:19 2012 -0500 |
305 |
+++ b/elftools/elf/dynamic.py Thu Nov 29 00:24:46 2012 -0500 |
306 |
@@ -6,6 +6,8 @@ |
307 |
# Mike Frysinger (vapier@g.o) |
308 |
# This code is in the public domain |
309 |
#------------------------------------------------------------------------------- |
310 |
+import itertools |
311 |
+ |
312 |
from .sections import Section |
313 |
from .segments import Segment |
314 |
from ..common.utils import struct_parse |
315 |
@@ -20,11 +22,12 @@ |
316 |
Similarly to Section objects, allows dictionary-like access to the |
317 |
dynamic tag. |
318 |
""" |
319 |
+ |
320 |
+ _HANDLED_TAGS = frozenset(['DT_NEEDED', 'DT_RPATH', 'DT_RUNPATH']) |
321 |
+ |
322 |
def __init__(self, entry, elffile): |
323 |
self.entry = entry |
324 |
- if entry.d_tag == 'DT_NEEDED' or \ |
325 |
- entry.d_tag == 'DT_RPATH' or \ |
326 |
- entry.d_tag == 'DT_RUNPATH': |
327 |
+ if entry.d_tag in self._HANDLED_TAGS: |
328 |
dynstr = elffile.get_section_by_name('.dynstr') |
329 |
setattr(self, entry.d_tag[3:].lower(), dynstr.get_string(self.entry.d_val)) |
330 |
|
331 |
@@ -37,9 +40,7 @@ |
332 |
return '<DynamicTag (%s): %r>' % (self.entry.d_tag, self.entry) |
333 |
|
334 |
def __str__(self): |
335 |
- if self.entry.d_tag == 'DT_NEEDED' or \ |
336 |
- self.entry.d_tag == 'DT_RPATH' or \ |
337 |
- self.entry.d_tag == 'DT_RUNPATH': |
338 |
+ if self.entry.d_tag in self._HANDLED_TAGS: |
339 |
s = '"%s"' % getattr(self, self.entry.d_tag[3:].lower()) |
340 |
else: |
341 |
s = '%#x' % self.entry.d_ptr |
342 |
@@ -58,16 +59,12 @@ |
343 |
def iter_tags(self, type=None): |
344 |
""" Yield all tags (limit to |type| if specified) |
345 |
""" |
346 |
- offset = self._offset - self._tagsize |
347 |
- for i in range(self.num_tags): |
348 |
- offset += self._tagsize |
349 |
- entry = struct_parse( |
350 |
- self._elfstructs.Elf_Dyn, |
351 |
- self._stream, |
352 |
- stream_pos=offset) |
353 |
- if type is not None and entry.d_tag != type: |
354 |
- continue |
355 |
- yield DynamicTag(entry, self._elffile) |
356 |
+ for n in itertools.count(): |
357 |
+ tag = self.get_tag(n) |
358 |
+ if type is None or tag.entry.d_tag == type: |
359 |
+ yield tag |
360 |
+ if tag.entry.d_tag == 'DT_NULL': |
361 |
+ break |
362 |
|
363 |
def get_tag(self, n): |
364 |
""" Get the tag at index #n from the file (DynamicTag object) |
365 |
@@ -86,17 +83,11 @@ |
366 |
if self._num_tags != -1: |
367 |
return self._num_tags |
368 |
|
369 |
- offset = self._offset |
370 |
- while True: |
371 |
- entry = struct_parse( |
372 |
- self._elfstructs.Elf_Dyn, |
373 |
- self._stream, |
374 |
- stream_pos=offset) |
375 |
- if entry.d_tag == 'DT_NULL': |
376 |
- self._num_tags = ((offset - self._offset) // self._tagsize) + 1 |
377 |
- break |
378 |
- offset += self._tagsize |
379 |
- return self._num_tags |
380 |
+ for n in itertools.count(): |
381 |
+ tag = self.get_tag(n) |
382 |
+ if tag.entry.d_tag == 'DT_NULL': |
383 |
+ self._num_tags = n |
384 |
+ return n |
385 |
|
386 |
|
387 |
class DynamicSection(Section, Dynamic): |