Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / pyelftools / elftools / elf / dynamic.py
1 #-------------------------------------------------------------------------------
2 # elftools: elf/dynamic.py
3 #
4 # ELF Dynamic Tags
5 #
6 # Mike Frysinger (vapier@gentoo.org)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
9 import itertools
10
11 from .sections import Section
12 from .segments import Segment
13 from ..common.utils import struct_parse
14
15 from enums import ENUM_D_TAG
16
17
18 class DynamicTag(object):
19     """ Dynamic Tag object - representing a single dynamic tag entry from a
20         dynamic section.
21
22         Similarly to Section objects, allows dictionary-like access to the
23         dynamic tag.
24     """
25
26     _HANDLED_TAGS = frozenset(['DT_NEEDED', 'DT_RPATH', 'DT_RUNPATH'])
27
28     def __init__(self, entry, elffile):
29         self.entry = entry
30         if entry.d_tag in self._HANDLED_TAGS:
31             dynstr = elffile.get_section_by_name('.dynstr')
32             setattr(self, entry.d_tag[3:].lower(), dynstr.get_string(self.entry.d_val))
33
34     def __getitem__(self, name):
35         """ Implement dict-like access to entries
36         """
37         return self.entry[name]
38
39     def __repr__(self):
40         return '<DynamicTag (%s): %r>' % (self.entry.d_tag, self.entry)
41
42     def __str__(self):
43         if self.entry.d_tag in self._HANDLED_TAGS:
44             s = '"%s"' % getattr(self, self.entry.d_tag[3:].lower())
45         else:
46             s = '%#x' % self.entry.d_ptr
47         return '<DynamicTag (%s) %s>' % (self.entry.d_tag, s)
48
49
50 class Dynamic(object):
51     def __init__(self, stream, elffile, position):
52         self._stream = stream
53         self._elffile = elffile
54         self._elfstructs = elffile.structs
55         self._num_tags = -1;
56         self._offset = position
57         self._tagsize = self._elfstructs.Elf_Dyn.sizeof()
58
59     def iter_tags(self, type=None):
60         """ Yield all tags (limit to |type| if specified)
61         """
62         for n in itertools.count():
63             tag = self.get_tag(n)
64             if type is None or tag.entry.d_tag == type:
65                 yield tag
66             if tag.entry.d_tag == 'DT_NULL':
67                 break
68
69     def get_tag(self, n):
70         """ Get the tag at index #n from the file (DynamicTag object)
71         """
72         offset = self._offset + n * self._tagsize
73         entry = struct_parse(
74             self._elfstructs.Elf_Dyn,
75             self._stream,
76             stream_pos=offset)
77         return DynamicTag(entry, self._elffile)
78
79     @property
80     def num_tags(self):
81         """ Number of dynamic tags in the file
82         """
83         if self._num_tags != -1:
84             return self._num_tags
85
86         for n in itertools.count():
87             tag = self.get_tag(n)
88             if tag.entry.d_tag == 'DT_NULL':
89                 self._num_tags = n
90                 return n
91
92
93 class DynamicSection(Section, Dynamic):
94     """ ELF dynamic table section.  Knows how to process the list of tags.
95     """
96     def __init__(self, header, name, stream, elffile):
97         Section.__init__(self, header, name, stream)
98         Dynamic.__init__(self, stream, elffile, self['sh_offset'])
99
100
101 class DynamicSegment(Segment, Dynamic):
102     """ ELF dynamic table segment.  Knows how to process the list of tags.
103     """
104     def __init__(self, header, stream, elffile):
105         Segment.__init__(self, header, stream)
106         Dynamic.__init__(self, stream, elffile, self['p_offset'])