diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 73 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h | 122 |
2 files changed, 194 insertions, 1 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index 3fd795be4c1..bfff9f3336e 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -153,6 +153,33 @@ ELFHeader::AddressSizeInBytes(const uint8_t *magic) return address_size; } +unsigned +ELFHeader::GetRelocationJumpSlotType() const +{ + unsigned slot = 0; + + switch (e_machine) + { + default: + assert(false && "architecture not supported"); + break; + case EM_386: + case EM_486: + slot = R_386_JUMP_SLOT; + break; + case EM_X86_64: + slot = R_X86_64_JUMP_SLOT; + break; + case EM_ARM: + slot = R_ARM_JUMP_SLOT; + break; + case EM_MBLAZE: + slot = R_MICROBLAZE_JUMP_SLOT; + } + + return slot; +} + //------------------------------------------------------------------------------ // ELFSectionHeader @@ -293,10 +320,54 @@ ELFDynamic::ELFDynamic() } bool -ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) +ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) { const unsigned byte_size = data.GetAddressByteSize(); return GetMaxS64(data, offset, &d_tag, byte_size, 2); } +//------------------------------------------------------------------------------ +// ELFRel + +ELFRel::ELFRel() +{ + memset(this, 0, sizeof(ELFRel)); +} + +bool +ELFRel::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) +{ + const unsigned byte_size = data.GetAddressByteSize(); + + // Read r_offset and r_info. + if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) + return false; + + return true; +} + +//------------------------------------------------------------------------------ +// ELFRela + +ELFRela::ELFRela() +{ + memset(this, 0, sizeof(ELFRela)); +} + +bool +ELFRela::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) +{ + const unsigned byte_size = data.GetAddressByteSize(); + + // Read r_offset and r_info. + if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) + return false; + + // Read r_addend; + if (GetMaxS64(data, offset, &r_addend, byte_size) == false) + return false; + + return true; +} + diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h index a4c0417fee4..45798574ccc 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -102,6 +102,11 @@ struct ELFHeader GetByteOrder() const; //-------------------------------------------------------------------------- + /// The jump slot relocation type of this ELF. + unsigned + GetRelocationJumpSlotType() const; + + //-------------------------------------------------------------------------- /// Parse an ELFSectionHeader entry starting at position \p offset and /// update the data extractor with the address size and byte order /// attributes as defined by the header. @@ -290,6 +295,123 @@ struct ELFDynamic Parse(const lldb_private::DataExtractor &data, uint32_t *offset); }; +//------------------------------------------------------------------------------ +/// @class ELFRel +/// @brief Represents a relocation entry with an implicit addend. +struct ELFRel +{ + elf_addr r_offset; ///< Address of reference. + elf_xword r_info; ///< symbol index and type of relocation. + + ELFRel(); + + /// Parse an ELFRel entry from the given DataExtractor starting at position + /// \p offset. The address size of the DataExtractor determines if a 32 or + /// 64 bit object is to be parsed. + /// + /// @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 + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFRel entry was successfully read and false otherwise. + bool + Parse(const lldb_private::DataExtractor &data, uint32_t *offset); + + /// Returns the type when the given entry represents a 32-bit relocation. + static unsigned + RelocType32(const ELFRel &rel) + { + return rel.r_info & 0x0ff; + } + + /// Returns the type when the given entry represents a 64-bit relocation. + static unsigned + RelocType64(const ELFRel &rel) + { + return rel.r_info & 0xffffffff; + } + + /// Returns the symbol index when the given entry represents a 32-bit + /// reloction. + static unsigned + RelocSymbol32(const ELFRel &rel) + { + return rel.r_info >> 8; + } + + /// Returns the symbol index when the given entry represents a 64-bit + /// reloction. + static unsigned + RelocSymbol64(const ELFRel &rel) + { + return rel.r_info >> 32; + } +}; + +//------------------------------------------------------------------------------ +/// @class ELFRela +/// @brief Represents a relocation entry with an explicit addend. +struct ELFRela +{ + elf_addr r_offset; ///< Address of reference. + elf_xword r_info; ///< Symbol index and type of relocation. + elf_sxword r_addend; ///< Constant part of expression. + + ELFRela(); + + /// Parse an ELFRela entry from the given DataExtractor starting at position + /// \p offset. The address size of the DataExtractor determines if a 32 or + /// 64 bit object is to be parsed. + /// + /// @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 + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFRela entry was successfully read and false otherwise. + bool + Parse(const lldb_private::DataExtractor &data, uint32_t *offset); + + /// Returns the type when the given entry represents a 32-bit relocation. + static unsigned + RelocType32(const ELFRela &rela) + { + return rela.r_info & 0x0ff; + } + + /// Returns the type when the given entry represents a 64-bit relocation. + static unsigned + RelocType64(const ELFRela &rela) + { + return rela.r_info & 0xffffffff; + } + + /// Returns the symbol index when the given entry represents a 32-bit + /// reloction. + static unsigned + RelocSymbol32(const ELFRela &rela) + { + return rela.r_info >> 8; + } + + /// Returns the symbol index when the given entry represents a 64-bit + /// reloction. + static unsigned + RelocSymbol64(const ELFRela &rela) + { + return rela.r_info >> 32; + } +}; + } // End namespace elf. #endif // #ifndef liblldb_ELFHeader_h_ |