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 18using namespace elf; 19using namespace lldb; 20using 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. 27static bool 28GetMaxU64(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 38static bool 39GetMaxU64(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 58static bool 59GetMaxS64(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 69static bool 70GetMaxS64(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 92ELFHeader::ELFHeader() 93{ 94 memset(this, 0, sizeof(ELFHeader)); 95} 96 97ByteOrder 98ELFHeader::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 107bool 108ELFHeader::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 142bool 143ELFHeader::MagicBytesMatch(const uint8_t *magic) 144{ 145 return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0; 146} 147 148unsigned 149ELFHeader::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 166unsigned 167ELFHeader::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_386: 177 case EM_486: 178 slot = R_386_JUMP_SLOT; 179 break; 180 case EM_X86_64: 181 slot = R_X86_64_JUMP_SLOT; 182 break; 183 case EM_ARM: 184 slot = R_ARM_JUMP_SLOT; 185 break; 186 } 187 188 return slot; 189} 190 191//------------------------------------------------------------------------------ 192// ELFSectionHeader 193 194ELFSectionHeader::ELFSectionHeader() 195{ 196 memset(this, 0, sizeof(ELFSectionHeader)); 197} 198 199bool 200ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, 201 lldb::offset_t *offset) 202{ 203 const unsigned byte_size = data.GetAddressByteSize(); 204 205 // Read sh_name and sh_type. 206 if (data.GetU32(offset, &sh_name, 2) == NULL) 207 return false; 208 209 // Read sh_flags. 210 if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) 211 return false; 212 213 // Read sh_addr, sh_off and sh_size. 214 if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) 215 return false; 216 217 // Read sh_link and sh_info. 218 if (data.GetU32(offset, &sh_link, 2) == NULL) 219 return false; 220 221 // Read sh_addralign and sh_entsize. 222 if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) 223 return false; 224 225 return true; 226} 227 228//------------------------------------------------------------------------------ 229// ELFSymbol 230 231ELFSymbol::ELFSymbol() 232{ 233 memset(this, 0, sizeof(ELFSymbol)); 234} 235 236#define ENUM_TO_CSTR(e) case e: return #e 237 238const char * 239ELFSymbol::bindingToCString(unsigned char binding) 240{ 241 switch (binding) 242 { 243 ENUM_TO_CSTR(STB_LOCAL); 244 ENUM_TO_CSTR(STB_GLOBAL); 245 ENUM_TO_CSTR(STB_WEAK); 246 ENUM_TO_CSTR(STB_LOOS); 247 ENUM_TO_CSTR(STB_HIOS); 248 ENUM_TO_CSTR(STB_LOPROC); 249 ENUM_TO_CSTR(STB_HIPROC); 250 } 251 return ""; 252} 253 254const char * 255ELFSymbol::typeToCString(unsigned char type) 256{ 257 switch (type) 258 { 259 ENUM_TO_CSTR(STT_NOTYPE); 260 ENUM_TO_CSTR(STT_OBJECT); 261 ENUM_TO_CSTR(STT_FUNC); 262 ENUM_TO_CSTR(STT_SECTION); 263 ENUM_TO_CSTR(STT_FILE); 264 ENUM_TO_CSTR(STT_COMMON); 265 ENUM_TO_CSTR(STT_TLS); 266 ENUM_TO_CSTR(STT_LOOS); 267 ENUM_TO_CSTR(STT_HIOS); 268 ENUM_TO_CSTR(STT_GNU_IFUNC); 269 ENUM_TO_CSTR(STT_LOPROC); 270 ENUM_TO_CSTR(STT_HIPROC); 271 } 272 return ""; 273} 274 275const char * 276ELFSymbol::sectionIndexToCString (elf_half shndx, 277 const lldb_private::SectionList *section_list) 278{ 279 switch (shndx) 280 { 281 ENUM_TO_CSTR(SHN_UNDEF); 282 ENUM_TO_CSTR(SHN_LOPROC); 283 ENUM_TO_CSTR(SHN_HIPROC); 284 ENUM_TO_CSTR(SHN_LOOS); 285 ENUM_TO_CSTR(SHN_HIOS); 286 ENUM_TO_CSTR(SHN_ABS); 287 ENUM_TO_CSTR(SHN_COMMON); 288 ENUM_TO_CSTR(SHN_XINDEX); 289 default: 290 { 291 const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get(); 292 if (section) 293 return section->GetName().AsCString(""); 294 } 295 break; 296 } 297 return ""; 298} 299 300void 301ELFSymbol::Dump (lldb_private::Stream *s, 302 uint32_t idx, 303 const lldb_private::DataExtractor *strtab_data, 304 const lldb_private::SectionList *section_list) 305{ 306 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", 307 idx, 308 st_value, 309 st_size, 310 st_name, 311 st_info, 312 bindingToCString (getBinding()), 313 typeToCString (getType()), 314 st_other, 315 st_shndx, 316 sectionIndexToCString (st_shndx, section_list), 317 strtab_data ? strtab_data->PeekCStr(st_name) : ""); 318} 319 320bool 321ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 322{ 323 const unsigned byte_size = data.GetAddressByteSize(); 324 const bool parsing_32 = byte_size == 4; 325 326 // Read st_name. 327 if (data.GetU32(offset, &st_name, 1) == NULL) 328 return false; 329 330 if (parsing_32) 331 { 332 // Read st_value and st_size. 333 if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) 334 return false; 335 336 // Read st_info and st_other. 337 if (data.GetU8(offset, &st_info, 2) == NULL) 338 return false; 339 340 // Read st_shndx. 341 if (data.GetU16(offset, &st_shndx, 1) == NULL) 342 return false; 343 } 344 else 345 { 346 // Read st_info and st_other. 347 if (data.GetU8(offset, &st_info, 2) == NULL) 348 return false; 349 350 // Read st_shndx. 351 if (data.GetU16(offset, &st_shndx, 1) == NULL) 352 return false; 353 354 // Read st_value and st_size. 355 if (data.GetU64(offset, &st_value, 2) == NULL) 356 return false; 357 } 358 return true; 359} 360 361//------------------------------------------------------------------------------ 362// ELFProgramHeader 363 364ELFProgramHeader::ELFProgramHeader() 365{ 366 memset(this, 0, sizeof(ELFProgramHeader)); 367} 368 369bool 370ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, 371 lldb::offset_t *offset) 372{ 373 const uint32_t byte_size = data.GetAddressByteSize(); 374 const bool parsing_32 = byte_size == 4; 375 376 // Read p_type; 377 if (data.GetU32(offset, &p_type, 1) == NULL) 378 return false; 379 380 if (parsing_32) { 381 // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. 382 if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) 383 return false; 384 385 // Read p_flags. 386 if (data.GetU32(offset, &p_flags, 1) == NULL) 387 return false; 388 389 // Read p_align. 390 if (GetMaxU64(data, offset, &p_align, byte_size) == false) 391 return false; 392 } 393 else { 394 // Read p_flags. 395 if (data.GetU32(offset, &p_flags, 1) == NULL) 396 return false; 397 398 // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. 399 if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) 400 return false; 401 } 402 403 return true; 404} 405 406//------------------------------------------------------------------------------ 407// ELFDynamic 408 409ELFDynamic::ELFDynamic() 410{ 411 memset(this, 0, sizeof(ELFDynamic)); 412} 413 414bool 415ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 416{ 417 const unsigned byte_size = data.GetAddressByteSize(); 418 return GetMaxS64(data, offset, &d_tag, byte_size, 2); 419} 420 421//------------------------------------------------------------------------------ 422// ELFRel 423 424ELFRel::ELFRel() 425{ 426 memset(this, 0, sizeof(ELFRel)); 427} 428 429bool 430ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 431{ 432 const unsigned byte_size = data.GetAddressByteSize(); 433 434 // Read r_offset and r_info. 435 if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) 436 return false; 437 438 return true; 439} 440 441//------------------------------------------------------------------------------ 442// ELFRela 443 444ELFRela::ELFRela() 445{ 446 memset(this, 0, sizeof(ELFRela)); 447} 448 449bool 450ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) 451{ 452 const unsigned byte_size = data.GetAddressByteSize(); 453 454 // Read r_offset and r_info. 455 if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) 456 return false; 457 458 // Read r_addend; 459 if (GetMaxS64(data, offset, &r_addend, byte_size) == false) 460 return false; 461 462 return true; 463} 464 465 466