diff options
Diffstat (limited to 'source/Plugins/ObjectFile/ELF')
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 47 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.h | 99 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 410 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 36 |
4 files changed, 228 insertions, 364 deletions
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index 3d4735286bf2..aa9871071b0e 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -1,9 +1,8 @@ //===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -19,7 +18,6 @@ using namespace elf; using namespace lldb; using namespace llvm::ELF; -//------------------------------------------------------------------------------ // Static utility functions. // // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor @@ -68,7 +66,6 @@ static bool GetMaxS64(const lldb_private::DataExtractor &data, return true; } -//------------------------------------------------------------------------------ // ELFHeader ELFHeader::ELFHeader() { memset(this, 0, sizeof(ELFHeader)); } @@ -117,7 +114,7 @@ void ELFHeader::ParseHeaderExtension(lldb_private::DataExtractor &data) { bool ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset) { // Read e_ident. This provides byte order and address size info. - if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) + if (data.GetU8(offset, &e_ident, EI_NIDENT) == nullptr) return false; const unsigned byte_size = Is32Bit() ? 4 : 8; @@ -125,11 +122,11 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data, data.SetAddressByteSize(byte_size); // Read e_type and e_machine. - if (data.GetU16(offset, &e_type, 2) == NULL) + if (data.GetU16(offset, &e_type, 2) == nullptr) return false; // Read e_version. - if (data.GetU32(offset, &e_version, 1) == NULL) + if (data.GetU32(offset, &e_version, 1) == nullptr) return false; // Read e_entry, e_phoff and e_shoff. @@ -137,11 +134,11 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data, return false; // Read e_flags. - if (data.GetU32(offset, &e_flags, 1) == NULL) + if (data.GetU32(offset, &e_flags, 1) == nullptr) return false; // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx. - if (data.GetU16(offset, &e_ehsize, 6) == NULL) + if (data.GetU16(offset, &e_ehsize, 6) == nullptr) return false; // Initialize e_phnum, e_shnum, and e_shstrndx with the values read from the @@ -216,7 +213,6 @@ unsigned ELFHeader::GetRelocationJumpSlotType() const { return slot; } -//------------------------------------------------------------------------------ // ELFSectionHeader ELFSectionHeader::ELFSectionHeader() { @@ -228,7 +224,7 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, const unsigned byte_size = data.GetAddressByteSize(); // Read sh_name and sh_type. - if (data.GetU32(offset, &sh_name, 2) == NULL) + if (data.GetU32(offset, &sh_name, 2) == nullptr) return false; // Read sh_flags. @@ -240,7 +236,7 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, return false; // Read sh_link and sh_info. - if (data.GetU32(offset, &sh_link, 2) == NULL) + if (data.GetU32(offset, &sh_link, 2) == nullptr) return false; // Read sh_addralign and sh_entsize. @@ -250,7 +246,6 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, return true; } -//------------------------------------------------------------------------------ // ELFSymbol ELFSymbol::ELFSymbol() { memset(this, 0, sizeof(ELFSymbol)); } @@ -327,7 +322,7 @@ bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, const bool parsing_32 = byte_size == 4; // Read st_name. - if (data.GetU32(offset, &st_name, 1) == NULL) + if (data.GetU32(offset, &st_name, 1) == nullptr) return false; if (parsing_32) { @@ -336,29 +331,28 @@ bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, return false; // Read st_info and st_other. - if (data.GetU8(offset, &st_info, 2) == NULL) + if (data.GetU8(offset, &st_info, 2) == nullptr) return false; // Read st_shndx. - if (data.GetU16(offset, &st_shndx, 1) == NULL) + if (data.GetU16(offset, &st_shndx, 1) == nullptr) return false; } else { // Read st_info and st_other. - if (data.GetU8(offset, &st_info, 2) == NULL) + if (data.GetU8(offset, &st_info, 2) == nullptr) return false; // Read st_shndx. - if (data.GetU16(offset, &st_shndx, 1) == NULL) + if (data.GetU16(offset, &st_shndx, 1) == nullptr) return false; // Read st_value and st_size. - if (data.GetU64(offset, &st_value, 2) == NULL) + if (data.GetU64(offset, &st_value, 2) == nullptr) return false; } return true; } -//------------------------------------------------------------------------------ // ELFProgramHeader ELFProgramHeader::ELFProgramHeader() { @@ -371,7 +365,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, const bool parsing_32 = byte_size == 4; // Read p_type; - if (data.GetU32(offset, &p_type, 1) == NULL) + if (data.GetU32(offset, &p_type, 1) == nullptr) return false; if (parsing_32) { @@ -380,7 +374,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, return false; // Read p_flags. - if (data.GetU32(offset, &p_flags, 1) == NULL) + if (data.GetU32(offset, &p_flags, 1) == nullptr) return false; // Read p_align. @@ -388,7 +382,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, return false; } else { // Read p_flags. - if (data.GetU32(offset, &p_flags, 1) == NULL) + if (data.GetU32(offset, &p_flags, 1) == nullptr) return false; // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. @@ -399,7 +393,6 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, return true; } -//------------------------------------------------------------------------------ // ELFDynamic ELFDynamic::ELFDynamic() { memset(this, 0, sizeof(ELFDynamic)); } @@ -410,7 +403,6 @@ bool ELFDynamic::Parse(const lldb_private::DataExtractor &data, return GetMaxS64(data, offset, &d_tag, byte_size, 2); } -//------------------------------------------------------------------------------ // ELFRel ELFRel::ELFRel() { memset(this, 0, sizeof(ELFRel)); } @@ -423,7 +415,6 @@ bool ELFRel::Parse(const lldb_private::DataExtractor &data, return GetMaxU64(data, offset, &r_offset, byte_size, 2) != false; } -//------------------------------------------------------------------------------ // ELFRela ELFRela::ELFRela() { memset(this, 0, sizeof(ELFRela)); } diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.h b/source/Plugins/ObjectFile/ELF/ELFHeader.h index faaf8be99d68..bb228e269d40 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -1,13 +1,12 @@ //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // -/// @file +/// \file /// Generic structures and typedefs for ELF files. /// /// This file provides definitions for the various entities comprising an ELF @@ -32,8 +31,7 @@ class DataExtractor; namespace elf { -//------------------------------------------------------------------------------ -/// @name ELF type definitions. +/// \name ELF type definitions. /// /// Types used to represent the various components of ELF structures. All /// types are signed or unsigned integral types wide enough to hold values @@ -50,8 +48,7 @@ typedef uint64_t elf_xword; typedef int64_t elf_sxword; //@} -//------------------------------------------------------------------------------ -/// @class ELFHeader +/// \class ELFHeader /// Generic representation of an ELF file header. /// /// This object is used to identify the general attributes on an ELF file and @@ -81,93 +78,83 @@ struct ELFHeader { ELFHeader(); - //-------------------------------------------------------------------------- /// Returns true if this is a 32 bit ELF file header. /// - /// @return + /// \return /// True if this is a 32 bit ELF file header. bool Is32Bit() const { return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32; } - //-------------------------------------------------------------------------- /// Returns true if this is a 64 bit ELF file header. /// - /// @return + /// \return /// True if this is a 64 bit ELF file header. bool Is64Bit() const { return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; } - //-------------------------------------------------------------------------- /// The byte order of this ELF file header. /// - /// @return + /// \return /// The byte order of this ELF file as described by the header. lldb::ByteOrder GetByteOrder() const; - //-------------------------------------------------------------------------- /// The jump slot relocation type of this ELF. unsigned GetRelocationJumpSlotType() const; - //-------------------------------------------------------------------------- /// Check if there should be header extension in section header #0 /// - /// @return + /// \return /// True if parsing the ELFHeader requires reading header extension /// and false otherwise. bool HasHeaderExtension() const; - //-------------------------------------------------------------------------- /// Parse an ELFHeader entry starting at position \p offset and update the /// data extractor with the address size and byte order attributes as /// defined by the header. /// - /// @param[in,out] data + /// \param[in,out] data /// The DataExtractor to read from. Updated with the address size and /// byte order attributes appropriate to this header. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFHeader was successfully read and false /// otherwise. bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); - //-------------------------------------------------------------------------- /// Examines at most EI_NIDENT bytes starting from the given pointer and /// determines if the magic ELF identification exists. /// - /// @return + /// \return /// True if the given sequence of bytes identifies an ELF file. static bool MagicBytesMatch(const uint8_t *magic); - //-------------------------------------------------------------------------- /// Examines at most EI_NIDENT bytes starting from the given address and /// determines the address size of the underlying ELF file. This function /// should only be called on an pointer for which MagicBytesMatch returns /// true. /// - /// @return + /// \return /// The number of bytes forming an address in the ELF file (either 4 or /// 8), else zero if the address size could not be determined. static unsigned AddressSizeInBytes(const uint8_t *magic); private: - //-------------------------------------------------------------------------- /// Parse an ELFHeader header extension entry. This method is called by /// Parse(). /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. void ParseHeaderExtension(lldb_private::DataExtractor &data); }; -//------------------------------------------------------------------------------ -/// @class ELFSectionHeader +/// \class ELFSectionHeader /// Generic representation of an ELF section header. struct ELFSectionHeader { elf_word sh_name; ///< Section name string index. @@ -183,26 +170,24 @@ struct ELFSectionHeader { ELFSectionHeader(); - //-------------------------------------------------------------------------- /// Parse an ELFSectionHeader entry from the given DataExtracter starting at /// position \p offset. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. The address size of the extractor /// determines if a 32 or 64 bit object should be read. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFSectionHeader was successfully read and false /// otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); }; -//------------------------------------------------------------------------------ -/// @class ELFProgramHeader +/// \class ELFProgramHeader /// Generic representation of an ELF program header. struct ELFProgramHeader { elf_word p_type; ///< Type of program segment. @@ -220,22 +205,21 @@ struct ELFProgramHeader { /// position \p offset. The address size of the DataExtractor determines if /// a 32 or 64 bit object is to be parsed. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. The address size of the extractor /// determines if a 32 or 64 bit object should be read. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFProgramHeader was successfully read and false /// otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); }; -//------------------------------------------------------------------------------ -/// @class ELFSymbol +/// \class ELFSymbol /// Represents a symbol within an ELF symbol table. struct ELFSymbol { elf_addr st_value; ///< Absolute or relocatable address. @@ -270,15 +254,15 @@ struct ELFSymbol { /// position \p offset. The address size of the DataExtractor determines if /// a 32 or 64 bit object is to be parsed. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. The address size of the extractor /// determines if a 32 or 64 bit object should be read. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFSymbol was successfully read and false otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); @@ -287,8 +271,7 @@ struct ELFSymbol { const lldb_private::SectionList *section_list); }; -//------------------------------------------------------------------------------ -/// @class ELFDynamic +/// \class ELFDynamic /// Represents an entry in an ELF dynamic table. struct ELFDynamic { elf_sxword d_tag; ///< Type of dynamic table entry. @@ -303,22 +286,21 @@ struct ELFDynamic { /// position \p offset. The address size of the DataExtractor determines if /// a 32 or 64 bit object is to be parsed. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. The address size of the extractor /// determines if a 32 or 64 bit object should be read. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFDynamic entry was successfully read and false /// otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); }; -//------------------------------------------------------------------------------ -/// @class ELFRel +/// \class ELFRel /// Represents a relocation entry with an implicit addend. struct ELFRel { elf_addr r_offset; ///< Address of reference. @@ -330,15 +312,15 @@ struct ELFRel { /// \p offset. The address size of the DataExtractor determines if a 32 or /// 64 bit object is to be parsed. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. The address size of the extractor /// determines if a 32 or 64 bit object should be read. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFRel entry was successfully read and false otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); @@ -359,8 +341,7 @@ struct ELFRel { static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; } }; -//------------------------------------------------------------------------------ -/// @class ELFRela +/// \class ELFRela /// Represents a relocation entry with an explicit addend. struct ELFRela { elf_addr r_offset; ///< Address of reference. @@ -373,15 +354,15 @@ struct ELFRela { /// \p offset. The address size of the DataExtractor determines if a 32 or /// 64 bit object is to be parsed. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. The address size of the extractor /// determines if a 32 or 64 bit object should be read. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFRela entry was successfully read and false otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 9a6563afa0a0..d62afa34bbe8 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1,9 +1,8 @@ //===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -17,7 +16,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RangeMap.h" #include "lldb/Core/Section.h" #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/DWARFCallFrameInfo.h" @@ -27,6 +25,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.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" @@ -56,8 +55,8 @@ namespace { const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; const char *const LLDB_NT_OWNER_GNU = "GNU"; const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; +const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; -const char *const LLDB_NT_OWNER_CSR = "csr"; const char *const LLDB_NT_OWNER_ANDROID = "Android"; const char *const LLDB_NT_OWNER_CORE = "CORE"; const char *const LLDB_NT_OWNER_LINUX = "LINUX"; @@ -71,8 +70,10 @@ const elf_word LLDB_NT_GNU_ABI_SIZE = 16; const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; -const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01; -const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4; +const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; +const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; +const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; +const elf_word LLDB_NT_NETBSD_PROCINFO = 1; // GNU ABI note OS constants const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; @@ -115,7 +116,7 @@ const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; #define NT_METAG_TLS 0x502 //===----------------------------------------------------------------------===// -/// @class ELFRelocation +/// \class ELFRelocation /// Generic wrapper for ELFRel and ELFRela. /// /// This helper class allows us to parse both ELFRel and ELFRela relocation @@ -125,7 +126,7 @@ public: /// Constructs an ELFRelocation entry with a personality as given by @p /// type. /// - /// @param type Either DT_REL or DT_RELA. Any other value is invalid. + /// \param type Either DT_REL or DT_RELA. Any other value is invalid. ELFRelocation(unsigned type); ~ELFRelocation(); @@ -161,7 +162,7 @@ ELFRelocation::ELFRelocation(unsigned type) { reloc = new ELFRela(); else { assert(false && "unexpected relocation type"); - reloc = static_cast<ELFRel *>(NULL); + reloc = static_cast<ELFRel *>(nullptr); } } @@ -242,7 +243,7 @@ static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; } bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { // Read all fields. - if (data.GetU32(offset, &n_namesz, 3) == NULL) + if (data.GetU32(offset, &n_namesz, 3) == nullptr) return false; // The name field is required to be nul-terminated, and n_namesz includes the @@ -261,7 +262,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { } const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); - if (cstr == NULL) { + if (cstr == nullptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); if (log) log->Printf("Failed to parse note name lacking nul terminator"); @@ -272,27 +273,6 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { return true; } -static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) { - const uint32_t dsp_rev = e_flags & 0xFF; - uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE; - switch (dsp_rev) { - // TODO(mg11) Support more variants - case 10: - kal_arch_variant = llvm::Triple::KalimbaSubArch_v3; - break; - case 14: - kal_arch_variant = llvm::Triple::KalimbaSubArch_v4; - break; - case 17: - case 20: - kal_arch_variant = llvm::Triple::KalimbaSubArch_v5; - break; - default: - break; - } - return kal_arch_variant; -} - static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) { const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH; uint32_t endian = header.e_ident[EI_DATA]; @@ -350,40 +330,13 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { if (header.e_machine == llvm::ELF::EM_MIPS) return mipsVariantFromElfFlags(header); - return llvm::ELF::EM_CSR_KALIMBA == header.e_machine - ? kalimbaVariantFromElfFlags(header.e_flags) - : LLDB_INVALID_CPUTYPE; -} - -//! The kalimba toolchain identifies a code section as being -//! one with the SHT_PROGBITS set in the section sh_type and the top -//! bit in the 32-bit address field set. -static lldb::SectionType -kalimbaSectionType(const elf::ELFHeader &header, - const elf::ELFSectionHeader §_hdr) { - if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine) { - return eSectionTypeOther; - } - - if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type) { - return eSectionTypeZeroFill; - } - - if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type) { - const lldb::addr_t KAL_CODE_BIT = 1 << 31; - return KAL_CODE_BIT & sect_hdr.sh_addr ? eSectionTypeCode - : eSectionTypeData; - } - - return eSectionTypeOther; + return LLDB_INVALID_CPUTYPE; } // Arbitrary constant used as UUID prefix for core files. const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C); -//------------------------------------------------------------------ // Static methods. -//------------------------------------------------------------------ void ObjectFileELF::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, @@ -436,14 +389,14 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, unsigned address_size = ELFHeader::AddressSizeInBytes(magic); if (address_size == 4 || address_size == 8) { - std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF( + std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF( module_sp, data_sp, data_offset, file, file_offset, length)); - ArchSpec spec = objfile_ap->GetArchitecture(); - if (spec && objfile_ap->SetModulesArchitecture(spec)) - return objfile_ap.release(); + ArchSpec spec = objfile_up->GetArchitecture(); + if (spec && objfile_up->SetModulesArchitecture(spec)) + return objfile_up.release(); } - return NULL; + return nullptr; } ObjectFile *ObjectFileELF::CreateMemoryInstance( @@ -454,15 +407,15 @@ ObjectFile *ObjectFileELF::CreateMemoryInstance( if (ELFHeader::MagicBytesMatch(magic)) { unsigned address_size = ELFHeader::AddressSizeInBytes(magic); if (address_size == 4 || address_size == 8) { - std::unique_ptr<ObjectFileELF> objfile_ap( + std::unique_ptr<ObjectFileELF> objfile_up( new ObjectFileELF(module_sp, data_sp, process_sp, header_addr)); - ArchSpec spec = objfile_ap->GetArchitecture(); - if (spec && objfile_ap->SetModulesArchitecture(spec)) - return objfile_ap.release(); + ArchSpec spec = objfile_up->GetArchitecture(); + if (spec && objfile_up->SetModulesArchitecture(spec)) + return objfile_up.release(); } } } - return NULL; + return nullptr; } bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, @@ -756,17 +709,13 @@ size_t ObjectFileELF::GetModuleSpecifications( return specs.GetSize() - initial_count; } -//------------------------------------------------------------------ // PluginInterface protocol -//------------------------------------------------------------------ lldb_private::ConstString ObjectFileELF::GetPluginName() { return GetPluginNameStatic(); } uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; } -//------------------------------------------------------------------ // ObjectFile protocol -//------------------------------------------------------------------ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, lldb::offset_t data_offset, @@ -775,7 +724,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), m_program_headers(), m_section_headers(), m_dynamic_symbols(), - m_filespec_ap(), m_entry_point_address(), m_arch_spec() { + m_filespec_up(), m_entry_point_address(), m_arch_spec() { if (file) m_file = *file; ::memset(&m_header, 0, sizeof(m_header)); @@ -788,7 +737,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), m_program_headers(), m_section_headers(), m_dynamic_symbols(), - m_filespec_ap(), m_entry_point_address(), m_arch_spec() { + m_filespec_up(), m_entry_point_address(), m_arch_spec() { ::memset(&m_header, 0, sizeof(m_header)); } @@ -897,49 +846,43 @@ bool ObjectFileELF::ParseHeader() { return m_header.Parse(m_data, &offset); } -bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) { +UUID ObjectFileELF::GetUUID() { // Need to parse the section list to get the UUIDs, so make sure that's been // done. if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile) - return false; + return UUID(); - using u32le = llvm::support::ulittle32_t; - if (m_uuid.IsValid()) { - // We have the full build id uuid. - *uuid = m_uuid; - return true; - } else if (GetType() == ObjectFile::eTypeCoreFile) { - uint32_t core_notes_crc = 0; + if (!m_uuid) { + using u32le = llvm::support::ulittle32_t; + if (GetType() == ObjectFile::eTypeCoreFile) { + uint32_t core_notes_crc = 0; - if (!ParseProgramHeaders()) - return false; + if (!ParseProgramHeaders()) + return UUID(); - core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); + core_notes_crc = + CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); - if (core_notes_crc) { - // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it look - // different form .gnu_debuglink crc - followed by 4 bytes of note - // segments crc. - u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; - m_uuid = UUID::fromData(data, sizeof(data)); - } - } else { - if (!m_gnu_debuglink_crc) - m_gnu_debuglink_crc = - calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize()); - if (m_gnu_debuglink_crc) { - // Use 4 bytes of crc from the .gnu_debuglink section. - u32le data(m_gnu_debuglink_crc); - m_uuid = UUID::fromData(&data, sizeof(data)); + if (core_notes_crc) { + // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it + // look different form .gnu_debuglink crc - followed by 4 bytes of note + // segments crc. + u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; + m_uuid = UUID::fromData(data, sizeof(data)); + } + } else { + if (!m_gnu_debuglink_crc) + m_gnu_debuglink_crc = calc_gnu_debuglink_crc32(m_data.GetDataStart(), + m_data.GetByteSize()); + if (m_gnu_debuglink_crc) { + // Use 4 bytes of crc from the .gnu_debuglink section. + u32le data(m_gnu_debuglink_crc); + m_uuid = UUID::fromData(&data, sizeof(data)); + } } } - if (m_uuid.IsValid()) { - *uuid = m_uuid; - return true; - } - - return false; + return m_uuid; } lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() { @@ -957,7 +900,7 @@ uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) { uint32_t num_specs = 0; for (unsigned i = 0; i < num_modules; ++i) { - if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i))) + if (files.AppendIfUnique(m_filespec_up->GetFileSpecAtIndex(i))) num_specs++; } @@ -1060,14 +1003,12 @@ Address ObjectFileELF::GetBaseAddress() { return LLDB_INVALID_ADDRESS; } -//---------------------------------------------------------------------- // ParseDependentModules -//---------------------------------------------------------------------- size_t ObjectFileELF::ParseDependentModules() { - if (m_filespec_ap.get()) - return m_filespec_ap->GetSize(); + if (m_filespec_up) + return m_filespec_up->GetSize(); - m_filespec_ap.reset(new FileSpecList()); + m_filespec_up.reset(new FileSpecList()); if (!ParseSectionHeaders()) return 0; @@ -1114,16 +1055,14 @@ size_t ObjectFileELF::ParseDependentModules() { const char *lib_name = dynstr_data.PeekCStr(str_index); FileSpec file_spec(lib_name); FileSystem::Instance().Resolve(file_spec); - m_filespec_ap->Append(file_spec); + m_filespec_up->Append(file_spec); } } - return m_filespec_ap->GetSize(); + return m_filespec_up->GetSize(); } -//---------------------------------------------------------------------- // GetProgramHeaderInfo -//---------------------------------------------------------------------- size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, DataExtractor &object_data, const ELFHeader &header) { @@ -1158,9 +1097,7 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, return program_headers.size(); } -//---------------------------------------------------------------------- // ParseProgramHeaders -//---------------------------------------------------------------------- bool ObjectFileELF::ParseProgramHeaders() { return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0; } @@ -1301,46 +1238,45 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); } - // Process NetBSD ELF notes. + // Process NetBSD ELF executables and shared libraries else if ((note.n_name == LLDB_NT_OWNER_NETBSD) && - (note.n_type == LLDB_NT_NETBSD_ABI_TAG) && - (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) { - // Pull out the min version info. + (note.n_type == LLDB_NT_NETBSD_IDENT_TAG) && + (note.n_descsz == LLDB_NT_NETBSD_IDENT_DESCSZ) && + (note.n_namesz == LLDB_NT_NETBSD_IDENT_NAMESZ)) { + // Pull out the version info. uint32_t version_info; if (data.GetU32(&offset, &version_info, 1) == nullptr) { error.SetErrorString("failed to read NetBSD ABI note payload"); return error; } - + // Convert the version info into a major/minor/patch number. + // #define __NetBSD_Version__ MMmmrrpp00 + // + // M = major version + // m = minor version; a minor number of 99 indicates current. + // r = 0 (since NetBSD 3.0 not used) + // p = patchlevel + const uint32_t version_major = version_info / 100000000; + const uint32_t version_minor = (version_info % 100000000) / 1000000; + const uint32_t version_patch = (version_info % 10000) / 100; + // Set the elf OS version to NetBSD. Also clear the vendor. + arch_spec.GetTriple().setOSName( + llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor, + version_patch).str()); + arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); + } + // Process NetBSD ELF core(5) notes + else if ((note.n_name == LLDB_NT_OWNER_NETBSDCORE) && + (note.n_type == LLDB_NT_NETBSD_PROCINFO)) { // Set the elf OS version to NetBSD. Also clear the vendor. arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD); arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); - - if (log) - log->Printf( - "ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, - __FUNCTION__, version_info); } // Process OpenBSD ELF notes. else if (note.n_name == LLDB_NT_OWNER_OPENBSD) { // Set the elf OS version to OpenBSD. Also clear the vendor. arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD); arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); - } - // Process CSR kalimba notes - else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) && - (note.n_name == LLDB_NT_OWNER_CSR)) { - arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); - arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR); - - // TODO At some point the description string could be processed. - // It could provide a steer towards the kalimba variant which this ELF - // targets. - if (note.n_descsz) { - const char *cstr = - data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4)); - (void)cstr; - } } else if (note.n_name == LLDB_NT_OWNER_ANDROID) { arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); arch_spec.GetTriple().setEnvironment( @@ -1354,8 +1290,6 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, // the contents look like this in a 64 bit ELF core file: count = // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index // start end file_ofs path ===== - // ------------------ ------------------ ------------------ - // ------------------------------------- [ 0] 0x0000000000400000 // 0x0000000000401000 0x0000000000000000 /tmp/a.out [ 1] // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [ // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out @@ -1479,9 +1413,7 @@ void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, } } -//---------------------------------------------------------------------- // GetSectionHeaderInfo -//---------------------------------------------------------------------- size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, DataExtractor &object_data, const elf::ELFHeader &header, @@ -1714,9 +1646,7 @@ ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { return symbol_name.substr(0, pos); } -//---------------------------------------------------------------------- // ParseSectionHeaders -//---------------------------------------------------------------------- size_t ObjectFileELF::ParseSectionHeaders() { return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, @@ -1726,12 +1656,12 @@ size_t ObjectFileELF::ParseSectionHeaders() { const ObjectFileELF::ELFSectionHeaderInfo * ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { if (!ParseSectionHeaders()) - return NULL; + return nullptr; if (id < m_section_headers.size()) return &m_section_headers[id]; - return NULL; + return nullptr; } lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { @@ -1744,37 +1674,40 @@ lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { } static SectionType GetSectionTypeFromName(llvm::StringRef Name) { + if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) { + return llvm::StringSwitch<SectionType>(Name) + .Case("abbrev", eSectionTypeDWARFDebugAbbrev) + .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) + .Case("addr", eSectionTypeDWARFDebugAddr) + .Case("aranges", eSectionTypeDWARFDebugAranges) + .Case("cu_index", eSectionTypeDWARFDebugCuIndex) + .Case("frame", eSectionTypeDWARFDebugFrame) + .Case("info", eSectionTypeDWARFDebugInfo) + .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo) + .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine) + .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr) + .Cases("loc", "loc.dwo", eSectionTypeDWARFDebugLoc) + .Cases("loclists", "loclists.dwo", eSectionTypeDWARFDebugLocLists) + .Case("macinfo", eSectionTypeDWARFDebugMacInfo) + .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro) + .Case("names", eSectionTypeDWARFDebugNames) + .Case("pubnames", eSectionTypeDWARFDebugPubNames) + .Case("pubtypes", eSectionTypeDWARFDebugPubTypes) + .Case("ranges", eSectionTypeDWARFDebugRanges) + .Case("rnglists", eSectionTypeDWARFDebugRngLists) + .Case("str", eSectionTypeDWARFDebugStr) + .Case("str.dwo", eSectionTypeDWARFDebugStrDwo) + .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets) + .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) + .Case("types", eSectionTypeDWARFDebugTypes) + .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo) + .Default(eSectionTypeOther); + } return llvm::StringSwitch<SectionType>(Name) .Case(".ARM.exidx", eSectionTypeARMexidx) .Case(".ARM.extab", eSectionTypeARMextab) .Cases(".bss", ".tbss", eSectionTypeZeroFill) .Cases(".data", ".tdata", eSectionTypeData) - .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) - .Case(".debug_abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) - .Case(".debug_addr", eSectionTypeDWARFDebugAddr) - .Case(".debug_aranges", eSectionTypeDWARFDebugAranges) - .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex) - .Case(".debug_frame", eSectionTypeDWARFDebugFrame) - .Case(".debug_info", eSectionTypeDWARFDebugInfo) - .Case(".debug_info.dwo", eSectionTypeDWARFDebugInfoDwo) - .Cases(".debug_line", ".debug_line.dwo", eSectionTypeDWARFDebugLine) - .Cases(".debug_line_str", ".debug_line_str.dwo", - eSectionTypeDWARFDebugLineStr) - .Cases(".debug_loc", ".debug_loc.dwo", eSectionTypeDWARFDebugLoc) - .Cases(".debug_loclists", ".debug_loclists.dwo", - eSectionTypeDWARFDebugLocLists) - .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo) - .Cases(".debug_macro", ".debug_macro.dwo", eSectionTypeDWARFDebugMacro) - .Case(".debug_names", eSectionTypeDWARFDebugNames) - .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames) - .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes) - .Case(".debug_ranges", eSectionTypeDWARFDebugRanges) - .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists) - .Case(".debug_str", eSectionTypeDWARFDebugStr) - .Case(".debug_str.dwo", eSectionTypeDWARFDebugStrDwo) - .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets) - .Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) - .Case(".debug_types", eSectionTypeDWARFDebugTypes) .Case(".eh_frame", eSectionTypeEHFrame) .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) .Case(".gosymtab", eSectionTypeGoSymtab) @@ -1798,14 +1731,7 @@ SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const { case SHT_DYNAMIC: return eSectionTypeELFDynamicLinkInfo; } - SectionType Type = GetSectionTypeFromName(H.section_name.GetStringRef()); - if (Type == eSectionTypeOther) { - // the kalimba toolchain assumes that ELF section names are free-form. - // It does support linkscripts which (can) give rise to various - // arbitrarily named sections being "Code" or "Data". - Type = kalimbaSectionType(m_header, H); - } - return Type; + return GetSectionTypeFromName(H.section_name.GetStringRef()); } static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) { @@ -1938,11 +1864,11 @@ public: } void ObjectFileELF::CreateSections(SectionList &unified_section_list) { - if (m_sections_ap) + if (m_sections_up) return; - m_sections_ap = llvm::make_unique<SectionList>(); - VMAddressProvider address_provider(CalculateType()); + m_sections_up = llvm::make_unique<SectionList>(); + VMAddressProvider address_provider(GetType()); size_t LoadID = 0; for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { @@ -1961,7 +1887,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0); Segment->SetPermissions(GetPermissions(PHdr)); - m_sections_ap->AddSection(Segment); + m_sections_up->AddSection(Segment); address_provider.AddSegment(*InfoOr, std::move(Segment)); } @@ -2007,7 +1933,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { section_sp->SetPermissions(GetPermissions(header)); section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS); - (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_ap) + (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up) .AddSection(section_sp); address_provider.AddSection(std::move(*InfoOr), std::move(section_sp)); } @@ -2015,7 +1941,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the // unified section list. if (GetType() != eTypeDebugInfo) - unified_section_list = *m_sections_ap; + unified_section_list = *m_sections_up; } // Find the arm/aarch64 mapping symbol character in the given symbol name. @@ -2073,8 +1999,8 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, // custom extension and file name makes it highly unlikely that this will // collide with anything else. ConstString file_extension = m_file.GetFileNameExtension(); - bool skip_oatdata_oatexec = file_extension == ConstString(".oat") || - file_extension == ConstString(".odex"); + bool skip_oatdata_oatexec = + file_extension == ".oat" || file_extension == ".odex"; ArchSpec arch = GetArchitecture(); ModuleSP module_sp(GetModule()); @@ -2166,7 +2092,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) { if (symbol_section_sp) { - const ConstString §_name = symbol_section_sp->GetName(); + ConstString sect_name = symbol_section_sp->GetName(); if (sect_name == text_section_name || sect_name == init_section_name || sect_name == fini_section_name || sect_name == ctors_section_name || sect_name == dtors_section_name) { @@ -2262,11 +2188,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, * class * accordingly. */ - const llvm::Triple::ArchType llvm_arch = arch.GetMachine(); - if (llvm_arch == llvm::Triple::mips || - llvm_arch == llvm::Triple::mipsel || - llvm_arch == llvm::Triple::mips64 || - llvm_arch == llvm::Triple::mips64el) { + if (arch.IsMIPS()) { if (IS_MICROMIPS(symbol.st_other)) m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA; else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) { @@ -2310,7 +2232,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, if (symbol_section_sp && module_section_list && module_section_list != section_list) { - const ConstString §_name = symbol_section_sp->GetName(); + ConstString sect_name = symbol_section_sp->GetName(); auto section_it = section_name_to_section.find(sect_name.GetCString()); if (section_it == section_name_to_section.end()) section_it = @@ -2391,7 +2313,7 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, } // Get section list for this object file. - SectionList *section_list = m_sections_ap.get(); + SectionList *section_list = m_sections_up.get(); if (!section_list) return 0; @@ -2457,7 +2379,7 @@ size_t ObjectFileELF::ParseDynamicSymbols() { const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) { if (!ParseDynamicSymbols()) - return NULL; + return nullptr; DynamicSymbolCollIter I = m_dynamic_symbols.begin(); DynamicSymbolCollIter E = m_dynamic_symbols.end(); @@ -2468,7 +2390,7 @@ const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) { return symbol; } - return NULL; + return nullptr; } unsigned ObjectFileELF::PLTRelocationType() { @@ -2619,7 +2541,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, if (!sym_hdr) return 0; - SectionList *section_list = m_sections_ap.get(); + SectionList *section_list = m_sections_up.get(); if (!section_list) return 0; @@ -2685,7 +2607,7 @@ unsigned ObjectFileELF::ApplyRelocations( if (!rel.Parse(rel_data, &offset)) break; - Symbol *symbol = NULL; + Symbol *symbol = nullptr; if (hdr->Is32Bit()) { switch (reloc_type(rel)) { @@ -2804,7 +2726,7 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, Symtab *ObjectFileELF::GetSymtab() { ModuleSP module_sp(GetModule()); if (!module_sp) - return NULL; + return nullptr; // We always want to use the main object file so we (hopefully) only have one // cached copy of our symtab, dynamic sections, etc. @@ -2812,10 +2734,10 @@ Symtab *ObjectFileELF::GetSymtab() { if (module_obj_file && module_obj_file != this) return module_obj_file->GetSymtab(); - if (m_symtab_ap.get() == NULL) { + if (m_symtab_up == nullptr) { SectionList *section_list = module_sp->GetSectionList(); if (!section_list) - return NULL; + return nullptr; uint64_t symbol_id = 0; std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); @@ -2836,8 +2758,8 @@ Symtab *ObjectFileELF::GetSymtab() { .get(); } if (symtab) { - m_symtab_ap.reset(new Symtab(symtab->GetObjectFile())); - symbol_id += ParseSymbolTable(m_symtab_ap.get(), symbol_id, symtab); + m_symtab_up.reset(new Symtab(symtab->GetObjectFile())); + symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab); } // DT_JMPREL @@ -2861,30 +2783,30 @@ Symtab *ObjectFileELF::GetSymtab() { GetSectionHeaderByIndex(reloc_id); assert(reloc_header); - if (m_symtab_ap == nullptr) - m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile())); + if (m_symtab_up == nullptr) + m_symtab_up.reset(new Symtab(reloc_section->GetObjectFile())); - ParseTrampolineSymbols(m_symtab_ap.get(), symbol_id, reloc_header, + ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header, reloc_id); } } - DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo(); - if (eh_frame) { - if (m_symtab_ap == nullptr) - m_symtab_ap.reset(new Symtab(this)); - ParseUnwindSymbols(m_symtab_ap.get(), eh_frame); + if (DWARFCallFrameInfo *eh_frame = + GetModule()->GetUnwindTable().GetEHFrameInfo()) { + if (m_symtab_up == nullptr) + m_symtab_up.reset(new Symtab(this)); + ParseUnwindSymbols(m_symtab_up.get(), eh_frame); } // If we still don't have any symtab then create an empty instance to avoid // do the section lookup next time. - if (m_symtab_ap == nullptr) - m_symtab_ap.reset(new Symtab(this)); + if (m_symtab_up == nullptr) + m_symtab_up.reset(new Symtab(this)); - m_symtab_ap->CalculateSymbolSizes(); + m_symtab_up->CalculateSymbolSizes(); } - return m_symtab_ap.get(); + return m_symtab_up.get(); } void ObjectFileELF::RelocateSection(lldb_private::Section *section) @@ -2991,7 +2913,6 @@ bool ObjectFileELF::IsStripped() { // // Dump the specifics of the runtime file container (such as any headers // segments, sections, etc). -//---------------------------------------------------------------------- void ObjectFileELF::Dump(Stream *s) { ModuleSP module_sp(GetModule()); if (!module_sp) { @@ -3016,20 +2937,18 @@ void ObjectFileELF::Dump(Stream *s) { s->EOL(); SectionList *section_list = GetSectionList(); if (section_list) - section_list->Dump(s, NULL, true, UINT32_MAX); + section_list->Dump(s, nullptr, true, UINT32_MAX); Symtab *symtab = GetSymtab(); if (symtab) - symtab->Dump(s, NULL, eSortOrderNone); + symtab->Dump(s, nullptr, eSortOrderNone); s->EOL(); DumpDependentModules(s); s->EOL(); } -//---------------------------------------------------------------------- // DumpELFHeader // // Dump the ELF header to the specified output stream -//---------------------------------------------------------------------- void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) { s->PutCString("ELF Header\n"); s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); @@ -3062,11 +2981,9 @@ void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) { s->Printf("e_shstrndx = 0x%8.8x\n", header.e_shstrndx); } -//---------------------------------------------------------------------- // 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) { switch (e_type) { case ET_NONE: @@ -3089,11 +3006,9 @@ 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) { switch (ei_data) { @@ -3111,11 +3026,9 @@ void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, } } -//---------------------------------------------------------------------- // DumpELFProgramHeader // // Dump a single ELF program header to the specified output stream -//---------------------------------------------------------------------- void ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph) { DumpELFProgramHeader_p_type(s, ph.p_type); @@ -3128,12 +3041,10 @@ void ObjectFileELF::DumpELFProgramHeader(Stream *s, s->Printf(") %8.8" PRIx64, ph.p_align); } -//---------------------------------------------------------------------- // 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) { const int kStrWidth = 15; switch (p_type) { @@ -3152,11 +3063,9 @@ 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) { *s << ((p_flags & PF_X) ? "PF_X" : " ") << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') @@ -3165,11 +3074,9 @@ void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) { << ((p_flags & PF_R) ? "PF_R" : " "); } -//---------------------------------------------------------------------- // DumpELFProgramHeaders // // Dump all of the ELF program header to the specified output stream -//---------------------------------------------------------------------- void ObjectFileELF::DumpELFProgramHeaders(Stream *s) { if (!ParseProgramHeaders()) return; @@ -3187,11 +3094,9 @@ 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) { s->Printf("%8.8x ", sh.sh_name); @@ -3204,12 +3109,10 @@ void ObjectFileELF::DumpELFSectionHeader(Stream *s, s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize); } -//---------------------------------------------------------------------- // 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) { const int kStrWidth = 12; switch (sh_type) { @@ -3235,11 +3138,9 @@ 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) { *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") @@ -3249,11 +3150,9 @@ void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); } -//---------------------------------------------------------------------- // DumpELFSectionHeaders // // Dump all of the ELF section header to the specified output stream -//---------------------------------------------------------------------- void ObjectFileELF::DumpELFSectionHeaders(Stream *s) { if (!ParseSectionHeaders()) return; @@ -3283,7 +3182,7 @@ void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) { if (num_modules > 0) { s->PutCString("Dependent Modules:\n"); for (unsigned i = 0; i < num_modules; ++i) { - const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); + const FileSpec &spec = m_filespec_up->GetFileSpecAtIndex(i); s->Printf(" %s\n", spec.GetFilename().GetCString()); } } @@ -3299,7 +3198,7 @@ ArchSpec ObjectFileELF::GetArchitecture() { } if (CalculateType() == eTypeCoreFile && - m_arch_spec.TripleOSIsUnspecifiedUnknown()) { + !m_arch_spec.TripleOSWasSpecified()) { // Core files don't have section headers yet they have PT_NOTE program // headers that might shed more light on the architecture for (const elf::ELFProgramHeader &H : ProgramHeaders()) { @@ -3405,7 +3304,8 @@ size_t ObjectFileELF::ReadSectionData(Section *section, return section->GetObjectFile()->ReadSectionData(section, section_data); size_t result = ObjectFile::ReadSectionData(section, section_data); - if (result == 0 || !section->Test(SHF_COMPRESSED)) + if (result == 0 || !llvm::object::Decompressor::isCompressedELFSection( + section->Get(), section->GetName().GetStringRef())) return result; auto Decompressor = llvm::object::Decompressor::create( diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 08fd5bdc60a9..b63a5d14d4f5 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -1,9 +1,8 @@ //===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -34,14 +33,14 @@ struct ELFNote { /// Parse an ELFNote entry from the given DataExtractor starting at position /// \p offset. /// - /// @param[in] data + /// \param[in] data /// The DataExtractor to read from. /// - /// @param[in,out] offset + /// \param[in,out] offset /// Pointer to an offset in the data. On return the offset will be /// advanced by the number of bytes read. /// - /// @return + /// \return /// True if the ELFRel entry was successfully read and false otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); @@ -50,8 +49,7 @@ struct ELFNote { } }; -//------------------------------------------------------------------------------ -/// @class ObjectFileELF +/// \class ObjectFileELF /// Generic ELF object file reader. /// /// This class provides a generic ELF (32/64 bit) reader plugin implementing @@ -60,9 +58,7 @@ class ObjectFileELF : public lldb_private::ObjectFile { public: ~ObjectFileELF() override; - //------------------------------------------------------------------ // Static Functions - //------------------------------------------------------------------ static void Initialize(); static void Terminate(); @@ -90,16 +86,12 @@ public: static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset, lldb::addr_t length); - //------------------------------------------------------------------ // PluginInterface protocol - //------------------------------------------------------------------ lldb_private::ConstString GetPluginName() override; uint32_t GetPluginVersion() override; - //------------------------------------------------------------------ // ObjectFile Protocol. - //------------------------------------------------------------------ bool ParseHeader() override; bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, @@ -123,7 +115,7 @@ public: lldb_private::ArchSpec GetArchitecture() override; - bool GetUUID(lldb_private::UUID *uuid) override; + lldb_private::UUID GetUUID() override; lldb_private::FileSpecList GetDebugSymbolFilePaths() override; @@ -211,7 +203,7 @@ private: /// List of file specifications corresponding to the modules (shared /// libraries) on which this object file depends. - mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap; + mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up; /// Cached value of the entry point for this module. lldb_private::Address m_entry_point_address; @@ -265,7 +257,7 @@ private: lldb_private::ArchSpec &arch_spec); /// Scans the dynamic section and locates all dependent modules (shared - /// libraries) populating m_filespec_ap. This method will compute the + /// libraries) populating m_filespec_up. This method will compute the /// dependent module list only once. Returns the number of dependent /// modules parsed. size_t ParseDependentModules(); @@ -275,7 +267,7 @@ private: /// number of dynamic symbols parsed. size_t ParseDynamicSymbols(); - /// Populates m_symtab_ap will all non-dynamic linker symbols. This method + /// Populates m_symtab_up will all non-dynamic linker symbols. This method /// will parse the symbols only once. Returns the number of symbols parsed. unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id, @@ -331,7 +323,7 @@ private: /// Returns the section header with the given id or NULL. const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id); - /// @name ELF header dump routines + /// \name ELF header dump routines //@{ static void DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader &header); @@ -343,7 +335,7 @@ private: elf::elf_half e_type); //@} - /// @name ELF program header dump routines + /// \name ELF program header dump routines //@{ void DumpELFProgramHeaders(lldb_private::Stream *s); @@ -357,7 +349,7 @@ private: elf::elf_word p_flags); //@} - /// @name ELF section header dump routines + /// \name ELF section header dump routines //@{ void DumpELFSectionHeaders(lldb_private::Stream *s); |