Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / pyelftools / elftools / elf / structs.py
1 #-------------------------------------------------------------------------------
2 # elftools: elf/structs.py
3 #
4 # Encapsulation of Construct structs for parsing an ELF file, adjusted for
5 # correct endianness and word-size.
6 #
7 # Eli Bendersky (eliben@gmail.com)
8 # This code is in the public domain
9 #-------------------------------------------------------------------------------
10 from ..construct import (
11     UBInt8, UBInt16, UBInt32, UBInt64,
12     ULInt8, ULInt16, ULInt32, ULInt64,
13     SBInt32, SLInt32, SBInt64, SLInt64,
14     Struct, Array, Enum, Padding, BitStruct, BitField, Value,
15     )
16
17 from .enums import *
18
19
20 class ELFStructs(object):
21     """ Accessible attributes:
22     
23             Elf_{byte|half|word|word64|addr|offset|sword|xword|xsword}:
24                 Data chunks, as specified by the ELF standard, adjusted for 
25                 correct endianness and word-size.
26
27             Elf_Ehdr:
28                 ELF file header
29             
30             Elf_Phdr:
31                 Program header
32             
33             Elf_Shdr:
34                 Section header
35             
36             Elf_Sym:
37                 Symbol table entry
38
39             Elf_Rel, Elf_Rela:
40                 Entries in relocation sections
41     """
42     def __init__(self, little_endian=True, elfclass=32):
43         assert elfclass == 32 or elfclass == 64
44         self.little_endian = little_endian
45         self.elfclass = elfclass        
46         self._create_structs()
47     
48     def _create_structs(self):
49         if self.little_endian:
50             self.Elf_byte = ULInt8
51             self.Elf_half = ULInt16
52             self.Elf_word = ULInt32
53             self.Elf_word64 = ULInt64
54             self.Elf_addr = ULInt32 if self.elfclass == 32 else ULInt64
55             self.Elf_offset = self.Elf_addr
56             self.Elf_sword = SLInt32
57             self.Elf_xword = ULInt32 if self.elfclass == 32 else ULInt64
58             self.Elf_sxword = SLInt32 if self.elfclass == 32 else SLInt64
59         else:
60             self.Elf_byte = UBInt8
61             self.Elf_half = UBInt16
62             self.Elf_word = UBInt32
63             self.Elf_word64 = UBInt64
64             self.Elf_addr = UBInt32 if self.elfclass == 32 else UBInt64
65             self.Elf_offset = self.Elf_addr
66             self.Elf_sword = SBInt32
67             self.Elf_xword = UBInt32 if self.elfclass == 32 else UBInt64
68             self.Elf_sxword = SBInt32 if self.elfclass == 32 else SBInt64
69         
70         self._create_ehdr()
71         self._create_phdr()
72         self._create_shdr()
73         self._create_sym()
74         self._create_rel()
75         self._create_dyn()
76     
77     def _create_ehdr(self):
78         self.Elf_Ehdr = Struct('Elf_Ehdr',
79             Struct('e_ident',
80                 Array(4, self.Elf_byte('EI_MAG')),
81                 Enum(self.Elf_byte('EI_CLASS'), **ENUM_EI_CLASS),
82                 Enum(self.Elf_byte('EI_DATA'), **ENUM_EI_DATA),
83                 Enum(self.Elf_byte('EI_VERSION'), **ENUM_E_VERSION),
84                 Enum(self.Elf_byte('EI_OSABI'), **ENUM_EI_OSABI),
85                 self.Elf_byte('EI_ABIVERSION'),
86                 Padding(7)
87             ),
88             Enum(self.Elf_half('e_type'), **ENUM_E_TYPE),
89             Enum(self.Elf_half('e_machine'), **ENUM_E_MACHINE),
90             Enum(self.Elf_word('e_version'), **ENUM_E_VERSION),
91             self.Elf_addr('e_entry'),
92             self.Elf_offset('e_phoff'),
93             self.Elf_offset('e_shoff'),
94             self.Elf_word('e_flags'),
95             self.Elf_half('e_ehsize'),
96             self.Elf_half('e_phentsize'),
97             self.Elf_half('e_phnum'),
98             self.Elf_half('e_shentsize'),
99             self.Elf_half('e_shnum'),
100             self.Elf_half('e_shstrndx'),
101         )
102     
103     def _create_phdr(self):
104         if self.elfclass == 32:
105             self.Elf_Phdr = Struct('Elf_Phdr',
106                 Enum(self.Elf_word('p_type'), **ENUM_P_TYPE),
107                 self.Elf_offset('p_offset'),
108                 self.Elf_addr('p_vaddr'),
109                 self.Elf_addr('p_paddr'),
110                 self.Elf_word('p_filesz'),
111                 self.Elf_word('p_memsz'),
112                 self.Elf_word('p_flags'),
113                 self.Elf_word('p_align'),
114             )
115         else: # 64
116             self.Elf_Phdr = Struct('Elf_Phdr',
117                 Enum(self.Elf_word('p_type'), **ENUM_P_TYPE),
118                 self.Elf_word('p_flags'),
119                 self.Elf_offset('p_offset'),
120                 self.Elf_addr('p_vaddr'),
121                 self.Elf_addr('p_paddr'),
122                 self.Elf_xword('p_filesz'),
123                 self.Elf_xword('p_memsz'),
124                 self.Elf_xword('p_align'),
125             )   
126         
127     def _create_shdr(self):
128         self.Elf_Shdr = Struct('Elf_Shdr',
129             self.Elf_word('sh_name'),
130             Enum(self.Elf_word('sh_type'), **ENUM_SH_TYPE),
131             self.Elf_xword('sh_flags'),
132             self.Elf_addr('sh_addr'),
133             self.Elf_offset('sh_offset'),
134             self.Elf_xword('sh_size'),
135             self.Elf_word('sh_link'),
136             self.Elf_word('sh_info'),
137             self.Elf_xword('sh_addralign'),
138             self.Elf_xword('sh_entsize'),
139         )
140     
141     def _create_rel(self):
142         # r_info is also taken apart into r_info_sym and r_info_type.
143         # This is done in Value to avoid endianity issues while parsing.
144         if self.elfclass == 32:
145             r_info_sym = Value('r_info_sym',
146                 lambda ctx: (ctx['r_info'] >> 8) & 0xFFFFFF)
147             r_info_type = Value('r_info_type',
148                 lambda ctx: ctx['r_info'] & 0xFF)
149         else: # 64
150             r_info_sym = Value('r_info_sym',
151                 lambda ctx: (ctx['r_info'] >> 32) & 0xFFFFFFFF)
152             r_info_type = Value('r_info_type',
153                 lambda ctx: ctx['r_info'] & 0xFFFFFFFF)
154
155         self.Elf_Rel = Struct('Elf_Rel',
156             self.Elf_addr('r_offset'),
157             self.Elf_xword('r_info'),
158             r_info_sym,
159             r_info_type,
160         )
161         self.Elf_Rela = Struct('Elf_Rela',
162             self.Elf_addr('r_offset'),
163             self.Elf_xword('r_info'),
164             r_info_sym,
165             r_info_type,
166             self.Elf_sxword('r_addend'),
167         )
168
169     def _create_dyn(self):
170         self.Elf_Dyn = Struct('Elf_Dyn',
171             Enum(self.Elf_sxword('d_tag'), **ENUM_D_TAG),
172             self.Elf_xword('d_val'),
173             Value('d_ptr', lambda ctx: ctx['d_val']),
174         )
175
176     def _create_sym(self):
177         # st_info is hierarchical. To access the type, use
178         # container['st_info']['type']
179         st_info_struct = BitStruct('st_info',
180             Enum(BitField('bind', 4), **ENUM_ST_INFO_BIND),
181             Enum(BitField('type', 4), **ENUM_ST_INFO_TYPE))
182         # st_other is hierarchical. To access the visibility,
183         # use container['st_other']['visibility']
184         st_other_struct = BitStruct('st_other',
185             Padding(5),
186             Enum(BitField('visibility', 3), **ENUM_ST_VISIBILITY))
187         if self.elfclass == 32:
188             self.Elf_Sym = Struct('Elf_Sym',
189                 self.Elf_word('st_name'),
190                 self.Elf_addr('st_value'),
191                 self.Elf_word('st_size'),
192                 st_info_struct,
193                 st_other_struct,
194                 Enum(self.Elf_half('st_shndx'), **ENUM_ST_SHNDX),
195             )
196         else:
197             self.Elf_Sym = Struct('Elf_Sym',
198                 self.Elf_word('st_name'),
199                 st_info_struct,
200                 st_other_struct,
201                 Enum(self.Elf_half('st_shndx'), **ENUM_ST_SHNDX),
202                 self.Elf_addr('st_value'),
203                 self.Elf_xword('st_size'),
204             )
205
206
207