llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

//===-- ObjectFileELF.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#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()

// ELF note owner definitions
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 =;

// ELF note type definitions
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 =;

// GNU ABI note OS constants
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
/// Generic wrapper for ELFRel and ELFRela.
///
/// This helper class allows us to parse both ELFRel and ELFRela relocation
/// entries in a generic manner.
class ELFRelocation {};
} // end anonymous namespace

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;

// Arbitrary constant used as UUID prefix for core files.
const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);

// Static methods.
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) {}

//
// WARNING : This function is being deprecated
// It's functionality has moved to ArchSpec::SetArchitecture This function is
// only being kept to validate the move.
//
// TODO : Remove this function
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) {}

// ObjectFile protocol

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() {}

// GetProgramHeaderInfo
size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
                                           DataExtractor &object_data,
                                           const ELFHeader &header) {}

// ParseProgramHeaders
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) {}

// GetSectionHeaderInfo
size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_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 {}

// ParseSectionHeaders
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 {};

// (Unlinked) ELF object files usually have 0 for every section address, meaning
// we need to compute synthetic addresses in order for "file addresses" from
// different sections to not overlap. This class handles that logic.
class VMAddressProvider {};
}

// We have to do this because ELF doesn't have section IDs, and also
// doesn't require section names to be unique.  (We use the section index
// for section IDs, but that isn't guaranteed to be the same in separate
// debug images.)
static SectionSP FindMatchingSection(const SectionList &section_list,
                                     SectionSP section) {}

void ObjectFileELF::CreateSections(SectionList &unified_section_list) {}

std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {}

// Find the arm/aarch64 mapping symbol character in the given symbol name.
// Mapping symbols have the form of "$<char>[.<any>]*". Additionally we
// recognize cases when the mapping symbol prefixed by an arbitrary string
// because if a symbol prefix added to each symbol in the object file with
// objcopy then the mapping symbols are also prefixed.
static char FindArmAarch64MappingSymbol(const char *symbol_name) {}

#define STO_MIPS_ISA
#define STO_MICROMIPS
#define IS_MICROMIPS(ST_OTHER)

// private
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() {}

// Returns the size of the normal plt entries and the offset of the first
// normal plt entry. The 0th entry in the plt table is usually a resolution
// entry which have different size in some architectures then the rest of the
// plt entries.
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() {}

//===----------------------------------------------------------------------===//
// Dump
//
// Dump the specifics of the runtime file container (such as any headers
// segments, sections, etc).
void ObjectFileELF::Dump(Stream *s) {}

// DumpELFHeader
//
// Dump the ELF header to the specified output stream
void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {}

// DumpELFHeader_e_type
//
// Dump an token value for the ELF header member e_type
void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {}

// DumpELFHeader_e_ident_EI_DATA
//
// Dump an token value for the ELF header member e_ident[EI_DATA]
void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
                                                  unsigned char ei_data) {}

// DumpELFProgramHeader
//
// Dump a single ELF program header to the specified output stream
void ObjectFileELF::DumpELFProgramHeader(Stream *s,
                                         const ELFProgramHeader &ph) {}

// DumpELFProgramHeader_p_type
//
// Dump an token value for the ELF program header member p_type which describes
// the type of the program header
void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {}

// DumpELFProgramHeader_p_flags
//
// Dump an token value for the ELF program header member p_flags
void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {}

// DumpELFProgramHeaders
//
// Dump all of the ELF program header to the specified output stream
void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {}

// DumpELFSectionHeader
//
// Dump a single ELF section header to the specified output stream
void ObjectFileELF::DumpELFSectionHeader(Stream *s,
                                         const ELFSectionHeaderInfo &sh) {}

// DumpELFSectionHeader_sh_type
//
// Dump an token value for the ELF section header member sh_type which
// describes the type of the section
void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {}

// DumpELFSectionHeader_sh_flags
//
// Dump an token value for the ELF section header member sh_flags
void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
                                                  elf_xword sh_flags) {}

// DumpELFSectionHeaders
//
// Dump all of the ELF section header to the specified output stream
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 &section_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() {}