#include "ObjectFileELF.h"
#include <algorithm>
#include <cassert>
#include <optional>
#include <unordered_map>
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Progress.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/LZMA.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpecList.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MipsABIFlags.h"
#define CASE_AND_STREAM(s, def, width) …
usingnamespacelldb;
usingnamespacelldb_private;
usingnamespaceelf;
usingnamespacellvm::ELF;
LLDB_PLUGIN_DEFINE(…)
static const char *const LLDB_NT_OWNER_FREEBSD = …;
static const char *const LLDB_NT_OWNER_GNU = …;
static const char *const LLDB_NT_OWNER_NETBSD = …;
static const char *const LLDB_NT_OWNER_NETBSDCORE = …;
static const char *const LLDB_NT_OWNER_OPENBSD = …;
static const char *const LLDB_NT_OWNER_ANDROID = …;
static const char *const LLDB_NT_OWNER_CORE = …;
static const char *const LLDB_NT_OWNER_LINUX = …;
static const elf_word LLDB_NT_FREEBSD_ABI_TAG = …;
static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = …;
static const elf_word LLDB_NT_GNU_ABI_TAG = …;
static const elf_word LLDB_NT_GNU_ABI_SIZE = …;
static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = …;
static const elf_word LLDB_NT_NETBSD_IDENT_TAG = …;
static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = …;
static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = …;
static const elf_word LLDB_NT_NETBSD_PROCINFO = …;
static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = …;
static const elf_word LLDB_NT_GNU_ABI_OS_HURD = …;
static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = …;
namespace {
class ELFRelocation { … };
}
ELFRelocation::ELFRelocation(unsigned type) { … }
ELFRelocation::~ELFRelocation() { … }
bool ELFRelocation::Parse(const lldb_private::DataExtractor &data,
lldb::offset_t *offset) { … }
unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) { … }
unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) { … }
unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) { … }
unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) { … }
elf_addr ELFRelocation::RelocOffset32(const ELFRelocation &rel) { … }
elf_addr ELFRelocation::RelocOffset64(const ELFRelocation &rel) { … }
elf_sxword ELFRelocation::RelocAddend32(const ELFRelocation &rel) { … }
elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) { … }
static user_id_t SegmentID(size_t PHdrIndex) { … }
bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { … }
static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) { … }
static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) { … }
static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) { … }
static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) { … }
static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { … }
char ObjectFileELF::ID;
const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
void ObjectFileELF::Initialize() { … }
void ObjectFileELF::Terminate() { … }
ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
DataBufferSP data_sp,
lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
lldb::offset_t file_offset,
lldb::offset_t length) { … }
ObjectFile *ObjectFileELF::CreateMemoryInstance(
const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { … }
bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
lldb::addr_t data_offset,
lldb::addr_t data_length) { … }
static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) { … }
uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
const ProgramHeaderColl &program_headers, DataExtractor &object_data) { … }
static const char *OSABIAsCString(unsigned char osabi_byte) { … }
static bool GetOsFromOSABI(unsigned char osabi_byte,
llvm::Triple::OSType &ostype) { … }
size_t ObjectFileELF::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) { … }
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
DataBufferSP data_sp, lldb::offset_t data_offset,
const FileSpec *file, lldb::offset_t file_offset,
lldb::offset_t length)
: … { … }
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
DataBufferSP header_data_sp,
const lldb::ProcessSP &process_sp,
addr_t header_addr)
: … { … }
bool ObjectFileELF::IsExecutable() const { … }
bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
bool value_is_offset) { … }
ByteOrder ObjectFileELF::GetByteOrder() const { … }
uint32_t ObjectFileELF::GetAddressByteSize() const { … }
AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) { … }
size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) { … }
size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const { … }
bool ObjectFileELF::ParseHeader() { … }
UUID ObjectFileELF::GetUUID() { … }
std::optional<FileSpec> ObjectFileELF::GetDebugLink() { … }
uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) { … }
Address ObjectFileELF::GetImageInfoAddress(Target *target) { … }
lldb_private::Address ObjectFileELF::GetEntryPointAddress() { … }
Address ObjectFileELF::GetBaseAddress() { … }
size_t ObjectFileELF::ParseDependentModules() { … }
size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
DataExtractor &object_data,
const ELFHeader &header) { … }
bool ObjectFileELF::ParseProgramHeaders() { … }
lldb_private::Status
ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
lldb_private::ArchSpec &arch_spec,
lldb_private::UUID &uuid) { … }
void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
ArchSpec &arch_spec) { … }
size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
DataExtractor &object_data,
const elf::ELFHeader &header,
lldb_private::UUID &uuid,
std::string &gnu_debuglink_file,
uint32_t &gnu_debuglink_crc,
ArchSpec &arch_spec) { … }
llvm::StringRef
ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { … }
size_t ObjectFileELF::ParseSectionHeaders() { … }
const ObjectFileELF::ELFSectionHeaderInfo *
ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { … }
lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { … }
static SectionType GetSectionTypeFromName(llvm::StringRef Name) { … }
SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const { … }
static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) { … }
static Permissions GetPermissions(const ELFSectionHeader &H) { … }
static Permissions GetPermissions(const ELFProgramHeader &H) { … }
namespace {
VMRange;
struct SectionAddressInfo { … };
class VMAddressProvider { … };
}
static SectionSP FindMatchingSection(const SectionList §ion_list,
SectionSP section) { … }
void ObjectFileELF::CreateSections(SectionList &unified_section_list) { … }
std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() { … }
static char FindArmAarch64MappingSymbol(const char *symbol_name) { … }
#define STO_MIPS_ISA …
#define STO_MICROMIPS …
#define IS_MICROMIPS(ST_OTHER) …
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
SectionList *section_list, const size_t num_symbols,
const DataExtractor &symtab_data,
const DataExtractor &strtab_data) { … }
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
lldb_private::Section *symtab) { … }
size_t ObjectFileELF::ParseDynamicSymbols() { … }
const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) { … }
unsigned ObjectFileELF::PLTRelocationType() { … }
static std::pair<uint64_t, uint64_t>
GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
const ELFSectionHeader *plt_hdr) { … }
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) { … }
unsigned
ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
const ELFSectionHeaderInfo *rel_hdr,
user_id_t rel_id) { … }
static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel,
DataExtractor &debug_data,
Section *rel_section) { … }
static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel,
DataExtractor &debug_data,
Section *rel_section, bool is_signed) { … }
static void ApplyELF32ABS32RelRelocation(Symtab *symtab, ELFRelocation &rel,
DataExtractor &debug_data,
Section *rel_section) { … }
unsigned ObjectFileELF::ApplyRelocations(
Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
DataExtractor &rel_data, DataExtractor &symtab_data,
DataExtractor &debug_data, Section *rel_section) { … }
unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
user_id_t rel_id,
lldb_private::Symtab *thetab) { … }
void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) { … }
void ObjectFileELF::RelocateSection(lldb_private::Section *section)
{ … }
void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
DWARFCallFrameInfo *eh_frame) { … }
bool ObjectFileELF::IsStripped() { … }
void ObjectFileELF::Dump(Stream *s) { … }
void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) { … }
void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) { … }
void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
unsigned char ei_data) { … }
void ObjectFileELF::DumpELFProgramHeader(Stream *s,
const ELFProgramHeader &ph) { … }
void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) { … }
void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) { … }
void ObjectFileELF::DumpELFProgramHeaders(Stream *s) { … }
void ObjectFileELF::DumpELFSectionHeader(Stream *s,
const ELFSectionHeaderInfo &sh) { … }
void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) { … }
void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
elf_xword sh_flags) { … }
void ObjectFileELF::DumpELFSectionHeaders(Stream *s) { … }
void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) { … }
std::string static getDynamicTagAsString(uint16_t Arch, uint64_t Type) { … }
void ObjectFileELF::DumpELFDynamic(lldb_private::Stream *s) { … }
ArchSpec ObjectFileELF::GetArchitecture() { … }
ObjectFile::Type ObjectFileELF::CalculateType() { … }
ObjectFile::Strata ObjectFileELF::CalculateStrata() { … }
size_t ObjectFileELF::ReadSectionData(Section *section,
lldb::offset_t section_offset, void *dst,
size_t dst_len) { … }
size_t ObjectFileELF::ReadSectionData(Section *section,
DataExtractor §ion_data) { … }
llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() { … }
DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) { … }
bool ObjectFileELF::AnySegmentHasPhysicalAddress() { … }
std::vector<ObjectFile::LoadableData>
ObjectFileELF::GetLoadableData(Target &target) { … }
lldb::WritableDataBufferSP
ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
uint64_t Offset) { … }
std::optional<DataExtractor> ObjectFileELF::GetDynstrData() { … }
std::optional<lldb_private::DataExtractor> ObjectFileELF::GetDynamicData() { … }