1 //===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <cstring> 11 12 #include "lldb/Core/DataExtractor.h" 13 #include "lldb/Core/Section.h" 14 #include "lldb/Core/Stream.h" 15 16 #include "ELFHeader.h" 17 18 using namespace elf; 19 using namespace lldb; 20 using namespace llvm::ELF; 21 22 //------------------------------------------------------------------------------ 23 // Static utility functions. 24 // 25 // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor 26 // with error handling code and provide for parsing a sequence of values. 27 static bool 28 GetMaxU64(const lldb_private::DataExtractor &data, 29 lldb::offset_t *offset, 30 uint64_t *value, 31 uint32_t byte_size) 32 { 33 const lldb::offset_t saved_offset = *offset; 34 *value = data.GetMaxU64(offset, byte_size); 35 return *offset != saved_offset; 36 } 37 38 static bool 39 GetMaxU64(const lldb_private::DataExtractor &data, 40 lldb::offset_t *offset, 41 uint64_t *value, 42 uint32_t byte_size, 43 uint32_t count) 44 { 45 lldb::offset_t saved_offset = *offset; 46 47 for (uint32_t i = 0; i < count; ++i, ++value) 48 { 49 if (GetMaxU64(data, offset, value, byte_size) == false) 50 { 51 *offset = saved_offset; 52 return false; 53 } 54 } 55 return true; 56 } 57 58 static bool 59 GetMaxS64(const lldb_private::DataExtractor &data, 60 lldb::offset_t *offset, 61 int64_t *value, 62 uint32_t byte_size) 63 { 64 const lldb::offset_t saved_offset = *offset; 65 *value = data.GetMaxS64(offset, byte_size); 66 return *offset != saved_offset; 67 } 68 69 static bool 70 GetMaxS64(const lldb_private::DataExtractor &data, 71 lldb::offset_t *offset, 72 int64_t *value, 73 uint32_t byte_size, 74 uint32_t count) 75 { 76 lldb::offset_t saved_offset = *offset; 77 78 for (uint32_t i = 0; i < count; ++i, ++value) 79 { 80 if (GetMaxS64(data, offset, value, byte_size) == false) 81 { 82 *offset = saved_offset; 83 return false; 84 } 85 } 86 return true; 87 } 88 89 //------------------------------------------------------------------------------ 90 // ELFHeader 91 92 ELFHeader::ELFHeader() 93 { 94 memset(this, 0, sizeof(ELFHeader)); 95 } 96 97 ByteOrder 98 ELFHeader::GetByteOrder() const 99 { 100 if (e_ident[EI_DATA] == ELFDATA2MSB) 101 return eByteOrderBig; 102 if (e_ident[EI_DATA] == ELFDATA2LSB) 103 return eByteOrderLittle; 104 return eByteOrderInvalid; 105 } 106 107 bool 108 ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset) 109 { 110 // Read e_ident. This provides byte order and address size info. 111 if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) 112 return false; 113 114 const unsigned byte_size = Is32Bit() ? 4 : 8; 115 data.SetByteOrder(GetByteOrder()); 116 data.SetAddressByteSize(byte_size); 117 118 // Read e_type and e_machine. 119 if (data.GetU16(offset, &e_type, 2) == NULL) 120 return false; 121 122 // Read e_version. 123 if (data.GetU32(offset, &e_version, 1) == NULL) 124 return false; 125 126 // Read e_entry, e_phoff and e_shoff. 127 if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) 128 return false; 129 130 // Read e_flags. 131 if (data.GetU32(offset, &e_flags, 1) == NULL) 132 return false; 133 134 // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and 135 // e_shstrndx. 136 if (data.GetU16(offset, &e_ehsize, 6) == NULL) 137 return false; 138 139 return true; 140 } 141 142 bool 143 ELFHeader::MagicBytesMatch(const uint8_t *magic) 144 { 145 return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0; 146 } 147 148 unsigned 149 ELFHeader::AddressSizeInBytes(const uint8_t *magic) 150 { 151 unsigned address_size = 0; 152 153 switch (magic[EI_CLASS]) 154 { 155 case ELFCLASS32: 156 address_size = 4; 157 break; 158 159 case ELFCLASS64: 160 address_size = 8; 161 break; 162 } 163 return address_size; 164 } 165 166 unsigned 167 ELFHeader::GetRelocationJumpSlotType() const 168 { 169 unsigned slot = 0; 170 171 switch (e_machine) 172 { 173 default: 174 assert(false && "architecture not supported"); 175 break; 176 case EM_PPC: 177 slot = R_PPC_JMP_SLOT; 178 break; 179 case EM_PPC64: 180 slot = R_PPC64_JMP_SLOT; 181 break; 182 case EM_386: 183 case EM_IAMCU: // FIXME: is this correct? 184 slot = R_386_JUMP_SLOT; 185 break; 186 case EM_X86_64: 187 slot = R_X86_64_JUMP_SLOT; 188 break; 189 case EM_ARM: 190 slot = R_ARM_JUMP_SLOT; 191 break; 192 case EM_HEXAGON: 193 slot = R_HEX_JMP_SLOT; 194 break; 195 case EM_AARCH64: 196 slot = R_AARCH64_JUMP_SLOT; 197 break; 198 case EM_MIPS: 199 slot = R_MIPS_JUMP_SLOT; 200 break; 201 case EM_S390: 202 slot = R_390_JMP_SLOT; 203 break; 204 } 205 206 return slot; 207 } 208 209 //------------------------------------------------------------------------------ 210 // ELFSectionHeader 211 212 ELFSectionHeader::ELFSectionHeader() 213 { 214 memset(this, 0, sizeof(ELFSectionHeader)); 215 } 216 217 bool 218 ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, 219 lldb::offset_t *offset) 220 { 221 const unsigned byte_size = data.GetAddressByteSize(); 222 223 // Read sh_name and sh_type. 224 if (data.GetU32(offset, &sh_name, 2) == NULL) 225 return false; 226 227 // Read sh_flags. 228 if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) 229 return false; 230 231 // Read sh_addr, sh_off and sh_size. 232 if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) 233 return false; 234 235 // Read sh_link and sh_info. 236 if (data.GetU32(offset, &sh_link, 2) == NULL) 237 return false; 238 239 // Read sh_addralign and sh_entsize. 240 if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) 241 return false; 242 243 return true; 244 } 245 246 //------------------------------------------------------------------------------ 247 // ELFSymbol 248 249 ELFSymbol::ELFSymbol() 250 { 251 memset(this, 0, sizeof(ELFSymbol)); 252 } 253 254 #define ENUM_TO_CSTR(e) case e: return #e 255 256 const char * 257 ELFSymbol::bindingToCString(unsigned char binding) 258 { 259 switch (binding) 260 { 261 ENUM_TO_CSTR(STB_LOCAL); 262 ENUM_TO_CSTR(STB_GLOBAL); 263 ENUM_TO_CSTR(STB_WEAK); 264 ENUM_TO_CSTR(STB_LOOS); 265 ENUM_TO_CSTR(STB_HIOS); 266 ENUM_TO_CSTR(STB_LOPROC); 267 ENUM_TO_CSTR(STB_HIPROC); 268 } 269 return ""; 270 } 271 272 const char * 273 ELFSymbol::typeToCString(unsigned char type) 274 { 275 switch (type) 276 { 277 ENUM_TO_CSTR(STT_NOTYPE); 278 ENUM_TO_CSTR(STT_OBJECT); 279 ENUM_TO_CSTR(STT_FUNC); 280 ENUM_TO_CSTR(STT_SECTION); 281 ENUM_TO_CSTR(STT_FILE); 282 ENUM_TO_CSTR(STT_COMMON); 283 ENUM_TO_CSTR(STT_TLS); 284 ENUM_TO_CSTR(STT_GNU_IFUNC); 285 ENUM_TO_CSTR(STT_HIOS); 286 ENUM_TO_CSTR(STT_LOPROC); 287 ENUM_TO_CSTR(STT_HIPROC); 288 } 289 return ""; 290 } 291 292 const char * 293 ELFSymbol::sectionIndexToCString (elf_half shndx, 294 const lldb_private::SectionList *section_list) 295 { 296 switch (shndx) 297 { 298 ENUM_TO_CSTR(SHN_UNDEF); 299 ENUM_TO_CSTR(SHN_LOPROC); 300 ENUM_TO_CSTR(SHN_HIPROC); 301 ENUM_TO_CSTR(SHN_LOOS); 302 ENUM_TO_CSTR(SHN_HIOS); 303 ENUM_TO_CSTR(SHN_ABS); 304 ENUM_TO_CSTR(SHN_COMMON); 305 ENUM_TO_CSTR(SHN_XINDEX); 306 default: 307 { 308 const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get(); 309 if (section) 310 return section->GetName().AsCString(""); 311 } 312 break; 313 } 314 return ""; 315 } 316 317 void 318 ELFSymbol::Dump (lldb_private::Stream *s, 319 uint32_t idx, 320 const lldb_private::DataExtractor *strtab_data, 321 const lldb_private::SectionList *section_list) 322 { 323 s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n", 324 idx, 325 st_value, 326 st_size, 327 st_name, 328 st_info, 329 bindingToCString (getBinding()), 330 typeToCString (getType()), 331 st_other, 332 st_shndx, 333 sectionIndexToCString (st_shndx, section_list), 334 strtab_data ? strtab_data->PeekCStr(st_name) : ""); 335 } 336 337 bool 338 ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 339 { 340 const unsigned byte_size = data.GetAddressByteSize(); 341 const bool parsing_32 = byte_size == 4; 342 343 // Read st_name. 344 if (data.GetU32(offset, &st_name, 1) == NULL) 345 return false; 346 347 if (parsing_32) 348 { 349 // Read st_value and st_size. 350 if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) 351 return false; 352 353 // Read st_info and st_other. 354 if (data.GetU8(offset, &st_info, 2) == NULL) 355 return false; 356 357 // Read st_shndx. 358 if (data.GetU16(offset, &st_shndx, 1) == NULL) 359 return false; 360 } 361 else 362 { 363 // Read st_info and st_other. 364 if (data.GetU8(offset, &st_info, 2) == NULL) 365 return false; 366 367 // Read st_shndx. 368 if (data.GetU16(offset, &st_shndx, 1) == NULL) 369 return false; 370 371 // Read st_value and st_size. 372 if (data.GetU64(offset, &st_value, 2) == NULL) 373 return false; 374 } 375 return true; 376 } 377 378 //------------------------------------------------------------------------------ 379 // ELFProgramHeader 380 381 ELFProgramHeader::ELFProgramHeader() 382 { 383 memset(this, 0, sizeof(ELFProgramHeader)); 384 } 385 386 bool 387 ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, 388 lldb::offset_t *offset) 389 { 390 const uint32_t byte_size = data.GetAddressByteSize(); 391 const bool parsing_32 = byte_size == 4; 392 393 // Read p_type; 394 if (data.GetU32(offset, &p_type, 1) == NULL) 395 return false; 396 397 if (parsing_32) { 398 // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. 399 if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) 400 return false; 401 402 // Read p_flags. 403 if (data.GetU32(offset, &p_flags, 1) == NULL) 404 return false; 405 406 // Read p_align. 407 if (GetMaxU64(data, offset, &p_align, byte_size) == false) 408 return false; 409 } 410 else { 411 // Read p_flags. 412 if (data.GetU32(offset, &p_flags, 1) == NULL) 413 return false; 414 415 // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. 416 if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) 417 return false; 418 } 419 420 return true; 421 } 422 423 //------------------------------------------------------------------------------ 424 // ELFDynamic 425 426 ELFDynamic::ELFDynamic() 427 { 428 memset(this, 0, sizeof(ELFDynamic)); 429 } 430 431 bool 432 ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 433 { 434 const unsigned byte_size = data.GetAddressByteSize(); 435 return GetMaxS64(data, offset, &d_tag, byte_size, 2); 436 } 437 438 //------------------------------------------------------------------------------ 439 // ELFRel 440 441 ELFRel::ELFRel() 442 { 443 memset(this, 0, sizeof(ELFRel)); 444 } 445 446 bool 447 ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 448 { 449 const unsigned byte_size = data.GetAddressByteSize(); 450 451 // Read r_offset and r_info. 452 if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) 453 return false; 454 455 return true; 456 } 457 458 //------------------------------------------------------------------------------ 459 // ELFRela 460 461 ELFRela::ELFRela() 462 { 463 memset(this, 0, sizeof(ELFRela)); 464 } 465 466 bool 467 ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 468 { 469 const unsigned byte_size = data.GetAddressByteSize(); 470 471 // Read r_offset and r_info. 472 if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) 473 return false; 474 475 // Read r_addend; 476 if (GetMaxS64(data, offset, &r_addend, byte_size) == false) 477 return false; 478 479 return true; 480 } 481 482 483