Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
39644 views
//===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H9#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H1011#include <cstdint>1213#include <optional>14#include <vector>1516#include "lldb/Symbol/ObjectFile.h"17#include "lldb/Utility/ArchSpec.h"18#include "lldb/Utility/FileSpec.h"19#include "lldb/Utility/UUID.h"20#include "lldb/lldb-private.h"2122#include "ELFHeader.h"2324struct ELFNote {25elf::elf_word n_namesz = 0;26elf::elf_word n_descsz = 0;27elf::elf_word n_type = 0;2829std::string n_name;3031ELFNote() = default;3233/// Parse an ELFNote entry from the given DataExtractor starting at position34/// \p offset.35///36/// \param[in] data37/// The DataExtractor to read from.38///39/// \param[in,out] offset40/// Pointer to an offset in the data. On return the offset will be41/// advanced by the number of bytes read.42///43/// \return44/// True if the ELFRel entry was successfully read and false otherwise.45bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);4647size_t GetByteSize() const {48return 12 + llvm::alignTo(n_namesz, 4) + llvm::alignTo(n_descsz, 4);49}50};5152/// \class ObjectFileELF53/// Generic ELF object file reader.54///55/// This class provides a generic ELF (32/64 bit) reader plugin implementing56/// the ObjectFile protocol.57class ObjectFileELF : public lldb_private::ObjectFile {58public:59// Static Functions60static void Initialize();6162static void Terminate();6364static llvm::StringRef GetPluginNameStatic() { return "elf"; }6566static llvm::StringRef GetPluginDescriptionStatic() {67return "ELF object file reader.";68}6970static lldb_private::ObjectFile *71CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,72lldb::offset_t data_offset, const lldb_private::FileSpec *file,73lldb::offset_t file_offset, lldb::offset_t length);7475static lldb_private::ObjectFile *CreateMemoryInstance(76const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,77const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);7879static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,80lldb::DataBufferSP &data_sp,81lldb::offset_t data_offset,82lldb::offset_t file_offset,83lldb::offset_t length,84lldb_private::ModuleSpecList &specs);8586static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,87lldb::addr_t length);8889// PluginInterface protocol90llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }9192// LLVM RTTI support93static char ID;94bool isA(const void *ClassID) const override {95return ClassID == &ID || ObjectFile::isA(ClassID);96}97static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }9899// ObjectFile Protocol.100bool ParseHeader() override;101102bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,103bool value_is_offset) override;104105lldb::ByteOrder GetByteOrder() const override;106107bool IsExecutable() const override;108109uint32_t GetAddressByteSize() const override;110111lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;112113void ParseSymtab(lldb_private::Symtab &symtab) override;114115bool IsStripped() override;116117void CreateSections(lldb_private::SectionList &unified_section_list) override;118119void Dump(lldb_private::Stream *s) override;120121lldb_private::ArchSpec GetArchitecture() override;122123lldb_private::UUID GetUUID() override;124125/// Return the contents of the .gnu_debuglink section, if the object file126/// contains it.127std::optional<lldb_private::FileSpec> GetDebugLink();128129uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;130131lldb_private::Address132GetImageInfoAddress(lldb_private::Target *target) override;133134lldb_private::Address GetEntryPointAddress() override;135136lldb_private::Address GetBaseAddress() override;137138ObjectFile::Type CalculateType() override;139140ObjectFile::Strata CalculateStrata() override;141142size_t ReadSectionData(lldb_private::Section *section,143lldb::offset_t section_offset, void *dst,144size_t dst_len) override;145146size_t ReadSectionData(lldb_private::Section *section,147lldb_private::DataExtractor §ion_data) override;148149llvm::ArrayRef<elf::ELFProgramHeader> ProgramHeaders();150lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H);151152llvm::StringRef153StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;154155void RelocateSection(lldb_private::Section *section) override;156157protected:158159std::vector<LoadableData>160GetLoadableData(lldb_private::Target &target) override;161162static lldb::WritableDataBufferSP163MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,164uint64_t Offset);165166private:167ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,168lldb::offset_t data_offset, const lldb_private::FileSpec *file,169lldb::offset_t offset, lldb::offset_t length);170171ObjectFileELF(const lldb::ModuleSP &module_sp,172lldb::DataBufferSP header_data_sp,173const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);174175typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl;176177struct ELFSectionHeaderInfo : public elf::ELFSectionHeader {178lldb_private::ConstString section_name;179};180181typedef std::vector<ELFSectionHeaderInfo> SectionHeaderColl;182typedef SectionHeaderColl::iterator SectionHeaderCollIter;183typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;184185typedef std::vector<elf::ELFDynamic> DynamicSymbolColl;186typedef DynamicSymbolColl::iterator DynamicSymbolCollIter;187typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;188189/// An ordered map of file address to address class. Used on architectures190/// like Arm where there is an alternative ISA mode like Thumb. The container191/// is ordered so that it can be binary searched.192typedef std::map<lldb::addr_t, lldb_private::AddressClass>193FileAddressToAddressClassMap;194195/// Version of this reader common to all plugins based on this class.196static const uint32_t m_plugin_version = 1;197static const uint32_t g_core_uuid_magic;198199/// ELF file header.200elf::ELFHeader m_header;201202/// ELF build ID.203lldb_private::UUID m_uuid;204205/// ELF .gnu_debuglink file and crc data if available.206std::string m_gnu_debuglink_file;207uint32_t m_gnu_debuglink_crc = 0;208209/// Collection of program headers.210ProgramHeaderColl m_program_headers;211212/// Collection of section headers.213SectionHeaderColl m_section_headers;214215/// Collection of symbols from the dynamic table.216DynamicSymbolColl m_dynamic_symbols;217218/// Object file parsed from .gnu_debugdata section (\sa219/// GetGnuDebugDataObjectFile())220std::shared_ptr<ObjectFileELF> m_gnu_debug_data_object_file;221222/// List of file specifications corresponding to the modules (shared223/// libraries) on which this object file depends.224mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up;225226/// Cached value of the entry point for this module.227lldb_private::Address m_entry_point_address;228229/// The architecture detected from parsing elf file contents.230lldb_private::ArchSpec m_arch_spec;231232/// The address class for each symbol in the elf file233FileAddressToAddressClassMap m_address_class_map;234235/// Returns the index of the given section header.236size_t SectionIndex(const SectionHeaderCollIter &I);237238/// Returns the index of the given section header.239size_t SectionIndex(const SectionHeaderCollConstIter &I) const;240241// Parses the ELF program headers.242static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers,243lldb_private::DataExtractor &object_data,244const elf::ELFHeader &header);245246// Finds PT_NOTE segments and calculates their crc sum.247static uint32_t248CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl &program_headers,249lldb_private::DataExtractor &data);250251/// Parses all section headers present in this object file and populates252/// m_program_headers. This method will compute the header list only once.253/// Returns true iff the headers have been successfully parsed.254bool ParseProgramHeaders();255256/// Parses all section headers present in this object file and populates257/// m_section_headers. This method will compute the header list only once.258/// Returns the number of headers parsed.259size_t ParseSectionHeaders();260261lldb::SectionType GetSectionType(const ELFSectionHeaderInfo &H) const;262263static void ParseARMAttributes(lldb_private::DataExtractor &data,264uint64_t length,265lldb_private::ArchSpec &arch_spec);266267/// Parses the elf section headers and returns the uuid, debug link name,268/// crc, archspec.269static size_t GetSectionHeaderInfo(SectionHeaderColl §ion_headers,270lldb_private::DataExtractor &object_data,271const elf::ELFHeader &header,272lldb_private::UUID &uuid,273std::string &gnu_debuglink_file,274uint32_t &gnu_debuglink_crc,275lldb_private::ArchSpec &arch_spec);276277/// Scans the dynamic section and locates all dependent modules (shared278/// libraries) populating m_filespec_up. This method will compute the279/// dependent module list only once. Returns the number of dependent280/// modules parsed.281size_t ParseDependentModules();282283/// Parses the dynamic symbol table and populates m_dynamic_symbols. The284/// vector retains the order as found in the object file. Returns the285/// number of dynamic symbols parsed.286size_t ParseDynamicSymbols();287288/// Populates the symbol table with all non-dynamic linker symbols. This289/// method will parse the symbols only once. Returns the number of symbols290/// parsed and a map of address types (used by targets like Arm that have291/// an alternative ISA mode like Thumb).292std::pair<unsigned, FileAddressToAddressClassMap>293ParseSymbolTable(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,294lldb_private::Section *symtab);295296/// Helper routine for ParseSymbolTable().297std::pair<unsigned, FileAddressToAddressClassMap>298ParseSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,299lldb_private::SectionList *section_list,300const size_t num_symbols,301const lldb_private::DataExtractor &symtab_data,302const lldb_private::DataExtractor &strtab_data);303304/// Scans the relocation entries and adds a set of artificial symbols to the305/// given symbol table for each PLT slot. Returns the number of symbols306/// added.307unsigned ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,308lldb::user_id_t start_id,309const ELFSectionHeaderInfo *rela_hdr,310lldb::user_id_t section_id);311312void ParseUnwindSymbols(lldb_private::Symtab *symbol_table,313lldb_private::DWARFCallFrameInfo *eh_frame);314315/// Relocates debug sections316unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr,317lldb::user_id_t rel_id,318lldb_private::Symtab *thetab);319320unsigned ApplyRelocations(lldb_private::Symtab *symtab,321const elf::ELFHeader *hdr,322const elf::ELFSectionHeader *rel_hdr,323const elf::ELFSectionHeader *symtab_hdr,324const elf::ELFSectionHeader *debug_hdr,325lldb_private::DataExtractor &rel_data,326lldb_private::DataExtractor &symtab_data,327lldb_private::DataExtractor &debug_data,328lldb_private::Section *rel_section);329330/// Loads the section name string table into m_shstr_data. Returns the331/// number of bytes constituting the table.332size_t GetSectionHeaderStringTable();333334/// Utility method for looking up a section given its name. Returns the335/// index of the corresponding section or zero if no section with the given336/// name can be found (note that section indices are always 1 based, and so337/// section index 0 is never valid).338lldb::user_id_t GetSectionIndexByName(const char *name);339340/// Returns the section header with the given id or NULL.341const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id);342343/// \name ELF header dump routines344//@{345static void DumpELFHeader(lldb_private::Stream *s,346const elf::ELFHeader &header);347348static void DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,349unsigned char ei_data);350351static void DumpELFHeader_e_type(lldb_private::Stream *s,352elf::elf_half e_type);353//@}354355/// \name ELF program header dump routines356//@{357void DumpELFProgramHeaders(lldb_private::Stream *s);358359static void DumpELFProgramHeader(lldb_private::Stream *s,360const elf::ELFProgramHeader &ph);361362static void DumpELFProgramHeader_p_type(lldb_private::Stream *s,363elf::elf_word p_type);364365static void DumpELFProgramHeader_p_flags(lldb_private::Stream *s,366elf::elf_word p_flags);367//@}368369/// \name ELF section header dump routines370//@{371void DumpELFSectionHeaders(lldb_private::Stream *s);372373static void DumpELFSectionHeader(lldb_private::Stream *s,374const ELFSectionHeaderInfo &sh);375376static void DumpELFSectionHeader_sh_type(lldb_private::Stream *s,377elf::elf_word sh_type);378379static void DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,380elf::elf_xword sh_flags);381//@}382383/// ELF dependent module dump routine.384void DumpDependentModules(lldb_private::Stream *s);385386const elf::ELFDynamic *FindDynamicSymbol(unsigned tag);387388unsigned PLTRelocationType();389390static lldb_private::Status391RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,392lldb_private::ArchSpec &arch_spec,393lldb_private::UUID &uuid);394395bool AnySegmentHasPhysicalAddress();396397/// Takes the .gnu_debugdata and returns the decompressed object file that is398/// stored within that section.399///400/// \returns either the decompressed object file stored within the401/// .gnu_debugdata section or \c nullptr if an error occured or if there's no402/// section with that name.403std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile();404};405406#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H407408409