14#include <unordered_map>
36#include "llvm/ADT/IntervalMap.h"
37#include "llvm/ADT/PointerUnion.h"
38#include "llvm/ADT/StringRef.h"
39#include "llvm/BinaryFormat/ELF.h"
40#include "llvm/Object/Decompressor.h"
41#include "llvm/Support/ARMBuildAttributes.h"
42#include "llvm/Support/CRC.h"
43#include "llvm/Support/FormatVariadic.h"
44#include "llvm/Support/MathExtras.h"
45#include "llvm/Support/MemoryBuffer.h"
46#include "llvm/Support/MipsABIFlags.h"
48#define CASE_AND_STREAM(s, def, width) \
50 s->Printf("%-*s", width, #def); \
56using namespace llvm::ELF;
103 ELFRelocation(
unsigned type);
109 static unsigned RelocType32(
const ELFRelocation &rel);
111 static unsigned RelocType64(
const ELFRelocation &rel);
113 static unsigned RelocSymbol32(
const ELFRelocation &rel);
115 static unsigned RelocSymbol64(
const ELFRelocation &rel);
117 static elf_addr RelocOffset32(
const ELFRelocation &rel);
119 static elf_addr RelocOffset64(
const ELFRelocation &rel);
121 static elf_sxword RelocAddend32(
const ELFRelocation &rel);
123 static elf_sxword RelocAddend64(
const ELFRelocation &rel);
125 bool IsRela() {
return (reloc.is<
ELFRela *>()); }
128 typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
134ELFRelocation::ELFRelocation(
unsigned type) {
135 if (type == DT_REL || type == SHT_REL)
137 else if (type == DT_RELA || type == SHT_RELA)
140 assert(
false &&
"unexpected relocation type");
141 reloc =
static_cast<ELFRel *
>(
nullptr);
145ELFRelocation::~ELFRelocation() {
147 delete reloc.get<
ELFRel *>();
155 return reloc.get<
ELFRel *>()->Parse(data, offset);
157 return reloc.get<
ELFRela *>()->Parse(data, offset);
160unsigned ELFRelocation::RelocType32(
const ELFRelocation &rel) {
161 if (rel.reloc.is<
ELFRel *>())
167unsigned ELFRelocation::RelocType64(
const ELFRelocation &rel) {
168 if (rel.reloc.is<
ELFRel *>())
174unsigned ELFRelocation::RelocSymbol32(
const ELFRelocation &rel) {
175 if (rel.reloc.is<
ELFRel *>())
181unsigned ELFRelocation::RelocSymbol64(
const ELFRelocation &rel) {
182 if (rel.reloc.is<
ELFRel *>())
188elf_addr ELFRelocation::RelocOffset32(
const ELFRelocation &rel) {
189 if (rel.reloc.is<
ELFRel *>())
190 return rel.reloc.get<
ELFRel *>()->r_offset;
192 return rel.reloc.get<
ELFRela *>()->r_offset;
195elf_addr ELFRelocation::RelocOffset64(
const ELFRelocation &rel) {
196 if (rel.reloc.is<
ELFRel *>())
197 return rel.reloc.get<
ELFRel *>()->r_offset;
199 return rel.reloc.get<
ELFRela *>()->r_offset;
202elf_sxword ELFRelocation::RelocAddend32(
const ELFRelocation &rel) {
203 if (rel.reloc.is<
ELFRel *>())
206 return rel.reloc.get<
ELFRela *>()->r_addend;
209elf_sxword ELFRelocation::RelocAddend64(
const ELFRelocation &rel) {
210 if (rel.reloc.is<
ELFRel *>())
213 return rel.reloc.get<
ELFRela *>()->r_addend;
233 if (strncmp(buf,
"CORE", 4) == 0) {
241 if (cstr ==
nullptr) {
243 LLDB_LOGF(log,
"Failed to parse note name lacking nul terminator");
260 if (header.
e_type == ET_CORE) {
262 case llvm::ELF::ELFCLASS32:
265 case llvm::ELF::ELFCLASS64:
274 case llvm::ELF::EF_MIPS_ARCH_1:
275 case llvm::ELF::EF_MIPS_ARCH_2:
276 case llvm::ELF::EF_MIPS_ARCH_32:
279 case llvm::ELF::EF_MIPS_ARCH_32R2:
282 case llvm::ELF::EF_MIPS_ARCH_32R6:
285 case llvm::ELF::EF_MIPS_ARCH_3:
286 case llvm::ELF::EF_MIPS_ARCH_4:
287 case llvm::ELF::EF_MIPS_ARCH_5:
288 case llvm::ELF::EF_MIPS_ARCH_64:
291 case llvm::ELF::EF_MIPS_ARCH_64R2:
294 case llvm::ELF::EF_MIPS_ARCH_64R6:
307 case llvm::ELF::ELFCLASS32:
309 case llvm::ELF::ELFCLASS64:
318 if (endian == ELFDATA2LSB)
327 case llvm::ELF::ELFCLASS32:
329 case llvm::ELF::ELFCLASS64:
337 if (header.
e_machine == llvm::ELF::EM_MIPS)
339 else if (header.
e_machine == llvm::ELF::EM_PPC64)
341 else if (header.
e_machine == llvm::ELF::EM_RISCV)
343 else if (header.
e_machine == llvm::ELF::EM_LOONGARCH)
366 DataBufferSP data_sp,
371 bool mapped_writable =
false;
377 mapped_writable =
true;
382 if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
385 const uint8_t *magic = data_sp->GetBytes() + data_offset;
390 if (data_sp->GetByteSize() < length) {
395 mapped_writable =
true;
396 magic = data_sp->GetBytes();
400 if (!mapped_writable) {
401 data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(),
402 data_sp->GetByteSize());
404 magic = data_sp->GetBytes();
408 if (address_size == 4 || address_size == 8) {
410 module_sp, data_sp, data_offset, file, file_offset, length));
411 ArchSpec spec = objfile_up->GetArchitecture();
412 if (spec && objfile_up->SetModulesArchitecture(spec))
413 return objfile_up.release();
420 const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
421 const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr) {
422 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
423 const uint8_t *magic = data_sp->GetBytes();
426 if (address_size == 4 || address_size == 8) {
427 std::unique_ptr<ObjectFileELF> objfile_up(
428 new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
429 ArchSpec spec = objfile_up->GetArchitecture();
430 if (spec && objfile_up->SetModulesArchitecture(spec))
431 return objfile_up.release();
442 data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
443 const uint8_t *magic = data_sp->GetBytes() + data_offset;
450 return llvm::crc32(init,
460 if (H.p_type == llvm::ELF::PT_NOTE) {
461 const elf_off ph_offset = H.p_offset;
462 const size_t ph_size = H.p_filesz;
465 if (segment_data.
SetData(object_data, ph_offset, ph_size) != ph_size) {
471 core_notes_crc =
calc_crc32(core_notes_crc, segment_data);
475 return core_notes_crc;
479#define _MAKE_OSABI_CASE(x) \
482 switch (osabi_byte) {
504 return "<unknown-osabi>";
506#undef _MAKE_OSABI_CASE
516 llvm::Triple::OSType &ostype) {
517 switch (osabi_byte) {
519 ostype = llvm::Triple::OSType::AIX;
521 case ELFOSABI_FREEBSD:
522 ostype = llvm::Triple::OSType::FreeBSD;
525 ostype = llvm::Triple::OSType::Linux;
527 case ELFOSABI_NETBSD:
528 ostype = llvm::Triple::OSType::NetBSD;
530 case ELFOSABI_OPENBSD:
531 ostype = llvm::Triple::OSType::OpenBSD;
533 case ELFOSABI_SOLARIS:
534 ostype = llvm::Triple::OSType::Solaris;
537 ostype = llvm::Triple::OSType::UnknownOS;
539 return ostype != llvm::Triple::OSType::UnknownOS;
548 const size_t initial_count = specs.
GetSize();
555 if (header.
Parse(data, &header_offset)) {
564 llvm::Triple::OSType ostype;
565 llvm::Triple::VendorType vendor;
566 llvm::Triple::OSType spec_ostype =
569 LLDB_LOGF(log,
"ObjectFileELF::%s file '%s' module OSABI: %s",
570 __FUNCTION__, file.
GetPath().c_str(),
575 assert(vendor == llvm::Triple::UnknownVendor);
581 assert(spec_ostype == ostype);
582 if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
584 "ObjectFileELF::%s file '%s' set ELF module OS type "
585 "from ELF header OSABI.",
586 __FUNCTION__, file.
GetPath().c_str());
589 if (data_sp->GetByteSize() < length)
599 header.
Parse(data, &header_offset);
603 std::string gnu_debuglink_file;
608 gnu_debuglink_file, gnu_debuglink_crc,
614 "ObjectFileELF::%s file '%s' module set to triple: %s "
616 __FUNCTION__, file.
GetPath().c_str(),
617 spec_triple.getTriple().c_str(),
623 if (!gnu_debuglink_crc) {
625 "Calculating module crc32 %s with size %" PRIu64
" KiB",
627 (length - file_offset) / 1024);
633 if (header.
e_type == llvm::ELF::ET_CORE) {
643 using u32le = llvm::support::ulittle32_t;
644 if (gnu_debuglink_crc) {
646 u32le data(gnu_debuglink_crc);
647 uuid =
UUID(&data,
sizeof(data));
648 }
else if (core_notes_crc) {
653 uuid =
UUID(data,
sizeof(data));
663 return specs.
GetSize() - initial_count;
672 :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
678 DataBufferSP header_data_sp,
679 const lldb::ProcessSP &process_sp,
681 :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
688 bool value_is_offset) {
691 size_t num_loaded_sections = 0;
694 if (!value_is_offset) {
701 const size_t num_sections = section_list->
GetSize();
704 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
708 if (section_sp->Test(SHF_ALLOC) ||
720 load_addr &= 0xFFFFFFFF;
724 ++num_loaded_sections;
727 return num_loaded_sections > 0;
748 return AddressClass::eUnknown;
753 if (symtab_objfile !=
nullptr && symtab_objfile !=
this)
757 if (res != AddressClass::eCode)
764 return AddressClass::eCode;
793 using u32le = llvm::support::ulittle32_t;
803 if (core_notes_crc) {
834 for (
unsigned i = 0; i < num_modules; ++i) {
835 if (files.AppendIfUnique(
m_filespec_up->GetFileSpecAtIndex(i)))
851 SectionSP dynsym_section_sp(
853 if (!dynsym_section_sp)
855 assert(dynsym_section_sp->GetObjectFile() ==
this);
857 user_id_t dynsym_id = dynsym_section_sp->GetID();
865 if (symbol.
d_tag == DT_DEBUG) {
869 return Address(dynsym_section_sp, offset);
873 else if ((symbol.
d_tag == DT_MIPS_RLD_MAP ||
874 symbol.
d_tag == DT_MIPS_RLD_MAP_REL) &&
877 addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
882 if (symbol.
d_tag == DT_MIPS_RLD_MAP) {
888 if (symbol.
d_tag == DT_MIPS_RLD_MAP_REL) {
896 addr_t debug_ptr_address =
978 while (offset < section_size) {
979 if (!symbol.
Parse(dynsym_data, &offset))
982 if (symbol.
d_tag != DT_NEEDED)
986 const char *lib_name = dynstr_data.
PeekCStr(str_index);
1001 if (!program_headers.empty())
1002 return program_headers.size();
1008 program_headers.resize(header.
e_phnum);
1009 if (program_headers.size() != header.
e_phnum)
1015 if (data.
SetData(object_data, ph_offset, ph_size) != ph_size)
1020 for (idx = 0, offset = 0; idx < header.
e_phnum; ++idx) {
1021 if (!program_headers[idx].Parse(data, &offset))
1025 if (idx < program_headers.size())
1026 program_headers.resize(idx);
1028 return program_headers.size();
1049 if (!note.
Parse(data, &offset)) {
1054 LLDB_LOGF(log,
"ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
1063 if (data.
GetU32(&offset, &version_info, 1) ==
nullptr) {
1064 error.SetErrorString(
"failed to read FreeBSD ABI note payload");
1069 const uint32_t version_major = version_info / 100000;
1070 const uint32_t version_minor = (version_info / 1000) % 100;
1073 snprintf(os_name,
sizeof(os_name),
"freebsd%" PRIu32
".%" PRIu32,
1074 version_major, version_minor);
1077 arch_spec.
GetTriple().setOSName(os_name);
1078 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1081 "ObjectFileELF::%s detected FreeBSD %" PRIu32
".%" PRIu32
1083 __FUNCTION__, version_major, version_minor,
1084 static_cast<uint32_t>(version_info % 1000));
1095 error.SetErrorString(
"failed to read GNU ABI note payload");
1100 switch (version_info[0]) {
1102 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1104 llvm::Triple::VendorType::UnknownVendor);
1106 "ObjectFileELF::%s detected Linux, min version %" PRIu32
1107 ".%" PRIu32
".%" PRIu32,
1108 __FUNCTION__, version_info[1], version_info[2],
1115 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
1117 llvm::Triple::VendorType::UnknownVendor);
1119 "ObjectFileELF::%s detected Hurd (unsupported), min "
1120 "version %" PRIu32
".%" PRIu32
".%" PRIu32,
1121 __FUNCTION__, version_info[1], version_info[2],
1125 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Solaris);
1127 llvm::Triple::VendorType::UnknownVendor);
1129 "ObjectFileELF::%s detected Solaris, min version %" PRIu32
1130 ".%" PRIu32
".%" PRIu32,
1131 __FUNCTION__, version_info[1], version_info[2],
1136 "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
1137 ", min version %" PRIu32
".%" PRIu32
".%" PRIu32,
1138 __FUNCTION__, version_info[0], version_info[1],
1139 version_info[2], version_info[3]);
1156 error.SetErrorString(
"failed to read GNU_BUILD_ID note payload");
1163 if (arch_spec.
IsMIPS() &&
1164 arch_spec.
GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1166 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1175 if (data.
GetU32(&offset, &version_info, 1) ==
nullptr) {
1176 error.SetErrorString(
"failed to read NetBSD ABI note payload");
1186 const uint32_t version_major = version_info / 100000000;
1187 const uint32_t version_minor = (version_info % 100000000) / 1000000;
1188 const uint32_t version_patch = (version_info % 10000) / 100;
1191 llvm::formatv(
"netbsd{0}.{1}.{2}", version_major, version_minor,
1192 version_patch).str());
1193 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1199 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::NetBSD);
1200 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1205 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::OpenBSD);
1206 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1208 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1210 llvm::Triple::EnvironmentType::Android);
1214 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1238 if (note.
n_type == NT_FILE) {
1242 offset += count * 3 *
1244 for (
size_t i = 0; i < count; ++i) {
1246 if (cstr ==
nullptr) {
1247 error.SetErrorStringWithFormat(
"ObjectFileELF::%s trying to read "
1248 "at an offset after the end "
1249 "(GetCStr returned nullptr)",
1253 llvm::StringRef path(cstr);
1254 if (path.contains(
"/lib/x86_64-linux-gnu") || path.contains(
"/lib/i386-linux-gnu")) {
1255 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1259 if (arch_spec.
IsMIPS() &&
1260 arch_spec.
GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1263 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1279 uint8_t FormatVersion = data.
GetU8(&Offset);
1280 if (FormatVersion != llvm::ELFAttrs::Format_Version)
1283 Offset = Offset +
sizeof(
uint32_t);
1284 llvm::StringRef VendorName = data.
GetCStr(&Offset);
1286 if (VendorName !=
"aeabi")
1289 if (arch_spec.
GetTriple().getEnvironment() ==
1290 llvm::Triple::UnknownEnvironment)
1291 arch_spec.
GetTriple().setEnvironment(llvm::Triple::EABI);
1293 while (Offset < length) {
1294 uint8_t Tag = data.
GetU8(&Offset);
1297 if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
1300 while (Offset < length) {
1306 else if (Tag % 2 == 0)
1313 case llvm::ARMBuildAttrs::CPU_raw_name:
1314 case llvm::ARMBuildAttrs::CPU_name:
1319 case llvm::ARMBuildAttrs::ABI_VFP_args: {
1322 if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
1323 if (arch_spec.
GetTriple().getEnvironment() ==
1324 llvm::Triple::UnknownEnvironment ||
1325 arch_spec.
GetTriple().getEnvironment() == llvm::Triple::EABIHF)
1326 arch_spec.
GetTriple().setEnvironment(llvm::Triple::EABI);
1329 }
else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
1330 if (arch_spec.
GetTriple().getEnvironment() ==
1331 llvm::Triple::UnknownEnvironment ||
1332 arch_spec.
GetTriple().getEnvironment() == llvm::Triple::EABI)
1333 arch_spec.
GetTriple().setEnvironment(llvm::Triple::EABIHF);
1350 std::string &gnu_debuglink_file,
1354 if (!section_headers.empty())
1355 return section_headers.size();
1359 if (arch_spec.
GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
1360 llvm::Triple::OSType ostype;
1361 llvm::Triple::OSType spec_ostype;
1373 spec_ostype = arch_spec.
GetTriple().getOS();
1374 assert(spec_ostype == ostype);
1378 if (arch_spec.
GetMachine() == llvm::Triple::mips ||
1379 arch_spec.
GetMachine() == llvm::Triple::mipsel ||
1380 arch_spec.
GetMachine() == llvm::Triple::mips64 ||
1381 arch_spec.
GetMachine() == llvm::Triple::mips64el) {
1382 switch (header.
e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
1383 case llvm::ELF::EF_MIPS_MICROMIPS:
1386 case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
1389 case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
1397 if (arch_spec.
GetMachine() == llvm::Triple::arm ||
1398 arch_spec.
GetMachine() == llvm::Triple::thumb) {
1399 if (header.
e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
1401 else if (header.
e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
1405 if (arch_spec.
GetMachine() == llvm::Triple::riscv32 ||
1406 arch_spec.
GetMachine() == llvm::Triple::riscv64) {
1409 if (header.
e_flags & llvm::ELF::EF_RISCV_RVC)
1411 if (header.
e_flags & llvm::ELF::EF_RISCV_RVE)
1414 if ((header.
e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) ==
1415 llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)
1417 else if ((header.
e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) ==
1418 llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)
1420 else if ((header.
e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) ==
1421 llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)
1433 section_headers.resize(header.
e_shnum);
1434 if (section_headers.size() != header.
e_shnum)
1440 if (sh_data.
SetData(object_data, sh_offset, sh_size) != sh_size)
1445 for (idx = 0, offset = 0; idx < header.
e_shnum; ++idx) {
1446 if (!section_headers[idx].Parse(sh_data, &offset))
1449 if (idx < section_headers.size())
1450 section_headers.resize(idx);
1452 const unsigned strtab_idx = header.
e_shstrndx;
1453 if (strtab_idx && strtab_idx < section_headers.size()) {
1455 const size_t byte_size = sheader.
sh_size;
1456 const Elf64_Off offset = sheader.
sh_offset;
1459 if (shstr_data.
SetData(object_data, offset, byte_size) == byte_size) {
1461 I != section_headers.end(); ++I) {
1462 static ConstString g_sect_name_gnu_debuglink(
".gnu_debuglink");
1464 const uint64_t section_size =
1468 I->section_name = name;
1470 if (arch_spec.
IsMIPS()) {
1473 if (sheader.
sh_type == SHT_MIPS_ABIFLAGS) {
1476 section_size) == section_size)) {
1479 arch_flags |= data.
GetU32(&offset);
1483 switch (data.
GetU8(&offset)) {
1484 case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
1487 case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
1490 case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
1493 case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
1496 case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
1499 case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
1502 case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
1505 case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
1512 switch (header.
e_flags & llvm::ELF::EF_MIPS_ABI) {
1513 case llvm::ELF::EF_MIPS_ABI_O32:
1516 case EF_MIPS_ABI_O64:
1519 case EF_MIPS_ABI_EABI32:
1522 case EF_MIPS_ABI_EABI64:
1527 if (header.
e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
1529 else if (header.
e_flags & llvm::ELF::EF_MIPS_ABI2)
1536 if (arch_spec.
GetMachine() == llvm::Triple::arm ||
1537 arch_spec.
GetMachine() == llvm::Triple::thumb) {
1540 if (sheader.
sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
1541 data.
SetData(object_data, sheader.
sh_offset, section_size) == section_size)
1545 if (name == g_sect_name_gnu_debuglink) {
1548 section_size) == section_size)) {
1550 gnu_debuglink_file = data.
GetCStr(&gnu_debuglink_offset);
1551 gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
1552 data.
GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
1557 bool is_note_header = (sheader.
sh_type == SHT_NOTE);
1561 static ConstString g_sect_name_android_ident(
".note.android.ident");
1562 if (!is_note_header && name == g_sect_name_android_ident)
1563 is_note_header =
true;
1565 if (is_note_header) {
1569 section_size) == section_size)) {
1572 LLDB_LOGF(log,
"ObjectFileELF::%s ELF note processing failed: %s",
1573 __FUNCTION__,
error.AsCString());
1580 if (arch_spec.
GetTriple().getVendor() == llvm::Triple::UnknownVendor)
1581 arch_spec.
GetTriple().setVendorName(llvm::StringRef());
1582 if (arch_spec.
GetTriple().getOS() == llvm::Triple::UnknownOS)
1583 arch_spec.
GetTriple().setOSName(llvm::StringRef());
1585 return section_headers.size();
1589 section_headers.clear();
1595 size_t pos = symbol_name.find(
'@');
1596 return symbol_name.substr(0, pos);
1627 if (Name.consume_front(
".debug_")) {
1628 return llvm::StringSwitch<SectionType>(Name)
1660 return llvm::StringSwitch<SectionType>(Name)
1704 Permissions Perm = Permissions(0);
1706 Perm |= ePermissionsReadable;
1708 Perm |= ePermissionsWritable;
1710 Perm |= ePermissionsExecutable;
1715 Permissions Perm = Permissions(0);
1717 Perm |= ePermissionsReadable;
1719 Perm |= ePermissionsWritable;
1721 Perm |= ePermissionsExecutable;
1729struct SectionAddressInfo {
1737class VMAddressProvider {
1738 using VMMap = llvm::IntervalMap<
addr_t, SectionSP, 4,
1739 llvm::IntervalMapHalfOpenInfo<addr_t>>;
1742 addr_t NextVMAddress = 0;
1743 VMMap::Allocator Alloc;
1745 VMMap Sections{Alloc};
1747 size_t SegmentCount = 0;
1748 std::string SegmentName;
1753 if (ObjectType == ObjectFile::Type::eTypeObjectFile &&
Segments.empty() && (H.
sh_flags & SHF_ALLOC)) {
1755 llvm::alignTo(NextVMAddress, std::max<addr_t>(H.
sh_addralign, 1));
1757 NextVMAddress += Size;
1764 : ObjectType(
Type), SegmentName(std::string(SegmentName)) {}
1766 std::string GetNextSegmentName()
const {
1767 return llvm::formatv(
"{0}[{1}]", SegmentName, SegmentCount).str();
1772 LLDB_LOG(
Log,
"Ignoring zero-sized {0} segment. Corrupt object file?",
1774 return std::nullopt;
1778 LLDB_LOG(
Log,
"Ignoring overlapping {0} segment. Corrupt object file?",
1780 return std::nullopt;
1785 std::optional<SectionAddressInfo> GetAddressInfo(
const ELFSectionHeader &H) {
1789 if ((H.
sh_flags & SHF_ALLOC) && It.valid()) {
1797 LLDB_LOG(
Log,
"Shortening section crossing segment boundaries. "
1798 "Corrupt object file?");
1804 LLDB_LOG(
Log,
"Ignoring overlapping section. Corrupt object file?");
1805 return std::nullopt;
1809 return SectionAddressInfo{Segment,
Range};
1817 void AddSection(SectionAddressInfo Info, SectionSP Sect) {
1818 if (Info.Range.GetByteSize() == 0)
1821 Info.Range.Slide(Info.Segment->GetFileAddress());
1822 Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(),
1833 VMAddressProvider regular_provider(
GetType(),
"PT_LOAD");
1834 VMAddressProvider tls_provider(
GetType(),
"PT_TLS");
1841 VMAddressProvider &provider =
1842 PHdr.
p_type == PT_TLS ? tls_provider : regular_provider;
1843 auto InfoOr = provider.GetAddressInfo(PHdr);
1847 uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.
p_align, 1));
1848 SectionSP Segment = std::make_shared<Section>(
1851 InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.
p_offset,
1854 Segment->SetIsThreadSpecific(PHdr.
p_type == PT_TLS);
1857 provider.AddSegment(*InfoOr, std::move(Segment));
1869 const uint64_t file_size =
1872 VMAddressProvider &provider =
1873 header.
sh_flags & SHF_TLS ? tls_provider : regular_provider;
1874 auto InfoOr = provider.GetAddressInfo(header);
1886 SectionSP section_sp(
new Section(
1893 InfoOr->Range.GetRangeBase(),
1894 InfoOr->Range.GetByteSize(),
1899 target_bytes_size));
1902 section_sp->SetIsThreadSpecific(header.
sh_flags & SHF_TLS);
1903 (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *
m_sections_up)
1904 .AddSection(section_sp);
1905 provider.AddSection(std::move(*InfoOr), std::move(section_sp));
1917 if (
auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
1918 if (SectionSP symtab_section_sp =
1919 gdd_objfile_section_list->FindSectionByType(
1923 if (module_section_sp)
1927 unified_section_list.
AddSection(symtab_section_sp);
1944 "No LZMA support found for reading .gnu_debugdata section");
1950 section->GetSectionData(data);
1951 llvm::SmallVector<uint8_t, 0> uncompressedData;
1955 "An error occurred while decompression the section {0}: {1}",
1956 section->GetName().AsCString(), llvm::toString(std::move(err)).c_str());
1961 DataBufferSP gdd_data_buf(
1962 new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
1964 llvm::StringRef(
"gnu_debugdata"));
1966 GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
1987 const char *dollar_pos = ::strchr(symbol_name,
'$');
1988 if (!dollar_pos || dollar_pos[1] ==
'\0')
1991 if (dollar_pos[2] ==
'\0' || dollar_pos[2] ==
'.')
1992 return dollar_pos[1];
1996#define STO_MIPS_ISA (3 << 6)
1997#define STO_MICROMIPS (2 << 6)
1998#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
2003 const size_t num_symbols,
2016 static ConstString rodata_section_name(
".rodata");
2017 static ConstString rodata1_section_name(
".rodata1");
2033 bool skip_oatdata_oatexec =
2034 file_extension ==
".oat" || file_extension ==
".odex";
2039 module_sp ? module_sp->GetSectionList() :
nullptr;
2044 std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
2047 for (i = 0; i < num_symbols; ++i) {
2048 if (!symbol.
Parse(symtab_data, &offset))
2056 if (symbol.
getType() != STT_SECTION &&
2057 (symbol_name ==
nullptr || symbol_name[0] ==
'\0'))
2062 if (skip_oatdata_oatexec && (::strcmp(symbol_name,
"oatdata") == 0 ||
2063 ::strcmp(symbol_name,
"oatexec") == 0))
2066 SectionSP symbol_section_sp;
2068 Elf64_Half shndx = symbol.
st_shndx;
2125 if (symbol_section_sp) {
2126 ConstString sect_name = symbol_section_sp->GetName();
2127 if (sect_name == text_section_name || sect_name == init_section_name ||
2128 sect_name == fini_section_name || sect_name == ctors_section_name ||
2129 sect_name == dtors_section_name) {
2131 }
else if (sect_name == data_section_name ||
2132 sect_name == data2_section_name ||
2133 sect_name == rodata_section_name ||
2134 sect_name == rodata1_section_name ||
2135 sect_name == bss_section_name) {
2141 int64_t symbol_value_offset = 0;
2145 if (arch.
GetMachine() == llvm::Triple::arm) {
2149 switch (mapping_symbol) {
2159 AddressClass::eCodeAlternateISA;
2170 }
else if (arch.
GetMachine() == llvm::Triple::aarch64) {
2174 switch (mapping_symbol) {
2190 if (arch.
GetMachine() == llvm::Triple::arm) {
2198 symbol_value_offset = -1;
2200 AddressClass::eCodeAlternateISA;
2241 uint64_t symbol_value = symbol.
st_value + symbol_value_offset;
2243 if (symbol_section_sp &&
2245 symbol_value -= symbol_section_sp->GetFileAddress();
2247 if (symbol_section_sp && module_section_list &&
2248 module_section_list != section_list) {
2249 ConstString sect_name = symbol_section_sp->GetName();
2250 auto section_it = section_name_to_section.find(sect_name.
GetCString());
2251 if (section_it == section_name_to_section.end())
2253 section_name_to_section
2257 if (section_it->second)
2258 symbol_section_sp = section_it->second;
2261 bool is_global = symbol.
getBinding() == STB_GLOBAL;
2263 llvm::StringRef symbol_ref(symbol_name);
2267 size_t version_pos = symbol_ref.find(
'@');
2268 bool has_suffix = version_pos != llvm::StringRef::npos;
2269 llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
2270 Mangled mangled(symbol_bare);
2275 llvm::StringRef suffix = symbol_ref.substr(version_pos);
2277 llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
2278 if (!mangled_name.empty())
2279 mangled.SetMangledName(
ConstString((mangled_name + suffix).str()));
2281 ConstString demangled = mangled.GetDemangledName();
2282 llvm::StringRef demangled_name = demangled.
GetStringRef();
2283 if (!demangled_name.empty())
2284 mangled.SetDemangledName(
ConstString((demangled_name + suffix).str()));
2292 bool symbol_size_valid =
2335 assert(symtab_hdr->
sh_type == SHT_SYMTAB ||
2336 symtab_hdr->
sh_type == SHT_DYNSYM);
2342 if (symtab && strtab) {
2352 return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
2353 symtab_data, strtab_data);
2382 while (cursor < section_size) {
2383 if (!symbol.
Parse(dynsym_data, &cursor))
2399 for (; I != E; ++I) {
2402 if (symbol->
d_tag == tag)
2418 return symbol->
d_val;
2427static std::pair<uint64_t, uint64_t>
2443 if (plt_entsize <= 4) {
2453 plt_entsize = plt_hdr->
sh_size / (num_relocations + 1);
2458 return std::make_pair(plt_entsize, plt_offset);
2465 const lldb::SectionSP &plt_section_sp,
DataExtractor &rel_data,
2467 ELFRelocation rel(rel_type);
2471 uint64_t plt_offset, plt_entsize;
2472 std::tie(plt_entsize, plt_offset) =
2476 typedef unsigned (*reloc_info_fn)(
const ELFRelocation &rel);
2477 reloc_info_fn reloc_type;
2478 reloc_info_fn reloc_symbol;
2481 reloc_type = ELFRelocation::RelocType32;
2482 reloc_symbol = ELFRelocation::RelocSymbol32;
2484 reloc_type = ELFRelocation::RelocType64;
2485 reloc_symbol = ELFRelocation::RelocSymbol64;
2490 for (i = 0; i < num_relocations; ++i) {
2491 if (!rel.Parse(rel_data, &offset))
2494 if (reloc_type(rel) != slot_type)
2498 if (!symbol.
Parse(symtab_data, &symbol_offset))
2502 uint64_t plt_index = plt_offset + i * plt_entsize;
2529 assert(rel_hdr->
sh_type == SHT_RELA || rel_hdr->
sh_type == SHT_REL);
2543 if (!symtab_id || !plt_id)
2563 if (!plt_section_sp)
2592 rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
2593 rel_data, symtab_data, strtab_data);
2605 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2606 uint64_t *dst =
reinterpret_cast<uint64_t *
>(
2608 ELFRelocation::RelocOffset64(rel));
2609 uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
2610 memcpy(dst, &val_offset,
sizeof(uint64_t));
2616 Section *rel_section,
bool is_signed) {
2620 value += ELFRelocation::RelocAddend32(rel);
2623 ((int64_t)value >
INT32_MAX || (int64_t)value < INT32_MIN))) {
2625 LLDB_LOGF(log,
"Failed to apply debug info relocations");
2628 uint32_t truncated_addr = (value & 0xFFFFFFFF);
2632 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2635 ELFRelocation::RelocOffset32(rel));
2636 memcpy(dst, &truncated_addr,
sizeof(
uint32_t));
2645 ELFRelocation rel(rel_hdr->
sh_type);
2648 typedef unsigned (*reloc_info_fn)(
const ELFRelocation &rel);
2649 reloc_info_fn reloc_type;
2650 reloc_info_fn reloc_symbol;
2653 reloc_type = ELFRelocation::RelocType32;
2654 reloc_symbol = ELFRelocation::RelocSymbol32;
2656 reloc_type = ELFRelocation::RelocType64;
2657 reloc_symbol = ELFRelocation::RelocSymbol64;
2660 for (
unsigned i = 0; i < num_relocations; ++i) {
2661 if (!rel.Parse(rel_data, &offset)) {
2662 GetModule()->ReportError(
".rel{0}[{1:d}] failed to parse relocation",
2666 Symbol *symbol =
nullptr;
2669 switch (reloc_type(rel)) {
2674 rel_section->
GetFileOffset() + ELFRelocation::RelocOffset32(rel);
2678 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2680 data_buffer->GetBytes() + f_offset);
2684 value += ELFRelocation::RelocAddend32(rel);
2690 GetModule()->ReportError(
".rel{0}[{1}] unknown symbol id: {2:d}",
2697 GetModule()->ReportError(
"unsupported 32-bit relocation:"
2698 " .rel{0}[{1}], type {2}",
2704 case llvm::ELF::EM_AARCH64:
2705 switch (reloc_type(rel)) {
2706 case R_AARCH64_ABS64:
2709 case R_AARCH64_ABS32:
2713 assert(
false &&
"unexpected relocation type");
2716 case llvm::ELF::EM_LOONGARCH:
2717 switch (reloc_type(rel)) {
2725 assert(
false &&
"unexpected relocation type");
2728 case llvm::ELF::EM_X86_64:
2729 switch (reloc_type(rel)) {
2742 assert(
false &&
"unexpected relocation type");
2746 assert(
false &&
"unsupported machine");
2757 assert(rel_hdr->
sh_type == SHT_RELA || rel_hdr->
sh_type == SHT_REL);
2795 rel_data, symtab_data, debug_data, debug);
2807 llvm::formatv(
"Parsing symbol table for {0}",
2813 ObjectFile *module_obj_file = module_sp->GetObjectFile();
2814 if (module_obj_file && module_obj_file !=
this)
2817 SectionList *section_list = module_sp->GetSectionList();
2821 uint64_t symbol_id = 0;
2863 if (reloc_section) {
2873 GetModule()->GetUnwindTable().GetEHFrameInfo()) {
2887 bool is_valid_entry_point =
2888 entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
2889 addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
2891 entry_point_file_addr)) {
2896 SectionSP section_sp = entry_point_addr.GetSection();
2915 if (arch.
GetMachine() == llvm::Triple::arm &&
2916 (entry_point_file_addr & 1)) {
2919 AddressClass::eCodeAlternateISA;
2930 static const char *debug_prefix =
".debug";
2942 if (section_name ==
nullptr)
2946 if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
2950 std::string needle = std::string(
".rel") + section_name;
2951 std::string needlea = std::string(
".rela") + section_name;
2955 if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
2956 const char *hay_name = I->section_name.GetCString();
2957 if (hay_name ==
nullptr)
2959 if (needle == hay_name || needlea == hay_name) {
2980 std::vector<Symbol> new_symbols;
2983 uint64_t last_symbol_id =
2990 symbol->SetByteSize(size);
2991 symbol->SetSizeIsSynthesized(true);
2994 SectionSP section_sp =
2997 addr_t offset = file_addr - section_sp->GetFileAddress();
2998 uint64_t symbol_id = ++last_symbol_id;
3016 new_symbols.push_back(eh_symbol);
3022 for (
const Symbol &s : new_symbols)
3042 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
3043 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
3049 *s <<
", file = '" <<
m_file
3075 s->
Printf(
"e_ident[EI_MAG0 ] = 0x%2.2x\n", header.
e_ident[EI_MAG0]);
3076 s->
Printf(
"e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.
e_ident[EI_MAG1],
3078 s->
Printf(
"e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.
e_ident[EI_MAG2],
3080 s->
Printf(
"e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.
e_ident[EI_MAG3],
3083 s->
Printf(
"e_ident[EI_CLASS ] = 0x%2.2x\n", header.
e_ident[EI_CLASS]);
3084 s->
Printf(
"e_ident[EI_DATA ] = 0x%2.2x ", header.
e_ident[EI_DATA]);
3086 s->
Printf(
"\ne_ident[EI_VERSION] = 0x%2.2x\n", header.
e_ident[EI_VERSION]);
3087 s->
Printf(
"e_ident[EI_PAD ] = 0x%2.2x\n", header.
e_ident[EI_PAD]);
3134 unsigned char ei_data) {
3137 *s <<
"ELFDATANONE";
3140 *s <<
"ELFDATA2LSB - Little Endian";
3143 *s <<
"ELFDATA2MSB - Big Endian";
3156 s->
Printf(
" %8.8" PRIx64
" %8.8" PRIx64
" %8.8" PRIx64, ph.
p_offset,
3170 const int kStrWidth = 15;
3182 s->
Printf(
"0x%8.8x%*s", p_type, kStrWidth - 10,
"");
3191 *s << ((p_flags & PF_X) ?
"PF_X" :
" ")
3192 << (((p_flags & PF_X) && (p_flags & PF_W)) ?
'+' :
' ')
3193 << ((p_flags & PF_W) ?
"PF_W" :
" ")
3194 << (((p_flags & PF_W) && (p_flags & PF_R)) ?
'+' :
' ')
3195 << ((p_flags & PF_R) ?
"PF_R" :
" ");
3206 s->
PutCString(
"IDX p_type p_offset p_vaddr p_paddr "
3207 "p_filesz p_memsz p_flags p_align\n");
3208 s->
PutCString(
"==== --------------- -------- -------- -------- "
3209 "-------- -------- ------------------------- --------\n");
3212 s->
Format(
"[{0,2}] ", H.index());
3227 s->
Printf(
") %8.8" PRIx64
" %8.8" PRIx64
" %8.8" PRIx64, sh.
sh_addr,
3238 const int kStrWidth = 12;
3257 s->
Printf(
"0x%8.8x%*s", sh_type, kStrWidth - 10,
"");
3267 *s << ((sh_flags & SHF_WRITE) ?
"WRITE" :
" ")
3268 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ?
'+' :
' ')
3269 << ((sh_flags & SHF_ALLOC) ?
"ALLOC" :
" ")
3270 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ?
'+' :
' ')
3271 << ((sh_flags & SHF_EXECINSTR) ?
"EXECINSTR" :
" ");
3283 "addr offset size link info addralgn "
3285 s->
PutCString(
"==== -------- ------------ -------------------------------- "
3286 "-------- -------- -------- -------- -------- -------- "
3287 "-------- ====================\n");
3292 s->
Printf(
"[%2u] ", idx);
3294 const char *section_name = I->section_name.AsCString(
"");
3296 *s <<
' ' << section_name <<
"\n";
3303 if (num_modules > 0) {
3305 for (
unsigned i = 0; i < num_modules; ++i) {
3326 if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
3329 if (data.
SetData(
m_data, H.p_offset, H.p_filesz) == H.p_filesz) {
3340 case llvm::ELF::ET_NONE:
3344 case llvm::ELF::ET_REL:
3348 case llvm::ELF::ET_EXEC:
3352 case llvm::ELF::ET_DYN:
3368 case llvm::ELF::ET_NONE:
3372 case llvm::ELF::ET_REL:
3376 case llvm::ELF::ET_EXEC:
3383 case llvm::ELF::ET_DYN:
3411 if (!section->
Test(SHF_COMPRESSED))
3418 return data.
CopyData(section_offset, dst_len, dst);
3428 if (result == 0 || !(section->
Get() & llvm::ELF::SHF_COMPRESSED))
3431 auto Decompressor = llvm::object::Decompressor::create(
3433 {reinterpret_cast<const char *>(section_data.GetDataStart()),
3434 size_t(section_data.GetByteSize())},
3436 if (!Decompressor) {
3438 "Unable to initialize decompressor for section '{0}': {1}",
3440 llvm::toString(Decompressor.takeError()).c_str());
3441 section_data.
Clear();
3446 std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
3447 if (
auto error = Decompressor->decompress(
3448 {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) {
3449 GetModule()->ReportWarning(
"Decompression of section '{0}' failed: {1}",
3451 llvm::toString(std::move(
error)).c_str());
3452 section_data.
Clear();
3456 section_data.
SetData(buffer_sp);
3457 return buffer_sp->GetByteSize();
3477std::vector<ObjectFile::LoadableData>
3481 std::vector<LoadableData> loadables;
3485 if (H.p_type != llvm::ELF::PT_LOAD)
3487 loadable.
Dest = should_use_paddr ? H.p_paddr : H.p_vaddr;
3490 if (H.p_filesz == 0)
3493 loadable.
Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
3494 segment_data.GetByteSize());
3495 loadables.push_back(loadable);
3500lldb::WritableDataBufferSP
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel, DataExtractor &debug_data, Section *rel_section, bool is_signed)
static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ
static const char *const LLDB_NT_OWNER_NETBSDCORE
static const elf_word LLDB_NT_FREEBSD_ABI_TAG
static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header)
static const elf_word LLDB_NT_GNU_ABI_OS_LINUX
static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header)
static bool GetOsFromOSABI(unsigned char osabi_byte, llvm::Triple::OSType &ostype)
#define _MAKE_OSABI_CASE(x)
static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header)
static uint32_t calc_crc32(uint32_t init, const DataExtractor &data)
static char FindArmAarch64MappingSymbol(const char *symbol_name)
static const char *const LLDB_NT_OWNER_CORE
static const elf_word LLDB_NT_NETBSD_IDENT_TAG
static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS
static std::pair< uint64_t, uint64_t > GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr, const ELFSectionHeader *plt_hdr)
static SectionType GetSectionTypeFromName(llvm::StringRef Name)
static const elf_word LLDB_NT_FREEBSD_ABI_SIZE
static const elf_word LLDB_NT_GNU_ABI_TAG
static const char *const LLDB_NT_OWNER_GNU
static const elf_word LLDB_NT_NETBSD_PROCINFO
#define CASE_AND_STREAM(s, def, width)
static user_id_t SegmentID(size_t PHdrIndex)
static const elf_word LLDB_NT_GNU_ABI_SIZE
static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch)
static const char *const LLDB_NT_OWNER_OPENBSD
static const char *const LLDB_NT_OWNER_FREEBSD
static const char *const LLDB_NT_OWNER_LINUX
static const char * OSABIAsCString(unsigned char osabi_byte)
static Permissions GetPermissions(const ELFSectionHeader &H)
static const char *const LLDB_NT_OWNER_ANDROID
#define IS_MICROMIPS(ST_OTHER)
static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ
static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header)
static const elf_word LLDB_NT_GNU_ABI_OS_HURD
static uint32_t mipsVariantFromElfFlags(const elf::ELFHeader &header)
static const char *const LLDB_NT_OWNER_NETBSD
static unsigned ParsePLTRelocations(Symtab *symbol_table, user_id_t start_id, unsigned rel_type, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr, const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data, DataExtractor &symtab_data, DataExtractor &strtab_data)
static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel, DataExtractor &debug_data, Section *rel_section)
static const elf_word LLDB_NT_GNU_BUILD_ID_TAG
#define LLDB_PLUGIN_DEFINE(PluginName)
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
#define LLDB_SCOPED_TIMERF(...)
Generic ELF object file reader.
static size_t GetSectionHeaderInfo(SectionHeaderColl §ion_headers, lldb_private::DataExtractor &object_data, const elf::ELFHeader &header, lldb_private::UUID &uuid, std::string &gnu_debuglink_file, uint32_t &gnu_debuglink_crc, lldb_private::ArchSpec &arch_spec)
Parses the elf section headers and returns the uuid, debug link name, crc, archspec.
std::vector< elf::ELFProgramHeader > ProgramHeaderColl
static void DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader &header)
unsigned ParseTrampolineSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id, const ELFSectionHeaderInfo *rela_hdr, lldb::user_id_t section_id)
Scans the relocation entries and adds a set of artificial symbols to the given symbol table for each ...
lldb_private::ArchSpec m_arch_spec
The architecture detected from parsing elf file contents.
static void DumpELFSectionHeader_sh_type(lldb_private::Stream *s, elf::elf_word sh_type)
std::shared_ptr< ObjectFileELF > m_gnu_debug_data_object_file
Object file parsed from .gnu_debugdata section (.
SectionHeaderColl::iterator SectionHeaderCollIter
uint32_t m_gnu_debuglink_crc
unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id, lldb_private::Symtab *thetab)
Relocates debug sections.
bool AnySegmentHasPhysicalAddress()
static void DumpELFProgramHeader(lldb_private::Stream *s, const elf::ELFProgramHeader &ph)
lldb_private::Address m_entry_point_address
Cached value of the entry point for this module.
size_t ReadSectionData(lldb_private::Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len) override
llvm::StringRef StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override
static void ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length, lldb_private::ArchSpec &arch_spec)
lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H)
void RelocateSection(lldb_private::Section *section) override
Perform relocations on the section if necessary.
FileAddressToAddressClassMap m_address_class_map
The address class for each symbol in the elf file.
static llvm::StringRef GetPluginDescriptionStatic()
static const uint32_t g_core_uuid_magic
static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs)
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
void DumpDependentModules(lldb_private::Stream *s)
ELF dependent module dump routine.
static void DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type)
static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers, lldb_private::DataExtractor &object_data, const elf::ELFHeader &header)
static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset, lldb::addr_t length)
DynamicSymbolColl m_dynamic_symbols
Collection of symbols from the dynamic table.
static void DumpELFSectionHeader(lldb_private::Stream *s, const ELFSectionHeaderInfo &sh)
std::vector< ELFSectionHeaderInfo > SectionHeaderColl
static void DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s, unsigned char ei_data)
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
std::optional< lldb_private::FileSpec > GetDebugLink()
Return the contents of the .gnu_debuglink section, if the object file contains it.
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override
Get the address type given a file address in an object file.
static void DumpELFSectionHeader_sh_flags(lldb_private::Stream *s, elf::elf_xword sh_flags)
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
static void DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type)
static lldb_private::Status RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid)
size_t SectionIndex(const SectionHeaderCollIter &I)
Returns the index of the given section header.
static void DumpELFProgramHeader_p_flags(lldb_private::Stream *s, elf::elf_word p_flags)
static llvm::StringRef GetPluginNameStatic()
size_t ParseDependentModules()
Scans the dynamic section and locates all dependent modules (shared libraries) populating m_filespec_...
void DumpELFSectionHeaders(lldb_private::Stream *s)
std::shared_ptr< ObjectFileELF > GetGnuDebugDataObjectFile()
Takes the .gnu_debugdata and returns the decompressed object file that is stored within that section.
static lldb::WritableDataBufferSP MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size, uint64_t Offset)
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
static uint32_t CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl &program_headers, lldb_private::DataExtractor &data)
lldb_private::UUID m_uuid
ELF build ID.
void DumpELFProgramHeaders(lldb_private::Stream *s)
size_t ParseDynamicSymbols()
Parses the dynamic symbol table and populates m_dynamic_symbols.
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
lldb::SectionType GetSectionType(const ELFSectionHeaderInfo &H) const
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
std::unique_ptr< lldb_private::FileSpecList > m_filespec_up
List of file specifications corresponding to the modules (shared libraries) on which this object file...
bool ParseProgramHeaders()
Parses all section headers present in this object file and populates m_program_headers.
DynamicSymbolColl::iterator DynamicSymbolCollIter
std::vector< LoadableData > GetLoadableData(lldb_private::Target &target) override
Loads this objfile to memory.
const ELFSectionHeaderInfo * GetSectionHeaderByIndex(lldb::user_id_t id)
Returns the section header with the given id or NULL.
void CreateSections(lldb_private::SectionList &unified_section_list) override
lldb::user_id_t GetSectionIndexByName(const char *name)
Utility method for looking up a section given its name.
unsigned ParseSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id, lldb_private::SectionList *section_list, const size_t num_symbols, const lldb_private::DataExtractor &symtab_data, const lldb_private::DataExtractor &strtab_data)
Helper routine for ParseSymbolTable().
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
SectionHeaderColl::const_iterator SectionHeaderCollConstIter
ProgramHeaderColl m_program_headers
Collection of program headers.
unsigned ApplyRelocations(lldb_private::Symtab *symtab, const elf::ELFHeader *hdr, const elf::ELFSectionHeader *rel_hdr, const elf::ELFSectionHeader *symtab_hdr, const elf::ELFSectionHeader *debug_hdr, lldb_private::DataExtractor &rel_data, lldb_private::DataExtractor &symtab_data, lldb_private::DataExtractor &debug_data, lldb_private::Section *rel_section)
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
bool ParseHeader() override
Attempts to parse the object header.
elf::ELFHeader m_header
ELF file header.
std::string m_gnu_debuglink_file
ELF .gnu_debuglink file and crc data if available.
void ParseUnwindSymbols(lldb_private::Symtab *symbol_table, lldb_private::DWARFCallFrameInfo *eh_frame)
unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id, lldb_private::Section *symtab)
Populates the symbol table with all non-dynamic linker symbols.
SectionHeaderColl m_section_headers
Collection of section headers.
lldb_private::Address GetEntryPointAddress() override
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
void ParseSymtab(lldb_private::Symtab &symtab) override
Parse the symbol table into the provides symbol table object.
unsigned PLTRelocationType()
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
size_t ParseSectionHeaders()
Parses all section headers present in this object file and populates m_section_headers.
lldb_private::Address GetBaseAddress() override
Returns base address of this object file.
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
const elf::ELFDynamic * FindDynamicSymbol(unsigned tag)
llvm::ArrayRef< elf::ELFProgramHeader > ProgramHeaders()
lldb_private::Address GetImageInfoAddress(lldb_private::Target *target) override
Similar to Process::GetImageInfoAddress().
A section + offset based address range class.
A section + offset based address class.
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
lldb::addr_t GetFileAddress() const
Get the file address.
bool IsValid() const
Check if the object state is valid.
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
An architecture specification class.
@ eLoongArchSubType_loongarch64
@ eLoongArchSubType_unknown
@ eLoongArchSubType_loongarch32
uint32_t GetCodeByteSize() const
Architecture code byte width accessor.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
void SetFlags(uint32_t flags)
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
bool IsMIPS() const
if MIPS architecture return true.
uint32_t GetDataByteSize() const
Architecture data byte width accessor.
uint32_t GetFlags() const
@ eMIPSSubType_mips32r6el
@ eMIPSSubType_mips64r6el
@ eMIPSSubType_mips64r2el
@ eMIPSSubType_mips32r2el
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
@ eRISCV_float_abi_double
single precision floating point, +f
@ eRISCV_float_abi_quad
double precision floating point, +d
@ eRISCV_float_abi_single
soft float
bool TripleOSWasSpecified() const
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
void ForEachFDEEntries(const std::function< bool(lldb::addr_t, uint32_t, dw_offset_t)> &callback)
A subclass of DataBuffer that stores a data buffer on the heap.
A class that measures elapsed time in an exception safe way.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
const ConstString & GetFilename() const
Filename string const get accessor.
ConstString GetLastPathComponent() const
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
ConstString GetFileNameExtension() const
Extract the extension of the file.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
std::shared_ptr< WritableDataBuffer > CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
static FileSystem & Instance()
ValueType Get() const
Get accessor for all flags.
bool Test(ValueType bit) const
Test a single flag bit.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const ModuleSpec &spec)
ArchSpec & GetArchitecture()
A plug-in interface definition class for object file parsers.
DataExtractor m_data
The data for this object file so things can be parsed lazily.
Symtab * GetSymtab()
Gets the symbol table for the currently selected architecture (and object for archives).
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
virtual void ParseSymtab(Symtab &symtab)=0
Parse the symbol table into the provides symbol table object.
virtual AddressClass GetAddressClass(lldb::addr_t file_addr)
Get the address type given a file address in an object file.
size_t GetData(lldb::offset_t offset, size_t length, DataExtractor &data) const
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeObjectFile
An intermediate object file.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A Progress indicator helper class.
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const
lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth=UINT32_MAX) const
size_t AddSection(const lldb::SectionSP §ion_sp)
bool ReplaceSection(lldb::user_id_t sect_id, const lldb::SectionSP §ion_sp, uint32_t depth=UINT32_MAX)
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
lldb::SectionSP GetSectionAtIndex(size_t idx) const
bool SetSectionLoadAddress(const lldb::SectionSP §ion_sp, lldb::addr_t load_addr, bool warn_multiple=false)
ConstString GetName() const
void SetIsRelocated(bool b)
lldb::offset_t GetFileOffset() const
ObjectFile * GetObjectFile()
lldb::offset_t GetFileSize() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
unsigned GetIndentLevel() const
Get the current indentation level.
bool GetByteSizeIsValid() const
Address & GetAddressRef()
Symbol * FindSymbolByID(lldb::user_id_t uid) const
Symbol * SymbolAtIndex(size_t idx)
Symbol * FindSymbolAtFileAddress(lldb::addr_t file_addr)
Symbol * FindSymbolContainingFileAddress(lldb::addr_t file_addr)
uint32_t AddSymbol(const Symbol &symbol)
void Dump(Stream *s, Target *target, SortOrder sort_type, Mangled::NamePreference name_preference=Mangled::ePreferDemangled)
ObjectFile * GetObjectFile() const
size_t GetNumSymbols() const
SectionLoadList & GetSectionLoadList()
bool ReadPointerFromMemory(const Address &addr, Status &error, Address &pointer_addr, bool force_live_memory=false)
uint64_t ReadUnsignedIntegerFromMemory(const Address &addr, size_t integer_byte_size, uint64_t fail_value, Status &error, bool force_live_memory=false)
#define LLDB_INVALID_CPUTYPE
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
llvm::Error uncompress(llvm::ArrayRef< uint8_t > InputBuffer, llvm::SmallVectorImpl< uint8_t > &Uncompressed)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ByteOrder
Byte ordering definitions.
@ eSectionTypeDWARFDebugStrOffsets
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeDWARFDebugPubNames
@ eSectionTypeDWARFDebugLocDwo
@ eSectionTypeDWARFDebugFrame
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeDWARFDebugLocLists
DWARF v5 .debug_loclists.
@ eSectionTypeDWARFDebugTypes
DWARF .debug_types section.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeDWARFDebugMacInfo
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Parse an ELFNote entry from the given DataExtractor starting at position offset.
size_t GetByteSize() const
Represents an entry in an ELF dynamic table.
elf_addr d_ptr
Pointer value of the table entry.
elf_xword d_val
Integer value of the table entry.
bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Parse an ELFDynamic entry from the given DataExtractor starting at position offset.
elf_sxword d_tag
Type of dynamic table entry.
Represents a relocation entry with an implicit addend.
static unsigned RelocSymbol64(const ELFRel &rel)
Returns the symbol index when the given entry represents a 64-bit relocation.
static unsigned RelocType64(const ELFRel &rel)
Returns the type when the given entry represents a 64-bit relocation.
static unsigned RelocType32(const ELFRel &rel)
Returns the type when the given entry represents a 32-bit relocation.
static unsigned RelocSymbol32(const ELFRel &rel)
Returns the symbol index when the given entry represents a 32-bit relocation.
Represents a relocation entry with an explicit addend.
static unsigned RelocSymbol64(const ELFRela &rela)
Returns the symbol index when the given entry represents a 64-bit relocation.
static unsigned RelocType64(const ELFRela &rela)
Returns the type when the given entry represents a 64-bit relocation.
static unsigned RelocType32(const ELFRela &rela)
Returns the type when the given entry represents a 32-bit relocation.
static unsigned RelocSymbol32(const ELFRela &rela)
Returns the symbol index when the given entry represents a 32-bit relocation.
Represents a symbol within an ELF symbol table.
unsigned char getType() const
Returns the type attribute of the st_info member.
elf_half st_shndx
Section to which this symbol applies.
unsigned char st_info
Symbol type and binding attributes.
unsigned char getBinding() const
Returns the binding attribute of the st_info member.
bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Parse an ELFSymbol entry from the given DataExtractor starting at position offset.
elf_addr st_value
Absolute or relocatable address.
elf_word st_name
Symbol name string index.
elf_xword st_size
Size of the symbol or zero.
unsigned char st_other
Reserved for future use.
llvm::ArrayRef< uint8_t > Contents
BaseType GetRangeBase() const
SizeType GetByteSize() const
BaseType GetRangeEnd() const
void Slide(BaseType slide)
void SetByteSize(SizeType s)
lldb::user_id_t GetID() const
Get accessor for the user ID.