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