1061da546Spatrick //===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H 11061da546Spatrick 12be691f3bSpatrick #include <cstdint> 13061da546Spatrick 14*f6aab3d8Srobert #include <optional> 15061da546Spatrick #include <vector> 16061da546Spatrick 17061da546Spatrick #include "lldb/Symbol/ObjectFile.h" 18061da546Spatrick #include "lldb/Utility/ArchSpec.h" 19061da546Spatrick #include "lldb/Utility/FileSpec.h" 20061da546Spatrick #include "lldb/Utility/UUID.h" 21061da546Spatrick #include "lldb/lldb-private.h" 22061da546Spatrick 23061da546Spatrick #include "ELFHeader.h" 24061da546Spatrick 25061da546Spatrick struct ELFNote { 26be691f3bSpatrick elf::elf_word n_namesz = 0; 27be691f3bSpatrick elf::elf_word n_descsz = 0; 28be691f3bSpatrick elf::elf_word n_type = 0; 29061da546Spatrick 30061da546Spatrick std::string n_name; 31061da546Spatrick 32be691f3bSpatrick ELFNote() = default; 33061da546Spatrick 34061da546Spatrick /// Parse an ELFNote entry from the given DataExtractor starting at position 35061da546Spatrick /// \p offset. 36061da546Spatrick /// 37061da546Spatrick /// \param[in] data 38061da546Spatrick /// The DataExtractor to read from. 39061da546Spatrick /// 40061da546Spatrick /// \param[in,out] offset 41061da546Spatrick /// Pointer to an offset in the data. On return the offset will be 42061da546Spatrick /// advanced by the number of bytes read. 43061da546Spatrick /// 44061da546Spatrick /// \return 45061da546Spatrick /// True if the ELFRel entry was successfully read and false otherwise. 46061da546Spatrick bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 47061da546Spatrick GetByteSizeELFNote48061da546Spatrick size_t GetByteSize() const { 49061da546Spatrick return 12 + llvm::alignTo(n_namesz, 4) + llvm::alignTo(n_descsz, 4); 50061da546Spatrick } 51061da546Spatrick }; 52061da546Spatrick 53061da546Spatrick /// \class ObjectFileELF 54061da546Spatrick /// Generic ELF object file reader. 55061da546Spatrick /// 56061da546Spatrick /// This class provides a generic ELF (32/64 bit) reader plugin implementing 57061da546Spatrick /// the ObjectFile protocol. 58061da546Spatrick class ObjectFileELF : public lldb_private::ObjectFile { 59061da546Spatrick public: 60061da546Spatrick // Static Functions 61061da546Spatrick static void Initialize(); 62061da546Spatrick 63061da546Spatrick static void Terminate(); 64061da546Spatrick GetPluginNameStatic()65*f6aab3d8Srobert static llvm::StringRef GetPluginNameStatic() { return "elf"; } 66061da546Spatrick GetPluginDescriptionStatic()67*f6aab3d8Srobert static llvm::StringRef GetPluginDescriptionStatic() { 68*f6aab3d8Srobert return "ELF object file reader."; 69*f6aab3d8Srobert } 70061da546Spatrick 71061da546Spatrick static lldb_private::ObjectFile * 72*f6aab3d8Srobert CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, 73061da546Spatrick lldb::offset_t data_offset, const lldb_private::FileSpec *file, 74061da546Spatrick lldb::offset_t file_offset, lldb::offset_t length); 75061da546Spatrick 76061da546Spatrick static lldb_private::ObjectFile *CreateMemoryInstance( 77*f6aab3d8Srobert const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, 78061da546Spatrick const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 79061da546Spatrick 80061da546Spatrick static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 81061da546Spatrick lldb::DataBufferSP &data_sp, 82061da546Spatrick lldb::offset_t data_offset, 83061da546Spatrick lldb::offset_t file_offset, 84061da546Spatrick lldb::offset_t length, 85061da546Spatrick lldb_private::ModuleSpecList &specs); 86061da546Spatrick 87061da546Spatrick static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset, 88061da546Spatrick lldb::addr_t length); 89061da546Spatrick 90061da546Spatrick // PluginInterface protocol GetPluginName()91*f6aab3d8Srobert llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 92061da546Spatrick 93061da546Spatrick // LLVM RTTI support 94061da546Spatrick static char ID; isA(const void * ClassID)95061da546Spatrick bool isA(const void *ClassID) const override { 96061da546Spatrick return ClassID == &ID || ObjectFile::isA(ClassID); 97061da546Spatrick } classof(const ObjectFile * obj)98061da546Spatrick static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } 99061da546Spatrick 100061da546Spatrick // ObjectFile Protocol. 101061da546Spatrick bool ParseHeader() override; 102061da546Spatrick 103061da546Spatrick bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, 104061da546Spatrick bool value_is_offset) override; 105061da546Spatrick 106061da546Spatrick lldb::ByteOrder GetByteOrder() const override; 107061da546Spatrick 108061da546Spatrick bool IsExecutable() const override; 109061da546Spatrick 110061da546Spatrick uint32_t GetAddressByteSize() const override; 111061da546Spatrick 112061da546Spatrick lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override; 113061da546Spatrick 114*f6aab3d8Srobert void ParseSymtab(lldb_private::Symtab &symtab) override; 115061da546Spatrick 116061da546Spatrick bool IsStripped() override; 117061da546Spatrick 118061da546Spatrick void CreateSections(lldb_private::SectionList &unified_section_list) override; 119061da546Spatrick 120061da546Spatrick void Dump(lldb_private::Stream *s) override; 121061da546Spatrick 122061da546Spatrick lldb_private::ArchSpec GetArchitecture() override; 123061da546Spatrick 124061da546Spatrick lldb_private::UUID GetUUID() override; 125061da546Spatrick 126061da546Spatrick /// Return the contents of the .gnu_debuglink section, if the object file 127061da546Spatrick /// contains it. 128*f6aab3d8Srobert std::optional<lldb_private::FileSpec> GetDebugLink(); 129061da546Spatrick 130061da546Spatrick uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; 131061da546Spatrick 132061da546Spatrick lldb_private::Address 133061da546Spatrick GetImageInfoAddress(lldb_private::Target *target) override; 134061da546Spatrick 135061da546Spatrick lldb_private::Address GetEntryPointAddress() override; 136061da546Spatrick 137061da546Spatrick lldb_private::Address GetBaseAddress() override; 138061da546Spatrick 139061da546Spatrick ObjectFile::Type CalculateType() override; 140061da546Spatrick 141061da546Spatrick ObjectFile::Strata CalculateStrata() override; 142061da546Spatrick 143061da546Spatrick size_t ReadSectionData(lldb_private::Section *section, 144061da546Spatrick lldb::offset_t section_offset, void *dst, 145061da546Spatrick size_t dst_len) override; 146061da546Spatrick 147061da546Spatrick size_t ReadSectionData(lldb_private::Section *section, 148061da546Spatrick lldb_private::DataExtractor §ion_data) override; 149061da546Spatrick 150061da546Spatrick llvm::ArrayRef<elf::ELFProgramHeader> ProgramHeaders(); 151061da546Spatrick lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H); 152061da546Spatrick 153061da546Spatrick llvm::StringRef 154061da546Spatrick StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override; 155061da546Spatrick 156061da546Spatrick void RelocateSection(lldb_private::Section *section) override; 157061da546Spatrick 158061da546Spatrick protected: 159061da546Spatrick 160061da546Spatrick std::vector<LoadableData> 161061da546Spatrick GetLoadableData(lldb_private::Target &target) override; 162061da546Spatrick 163*f6aab3d8Srobert static lldb::WritableDataBufferSP 164*f6aab3d8Srobert MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size, 165*f6aab3d8Srobert uint64_t Offset); 166*f6aab3d8Srobert 167061da546Spatrick private: 168*f6aab3d8Srobert ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, 169061da546Spatrick lldb::offset_t data_offset, const lldb_private::FileSpec *file, 170061da546Spatrick lldb::offset_t offset, lldb::offset_t length); 171061da546Spatrick 172061da546Spatrick ObjectFileELF(const lldb::ModuleSP &module_sp, 173*f6aab3d8Srobert lldb::DataBufferSP header_data_sp, 174061da546Spatrick const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 175061da546Spatrick 176061da546Spatrick typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl; 177061da546Spatrick 178061da546Spatrick struct ELFSectionHeaderInfo : public elf::ELFSectionHeader { 179061da546Spatrick lldb_private::ConstString section_name; 180061da546Spatrick }; 181061da546Spatrick 182061da546Spatrick typedef std::vector<ELFSectionHeaderInfo> SectionHeaderColl; 183061da546Spatrick typedef SectionHeaderColl::iterator SectionHeaderCollIter; 184061da546Spatrick typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; 185061da546Spatrick 186061da546Spatrick typedef std::vector<elf::ELFDynamic> DynamicSymbolColl; 187061da546Spatrick typedef DynamicSymbolColl::iterator DynamicSymbolCollIter; 188061da546Spatrick typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter; 189061da546Spatrick 190061da546Spatrick typedef std::map<lldb::addr_t, lldb_private::AddressClass> 191061da546Spatrick FileAddressToAddressClassMap; 192061da546Spatrick 193061da546Spatrick /// Version of this reader common to all plugins based on this class. 194061da546Spatrick static const uint32_t m_plugin_version = 1; 195061da546Spatrick static const uint32_t g_core_uuid_magic; 196061da546Spatrick 197061da546Spatrick /// ELF file header. 198061da546Spatrick elf::ELFHeader m_header; 199061da546Spatrick 200061da546Spatrick /// ELF build ID. 201061da546Spatrick lldb_private::UUID m_uuid; 202061da546Spatrick 203061da546Spatrick /// ELF .gnu_debuglink file and crc data if available. 204061da546Spatrick std::string m_gnu_debuglink_file; 205061da546Spatrick uint32_t m_gnu_debuglink_crc = 0; 206061da546Spatrick 207061da546Spatrick /// Collection of program headers. 208061da546Spatrick ProgramHeaderColl m_program_headers; 209061da546Spatrick 210061da546Spatrick /// Collection of section headers. 211061da546Spatrick SectionHeaderColl m_section_headers; 212061da546Spatrick 213061da546Spatrick /// Collection of symbols from the dynamic table. 214061da546Spatrick DynamicSymbolColl m_dynamic_symbols; 215061da546Spatrick 216061da546Spatrick /// Object file parsed from .gnu_debugdata section (\sa 217061da546Spatrick /// GetGnuDebugDataObjectFile()) 218061da546Spatrick std::shared_ptr<ObjectFileELF> m_gnu_debug_data_object_file; 219061da546Spatrick 220061da546Spatrick /// List of file specifications corresponding to the modules (shared 221061da546Spatrick /// libraries) on which this object file depends. 222061da546Spatrick mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up; 223061da546Spatrick 224061da546Spatrick /// Cached value of the entry point for this module. 225061da546Spatrick lldb_private::Address m_entry_point_address; 226061da546Spatrick 227061da546Spatrick /// The architecture detected from parsing elf file contents. 228061da546Spatrick lldb_private::ArchSpec m_arch_spec; 229061da546Spatrick 230061da546Spatrick /// The address class for each symbol in the elf file 231061da546Spatrick FileAddressToAddressClassMap m_address_class_map; 232061da546Spatrick 233061da546Spatrick /// Returns the index of the given section header. 234061da546Spatrick size_t SectionIndex(const SectionHeaderCollIter &I); 235061da546Spatrick 236061da546Spatrick /// Returns the index of the given section header. 237061da546Spatrick size_t SectionIndex(const SectionHeaderCollConstIter &I) const; 238061da546Spatrick 239061da546Spatrick // Parses the ELF program headers. 240061da546Spatrick static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers, 241061da546Spatrick lldb_private::DataExtractor &object_data, 242061da546Spatrick const elf::ELFHeader &header); 243061da546Spatrick 244061da546Spatrick // Finds PT_NOTE segments and calculates their crc sum. 245061da546Spatrick static uint32_t 246061da546Spatrick CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl &program_headers, 247061da546Spatrick lldb_private::DataExtractor &data); 248061da546Spatrick 249061da546Spatrick /// Parses all section headers present in this object file and populates 250061da546Spatrick /// m_program_headers. This method will compute the header list only once. 251061da546Spatrick /// Returns true iff the headers have been successfully parsed. 252061da546Spatrick bool ParseProgramHeaders(); 253061da546Spatrick 254061da546Spatrick /// Parses all section headers present in this object file and populates 255061da546Spatrick /// m_section_headers. This method will compute the header list only once. 256061da546Spatrick /// Returns the number of headers parsed. 257061da546Spatrick size_t ParseSectionHeaders(); 258061da546Spatrick 259061da546Spatrick lldb::SectionType GetSectionType(const ELFSectionHeaderInfo &H) const; 260061da546Spatrick 261061da546Spatrick static void ParseARMAttributes(lldb_private::DataExtractor &data, 262061da546Spatrick uint64_t length, 263061da546Spatrick lldb_private::ArchSpec &arch_spec); 264061da546Spatrick 265061da546Spatrick /// Parses the elf section headers and returns the uuid, debug link name, 266061da546Spatrick /// crc, archspec. 267061da546Spatrick static size_t GetSectionHeaderInfo(SectionHeaderColl §ion_headers, 268061da546Spatrick lldb_private::DataExtractor &object_data, 269061da546Spatrick const elf::ELFHeader &header, 270061da546Spatrick lldb_private::UUID &uuid, 271061da546Spatrick std::string &gnu_debuglink_file, 272061da546Spatrick uint32_t &gnu_debuglink_crc, 273061da546Spatrick lldb_private::ArchSpec &arch_spec); 274061da546Spatrick 275061da546Spatrick /// Scans the dynamic section and locates all dependent modules (shared 276061da546Spatrick /// libraries) populating m_filespec_up. This method will compute the 277061da546Spatrick /// dependent module list only once. Returns the number of dependent 278061da546Spatrick /// modules parsed. 279061da546Spatrick size_t ParseDependentModules(); 280061da546Spatrick 281061da546Spatrick /// Parses the dynamic symbol table and populates m_dynamic_symbols. The 282061da546Spatrick /// vector retains the order as found in the object file. Returns the 283061da546Spatrick /// number of dynamic symbols parsed. 284061da546Spatrick size_t ParseDynamicSymbols(); 285061da546Spatrick 286*f6aab3d8Srobert /// Populates the symbol table with all non-dynamic linker symbols. This 287*f6aab3d8Srobert /// method will parse the symbols only once. Returns the number of symbols 288*f6aab3d8Srobert /// parsed. 289061da546Spatrick unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table, 290061da546Spatrick lldb::user_id_t start_id, 291061da546Spatrick lldb_private::Section *symtab); 292061da546Spatrick 293061da546Spatrick /// Helper routine for ParseSymbolTable(). 294061da546Spatrick unsigned ParseSymbols(lldb_private::Symtab *symbol_table, 295061da546Spatrick lldb::user_id_t start_id, 296061da546Spatrick lldb_private::SectionList *section_list, 297061da546Spatrick const size_t num_symbols, 298061da546Spatrick const lldb_private::DataExtractor &symtab_data, 299061da546Spatrick const lldb_private::DataExtractor &strtab_data); 300061da546Spatrick 301061da546Spatrick /// Scans the relocation entries and adds a set of artificial symbols to the 302061da546Spatrick /// given symbol table for each PLT slot. Returns the number of symbols 303061da546Spatrick /// added. 304061da546Spatrick unsigned ParseTrampolineSymbols(lldb_private::Symtab *symbol_table, 305061da546Spatrick lldb::user_id_t start_id, 306061da546Spatrick const ELFSectionHeaderInfo *rela_hdr, 307061da546Spatrick lldb::user_id_t section_id); 308061da546Spatrick 309061da546Spatrick void ParseUnwindSymbols(lldb_private::Symtab *symbol_table, 310061da546Spatrick lldb_private::DWARFCallFrameInfo *eh_frame); 311061da546Spatrick 312061da546Spatrick /// Relocates debug sections 313061da546Spatrick unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, 314061da546Spatrick lldb::user_id_t rel_id, 315061da546Spatrick lldb_private::Symtab *thetab); 316061da546Spatrick 317061da546Spatrick unsigned ApplyRelocations(lldb_private::Symtab *symtab, 318061da546Spatrick const elf::ELFHeader *hdr, 319061da546Spatrick const elf::ELFSectionHeader *rel_hdr, 320061da546Spatrick const elf::ELFSectionHeader *symtab_hdr, 321061da546Spatrick const elf::ELFSectionHeader *debug_hdr, 322061da546Spatrick lldb_private::DataExtractor &rel_data, 323061da546Spatrick lldb_private::DataExtractor &symtab_data, 324061da546Spatrick lldb_private::DataExtractor &debug_data, 325061da546Spatrick lldb_private::Section *rel_section); 326061da546Spatrick 327061da546Spatrick /// Loads the section name string table into m_shstr_data. Returns the 328061da546Spatrick /// number of bytes constituting the table. 329061da546Spatrick size_t GetSectionHeaderStringTable(); 330061da546Spatrick 331061da546Spatrick /// Utility method for looking up a section given its name. Returns the 332061da546Spatrick /// index of the corresponding section or zero if no section with the given 333061da546Spatrick /// name can be found (note that section indices are always 1 based, and so 334061da546Spatrick /// section index 0 is never valid). 335061da546Spatrick lldb::user_id_t GetSectionIndexByName(const char *name); 336061da546Spatrick 337061da546Spatrick /// Returns the section header with the given id or NULL. 338061da546Spatrick const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id); 339061da546Spatrick 340061da546Spatrick /// \name ELF header dump routines 341061da546Spatrick //@{ 342061da546Spatrick static void DumpELFHeader(lldb_private::Stream *s, 343061da546Spatrick const elf::ELFHeader &header); 344061da546Spatrick 345061da546Spatrick static void DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s, 346061da546Spatrick unsigned char ei_data); 347061da546Spatrick 348061da546Spatrick static void DumpELFHeader_e_type(lldb_private::Stream *s, 349061da546Spatrick elf::elf_half e_type); 350061da546Spatrick //@} 351061da546Spatrick 352061da546Spatrick /// \name ELF program header dump routines 353061da546Spatrick //@{ 354061da546Spatrick void DumpELFProgramHeaders(lldb_private::Stream *s); 355061da546Spatrick 356061da546Spatrick static void DumpELFProgramHeader(lldb_private::Stream *s, 357061da546Spatrick const elf::ELFProgramHeader &ph); 358061da546Spatrick 359061da546Spatrick static void DumpELFProgramHeader_p_type(lldb_private::Stream *s, 360061da546Spatrick elf::elf_word p_type); 361061da546Spatrick 362061da546Spatrick static void DumpELFProgramHeader_p_flags(lldb_private::Stream *s, 363061da546Spatrick elf::elf_word p_flags); 364061da546Spatrick //@} 365061da546Spatrick 366061da546Spatrick /// \name ELF section header dump routines 367061da546Spatrick //@{ 368061da546Spatrick void DumpELFSectionHeaders(lldb_private::Stream *s); 369061da546Spatrick 370061da546Spatrick static void DumpELFSectionHeader(lldb_private::Stream *s, 371061da546Spatrick const ELFSectionHeaderInfo &sh); 372061da546Spatrick 373061da546Spatrick static void DumpELFSectionHeader_sh_type(lldb_private::Stream *s, 374061da546Spatrick elf::elf_word sh_type); 375061da546Spatrick 376061da546Spatrick static void DumpELFSectionHeader_sh_flags(lldb_private::Stream *s, 377061da546Spatrick elf::elf_xword sh_flags); 378061da546Spatrick //@} 379061da546Spatrick 380061da546Spatrick /// ELF dependent module dump routine. 381061da546Spatrick void DumpDependentModules(lldb_private::Stream *s); 382061da546Spatrick 383061da546Spatrick const elf::ELFDynamic *FindDynamicSymbol(unsigned tag); 384061da546Spatrick 385061da546Spatrick unsigned PLTRelocationType(); 386061da546Spatrick 387061da546Spatrick static lldb_private::Status 388061da546Spatrick RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, 389061da546Spatrick lldb_private::ArchSpec &arch_spec, 390061da546Spatrick lldb_private::UUID &uuid); 391061da546Spatrick 392061da546Spatrick bool AnySegmentHasPhysicalAddress(); 393061da546Spatrick 394061da546Spatrick /// Takes the .gnu_debugdata and returns the decompressed object file that is 395061da546Spatrick /// stored within that section. 396061da546Spatrick /// 397061da546Spatrick /// \returns either the decompressed object file stored within the 398061da546Spatrick /// .gnu_debugdata section or \c nullptr if an error occured or if there's no 399061da546Spatrick /// section with that name. 400061da546Spatrick std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile(); 401061da546Spatrick }; 402061da546Spatrick 403dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H 404