1# 2# Copyright (C) 2018 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16"""This file contains ELF C structs and data types.""" 17 18import ctypes 19 20from vts.utils.python.library.elf import consts 21 22 23# ELF data types. 24 25 26Elf32_Addr = ctypes.c_uint32 27Elf32_Off = ctypes.c_uint32 28Elf32_Half = ctypes.c_uint16 29Elf32_Word = ctypes.c_uint32 30Elf32_Sword = ctypes.c_int32 31 32Elf64_Addr = ctypes.c_uint64 33Elf64_Off = ctypes.c_uint64 34Elf64_Half = ctypes.c_uint16 35Elf64_Word = ctypes.c_uint32 36Elf64_Sword = ctypes.c_int32 37Elf64_Xword = ctypes.c_uint64 38Elf64_Sxword = ctypes.c_int64 39 40 41# ELF C structs. 42 43 44class CStructure(ctypes.LittleEndianStructure): 45 """Little endian C structure base class.""" 46 pass 47 48 49class CUnion(ctypes.Union): 50 """Native endian C union base class.""" 51 pass 52 53 54class _Ehdr(CStructure): 55 """ELF header base class.""" 56 57 def GetFileClass(self): 58 """Returns the file class.""" 59 return self.e_ident[consts.EI_CLASS] 60 61 def GetDataEncoding(self): 62 """Returns the data encoding of the file.""" 63 return self.e_ident[consts.EI_DATA] 64 65 66class Elf32_Ehdr(_Ehdr): 67 """ELF 32-bit header.""" 68 _fields_ = [('e_ident', ctypes.c_uint8 * consts.EI_NIDENT), 69 ('e_type', Elf32_Half), 70 ('e_machine', Elf32_Half), 71 ('e_version', Elf32_Word), 72 ('e_entry', Elf32_Addr), 73 ('e_phoff', Elf32_Off), 74 ('e_shoff', Elf32_Off), 75 ('e_flags', Elf32_Word), 76 ('e_ehsize', Elf32_Half), 77 ('e_phentsize', Elf32_Half), 78 ('e_phnum', Elf32_Half), 79 ('e_shentsize', Elf32_Half), 80 ('e_shnum', Elf32_Half), 81 ('e_shstrndx', Elf32_Half)] 82 83 84class Elf64_Ehdr(_Ehdr): 85 """ELF 64-bit header.""" 86 _fields_ = [('e_ident', ctypes.c_uint8 * consts.EI_NIDENT), 87 ('e_type', Elf64_Half), 88 ('e_machine', Elf64_Half), 89 ('e_version', Elf64_Word), 90 ('e_entry', Elf64_Addr), 91 ('e_phoff', Elf64_Off), 92 ('e_shoff', Elf64_Off), 93 ('e_flags', Elf64_Word), 94 ('e_ehsize', Elf64_Half), 95 ('e_phentsize', Elf64_Half), 96 ('e_phnum', Elf64_Half), 97 ('e_shentsize', Elf64_Half), 98 ('e_shnum', Elf64_Half), 99 ('e_shstrndx', Elf64_Half)] 100 101 102class Elf32_Shdr(CStructure): 103 """ELF 32-bit section header.""" 104 _fields_ = [('sh_name', Elf32_Word), 105 ('sh_type', Elf32_Word), 106 ('sh_flags', Elf32_Word), 107 ('sh_addr', Elf32_Addr), 108 ('sh_offset', Elf32_Off), 109 ('sh_size', Elf32_Word), 110 ('sh_link', Elf32_Word), 111 ('sh_info', Elf32_Word), 112 ('sh_addralign', Elf32_Word), 113 ('sh_entsize', Elf32_Word)] 114 115 116class Elf64_Shdr(CStructure): 117 """ELF 64-bit section header.""" 118 _fields_ = [('sh_name', Elf64_Word), 119 ('sh_type', Elf64_Word), 120 ('sh_flags', Elf64_Xword), 121 ('sh_addr', Elf64_Addr), 122 ('sh_offset', Elf64_Off), 123 ('sh_size', Elf64_Xword), 124 ('sh_link', Elf64_Word), 125 ('sh_info', Elf64_Word), 126 ('sh_addralign', Elf64_Xword), 127 ('sh_entsize', Elf64_Xword)] 128 129 130class Elf32_Dyn(CStructure): 131 """ELF 32-bit dynamic section entry.""" 132 class _Elf32_Dyn__d_un(CUnion): 133 _fields_ = [('d_val', Elf32_Word), 134 ('d_ptr', Elf32_Addr)] 135 _fields_ = [('d_tag', Elf32_Sword), 136 ('d_un', _Elf32_Dyn__d_un)] 137 138 139class Elf64_Dyn(CStructure): 140 """ELF 64-bit dynamic section entry.""" 141 class _Elf64_Dyn__d_un(CUnion): 142 _fields_ = [('d_val', Elf64_Xword), 143 ('d_ptr', Elf64_Addr)] 144 _fields_ = [('d_tag', Elf64_Sxword), 145 ('d_un', _Elf64_Dyn__d_un)] 146 147 148class _Sym(CStructure): 149 """ELF symbol table entry base class.""" 150 151 def GetBinding(self): 152 """Returns the symbol binding.""" 153 return self.st_info >> 4 154 155 def GetType(self): 156 """Returns the symbol type.""" 157 return self.st_info & 0xf 158 159 def SetBinding(self, binding): 160 """Sets the symbol binding. 161 162 Args: 163 binding: An integer specifying the new binding. 164 """ 165 self.SetSymbolAndType(binding, self.GetType()) 166 167 def SetType(self, type_): 168 """Sets the symbol type. 169 170 Args: 171 type_: An integer specifying the new type. 172 """ 173 self.SetSymbolAndType(self.GetBinding(), type_) 174 175 def SetBindingAndType(self, binding, type_): 176 """Sets the symbol binding and type. 177 178 Args: 179 binding: An integer specifying the new binding. 180 type_: An integer specifying the new type. 181 """ 182 self.st_info = (binding << 4) | (type_ & 0xf) 183 184 185class Elf32_Sym(_Sym): 186 """ELF 32-bit symbol table entry.""" 187 _fields_ = [('st_name', Elf32_Word), 188 ('st_value', Elf32_Addr), 189 ('st_size', Elf32_Word), 190 ('st_info', ctypes.c_uint8), 191 ('st_other', ctypes.c_uint8), 192 ('st_shndx', Elf32_Half)] 193 194 195class Elf64_Sym(_Sym): 196 """ELF 64-bit symbol table entry.""" 197 _fields_ = [('st_name', Elf64_Word), 198 ('st_info', ctypes.c_uint8), 199 ('st_other', ctypes.c_uint8), 200 ('st_shndx', Elf64_Half), 201 ('st_value', Elf64_Addr), 202 ('st_size', Elf64_Xword)] 203 204 205class _32_Rel(CStructure): 206 """ELF 32-bit relocation table entry base class.""" 207 208 def GetSymbol(self): 209 """Returns the symbol table index with respect to the relocation. 210 211 Symbol table index with respect to which the relocation must be made. 212 """ 213 return self.r_info >> 8 214 215 def GetType(self): 216 """Returns the relocation type.""" 217 return self.r_info & 0xff 218 219 def SetSymbol(self, symndx): 220 """Sets the relocation's symbol table index. 221 222 Args: 223 symndx: An integer specifying the new symbol table index. 224 """ 225 self.SetSymbolAndType(symndx, self.GetType()) 226 227 def SetType(self, type_): 228 """Sets the relocation type. 229 230 Args: 231 type_: An integer specifying the new relocation type. 232 """ 233 self.SetSymbolAndType(self.GetSymbol(), type_) 234 235 def SetSymbolAndType(self, symndx, type_): 236 """Sets the relocation's symbol table index and type. 237 238 Args: 239 symndx: An integer specifying the new symbol table index. 240 type_: An integer specifying the new relocation type. 241 """ 242 self.r_info = (symndx << 8) | (type_ & 0xff) 243 244 245class Elf32_Rel(_32_Rel): 246 """ELF 32-bit relocation table entry.""" 247 _fields_ = [('r_offset', Elf32_Addr), 248 ('r_info', Elf32_Word)] 249 250 251class Elf32_Rela(_32_Rel): 252 """ELF 32-bit relocation table entry with explicit addend.""" 253 _fields_ = [('r_offset', Elf32_Addr), 254 ('r_info', Elf32_Word), 255 ('r_addend', Elf32_Sword)] 256 257 258class _64_Rel(CStructure): 259 """ELF 64-bit relocation table entry base class.""" 260 261 def GetSymbol(self): 262 """Returns the symbol table index with respect to the relocation. 263 264 Symbol table index with respect to which the relocation must be made. 265 """ 266 return self.r_info >> 32 267 268 def GetType(self): 269 """Returns the relocation type.""" 270 return self.r_info & 0xffffffff 271 272 def SetSymbol(self, symndx): 273 """Sets the relocation's symbol table index. 274 275 Args: 276 symndx: An integer specifying the new symbol table index. 277 """ 278 self.SetSymbolAndType(symndx, self.GetType()) 279 280 def SetType(self, type_): 281 """Sets the relocation type. 282 283 Args: 284 type_: An integer specifying the new relocation type. 285 """ 286 self.SetSymbolAndType(self.GetSymbol(), type_) 287 288 def SetSymbolAndType(self, symndx, type_): 289 """Sets the relocation's symbol table index and type. 290 291 Args: 292 symndx: An integer specifying the new symbol table index. 293 type_: An integer specifying the new relocation type. 294 """ 295 self.r_info = (symndx << 32) | (type_ & 0xffffffff) 296 297 298class Elf64_Rel(_64_Rel): 299 """ELF 64-bit relocation table entry.""" 300 _fields_ = [('r_offset', Elf64_Addr), 301 ('r_info', Elf64_Xword)] 302 303 304class Elf64_Rela(_64_Rel): 305 """ELF 64-bit relocation table entry with explicit addend.""" 306 _fields_ = [('r_offset', Elf64_Addr), 307 ('r_info', Elf64_Xword), 308 ('r_addend', Elf64_Sxword)] 309 310 311class Elf32_Phdr(CStructure): 312 """ELF 32-bit program header.""" 313 _fields_ = [('p_type', Elf32_Word), 314 ('p_offset', Elf32_Off), 315 ('p_vaddr', Elf32_Addr), 316 ('p_paddr', Elf32_Addr), 317 ('p_filesz', Elf32_Word), 318 ('p_memsz', Elf32_Word), 319 ('p_flags', Elf32_Word), 320 ('p_align', Elf32_Word)] 321 322 323class Elf64_Phdr(CStructure): 324 """ELF 64-bit program header.""" 325 _fields_ = [('p_type', Elf64_Word), 326 ('p_flags', Elf64_Word), 327 ('p_offset', Elf64_Off), 328 ('p_vaddr', Elf64_Addr), 329 ('p_paddr', Elf64_Addr), 330 ('p_filesz', Elf64_Xword), 331 ('p_memsz', Elf64_Xword), 332 ('p_align', Elf64_Xword)] 333 334 335class Elf32_Nhdr(CStructure): 336 """ELF 32-bit note header.""" 337 _fields_ = [('n_namesz', Elf32_Word), 338 ('n_descsz', Elf32_Word), 339 ('n_type', Elf32_Word)] 340 341 342class Elf64_Nhdr(CStructure): 343 """ELF 64-bit note header.""" 344 _fields_ = [('n_namesz', Elf64_Word), 345 ('n_descsz', Elf64_Word), 346 ('n_type', Elf64_Word)] 347