forked from OSchip/llvm-project
elf: add support for ELF relocation entries
llvm-svn: 128548
This commit is contained in:
parent
84ffe7033c
commit
43fe645b62
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -101,6 +101,11 @@ struct ELFHeader
|
|||
lldb::ByteOrder
|
||||
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
|
||||
|
@ -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_
|
||||
|
|
Loading…
Reference in New Issue