12926Sphk//===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===// 22886Sphk// 32886Sphk// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42926Sphk// See https://llvm.org/LICENSE.txt for license information. 52886Sphk// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62886Sphk// 72886Sphk//===----------------------------------------------------------------------===// 82886Sphk 92886Sphk#include <cstring> 102886Sphk 112886Sphk#include "lldb/Core/Section.h" 122886Sphk#include "lldb/Utility/DataExtractor.h" 132886Sphk#include "lldb/Utility/Stream.h" 142886Sphk 152886Sphk#include "ELFHeader.h" 162886Sphk 172886Sphkusing namespace elf; 182886Sphkusing namespace lldb; 192886Sphkusing namespace llvm::ELF; 202886Sphk 212926Sphk// Static utility functions. 222886Sphk// 232886Sphk// GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor 242886Sphk// with error handling code and provide for parsing a sequence of values. 252886Sphkstatic bool GetMaxU64(const lldb_private::DataExtractor &data, 262886Sphk lldb::offset_t *offset, uint64_t *value, 272886Sphk uint32_t byte_size) { 282886Sphk const lldb::offset_t saved_offset = *offset; 292886Sphk *value = data.GetMaxU64(offset, byte_size); 302886Sphk return *offset != saved_offset; 312886Sphk} 322886Sphk 332886Sphkstatic bool GetMaxU64(const lldb_private::DataExtractor &data, 342886Sphk lldb::offset_t *offset, uint64_t *value, 352886Sphk uint32_t byte_size, uint32_t count) { 362886Sphk lldb::offset_t saved_offset = *offset; 372886Sphk 382886Sphk for (uint32_t i = 0; i < count; ++i, ++value) { 392886Sphk if (!GetMaxU64(data, offset, value, byte_size)) { 402886Sphk *offset = saved_offset; 412886Sphk return false; 422926Sphk } 432886Sphk } 442886Sphk return true; 452886Sphk} 462886Sphk 472886Sphkstatic bool GetMaxS64(const lldb_private::DataExtractor &data, 482886Sphk lldb::offset_t *offset, int64_t *value, 492886Sphk uint32_t byte_size) { 502886Sphk const lldb::offset_t saved_offset = *offset; 512926Sphk *value = data.GetMaxS64(offset, byte_size); 522886Sphk return *offset != saved_offset; 532948Sphk} 542926Sphk 552926Sphkstatic bool GetMaxS64(const lldb_private::DataExtractor &data, 562926Sphk lldb::offset_t *offset, int64_t *value, 572926Sphk uint32_t byte_size, uint32_t count) { 582926Sphk lldb::offset_t saved_offset = *offset; 592926Sphk 602886Sphk for (uint32_t i = 0; i < count; ++i, ++value) { 612886Sphk if (!GetMaxS64(data, offset, value, byte_size)) { 622886Sphk *offset = saved_offset; 632886Sphk return false; 642886Sphk } 652886Sphk } 662886Sphk return true; 672886Sphk} 682886Sphk 692886Sphk// ELFHeader 702886Sphk 712886SphkELFHeader::ELFHeader() { memset(this, 0, sizeof(ELFHeader)); } 722886Sphk 732886SphkByteOrder ELFHeader::GetByteOrder() const { 742886Sphk if (e_ident[EI_DATA] == ELFDATA2MSB) 752886Sphk return eByteOrderBig; 762926Sphk if (e_ident[EI_DATA] == ELFDATA2LSB) 772886Sphk return eByteOrderLittle; 782886Sphk return eByteOrderInvalid; 792886Sphk} 802886Sphk 812886Sphkbool ELFHeader::HasHeaderExtension() const { 822886Sphk bool result = false; 832886Sphk 842886Sphk // Check if any of these values looks like sentinel. 852926Sphk result |= e_phnum_hdr == 0xFFFF; // PN_XNUM 862886Sphk result |= e_shnum_hdr == SHN_UNDEF; 872886Sphk result |= e_shstrndx_hdr == SHN_XINDEX; 882886Sphk 892886Sphk // If header extension is present, the section offset cannot be null. 902886Sphk result &= e_shoff != 0; 912886Sphk 922886Sphk // Done. 932886Sphk return result; 942886Sphk} 952886Sphk 962886Sphkvoid ELFHeader::ParseHeaderExtension(lldb_private::DataExtractor &data) { 972886Sphk // Extract section #0 header. 982886Sphk ELFSectionHeader section_zero; 992886Sphk lldb::offset_t offset = 0; 1002886Sphk lldb_private::DataExtractor sh_data(data, e_shoff, e_shentsize); 1012886Sphk bool ok = section_zero.Parse(sh_data, &offset); 1022886Sphk 1032886Sphk // If we succeeded, fix the header. 1042886Sphk if (ok) { 1052886Sphk if (e_phnum_hdr == 0xFFFF) // PN_XNUM 1062886Sphk e_phnum = section_zero.sh_info; 1072886Sphk if (e_shnum_hdr == SHN_UNDEF) 1082886Sphk e_shnum = section_zero.sh_size; 1092886Sphk if (e_shstrndx_hdr == SHN_XINDEX) 1102886Sphk e_shstrndx = section_zero.sh_link; 1112886Sphk } 1122886Sphk} 1132886Sphk 1142886Sphkbool ELFHeader::Parse(lldb_private::DataExtractor &data, 1152886Sphk lldb::offset_t *offset) { 1162886Sphk // Read e_ident. This provides byte order and address size info. 1172886Sphk if (data.GetU8(offset, &e_ident, EI_NIDENT) == nullptr) 1182886Sphk return false; 1192886Sphk 1202886Sphk const unsigned byte_size = Is32Bit() ? 4 : 8; 1212886Sphk data.SetByteOrder(GetByteOrder()); 1222886Sphk data.SetAddressByteSize(byte_size); 1232926Sphk 1242886Sphk // Read e_type and e_machine. 1252886Sphk if (data.GetU16(offset, &e_type, 2) == nullptr) 1262886Sphk return false; 1272886Sphk 1282886Sphk // Read e_version. 1292886Sphk if (data.GetU32(offset, &e_version, 1) == nullptr) 1302926Sphk return false; 1312886Sphk 1322886Sphk // Read e_entry, e_phoff and e_shoff. 1332886Sphk if (!GetMaxU64(data, offset, &e_entry, byte_size, 3)) 1342886Sphk return false; 1352886Sphk 1362886Sphk // Read e_flags. 1372886Sphk if (data.GetU32(offset, &e_flags, 1) == nullptr) 1382886Sphk return false; 1392886Sphk 1402886Sphk // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx. 1412886Sphk if (data.GetU16(offset, &e_ehsize, 6) == nullptr) 1422926Sphk return false; 1432886Sphk 1442886Sphk // Initialize e_phnum, e_shnum, and e_shstrndx with the values read from the 1452926Sphk // header. 1462886Sphk e_phnum = e_phnum_hdr; 1472886Sphk e_shnum = e_shnum_hdr; 1482886Sphk e_shstrndx = e_shstrndx_hdr; 1492886Sphk 1502886Sphk // See if we have extended header in section #0. 1512886Sphk if (HasHeaderExtension()) 1522926Sphk ParseHeaderExtension(data); 1532886Sphk 1542886Sphk return true; 1552926Sphk} 1562886Sphk 1572886Sphkbool ELFHeader::MagicBytesMatch(const uint8_t *magic) { 1582886Sphk return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0; 1592886Sphk} 1602886Sphk 1612886Sphkunsigned ELFHeader::AddressSizeInBytes(const uint8_t *magic) { 1622926Sphk unsigned address_size = 0; 1632948Sphk 1642948Sphk switch (magic[EI_CLASS]) { 1652948Sphk case ELFCLASS32: 1662948Sphk address_size = 4; 1672948Sphk break; 1682886Sphk 1692886Sphk case ELFCLASS64: 1702926Sphk address_size = 8; 1712886Sphk break; 1722886Sphk } 1732886Sphk return address_size; 1742886Sphk} 1752926Sphk 1762886Sphkunsigned ELFHeader::GetRelocationJumpSlotType() const { 1772926Sphk unsigned slot = 0; 1782948Sphk 1792886Sphk switch (e_machine) { 1802886Sphk default: 181 assert(false && "architecture not supported"); 182 break; 183 case EM_PPC: 184 slot = R_PPC_JMP_SLOT; 185 break; 186 case EM_PPC64: 187 slot = R_PPC64_JMP_SLOT; 188 break; 189 case EM_386: 190 case EM_IAMCU: // FIXME: is this correct? 191 slot = R_386_JUMP_SLOT; 192 break; 193 case EM_X86_64: 194 slot = R_X86_64_JUMP_SLOT; 195 break; 196 case EM_ARM: 197 slot = R_ARM_JUMP_SLOT; 198 break; 199 case EM_HEXAGON: 200 slot = R_HEX_JMP_SLOT; 201 break; 202 case EM_AARCH64: 203 slot = R_AARCH64_JUMP_SLOT; 204 break; 205 case EM_MIPS: 206 slot = R_MIPS_JUMP_SLOT; 207 break; 208 case EM_S390: 209 slot = R_390_JMP_SLOT; 210 break; 211 } 212 213 return slot; 214} 215 216// ELFSectionHeader 217 218ELFSectionHeader::ELFSectionHeader() { 219 memset(this, 0, sizeof(ELFSectionHeader)); 220} 221 222bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, 223 lldb::offset_t *offset) { 224 const unsigned byte_size = data.GetAddressByteSize(); 225 226 // Read sh_name and sh_type. 227 if (data.GetU32(offset, &sh_name, 2) == nullptr) 228 return false; 229 230 // Read sh_flags. 231 if (!GetMaxU64(data, offset, &sh_flags, byte_size)) 232 return false; 233 234 // Read sh_addr, sh_off and sh_size. 235 if (!GetMaxU64(data, offset, &sh_addr, byte_size, 3)) 236 return false; 237 238 // Read sh_link and sh_info. 239 if (data.GetU32(offset, &sh_link, 2) == nullptr) 240 return false; 241 242 // Read sh_addralign and sh_entsize. 243 if (!GetMaxU64(data, offset, &sh_addralign, byte_size, 2)) 244 return false; 245 246 return true; 247} 248 249// ELFSymbol 250 251ELFSymbol::ELFSymbol() { memset(this, 0, sizeof(ELFSymbol)); } 252 253#define ENUM_TO_CSTR(e) \ 254 case e: \ 255 return #e 256 257const char *ELFSymbol::bindingToCString(unsigned char binding) { 258 switch (binding) { 259 ENUM_TO_CSTR(STB_LOCAL); 260 ENUM_TO_CSTR(STB_GLOBAL); 261 ENUM_TO_CSTR(STB_WEAK); 262 ENUM_TO_CSTR(STB_LOOS); 263 ENUM_TO_CSTR(STB_HIOS); 264 ENUM_TO_CSTR(STB_LOPROC); 265 ENUM_TO_CSTR(STB_HIPROC); 266 } 267 return ""; 268} 269 270const char *ELFSymbol::typeToCString(unsigned char type) { 271 switch (type) { 272 ENUM_TO_CSTR(STT_NOTYPE); 273 ENUM_TO_CSTR(STT_OBJECT); 274 ENUM_TO_CSTR(STT_FUNC); 275 ENUM_TO_CSTR(STT_SECTION); 276 ENUM_TO_CSTR(STT_FILE); 277 ENUM_TO_CSTR(STT_COMMON); 278 ENUM_TO_CSTR(STT_TLS); 279 ENUM_TO_CSTR(STT_GNU_IFUNC); 280 ENUM_TO_CSTR(STT_HIOS); 281 ENUM_TO_CSTR(STT_LOPROC); 282 ENUM_TO_CSTR(STT_HIPROC); 283 } 284 return ""; 285} 286 287const char *ELFSymbol::sectionIndexToCString( 288 elf_half shndx, const lldb_private::SectionList *section_list) { 289 switch (shndx) { 290 ENUM_TO_CSTR(SHN_UNDEF); 291 ENUM_TO_CSTR(SHN_LOPROC); 292 ENUM_TO_CSTR(SHN_HIPROC); 293 ENUM_TO_CSTR(SHN_LOOS); 294 ENUM_TO_CSTR(SHN_HIOS); 295 ENUM_TO_CSTR(SHN_ABS); 296 ENUM_TO_CSTR(SHN_COMMON); 297 ENUM_TO_CSTR(SHN_XINDEX); 298 default: { 299 const lldb_private::Section *section = 300 section_list->GetSectionAtIndex(shndx).get(); 301 if (section) 302 return section->GetName().AsCString(""); 303 } break; 304 } 305 return ""; 306} 307 308void ELFSymbol::Dump(lldb_private::Stream *s, uint32_t idx, 309 const lldb_private::DataExtractor *strtab_data, 310 const lldb_private::SectionList *section_list) { 311 s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 312 " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n", 313 idx, st_value, st_size, st_name, st_info, 314 bindingToCString(getBinding()), typeToCString(getType()), st_other, 315 st_shndx, sectionIndexToCString(st_shndx, section_list), 316 strtab_data ? strtab_data->PeekCStr(st_name) : ""); 317} 318 319bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, 320 lldb::offset_t *offset) { 321 const unsigned byte_size = data.GetAddressByteSize(); 322 const bool parsing_32 = byte_size == 4; 323 324 // Read st_name. 325 if (data.GetU32(offset, &st_name, 1) == nullptr) 326 return false; 327 328 if (parsing_32) { 329 // Read st_value and st_size. 330 if (!GetMaxU64(data, offset, &st_value, byte_size, 2)) 331 return false; 332 333 // Read st_info and st_other. 334 if (data.GetU8(offset, &st_info, 2) == nullptr) 335 return false; 336 337 // Read st_shndx. 338 if (data.GetU16(offset, &st_shndx, 1) == nullptr) 339 return false; 340 } else { 341 // Read st_info and st_other. 342 if (data.GetU8(offset, &st_info, 2) == nullptr) 343 return false; 344 345 // Read st_shndx. 346 if (data.GetU16(offset, &st_shndx, 1) == nullptr) 347 return false; 348 349 // Read st_value and st_size. 350 if (data.GetU64(offset, &st_value, 2) == nullptr) 351 return false; 352 } 353 return true; 354} 355 356// ELFProgramHeader 357 358ELFProgramHeader::ELFProgramHeader() { 359 memset(this, 0, sizeof(ELFProgramHeader)); 360} 361 362bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, 363 lldb::offset_t *offset) { 364 const uint32_t byte_size = data.GetAddressByteSize(); 365 const bool parsing_32 = byte_size == 4; 366 367 // Read p_type; 368 if (data.GetU32(offset, &p_type, 1) == nullptr) 369 return false; 370 371 if (parsing_32) { 372 // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. 373 if (!GetMaxU64(data, offset, &p_offset, byte_size, 5)) 374 return false; 375 376 // Read p_flags. 377 if (data.GetU32(offset, &p_flags, 1) == nullptr) 378 return false; 379 380 // Read p_align. 381 if (!GetMaxU64(data, offset, &p_align, byte_size)) 382 return false; 383 } else { 384 // Read p_flags. 385 if (data.GetU32(offset, &p_flags, 1) == nullptr) 386 return false; 387 388 // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. 389 if (!GetMaxU64(data, offset, &p_offset, byte_size, 6)) 390 return false; 391 } 392 393 return true; 394} 395 396// ELFDynamic 397 398ELFDynamic::ELFDynamic() { memset(this, 0, sizeof(ELFDynamic)); } 399 400bool ELFDynamic::Parse(const lldb_private::DataExtractor &data, 401 lldb::offset_t *offset) { 402 const unsigned byte_size = data.GetAddressByteSize(); 403 return GetMaxS64(data, offset, &d_tag, byte_size, 2); 404} 405 406// ELFRel 407 408ELFRel::ELFRel() { memset(this, 0, sizeof(ELFRel)); } 409 410bool ELFRel::Parse(const lldb_private::DataExtractor &data, 411 lldb::offset_t *offset) { 412 const unsigned byte_size = data.GetAddressByteSize(); 413 414 // Read r_offset and r_info. 415 return GetMaxU64(data, offset, &r_offset, byte_size, 2) != false; 416} 417 418// ELFRela 419 420ELFRela::ELFRela() { memset(this, 0, sizeof(ELFRela)); } 421 422bool ELFRela::Parse(const lldb_private::DataExtractor &data, 423 lldb::offset_t *offset) { 424 const unsigned byte_size = data.GetAddressByteSize(); 425 426 // Read r_offset and r_info. 427 if (!GetMaxU64(data, offset, &r_offset, byte_size, 2)) 428 return false; 429 430 // Read r_addend; 431 if (!GetMaxS64(data, offset, &r_addend, byte_size)) 432 return false; 433 434 return true; 435} 436