14#include <unordered_map>
40#include "llvm/ADT/IntervalMap.h"
41#include "llvm/ADT/PointerUnion.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/BinaryFormat/ELF.h"
44#include "llvm/Object/Decompressor.h"
45#include "llvm/Support/ARMBuildAttributes.h"
46#include "llvm/Support/CRC.h"
47#include "llvm/Support/FormatVariadic.h"
48#include "llvm/Support/MathExtras.h"
49#include "llvm/Support/MemoryBuffer.h"
50#include "llvm/Support/MipsABIFlags.h"
51#include "llvm/Support/RISCVAttributes.h"
52#include "llvm/TargetParser/RISCVISAInfo.h"
53#include "llvm/TargetParser/SubtargetFeature.h"
55#define CASE_AND_STREAM(s, def, width) \
57 s->Printf("%-*s", width, #def); \
63using namespace llvm::ELF;
110 ELFRelocation(
unsigned type);
116 static unsigned RelocType32(
const ELFRelocation &rel);
118 static unsigned RelocType64(
const ELFRelocation &rel);
120 static unsigned RelocSymbol32(
const ELFRelocation &rel);
122 static unsigned RelocSymbol64(
const ELFRelocation &rel);
124 static elf_addr RelocOffset32(
const ELFRelocation &rel);
126 static elf_addr RelocOffset64(
const ELFRelocation &rel);
128 static elf_sxword RelocAddend32(
const ELFRelocation &rel);
130 static elf_sxword RelocAddend64(
const ELFRelocation &rel);
132 bool IsRela() {
return (llvm::isa<ELFRela *>(reloc)); }
135 typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
145 assert(lhs_module_parent && rhs_module_parent);
148 if (lhs->GetFileAddress() != rhs->GetFileAddress())
149 lhs_module_parent->ReportWarning(
150 "mismatch addresses for section {0} when "
151 "merging with {1}, expected: {2:x}, "
153 lhs->GetTypeAsCString(), rhs_module_parent->GetFileSpec().GetPath(),
154 lhs->GetFileAddress(), rhs->GetFileAddress());
159 return rhs->GetFileSize() > lhs->GetFileSize() ? rhs : lhs;
163ELFRelocation::ELFRelocation(
unsigned type) {
164 if (type == DT_REL || type == SHT_REL)
165 reloc =
new ELFRel();
166 else if (type == DT_RELA || type == SHT_RELA)
167 reloc =
new ELFRela();
169 assert(
false &&
"unexpected relocation type");
170 reloc =
static_cast<ELFRel *
>(
nullptr);
174ELFRelocation::~ELFRelocation() {
175 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(reloc))
178 delete llvm::cast<ELFRela *>(reloc);
181bool ELFRelocation::Parse(
const lldb_private::DataExtractor &data,
183 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(reloc))
184 return elfrel->Parse(data, offset);
186 return llvm::cast<ELFRela *>(reloc)->Parse(data, offset);
189unsigned ELFRelocation::RelocType32(
const ELFRelocation &rel) {
190 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(rel.reloc))
196unsigned ELFRelocation::RelocType64(
const ELFRelocation &rel) {
197 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(rel.reloc))
203unsigned ELFRelocation::RelocSymbol32(
const ELFRelocation &rel) {
204 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(rel.reloc))
210unsigned ELFRelocation::RelocSymbol64(
const ELFRelocation &rel) {
211 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(rel.reloc))
217elf_addr ELFRelocation::RelocOffset32(
const ELFRelocation &rel) {
218 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(rel.reloc))
219 return elfrel->r_offset;
221 return llvm::cast<ELFRela *>(rel.reloc)->r_offset;
224elf_addr ELFRelocation::RelocOffset64(
const ELFRelocation &rel) {
225 if (
auto *elfrel = llvm::dyn_cast<ELFRel *>(rel.reloc))
226 return elfrel->r_offset;
228 return llvm::cast<ELFRela *>(rel.reloc)->r_offset;
231elf_sxword ELFRelocation::RelocAddend32(
const ELFRelocation &rel) {
232 if (llvm::isa<ELFRel *>(rel.reloc))
235 return llvm::cast<ELFRela *>(rel.reloc)->r_addend;
238elf_sxword ELFRelocation::RelocAddend64(
const ELFRelocation &rel) {
239 if (llvm::isa<ELFRel *>(rel.reloc))
242 return llvm::cast<ELFRela *>(rel.reloc)->r_addend;
262 if (strncmp(buf,
"CORE", 4) == 0) {
270 if (cstr ==
nullptr) {
272 LLDB_LOGF(log,
"Failed to parse note name lacking nul terminator");
281 const uint32_t mips_arch = header.
e_flags & llvm::ELF::EF_MIPS_ARCH;
284 uint32_t fileclass = header.
e_ident[EI_CLASS];
289 if (header.
e_type == ET_CORE) {
291 case llvm::ELF::ELFCLASS32:
294 case llvm::ELF::ELFCLASS64:
303 case llvm::ELF::EF_MIPS_ARCH_1:
304 case llvm::ELF::EF_MIPS_ARCH_2:
305 case llvm::ELF::EF_MIPS_ARCH_32:
308 case llvm::ELF::EF_MIPS_ARCH_32R2:
311 case llvm::ELF::EF_MIPS_ARCH_32R6:
314 case llvm::ELF::EF_MIPS_ARCH_3:
315 case llvm::ELF::EF_MIPS_ARCH_4:
316 case llvm::ELF::EF_MIPS_ARCH_5:
317 case llvm::ELF::EF_MIPS_ARCH_64:
320 case llvm::ELF::EF_MIPS_ARCH_64R2:
323 case llvm::ELF::EF_MIPS_ARCH_64R6:
334 uint32_t fileclass = header.
e_ident[EI_CLASS];
336 case llvm::ELF::ELFCLASS32:
338 case llvm::ELF::ELFCLASS64:
347 if (
endian == ELFDATA2LSB)
354 uint32_t fileclass = header.
e_ident[EI_CLASS];
356 case llvm::ELF::ELFCLASS32:
358 case llvm::ELF::ELFCLASS64:
367 if (header.
e_ident[EI_OSABI] == ELFOSABI_AMDGPU_HSA) {
368 switch (header.
e_ident[EI_ABIVERSION]) {
370 case ELFABIVERSION_AMDGPU_HSA_V2:
373 case ELFABIVERSION_AMDGPU_HSA_V3:
374 case ELFABIVERSION_AMDGPU_HSA_V4:
375 case ELFABIVERSION_AMDGPU_HSA_V5:
376 case ELFABIVERSION_AMDGPU_HSA_V6:
379 return header.
e_flags & EF_AMDGPU_MACH;
386 if (header.
e_machine == llvm::ELF::EM_MIPS)
388 else if (header.
e_machine == llvm::ELF::EM_PPC64)
390 else if (header.
e_machine == llvm::ELF::EM_RISCV)
392 else if (header.
e_machine == llvm::ELF::EM_LOONGARCH)
394 else if (header.
e_machine == llvm::ELF::EM_AMDGPU)
422 bool mapped_writable =
false;
423 if (!extractor_sp || !extractor_sp->HasData()) {
427 extractor_sp = std::make_shared<DataExtractor>(buffer_sp);
429 mapped_writable =
true;
432 assert(extractor_sp && extractor_sp->HasData());
434 DataBufferSP data_sp = extractor_sp->GetSharedDataBuffer();
436 if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
439 const uint8_t *magic = data_sp->GetBytes() + data_offset;
444 if (data_sp->GetByteSize() < length) {
449 mapped_writable =
true;
450 magic = data_sp->GetBytes();
451 extractor_sp->SetData(data_sp);
455 if (!mapped_writable) {
456 data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(),
457 data_sp->GetByteSize());
459 magic = data_sp->GetBytes();
460 extractor_sp->SetData(data_sp);
464 if (address_size == 4 || address_size == 8) {
465 extractor_sp->SetAddressByteSize(address_size);
467 module_sp, extractor_sp, data_offset, file, file_offset, length));
468 ArchSpec spec = objfile_up->GetArchitecture();
469 if (spec && objfile_up->SetModulesArchitecture(spec))
470 return objfile_up.release();
479 if (!data_sp || data_sp->GetByteSize() < (llvm::ELF::EI_NIDENT))
481 const uint8_t *magic = data_sp->GetBytes();
490 if (!hdr.
Parse(data, &offset))
499 if (end_phdrs > data_sp->GetByteSize())
500 data_sp =
ReadMemory(process_sp, header_addr, end_phdrs);
502 std::unique_ptr<ObjectFileELF> objfile_up(
503 new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
504 ArchSpec spec = objfile_up->GetArchitecture();
505 if (spec && objfile_up->SetModulesArchitecture(spec))
506 return objfile_up.release();
515 data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
516 const uint8_t *magic = data_sp->GetBytes() + data_offset;
523 return llvm::crc32(init,
530 uint32_t core_notes_crc = 0;
533 if (H.p_type == llvm::ELF::PT_NOTE) {
534 const elf_off ph_offset = H.p_offset;
535 const size_t ph_size = H.p_filesz;
538 if (segment_data.
SetData(object_data, ph_offset, ph_size) != ph_size) {
544 core_notes_crc =
calc_crc32(core_notes_crc, segment_data);
548 return core_notes_crc;
552#define _MAKE_OSABI_CASE(x) \
555 switch (osabi_byte) {
577 return "<unknown-osabi>";
579#undef _MAKE_OSABI_CASE
589 llvm::Triple::OSType &ostype) {
590 switch (osabi_byte) {
592 ostype = llvm::Triple::OSType::AIX;
594 case ELFOSABI_FREEBSD:
595 ostype = llvm::Triple::OSType::FreeBSD;
598 ostype = llvm::Triple::OSType::Linux;
600 case ELFOSABI_NETBSD:
601 ostype = llvm::Triple::OSType::NetBSD;
603 case ELFOSABI_OPENBSD:
604 ostype = llvm::Triple::OSType::OpenBSD;
606 case ELFOSABI_SOLARIS:
607 ostype = llvm::Triple::OSType::Solaris;
609 case ELFOSABI_AMDGPU_HSA:
610 ostype = llvm::Triple::OSType::AMDHSA;
613 ostype = llvm::Triple::OSType::UnknownOS;
615 return ostype != llvm::Triple::OSType::UnknownOS;
623 if (!extractor_sp || !extractor_sp->HasData())
626 extractor_sp->GetByteSize())) {
629 if (header.
Parse(*extractor_sp, &header_offset)) {
645 llvm::Triple::OSType ostype;
646 llvm::Triple::OSType spec_ostype =
649 LLDB_LOGF(log,
"ObjectFileELF::%s file '%s' module OSABI: %s",
650 __FUNCTION__, file.
GetPath().c_str(),
655 assert(spec_ostype == ostype);
656 if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
658 "ObjectFileELF::%s file '%s' set ELF module OS type "
659 "from ELF header OSABI.",
660 __FUNCTION__, file.
GetPath().c_str());
667 if (extractor_sp->GetByteSize() < length)
669 extractor_sp->SetData(data_sp);
677 header.
Parse(*extractor_sp, &header_offset);
680 uint32_t gnu_debuglink_crc = 0;
681 std::string gnu_debuglink_file;
686 gnu_debuglink_file, gnu_debuglink_crc,
692 "ObjectFileELF::%s file '%s' module set to triple: %s "
694 __FUNCTION__, file.
GetPath().c_str(),
695 spec_triple.getTriple().c_str(),
699 uint32_t core_notes_crc = 0;
701 if (!gnu_debuglink_crc) {
705 (length - file_offset) / 1024);
711 if (header.
e_type == llvm::ELF::ET_CORE) {
718 gnu_debuglink_crc =
calc_crc32(0, *extractor_sp);
721 using u32le = llvm::support::ulittle32_t;
722 if (gnu_debuglink_crc) {
724 u32le data(gnu_debuglink_crc);
725 uuid =
UUID(&data,
sizeof(data));
726 }
else if (core_notes_crc) {
731 uuid =
UUID(data,
sizeof(data));
751 :
ObjectFile(module_sp, file, file_offset, length, extractor_sp,
761 :
ObjectFile(module_sp, process_sp, header_addr,
769 bool value_is_offset) {
772 size_t num_loaded_sections = 0;
775 if (!value_is_offset) {
782 const size_t num_sections = section_list->
GetSize();
785 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
801 if (section_sp->IsThreadSpecific())
803 if (section_sp->Test(SHF_ALLOC) ||
815 load_addr &= 0xFFFFFFFF;
818 ++num_loaded_sections;
821 return num_loaded_sections > 0;
828 if (
m_header.e_ident[EI_DATA] == ELFDATA2MSB)
830 if (
m_header.e_ident[EI_DATA] == ELFDATA2LSB)
847 if (symtab_objfile !=
nullptr && symtab_objfile !=
this)
888 if (H.p_type == llvm::ELF::PT_NOTE) {
905 using u32le = llvm::support::ulittle32_t;
907 uint32_t core_notes_crc = 0;
915 if (core_notes_crc) {
944 uint32_t num_specs = 0;
946 for (
unsigned i = 0; i < num_modules; ++i) {
965 if (symbol.
d_tag != DT_DEBUG && symbol.
d_tag != DT_MIPS_RLD_MAP &&
966 symbol.
d_tag != DT_MIPS_RLD_MAP_REL)
976 if (symbol.
d_tag == DT_DEBUG)
981 if ((symbol.
d_tag == DT_MIPS_RLD_MAP ||
982 symbol.
d_tag == DT_MIPS_RLD_MAP_REL) &&
989 if (symbol.
d_tag == DT_MIPS_RLD_MAP) {
996 if (symbol.
d_tag == DT_MIPS_RLD_MAP_REL) {
1005 addr_t debug_ptr_address =
1063 if (entry.symbol.d_tag != DT_FILTER && entry.symbol.d_tag != DT_AUXILIARY)
1065 if (!entry.name.empty())
1079 if (entry.symbol.d_tag != DT_NEEDED)
1081 if (!entry.name.empty()) {
1096 if (!program_headers.empty())
1097 return program_headers.size();
1103 program_headers.resize(header.
e_phnum);
1104 if (program_headers.size() != header.
e_phnum)
1110 if (data.
SetData(object_data, ph_offset, ph_size) != ph_size)
1115 for (idx = 0, offset = 0; idx < header.
e_phnum; ++idx) {
1116 if (!program_headers[idx].Parse(data, &offset))
1120 if (idx < program_headers.size())
1121 program_headers.resize(idx);
1123 return program_headers.size();
1144 if (!
note.Parse(data, &offset)) {
1149 LLDB_LOGF(log,
"ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
1150 __FUNCTION__,
note.n_name.c_str(),
note.n_type);
1157 uint32_t version_info;
1158 if (data.
GetU32(&offset, &version_info, 1) ==
nullptr) {
1165 const uint32_t version_major = version_info / 100000;
1166 const uint32_t version_minor = (version_info / 1000) % 100;
1169 snprintf(os_name,
sizeof(os_name),
"freebsd%" PRIu32
".%" PRIu32,
1170 version_major, version_minor);
1173 arch_spec.
GetTriple().setOSName(os_name);
1174 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1177 "ObjectFileELF::%s detected FreeBSD %" PRIu32
".%" PRIu32
1179 __FUNCTION__, version_major, version_minor,
1180 static_cast<uint32_t
>(version_info % 1000));
1184 switch (
note.n_type) {
1188 uint32_t version_info[4];
1189 if (data.
GetU32(&offset, &version_info[0],
note.n_descsz / 4) ==
1197 switch (version_info[0]) {
1199 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1201 llvm::Triple::VendorType::UnknownVendor);
1203 "ObjectFileELF::%s detected Linux, min version %" PRIu32
1204 ".%" PRIu32
".%" PRIu32,
1205 __FUNCTION__, version_info[1], version_info[2],
1212 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
1214 llvm::Triple::VendorType::UnknownVendor);
1216 "ObjectFileELF::%s detected Hurd (unsupported), min "
1217 "version %" PRIu32
".%" PRIu32
".%" PRIu32,
1218 __FUNCTION__, version_info[1], version_info[2],
1222 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Solaris);
1224 llvm::Triple::VendorType::UnknownVendor);
1226 "ObjectFileELF::%s detected Solaris, min version %" PRIu32
1227 ".%" PRIu32
".%" PRIu32,
1228 __FUNCTION__, version_info[1], version_info[2],
1233 "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
1234 ", min version %" PRIu32
".%" PRIu32
".%" PRIu32,
1235 __FUNCTION__, version_info[0], version_info[1],
1236 version_info[2], version_info[3]);
1248 if (
note.n_descsz >= 4) {
1249 if (
const uint8_t *buf = data.
PeekData(offset,
note.n_descsz)) {
1254 "failed to read GNU_BUILD_ID note payload");
1261 if (arch_spec.
IsMIPS() &&
1262 arch_spec.
GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1264 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1272 uint32_t version_info;
1273 if (data.
GetU32(&offset, &version_info, 1) ==
nullptr) {
1285 const uint32_t version_major = version_info / 100000000;
1286 const uint32_t version_minor = (version_info % 100000000) / 1000000;
1287 const uint32_t version_patch = (version_info % 10000) / 100;
1290 llvm::formatv(
"netbsd{0}.{1}.{2}", version_major, version_minor,
1291 version_patch).str());
1292 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1298 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::NetBSD);
1299 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1304 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::OpenBSD);
1305 arch_spec.
GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1307 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1309 llvm::Triple::EnvironmentType::Android);
1313 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1337 if (
note.n_type == NT_FILE) {
1341 offset += count * 3 *
1343 for (
size_t i = 0; i < count; ++i) {
1345 if (cstr ==
nullptr) {
1347 "ObjectFileELF::%s trying to read "
1348 "at an offset after the end "
1349 "(GetCStr returned nullptr)",
1353 llvm::StringRef path(cstr);
1354 if (path.contains(
"/lib/x86_64-linux-gnu") || path.contains(
"/lib/i386-linux-gnu")) {
1355 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1359 if (arch_spec.
IsMIPS() &&
1360 arch_spec.
GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1363 arch_spec.
GetTriple().setOS(llvm::Triple::OSType::Linux);
1369 offset = note_offset +
note.GetByteSize();
1379 uint8_t FormatVersion = data.
GetU8(&Offset);
1380 if (FormatVersion != llvm::ELFAttrs::Format_Version)
1383 Offset = Offset +
sizeof(uint32_t);
1384 llvm::StringRef VendorName = data.
GetCStr(&Offset);
1386 if (VendorName !=
"aeabi")
1389 if (arch_spec.
GetTriple().getEnvironment() ==
1390 llvm::Triple::UnknownEnvironment)
1391 arch_spec.
GetTriple().setEnvironment(llvm::Triple::EABI);
1393 while (Offset < length) {
1394 uint8_t Tag = data.
GetU8(&Offset);
1395 uint32_t Size = data.
GetU32(&Offset);
1397 if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
1400 while (Offset < length) {
1406 else if (Tag % 2 == 0)
1413 case llvm::ARMBuildAttrs::CPU_raw_name:
1414 case llvm::ARMBuildAttrs::CPU_name:
1419 case llvm::ARMBuildAttrs::ABI_VFP_args: {
1422 if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
1423 if (arch_spec.
GetTriple().getEnvironment() ==
1424 llvm::Triple::UnknownEnvironment ||
1425 arch_spec.
GetTriple().getEnvironment() == llvm::Triple::EABIHF)
1426 arch_spec.
GetTriple().setEnvironment(llvm::Triple::EABI);
1429 }
else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
1430 if (arch_spec.
GetTriple().getEnvironment() ==
1431 llvm::Triple::UnknownEnvironment ||
1432 arch_spec.
GetTriple().getEnvironment() == llvm::Triple::EABI)
1433 arch_spec.
GetTriple().setEnvironment(llvm::Triple::EABIHF);
1445static std::optional<lldb::offset_t>
1447 uint32_t length, llvm::StringRef name) {
1448 uint32_t section_length = 0;
1449 llvm::StringRef section_name;
1451 offset += section_length;
1455 auto tmp_offset = offset;
1456 section_length = data.
GetU32(&tmp_offset);
1457 section_name = data.
GetCStr(&tmp_offset);
1458 }
while (section_name != name && offset + section_length < length);
1460 if (section_name == name)
1463 return std::nullopt;
1466static std::optional<lldb::offset_t>
1471 auto parent_section_length = data.
GetU32(&offset);
1473 auto parent_section_end_offset = offset + parent_section_length;
1475 uint32_t section_length = 0;
1476 unsigned section_tag = 0;
1478 offset += section_length;
1481 auto tmp_offset = offset;
1483 section_length = data.
GetU32(&tmp_offset);
1484 }
while (section_tag != tag &&
1485 offset + section_length < parent_section_end_offset);
1487 if (section_tag == tag)
1490 return std::nullopt;
1493static std::optional<std::variant<uint64_t, llvm::StringRef>>
1499 auto parent_section_length = data.
GetU32(&offset);
1500 auto parent_section_end_offset = offset + parent_section_length;
1502 std::variant<uint64_t, llvm::StringRef> result;
1503 unsigned attribute_tag = 0;
1509 if (attribute_tag % 2)
1510 result = data.
GetCStr(&offset);
1513 }
while (attribute_tag != tag && offset < parent_section_end_offset);
1515 if (attribute_tag == tag)
1518 return std::nullopt;
1522 uint64_t length,
ArchSpec &arch_spec) {
1568 uint8_t format_version = data.
GetU8(&offset);
1569 if (format_version != llvm::ELFAttrs::Format_Version)
1572 auto subsection_or_opt =
1574 if (!subsection_or_opt) {
1576 "ObjectFileELF::%s Ill-formed .riscv.attributes section: "
1577 "mandatory 'riscv' sub-section was not preserved",
1583 data, *subsection_or_opt, llvm::ELFAttrs::File);
1584 if (!subsubsection_or_opt)
1588 llvm::RISCVAttrs::ARCH);
1592 auto normalized_isa_info = llvm::RISCVISAInfo::parseNormalizedArchString(
1593 std::get<llvm::StringRef>(*value_or_opt));
1594 if (llvm::errorToBool(normalized_isa_info.takeError()))
1597 llvm::SubtargetFeatures features;
1598 features.addFeaturesVector((*normalized_isa_info)->toFeatures());
1604 auto isa_info = llvm::RISCVISAInfo::parseArchString(
1605 std::get<llvm::StringRef>(*value_or_opt),
1607 if (
auto error = isa_info.takeError()) {
1609 ss <<
"the .riscv.attributes section contains an invalid RISC-V arch "
1611 << llvm::toString(std::move(
error))
1612 <<
"\n\tThis could result in misleading disassembler output\n";
1622 std::string &gnu_debuglink_file,
1623 uint32_t &gnu_debuglink_crc,
1626 if (!section_headers.empty())
1627 return section_headers.size();
1631 if (arch_spec.
GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
1632 llvm::Triple::OSType ostype;
1633 llvm::Triple::OSType spec_ostype;
1645 spec_ostype = arch_spec.
GetTriple().getOS();
1646 assert(spec_ostype == ostype);
1650 if (arch_spec.
GetMachine() == llvm::Triple::mips ||
1651 arch_spec.
GetMachine() == llvm::Triple::mipsel ||
1652 arch_spec.
GetMachine() == llvm::Triple::mips64 ||
1653 arch_spec.
GetMachine() == llvm::Triple::mips64el) {
1654 switch (header.
e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
1655 case llvm::ELF::EF_MIPS_MICROMIPS:
1658 case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
1661 case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
1669 if (arch_spec.
GetMachine() == llvm::Triple::arm ||
1670 arch_spec.
GetMachine() == llvm::Triple::thumb) {
1671 if (header.
e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
1673 else if (header.
e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
1677 if (arch_spec.
GetMachine() == llvm::Triple::riscv32 ||
1678 arch_spec.
GetMachine() == llvm::Triple::riscv64) {
1679 uint32_t flags = arch_spec.
GetFlags();
1681 if (header.
e_flags & llvm::ELF::EF_RISCV_RVC)
1683 if (header.
e_flags & llvm::ELF::EF_RISCV_RVE)
1686 if ((header.
e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) ==
1687 llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)
1689 else if ((header.
e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) ==
1690 llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)
1692 else if ((header.
e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) ==
1693 llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)
1699 if (arch_spec.
GetMachine() == llvm::Triple::loongarch32 ||
1700 arch_spec.
GetMachine() == llvm::Triple::loongarch64) {
1701 uint32_t flags = arch_spec.
GetFlags();
1702 switch (header.
e_flags & llvm::ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) {
1703 case llvm::ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT:
1706 case llvm::ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT:
1709 case llvm::ELF::EF_LOONGARCH_ABI_SOFT_FLOAT:
1722 section_headers.resize(header.
e_shnum);
1723 if (section_headers.size() != header.
e_shnum)
1729 if (sh_data.
SetData(object_data, sh_offset, sh_size) != sh_size)
1734 for (idx = 0, offset = 0; idx < header.
e_shnum; ++idx) {
1735 if (!section_headers[idx].Parse(sh_data, &offset))
1738 if (idx < section_headers.size())
1739 section_headers.resize(idx);
1741 const unsigned strtab_idx = header.
e_shstrndx;
1742 if (strtab_idx && strtab_idx < section_headers.size()) {
1744 const size_t byte_size = sheader.
sh_size;
1745 const Elf64_Off offset = sheader.
sh_offset;
1748 if (shstr_data.
SetData(object_data, offset, byte_size) == byte_size) {
1750 I != section_headers.end(); ++I) {
1751 static ConstString g_sect_name_gnu_debuglink(
".gnu_debuglink");
1753 const uint64_t section_size =
1755 llvm::StringRef name(shstr_data.
PeekCStr(I->sh_name));
1756 I->section_name = name.str();
1758 if (arch_spec.
IsMIPS()) {
1759 uint32_t arch_flags = arch_spec.
GetFlags();
1761 if (sheader.
sh_type == SHT_MIPS_ABIFLAGS) {
1764 section_size) == section_size)) {
1767 arch_flags |= data.
GetU32(&offset);
1771 switch (data.
GetU8(&offset)) {
1772 case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
1775 case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
1778 case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
1781 case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
1784 case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
1787 case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
1790 case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
1793 case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
1800 switch (header.
e_flags & llvm::ELF::EF_MIPS_ABI) {
1801 case llvm::ELF::EF_MIPS_ABI_O32:
1804 case EF_MIPS_ABI_O64:
1807 case EF_MIPS_ABI_EABI32:
1810 case EF_MIPS_ABI_EABI64:
1815 if (header.
e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
1817 else if (header.
e_flags & llvm::ELF::EF_MIPS_ABI2)
1824 if (arch_spec.
GetMachine() == llvm::Triple::arm ||
1825 arch_spec.
GetMachine() == llvm::Triple::thumb) {
1828 if (sheader.
sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
1829 data.
SetData(object_data, sheader.
sh_offset, section_size) == section_size)
1835 if (sheader.
sh_type == llvm::ELF::SHT_RISCV_ATTRIBUTES &&
1836 section_size != 0 &&
1842 if (name == g_sect_name_gnu_debuglink) {
1845 section_size) == section_size)) {
1847 gnu_debuglink_file = data.
GetCStr(&gnu_debuglink_offset);
1848 gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
1849 data.
GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
1854 bool is_note_header = (sheader.
sh_type == SHT_NOTE);
1858 static ConstString g_sect_name_android_ident(
".note.android.ident");
1859 if (!is_note_header && name == g_sect_name_android_ident)
1860 is_note_header =
true;
1862 if (is_note_header) {
1866 section_size) == section_size)) {
1869 LLDB_LOGF(log,
"ObjectFileELF::%s ELF note processing failed: %s",
1870 __FUNCTION__,
error.AsCString());
1877 if (arch_spec.
GetTriple().getVendor() == llvm::Triple::UnknownVendor)
1878 arch_spec.
GetTriple().setVendorName(llvm::StringRef());
1879 if (arch_spec.
GetTriple().getOS() == llvm::Triple::UnknownOS)
1880 arch_spec.
GetTriple().setOSName(llvm::StringRef());
1882 return section_headers.size();
1886 section_headers.clear();
1892 size_t pos = symbol_name.find(
'@');
1893 return symbol_name.substr(0, pos);
1924 if (Name.consume_front(
".debug_"))
1927 return llvm::StringSwitch<SectionType>(Name)
1966 Permissions Perm = Permissions(0);
1968 Perm |= ePermissionsReadable;
1970 Perm |= ePermissionsWritable;
1972 Perm |= ePermissionsExecutable;
1977 Permissions Perm = Permissions(0);
1979 Perm |= ePermissionsReadable;
1981 Perm |= ePermissionsWritable;
1983 Perm |= ePermissionsExecutable;
1991struct SectionAddressInfo {
1999class VMAddressProvider {
2001 llvm::IntervalMapHalfOpenInfo<addr_t>>;
2004 addr_t NextVMAddress = 0;
2005 VMMap::Allocator Alloc;
2006 VMMap Segments{Alloc};
2007 VMMap Sections{Alloc};
2008 lldb_private::Log *Log =
GetLog(LLDBLog::Modules);
2009 size_t SegmentCount = 0;
2010 std::string SegmentName;
2012 VMRange GetVMRange(
const ELFSectionHeader &H) {
2018 if ((ObjectType == ObjectFile::Type::eTypeObjectFile ||
2019 (ObjectType == ObjectFile::Type::eTypeDebugInfo && H.
sh_addr == 0)) &&
2020 Segments.empty() && (H.
sh_flags & SHF_ALLOC)) {
2022 llvm::alignTo(NextVMAddress, std::max<addr_t>(H.
sh_addralign, 1));
2023 Address = NextVMAddress;
2024 NextVMAddress += Size;
2026 return VMRange(Address, Size);
2031 : ObjectType(
Type), SegmentName(std::string(SegmentName)) {}
2033 std::string GetNextSegmentName()
const {
2034 return llvm::formatv(
"{0}[{1}]", SegmentName, SegmentCount).str();
2037 std::optional<VMRange> GetAddressInfo(
const ELFProgramHeader &H) {
2039 LLDB_LOG(Log,
"Ignoring zero-sized {0} segment. Corrupt object file?",
2041 return std::nullopt;
2045 LLDB_LOG(Log,
"Ignoring overlapping {0} segment. Corrupt object file?",
2047 return std::nullopt;
2052 std::optional<SectionAddressInfo> GetAddressInfo(
const ELFSectionHeader &H) {
2053 VMRange Range = GetVMRange(H);
2055 auto It = Segments.find(Range.GetRangeBase());
2056 if ((H.
sh_flags & SHF_ALLOC) && It.valid()) {
2058 if (It.start() <= Range.GetRangeBase()) {
2059 MaxSize = It.stop() - Range.GetRangeBase();
2062 MaxSize = It.start() - Range.GetRangeBase();
2063 if (Range.GetByteSize() > MaxSize) {
2064 LLDB_LOG(Log,
"Shortening section crossing segment boundaries. "
2065 "Corrupt object file?");
2066 Range.SetByteSize(MaxSize);
2069 if (Range.GetByteSize() > 0 &&
2070 Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) {
2071 LLDB_LOG(Log,
"Ignoring overlapping section. Corrupt object file?");
2072 return std::nullopt;
2075 Range.Slide(-Segment->GetFileAddress());
2076 return SectionAddressInfo{Segment, Range};
2079 void AddSegment(
const VMRange &Range,
SectionSP Seg) {
2080 Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
2084 void AddSection(SectionAddressInfo Info,
SectionSP Sect) {
2085 if (Info.Range.GetByteSize() == 0)
2088 Info.Range.Slide(Info.Segment->GetFileAddress());
2089 Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(),
2103 addr_t vm_addr = section->GetFileAddress();
2104 llvm::StringRef name = section->GetName();
2105 offset_t byte_size = section->GetByteSize();
2106 bool thread_specific = section->IsThreadSpecific();
2107 uint32_t permissions = section->GetPermissions();
2108 uint32_t alignment = section->GetLog2Align();
2110 for (
auto sect : section_list) {
2111 if (sect->GetName() == name &&
2112 sect->IsThreadSpecific() == thread_specific &&
2113 sect->GetPermissions() == permissions &&
2114 sect->GetByteSize() == byte_size && sect->GetFileAddress() == vm_addr &&
2115 sect->GetLog2Align() == alignment) {
2133 VMAddressProvider regular_provider(
GetType(),
"PT_LOAD");
2134 VMAddressProvider tls_provider(
GetType(),
"PT_TLS");
2141 VMAddressProvider &provider =
2142 PHdr.
p_type == PT_TLS ? tls_provider : regular_provider;
2143 auto InfoOr = provider.GetAddressInfo(PHdr);
2147 uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.
p_align, 1));
2148 SectionSP Segment = std::make_shared<Section>(
2151 InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.
p_offset,
2154 Segment->SetIsThreadSpecific(PHdr.
p_type == PT_TLS);
2157 provider.AddSegment(*InfoOr, std::move(Segment));
2169 const uint64_t file_size =
2172 VMAddressProvider &provider =
2173 header.
sh_flags & SHF_TLS ? tls_provider : regular_provider;
2174 auto InfoOr = provider.GetAddressInfo(header);
2183 SectionSP section_sp = std::make_shared<Section>(
2190 InfoOr->Range.GetRangeBase(),
2191 InfoOr->Range.GetByteSize(),
2198 section_sp->SetIsThreadSpecific(header.
sh_flags & SHF_TLS);
2199 (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *
m_sections_up)
2200 .AddSection(section_sp);
2201 provider.AddSection(std::move(*InfoOr), std::move(section_sp));
2206 unified_section_list =
2213 if (
auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
2215 gdd_objfile_section_list->FindSectionByType(
2219 if (module_section_sp)
2223 unified_section_list.
AddSection(symtab_section_sp);
2239 "no LZMA support found for reading .gnu_debugdata section");
2245 section->GetSectionData(data);
2246 llvm::SmallVector<uint8_t, 0> uncompressedData;
2250 "an error occurred while decompressing the section {0}: {1}",
2251 section->GetName(), llvm::toString(std::move(err)).c_str());
2257 new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
2258 DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(gdd_data_buf);
2260 llvm::StringRef(
"gnu_debugdata"));
2262 GetModule(), extractor_sp, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
2283 const char *dollar_pos = ::strchr(symbol_name,
'$');
2284 if (!dollar_pos || dollar_pos[1] ==
'\0')
2287 if (dollar_pos[2] ==
'\0' || dollar_pos[2] ==
'.')
2288 return dollar_pos[1];
2296 if (strcmp(symbol_name,
"$d") == 0) {
2299 if (strcmp(symbol_name,
"$x") == 0) {
2305#define STO_MIPS_ISA (3 << 6)
2306#define STO_MICROMIPS (2 << 6)
2307#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
2310std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
2312 SectionList *section_list,
const size_t num_symbols,
2329 static ConstString rodata_section_name(
".rodata");
2330 static ConstString rodata1_section_name(
".rodata1");
2345 llvm::StringRef file_extension =
m_file.GetFileNameExtension();
2346 bool skip_oatdata_oatexec =
2347 file_extension ==
".oat" || file_extension ==
".odex";
2352 module_sp ? module_sp->GetSectionList() :
nullptr;
2359 std::unordered_map<lldb::SectionSP, lldb::SectionSP> section_map;
2362 for (i = 0; i < num_symbols; ++i) {
2363 if (!symbol.
Parse(symtab_data, &offset))
2374 if (llvm::StringRef(symbol_name).starts_with(
".L"))
2382 if (symbol.
getType() == STT_FUNC &&
2383 llvm::StringRef(symbol_name).ends_with(
"$plt"))
2387 if (symbol.
getType() != STT_SECTION &&
2388 (symbol_name ==
nullptr || symbol_name[0] ==
'\0'))
2393 if (skip_oatdata_oatexec && (::strcmp(symbol_name,
"oatdata") == 0 ||
2394 ::strcmp(symbol_name,
"oatexec") == 0))
2399 Elf64_Half shndx = symbol.
st_shndx;
2462 if (symbol_section_sp) {
2463 llvm::StringRef sect_name = symbol_section_sp->GetName();
2464 if (sect_name == text_section_name || sect_name == init_section_name ||
2465 sect_name == fini_section_name || sect_name == ctors_section_name ||
2466 sect_name == dtors_section_name) {
2468 }
else if (sect_name == data_section_name ||
2469 sect_name == data2_section_name ||
2470 sect_name == rodata_section_name ||
2471 sect_name == rodata1_section_name ||
2472 sect_name == bss_section_name) {
2474 }
else if (symbol_section_sp->Get() & SHF_ALLOC)
2482 int64_t symbol_value_offset = 0;
2483 uint32_t additional_flags = 0;
2485 if (arch.
GetMachine() == llvm::Triple::arm) {
2489 switch (mapping_symbol) {
2498 address_class_map[symbol.
st_value] =
2510 }
else if (arch.
GetMachine() == llvm::Triple::aarch64) {
2514 switch (mapping_symbol) {
2528 }
else if (arch.
GetTriple().isRISCV()) {
2535 switch (mapping_symbol) {
2551 if (arch.
GetMachine() == llvm::Triple::arm) {
2559 symbol_value_offset = -1;
2560 address_class_map[symbol.
st_value ^ 1] =
2602 uint64_t symbol_value = symbol.
st_value + symbol_value_offset;
2604 if (symbol_section_sp &&
2606 symbol_value -= symbol_section_sp->GetFileAddress();
2608 if (symbol_section_sp && module_section_list &&
2609 module_section_list != section_list) {
2610 auto section_it = section_map.find(symbol_section_sp);
2611 if (section_it == section_map.end()) {
2612 section_it = section_map
2613 .emplace(symbol_section_sp,
2618 if (section_it->second)
2619 symbol_section_sp = section_it->second;
2622 bool is_global = symbol.
getBinding() == STB_GLOBAL;
2623 uint32_t flags = symbol.
st_other << 8 | symbol.
st_info | additional_flags;
2624 llvm::StringRef symbol_ref(symbol_name);
2628 size_t version_pos = symbol_ref.find(
'@');
2629 bool has_suffix = version_pos != llvm::StringRef::npos;
2630 llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
2636 llvm::StringRef suffix = symbol_ref.substr(version_pos);
2639 if (!mangled_name.empty())
2643 llvm::StringRef demangled_name = demangled.
GetStringRef();
2644 if (!demangled_name.empty())
2653 bool symbol_size_valid =
2656 bool is_trampoline =
false;
2665 if (trampoline_name.starts_with(
"__AArch64ADRPThunk_") ||
2666 trampoline_name.starts_with(
"__AArch64AbsLongThunk_")) {
2668 is_trampoline =
true;
2694 return {i, address_class_map};
2697std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
2705 auto [num_symbols, address_class_map] =
2712 return {num_symbols, address_class_map};
2722 assert(symtab_hdr->
sh_type == SHT_SYMTAB ||
2723 symtab_hdr->
sh_type == SHT_DYNSYM);
2729 if (symtab && strtab) {
2739 return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
2740 symtab_data, strtab_data);
2762 if (std::optional<DataExtractor> dynstr_data =
GetDynstrData()) {
2764 switch (entry.symbol.d_tag) {
2772 const char *name = dynstr_data->GetCStr(&cursor);
2774 entry.name = std::string(name);
2789 if (entry.symbol.d_tag == tag)
2790 return &entry.symbol;
2804 return symbol->
d_val;
2813static std::pair<uint64_t, uint64_t>
2829 if (plt_entsize <= 4) {
2839 plt_entsize = plt_hdr->
sh_size / (num_relocations + 1);
2844 return std::make_pair(plt_entsize, plt_offset);
2853 ELFRelocation rel(rel_type);
2857 uint64_t plt_offset, plt_entsize;
2858 std::tie(plt_entsize, plt_offset) =
2862 typedef unsigned (*reloc_info_fn)(
const ELFRelocation &rel);
2863 reloc_info_fn reloc_type;
2864 reloc_info_fn reloc_symbol;
2867 reloc_type = ELFRelocation::RelocType32;
2868 reloc_symbol = ELFRelocation::RelocSymbol32;
2870 reloc_type = ELFRelocation::RelocType64;
2871 reloc_symbol = ELFRelocation::RelocSymbol64;
2876 for (i = 0; i < num_relocations; ++i) {
2877 if (!rel.Parse(rel_data, &offset))
2880 if (reloc_type(rel) != slot_type)
2884 if (!symbol.
Parse(symtab_data, &symbol_offset))
2888 uint64_t plt_index = plt_offset + i * plt_entsize;
2915 assert(rel_hdr->
sh_type == SHT_RELA || rel_hdr->
sh_type == SHT_REL);
2929 if (!symtab_id || !plt_id)
2949 if (!plt_section_sp)
2978 rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
2979 rel_data, symtab_data, strtab_data);
2992 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2994 ELFRelocation::RelocOffset64(rel);
2995 uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
2996 memcpy(dst, &val_offset,
sizeof(uint64_t));
3002 Section *rel_section,
bool is_signed) {
3007 value += ELFRelocation::RelocAddend32(rel);
3010 ((int64_t)value >
INT32_MAX || (int64_t)value < INT32_MIN))) {
3012 LLDB_LOGF(log,
"Failed to apply debug info relocations");
3015 uint32_t truncated_addr = (value & 0xFFFFFFFF);
3019 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
3021 ELFRelocation::RelocOffset32(rel);
3022 memcpy(dst, &truncated_addr,
sizeof(uint32_t));
3036 LLDB_LOGF(log,
"Debug info symbol invalid: %s", name);
3039 assert(llvm::isUInt<32>(value) &&
"Valid addresses are 32-bit");
3043 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
3045 ELFRelocation::RelocOffset32(rel);
3048 memcpy(&addend, dst,
sizeof(int32_t));
3051 if (addend < 0 &&
static_cast<uint32_t
>(-addend) > value) {
3052 LLDB_LOGF(log,
"Debug info relocation overflow: 0x%" PRIx64,
3053 static_cast<int64_t
>(value) + addend);
3056 if (!llvm::isUInt<32>(value + addend)) {
3057 LLDB_LOGF(log,
"Debug info relocation out of range: 0x%" PRIx64, value);
3060 uint32_t addr = value + addend;
3061 memcpy(dst, &addr,
sizeof(uint32_t));
3070 ELFRelocation rel(rel_hdr->
sh_type);
3073 typedef unsigned (*reloc_info_fn)(
const ELFRelocation &rel);
3074 reloc_info_fn reloc_type;
3075 reloc_info_fn reloc_symbol;
3078 reloc_type = ELFRelocation::RelocType32;
3079 reloc_symbol = ELFRelocation::RelocSymbol32;
3081 reloc_type = ELFRelocation::RelocType64;
3082 reloc_symbol = ELFRelocation::RelocSymbol64;
3085 for (
unsigned i = 0; i < num_relocations; ++i) {
3086 if (!rel.Parse(rel_data, &offset)) {
3087 GetModule()->ReportError(
".rel{0}[{1:d}] failed to parse relocation",
3091 const Symbol *symbol =
nullptr;
3095 case llvm::ELF::EM_ARM:
3096 switch (reloc_type(rel)) {
3101 GetModule()->ReportError(
"unsupported AArch32 relocation:"
3102 " .rel{0}[{1}], type {2}",
3103 rel_section->
GetName(), i, reloc_type(rel));
3106 assert(
false &&
"unexpected relocation type");
3109 case llvm::ELF::EM_386:
3110 switch (reloc_type(rel)) {
3115 rel_section->
GetFileOffset() + ELFRelocation::RelocOffset32(rel);
3119 llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
3120 uint32_t *dst =
reinterpret_cast<uint32_t *
>(
3121 data_buffer->
GetBytes() + f_offset);
3125 value += ELFRelocation::RelocAddend32(rel);
3131 GetModule()->ReportError(
".rel{0}[{1}] unknown symbol id: {2:d}",
3138 GetModule()->ReportError(
"unsupported i386 relocation:"
3139 " .rel{0}[{1}], type {2}",
3140 rel_section->
GetName(), i, reloc_type(rel));
3143 assert(
false &&
"unexpected relocation type");
3148 GetModule()->ReportError(
"unsupported 32-bit ELF machine arch: {0}", hdr->
e_machine);
3153 case llvm::ELF::EM_AARCH64:
3154 switch (reloc_type(rel)) {
3155 case R_AARCH64_ABS64:
3158 case R_AARCH64_ABS32:
3162 assert(
false &&
"unexpected relocation type");
3165 case llvm::ELF::EM_LOONGARCH:
3166 switch (reloc_type(rel)) {
3174 assert(
false &&
"unexpected relocation type");
3177 case llvm::ELF::EM_X86_64:
3178 switch (reloc_type(rel)) {
3191 assert(
false &&
"unexpected relocation type");
3195 GetModule()->ReportError(
"unsupported 64-bit ELF machine arch: {0}", hdr->
e_machine);
3207 assert(rel_hdr->
sh_type == SHT_RELA || rel_hdr->
sh_type == SHT_REL);
3245 *rel_data_sp, *symtab_data_sp, *debug_data_sp, debug);
3256 Progress progress(
"Parsing symbol table",
3257 m_file.GetFilename().nonEmptyOr(
"<Unknown>").str());
3262 ObjectFile *module_obj_file = module_sp->GetObjectFile();
3263 if (module_obj_file && module_obj_file !=
this)
3266 SectionList *section_list = module_sp->GetSectionList();
3270 uint64_t symbol_id = 0;
3280 auto [num_symbols, address_class_map] =
3283 symbol_id += num_symbols;
3292 if (!symtab ||
GetSectionList()->FindSectionByName(
".gnu_debugdata")) {
3297 auto [num_symbols, address_class_map] =
3299 symbol_id += num_symbols;
3303 uint32_t dynamic_num_symbols = 0;
3304 std::optional<DataExtractor> symtab_data =
3307 if (symtab_data && strtab_data) {
3308 auto [num_symbols_parsed, address_class_map] =
ParseSymbols(
3309 &lldb_symtab, symbol_id, section_list, dynamic_num_symbols,
3310 symtab_data.value(), strtab_data.value());
3311 symbol_id += num_symbols_parsed;
3332 if (reloc_section) {
3342 GetModule()->GetUnwindTable().GetEHFrameInfo()) {
3356 bool is_valid_entry_point =
3357 entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
3358 addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
3360 entry_point_file_addr)) {
3365 SectionSP section_sp = entry_point_addr.GetSection();
3375 entry_point_addr.GetOffset(),
3384 if (arch.
GetMachine() == llvm::Triple::arm &&
3385 (entry_point_file_addr & 1)) {
3399 static llvm::StringRef debug_prefix(
".debug");
3409 llvm::StringRef section_name = section->
GetName();
3411 if (section_name.empty())
3415 if (!section_name.starts_with(debug_prefix))
3419 std::string needle = std::string(
".rel") + section_name.str();
3420 std::string needlea = std::string(
".rela") + section_name.str();
3424 if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
3425 llvm::StringRef hay_name(I->section_name);
3426 if (hay_name.empty())
3428 if (needle == hay_name || needlea == hay_name) {
3449 std::vector<Symbol> new_symbols;
3452 uint64_t last_symbol_id =
3466 addr_t offset = file_addr - section_sp->GetFileAddress();
3467 uint64_t symbol_id = ++last_symbol_id;
3485 new_symbols.push_back(eh_symbol);
3491 for (
const Symbol &s : new_symbols)
3511 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
3512 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
3518 *s <<
", file = '" <<
m_file
3543 if (image_info_addr.
IsValid())
3544 s->
Printf(
"image_info_address = %#16.16" PRIx64
"\n",
3553 s->
Printf(
"e_ident[EI_MAG0 ] = 0x%2.2x\n", header.
e_ident[EI_MAG0]);
3554 s->
Printf(
"e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.
e_ident[EI_MAG1],
3556 s->
Printf(
"e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.
e_ident[EI_MAG2],
3558 s->
Printf(
"e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.
e_ident[EI_MAG3],
3561 s->
Printf(
"e_ident[EI_CLASS ] = 0x%2.2x\n", header.
e_ident[EI_CLASS]);
3562 s->
Printf(
"e_ident[EI_DATA ] = 0x%2.2x ", header.
e_ident[EI_DATA]);
3564 s->
Printf(
"\ne_ident[EI_VERSION] = 0x%2.2x\n", header.
e_ident[EI_VERSION]);
3565 s->
Printf(
"e_ident[EI_PAD ] = 0x%2.2x\n", header.
e_ident[EI_PAD]);
3612 unsigned char ei_data) {
3615 *s <<
"ELFDATANONE";
3618 *s <<
"ELFDATA2LSB - Little Endian";
3621 *s <<
"ELFDATA2MSB - Big Endian";
3634 s->
Printf(
" %8.8" PRIx64
" %8.8" PRIx64
" %8.8" PRIx64, ph.
p_offset,
3648 const int kStrWidth = 15;
3660 s->
Printf(
"0x%8.8x%*s", p_type, kStrWidth - 10,
"");
3669 *s << ((p_flags & PF_X) ?
"PF_X" :
" ")
3670 << (((p_flags & PF_X) && (p_flags & PF_W)) ?
'+' :
' ')
3671 << ((p_flags & PF_W) ?
"PF_W" :
" ")
3672 << (((p_flags & PF_W) && (p_flags & PF_R)) ?
'+' :
' ')
3673 << ((p_flags & PF_R) ?
"PF_R" :
" ");
3684 s->
PutCString(
"IDX p_type p_offset p_vaddr p_paddr "
3685 "p_filesz p_memsz p_flags p_align\n");
3686 s->
PutCString(
"==== --------------- -------- -------- -------- "
3687 "-------- -------- ------------------------- --------\n");
3690 s->
Format(
"[{0,2}] ", H.index());
3705 s->
Printf(
") %8.8" PRIx64
" %8.8" PRIx64
" %8.8" PRIx64, sh.
sh_addr,
3716 const int kStrWidth = 12;
3735 s->
Printf(
"0x%8.8x%*s", sh_type, kStrWidth - 10,
"");
3745 *s << ((sh_flags & SHF_WRITE) ?
"WRITE" :
" ")
3746 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ?
'+' :
' ')
3747 << ((sh_flags & SHF_ALLOC) ?
"ALLOC" :
" ")
3748 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ?
'+' :
' ')
3749 << ((sh_flags & SHF_EXECINSTR) ?
"EXECINSTR" :
" ");
3761 "addr offset size link info addralgn "
3763 s->
PutCString(
"==== -------- ------------ -------------------------------- "
3764 "-------- -------- -------- -------- -------- -------- "
3765 "-------- ====================\n");
3770 s->
Printf(
"[%2u] ", idx);
3772 const std::string §ion_name = I->section_name;
3773 if (!section_name.empty())
3774 *s <<
' ' << section_name <<
"\n";
3781 if (num_modules > 0) {
3783 for (
unsigned i = 0; i < num_modules; ++i) {
3791#define DYNAMIC_STRINGIFY_ENUM(tag, value) \
3795#define DYNAMIC_TAG(n, v)
3797 case llvm::ELF::EM_AARCH64:
3799#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3800#include "llvm/BinaryFormat/DynamicTags.def"
3801#undef AARCH64_DYNAMIC_TAG
3805 case llvm::ELF::EM_HEXAGON:
3807#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3808#include "llvm/BinaryFormat/DynamicTags.def"
3809#undef HEXAGON_DYNAMIC_TAG
3813 case llvm::ELF::EM_MIPS:
3815#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3816#include "llvm/BinaryFormat/DynamicTags.def"
3817#undef MIPS_DYNAMIC_TAG
3821 case llvm::ELF::EM_PPC:
3823#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3824#include "llvm/BinaryFormat/DynamicTags.def"
3825#undef PPC_DYNAMIC_TAG
3829 case llvm::ELF::EM_PPC64:
3831#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3832#include "llvm/BinaryFormat/DynamicTags.def"
3833#undef PPC64_DYNAMIC_TAG
3837 case llvm::ELF::EM_RISCV:
3839#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3840#include "llvm/BinaryFormat/DynamicTags.def"
3841#undef RISCV_DYNAMIC_TAG
3845 case llvm::ELF::EM_SPARC:
3846 case llvm::ELF::EM_SPARC32PLUS:
3847 case llvm::ELF::EM_SPARCV9:
3849#define SPARC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3850#include "llvm/BinaryFormat/DynamicTags.def"
3851#undef SPARC_DYNAMIC_TAG
3855 case llvm::ELF::EM_X86_64:
3857#define X86_64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
3858#include "llvm/BinaryFormat/DynamicTags.def"
3859#undef X86_64_DYNAMIC_TAG
3866#define AARCH64_DYNAMIC_TAG(name, value)
3867#define MIPS_DYNAMIC_TAG(name, value)
3868#define HEXAGON_DYNAMIC_TAG(name, value)
3869#define PPC_DYNAMIC_TAG(name, value)
3870#define PPC64_DYNAMIC_TAG(name, value)
3871#define RISCV_DYNAMIC_TAG(name, value)
3872#define SPARC_DYNAMIC_TAG(name, value)
3873#define X86_64_DYNAMIC_TAG(name, value)
3875#define DYNAMIC_TAG_MARKER(name, value)
3876#define DYNAMIC_TAG(name, value) \
3879#include "llvm/BinaryFormat/DynamicTags.def"
3881#undef AARCH64_DYNAMIC_TAG
3882#undef MIPS_DYNAMIC_TAG
3883#undef HEXAGON_DYNAMIC_TAG
3884#undef PPC_DYNAMIC_TAG
3885#undef PPC64_DYNAMIC_TAG
3886#undef RISCV_DYNAMIC_TAG
3887#undef SPARC_DYNAMIC_TAG
3888#undef X86_64_DYNAMIC_TAG
3889#undef DYNAMIC_TAG_MARKER
3890#undef DYNAMIC_STRINGIFY_ENUM
3892 return "<unknown:>0x" + llvm::utohexstr(
Type,
true);
3903 s->
PutCString(
"==== ---------------- ------------------\n");
3906 s->
Printf(
"[%2u] ", idx++);
3908 "%-16s 0x%16.16" PRIx64,
3910 entry.symbol.d_ptr);
3911 if (!entry.name.empty())
3912 s->
Printf(
" \"%s\"", entry.name.c_str());
3931 if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
3945 case llvm::ELF::ET_NONE:
3949 case llvm::ELF::ET_REL:
3953 case llvm::ELF::ET_EXEC:
3957 case llvm::ELF::ET_DYN:
3973 case llvm::ELF::ET_NONE:
3977 case llvm::ELF::ET_REL:
3981 case llvm::ELF::ET_EXEC:
3986 llvm::StringRef loader_section_name(
".interp");
3989 if (loader_section) {
3997 llvm::StringRef loader_name(buffer, read_size - 1);
3998 llvm::StringRef freebsd_kernel_loader_name(
"/red/herring");
3999 if (loader_name == freebsd_kernel_loader_name)
4006 case llvm::ELF::ET_DYN:
4034 if (!section->
Test(SHF_COMPRESSED))
4041 return data.
CopyData(section_offset, dst_len, dst);
4051 if (result == 0 || !(section->
Get() & llvm::ELF::SHF_COMPRESSED))
4054 auto Decompressor = llvm::object::Decompressor::create(
4056 {reinterpret_cast<const char *>(section_data.GetDataStart()),
4057 size_t(section_data.GetByteSize())},
4059 if (!Decompressor) {
4061 "unable to initialize decompressor for section '{0}': {1}",
4062 section->
GetName(), llvm::toString(Decompressor.takeError()).c_str());
4063 section_data.
Clear();
4068 std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
4069 if (
auto error = Decompressor->decompress(
4070 {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) {
4071 GetModule()->ReportWarning(
"decompression of section '{0}' failed: {1}",
4073 llvm::toString(std::move(
error)).c_str());
4074 section_data.
Clear();
4078 section_data.
SetData(buffer_sp);
4079 return buffer_sp->GetByteSize();
4116std::vector<ObjectFile::LoadableData>
4120 std::vector<LoadableData> loadables;
4124 if (H.p_type != llvm::ELF::PT_LOAD)
4126 loadable.
Dest = should_use_paddr ? H.p_paddr : H.p_vaddr;
4129 if (H.p_filesz == 0)
4132 loadable.
Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
4133 segment_data.GetByteSize());
4134 loadables.push_back(loadable);
4146std::optional<DataExtractor>
4163 return std::nullopt;
4169 return std::nullopt;
4179 assert(dynamic->GetObjectFile() ==
this);
4185 section_list->FindSectionByID(header->sh_link).get()) {
4204 if (strtab ==
nullptr || strsz ==
nullptr)
4205 return std::nullopt;
4216 if (H.p_type == llvm::ELF::PT_DYNAMIC) {
4231 assert(dynamic->GetObjectFile() ==
this);
4238 return std::nullopt;
4243 if (hash ==
nullptr)
4244 return std::nullopt;
4247 struct DtHashHeader {
4254 offset_t offset = offsetof(DtHashHeader, nchain);
4255 return data->
GetU32(&offset);
4258 return std::nullopt;
4263 if (gnu_hash ==
nullptr)
4264 return std::nullopt;
4268 struct DtGnuHashHeader {
4269 uint32_t nbuckets = 0;
4270 uint32_t symoffset = 0;
4271 uint32_t bloom_size = 0;
4272 uint32_t bloom_shift = 0;
4274 uint32_t num_symbols = 0;
4278 DtGnuHashHeader header;
4279 header.nbuckets = data->
GetU32(&offset);
4280 header.symoffset = data->
GetU32(&offset);
4281 header.bloom_size = data->
GetU32(&offset);
4282 header.bloom_shift = data->
GetU32(&offset);
4284 const addr_t buckets_offset =
4285 sizeof(DtGnuHashHeader) + addr_size * header.bloom_size;
4286 std::vector<uint32_t> buckets;
4290 for (uint32_t i = 0; i < header.nbuckets; ++i)
4291 buckets.push_back(bucket_data->GetU32(&offset));
4293 uint32_t last_symbol = 0;
4294 for (uint32_t bucket_value : buckets)
4295 last_symbol = std::max(bucket_value, last_symbol);
4296 if (last_symbol < header.symoffset) {
4297 num_symbols = header.symoffset;
4300 const addr_t chains_base_offset = buckets_offset + header.nbuckets * 4;
4304 chains_base_offset + (last_symbol - header.symoffset) * 4)) {
4306 uint32_t chain_entry = chain_entry_data->GetU32(&offset);
4309 if (chain_entry & 1)
4315 num_symbols = last_symbol;
4319 if (num_symbols > 0)
4322 return std::nullopt;
4325std::optional<DataExtractor>
4343 if (symtab ==
nullptr || syment ==
nullptr)
4344 return std::nullopt;
4347 num_symbols = *syms;
4349 num_symbols = *syms;
4351 return std::nullopt;
4352 if (num_symbols == 0)
4353 return std::nullopt;
static llvm::raw_ostream & error(Stream &strm)
static llvm::raw_ostream & note(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 uint32_t AMDGPUVariantFromElfFlags(const elf::ELFHeader &header)
static const char *const LLDB_NT_OWNER_NETBSDCORE
static const elf_word LLDB_NT_FREEBSD_ABI_TAG
static std::string getDynamicTagAsString(uint16_t Arch, uint64_t Type)
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 std::optional< lldb::offset_t > FindSubSectionOffsetByName(const DataExtractor &data, lldb::offset_t offset, uint32_t length, llvm::StringRef name)
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 char FindRISCVMappingSymbol(const char *symbol_name)
static SectionSP FindMatchingSection(const SectionList §ion_list, SectionSP section)
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 void ApplyELF32ABS32RelRelocation(Symtab *symtab, ELFRelocation &rel, DataExtractor &debug_data, Section *rel_section)
static std::optional< std::variant< uint64_t, llvm::StringRef > > GetAttributeValueByTag(const DataExtractor &data, lldb::offset_t offset, unsigned tag)
static const elf_word LLDB_NT_GNU_ABI_SIZE
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
static std::optional< lldb::offset_t > FindSubSubSectionOffsetByTag(const DataExtractor &data, lldb::offset_t offset, unsigned tag)
#define LLDB_PLUGIN_DEFINE(PluginName)
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
#define LLDB_SCOPED_TIMERF(...)
Generic COFF 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
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)
std::optional< lldb_private::DataExtractor > GetDynsymDataFromDynamic(uint32_t &num_symbols)
Get the bytes that represent the dynamic symbol table from the .dynamic section from process memory.
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.
std::optional< uint32_t > GetNumSymbolsFromDynamicGnuHash()
Get the number of symbols from the DT_GNU_HASH dynamic entry.
std::optional< lldb_private::DataExtractor > ReadDataFromDynamic(const elf::ELFDynamic *dyn, uint64_t length, uint64_t offset=0)
Read the bytes pointed to by the dyn dynamic entry.
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)
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
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)
std::pair< unsigned, FileAddressToAddressClassMap > 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.
size_t ParseDynamicSymbols()
Parses the dynamic symbol table and populates m_dynamic_symbols.
static lldb_private::ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
std::optional< lldb_private::DataExtractor > GetDynamicData()
Get the bytes that represent the .dynamic section.
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...
lldb_private::FileSpecList GetReExportedLibraries() override
Gets the file spec list of libraries re-exported by this object file.
std::unique_ptr< lldb_private::FileSpecList > m_filespec_up
List of file specifications corresponding to the modules (shared libraries) on which this object file...
std::optional< uint32_t > GetNumSymbolsFromDynamicHash()
Get the number of symbols from the DT_HASH dynamic entry.
bool ParseProgramHeaders()
Parses all section headers present in this object file and populates m_program_headers.
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
static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset, lldb::addr_t length)
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
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.
void DumpELFDynamic(lldb_private::Stream *s)
ELF dump the .dynamic section.
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.
static void ParseRISCVAttributes(const lldb_private::DataExtractor &data, uint64_t length, lldb_private::ArchSpec &arch_spec)
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)
std::pair< unsigned, FileAddressToAddressClassMap > 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().
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)
lldb::user_id_t GetSectionIndexByName(llvm::StringRef name)
Utility method for looking up a section given its name.
lldb::addr_t m_dynamic_base_addr
The file address of the .dynamic section.
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
Extract the dependent modules from an object file.
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)
std::map< lldb::addr_t, lldb_private::AddressClass > FileAddressToAddressClassMap
An ordered map of file address to address class.
llvm::ArrayRef< elf::ELFProgramHeader > ProgramHeaders()
std::optional< lldb_private::DataExtractor > GetDynstrData()
Get the bytes that represent the dynamic string table data.
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.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
lldb::SectionSP GetSection() const
Get const accessor for the section.
bool Slide(int64_t offset)
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
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.
@ eLoongArch_abi_single_float
soft float
@ eLoongArch_abi_double_float
single precision floating point, +f
bool IsMIPS() const
if MIPS architecture return true.
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
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
void SetSubtargetFeatures(llvm::SubtargetFeatures &&subtarget_features)
A uniqued constant string class.
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.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
A class that measures elapsed time in an exception safe way.
void EmplaceBack(Args &&...args)
Inserts a new FileSpec into the FileSpecList constructed in-place with the given arguments.
bool AppendIfUnique(const FileSpec &file)
Append a FileSpec object if unique.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
llvm::StringRef GetFilename() const
Filename string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
std::shared_ptr< WritableDataBuffer > CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
ValueType Get() const
Get accessor for all flags.
bool Test(ValueType bit) const
Test a single flag bit.
A class that handles mangled names.
void SetDemangledName(ConstString name)
ConstString GetMangledName() const
Mangled name get accessor.
ConstString GetDemangledName() const
Demangled name get accessor.
void SetMangledName(ConstString name)
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const ModuleSpec &spec)
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
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.
Symtab * GetSymtab(bool can_create=true)
Gets the symbol table for the currently selected architecture (and object for archives).
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
static lldb::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
@ 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.
size_t GetData(lldb::offset_t offset, size_t length, lldb::DataExtractorSP &data_sp) const
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
bool IsInMemory() const
Returns true if the object file exists only in memory.
lldb::ProcessWP m_process_wp
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.
bool ReplaceSection(const lldb::SectionSP &remove_section_sp, const lldb::SectionSP &replace_section_sp, uint32_t depth=UINT32_MAX)
static SectionList Merge(SectionList &lhs, SectionList &rhs, MergeCallback filter)
lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const
lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth=UINT32_MAX) const
lldb::SectionSP FindSectionByName(llvm::StringRef section_name) const
size_t AddSection(const lldb::SectionSP §ion_sp)
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
void SetIsRelocated(bool b)
lldb::offset_t GetFileOffset() const
llvm::StringRef GetName() const
ObjectFile * GetObjectFile()
lldb::offset_t GetFileSize() const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
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.
void SetSizeIsSynthesized(bool b)
bool GetByteSizeIsValid() const
Address & GetAddressRef()
ConstString GetName() const
void SetByteSize(lldb::addr_t size)
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
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)
bool SetSectionLoadAddress(const lldb::SectionSP §ion, lldb::addr_t load_addr, bool warn_multiple=false)
Represents UUID's of various sizes.
uint8_t * GetBytes()
Get a pointer to the data.
#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.
std::shared_ptr< lldb_private::Process > ProcessSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeLLDBFormatters
@ eSectionTypeLLDBTypeSummaries
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP
bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Parse an ELFNote entry from the given DataExtractor starting at position offset.
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.
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.
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
lldb::user_id_t GetID() const
Get accessor for the user ID.