Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
39644 views
//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// \file9/// Generic structures and typedefs for ELF files.10///11/// This file provides definitions for the various entities comprising an ELF12/// file. The structures are generic in the sense that they do not correspond13/// to the exact binary layout of an ELF, but can be used to hold the14/// information present in both 32 and 64 bit variants of the format. Each15/// entity provides a \c Parse method which is capable of transparently16/// reading both 32 and 64 bit instances of the object.17//===----------------------------------------------------------------------===//1819#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H20#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H2122#include "llvm/BinaryFormat/ELF.h"2324#include "lldb/lldb-enumerations.h"25#include "lldb/lldb-types.h"2627namespace lldb_private {28class DataExtractor;29} // End namespace lldb_private.3031namespace elf {3233/// \name ELF type definitions.34///35/// Types used to represent the various components of ELF structures. All36/// types are signed or unsigned integral types wide enough to hold values37/// from both38/// 32 and 64 bit ELF variants.39//@{40typedef uint64_t elf_addr;41typedef uint64_t elf_off;42typedef uint16_t elf_half;43typedef uint32_t elf_word;44typedef int32_t elf_sword;45typedef uint64_t elf_size;46typedef uint64_t elf_xword;47typedef int64_t elf_sxword;48//@}4950/// \class ELFHeader51/// Generic representation of an ELF file header.52///53/// This object is used to identify the general attributes on an ELF file and54/// to locate additional sections within the file.55struct ELFHeader {56unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.57elf_addr e_entry; ///< Virtual address program entry point.58elf_off e_phoff; ///< File offset of program header table.59elf_off e_shoff; ///< File offset of section header table.60elf_word e_flags; ///< Processor specific flags.61elf_word e_version; ///< Version of object file (always 1).62elf_half e_type; ///< Object file type.63elf_half e_machine; ///< Target architecture.64elf_half e_ehsize; ///< Byte size of the ELF header.65elf_half e_phentsize; ///< Size of a program header table entry.66elf_half e_phnum_hdr; ///< Number of program header entries.67elf_half e_shentsize; ///< Size of a section header table entry.68elf_half e_shnum_hdr; ///< Number of section header entries.69elf_half e_shstrndx_hdr; ///< String table section index.7071// In some cases these numbers do not fit in 16 bits and they are72// stored outside of the header in section #0. Here are the actual73// values.74elf_word e_phnum; ///< Number of program header entries.75elf_word e_shnum; ///< Number of section header entries.76elf_word e_shstrndx; ///< String table section index.7778ELFHeader();7980/// Returns true if this is a 32 bit ELF file header.81///82/// \return83/// True if this is a 32 bit ELF file header.84bool Is32Bit() const {85return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;86}8788/// Returns true if this is a 64 bit ELF file header.89///90/// \return91/// True if this is a 64 bit ELF file header.92bool Is64Bit() const {93return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;94}9596/// The byte order of this ELF file header.97///98/// \return99/// The byte order of this ELF file as described by the header.100lldb::ByteOrder GetByteOrder() const;101102/// The jump slot relocation type of this ELF.103unsigned GetRelocationJumpSlotType() const;104105/// Check if there should be header extension in section header #0106///107/// \return108/// True if parsing the ELFHeader requires reading header extension109/// and false otherwise.110bool HasHeaderExtension() const;111112/// Parse an ELFHeader entry starting at position \p offset and update the113/// data extractor with the address size and byte order attributes as114/// defined by the header.115///116/// \param[in,out] data117/// The DataExtractor to read from. Updated with the address size and118/// byte order attributes appropriate to this header.119///120/// \param[in,out] offset121/// Pointer to an offset in the data. On return the offset will be122/// advanced by the number of bytes read.123///124/// \return125/// True if the ELFHeader was successfully read and false126/// otherwise.127bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);128129/// Examines at most EI_NIDENT bytes starting from the given pointer and130/// determines if the magic ELF identification exists.131///132/// \return133/// True if the given sequence of bytes identifies an ELF file.134static bool MagicBytesMatch(const uint8_t *magic);135136/// Examines at most EI_NIDENT bytes starting from the given address and137/// determines the address size of the underlying ELF file. This function138/// should only be called on an pointer for which MagicBytesMatch returns139/// true.140///141/// \return142/// The number of bytes forming an address in the ELF file (either 4 or143/// 8), else zero if the address size could not be determined.144static unsigned AddressSizeInBytes(const uint8_t *magic);145146private:147148/// Parse an ELFHeader header extension entry. This method is called by149/// Parse().150///151/// \param[in] data152/// The DataExtractor to read from.153void ParseHeaderExtension(lldb_private::DataExtractor &data);154};155156/// \class ELFSectionHeader157/// Generic representation of an ELF section header.158struct ELFSectionHeader {159elf_word sh_name; ///< Section name string index.160elf_word sh_type; ///< Section type.161elf_xword sh_flags; ///< Section attributes.162elf_addr sh_addr; ///< Virtual address of the section in memory.163elf_off sh_offset; ///< Start of section from beginning of file.164elf_xword sh_size; ///< Number of bytes occupied in the file.165elf_word sh_link; ///< Index of associated section.166elf_word sh_info; ///< Extra section info (overloaded).167elf_xword sh_addralign; ///< Power of two alignment constraint.168elf_xword sh_entsize; ///< Byte size of each section entry.169170ELFSectionHeader();171172/// Parse an ELFSectionHeader entry from the given DataExtracter starting at173/// position \p offset.174///175/// \param[in] data176/// The DataExtractor to read from. The address size of the extractor177/// determines if a 32 or 64 bit object should be read.178///179/// \param[in,out] offset180/// Pointer to an offset in the data. On return the offset will be181/// advanced by the number of bytes read.182///183/// \return184/// True if the ELFSectionHeader was successfully read and false185/// otherwise.186bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);187};188189/// \class ELFProgramHeader190/// Generic representation of an ELF program header.191struct ELFProgramHeader {192elf_word p_type; ///< Type of program segment.193elf_word p_flags; ///< Segment attributes.194elf_off p_offset; ///< Start of segment from beginning of file.195elf_addr p_vaddr; ///< Virtual address of segment in memory.196elf_addr p_paddr; ///< Physical address (for non-VM systems).197elf_xword p_filesz; ///< Byte size of the segment in file.198elf_xword p_memsz; ///< Byte size of the segment in memory.199elf_xword p_align; ///< Segment alignment constraint.200201ELFProgramHeader();202203/// Parse an ELFProgramHeader entry from the given DataExtractor starting at204/// position \p offset. The address size of the DataExtractor determines if205/// a 32 or 64 bit object is to be parsed.206///207/// \param[in] data208/// The DataExtractor to read from. The address size of the extractor209/// determines if a 32 or 64 bit object should be read.210///211/// \param[in,out] offset212/// Pointer to an offset in the data. On return the offset will be213/// advanced by the number of bytes read.214///215/// \return216/// True if the ELFProgramHeader was successfully read and false217/// otherwise.218bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);219};220221/// \class ELFSymbol222/// Represents a symbol within an ELF symbol table.223struct ELFSymbol {224elf_addr st_value; ///< Absolute or relocatable address.225elf_xword st_size; ///< Size of the symbol or zero.226elf_word st_name; ///< Symbol name string index.227unsigned char st_info; ///< Symbol type and binding attributes.228unsigned char st_other; ///< Reserved for future use.229elf_half st_shndx; ///< Section to which this symbol applies.230231ELFSymbol();232233/// Returns the binding attribute of the st_info member.234unsigned char getBinding() const { return st_info >> 4; }235236/// Returns the type attribute of the st_info member.237unsigned char getType() const { return st_info & 0x0F; }238239/// Sets the binding and type of the st_info member.240void setBindingAndType(unsigned char binding, unsigned char type) {241st_info = (binding << 4) + (type & 0x0F);242}243244static const char *bindingToCString(unsigned char binding);245246static const char *typeToCString(unsigned char type);247248static const char *249sectionIndexToCString(elf_half shndx,250const lldb_private::SectionList *section_list);251252/// Parse an ELFSymbol entry from the given DataExtractor starting at253/// position \p offset. The address size of the DataExtractor determines if254/// a 32 or 64 bit object is to be parsed.255///256/// \param[in] data257/// The DataExtractor to read from. The address size of the extractor258/// determines if a 32 or 64 bit object should be read.259///260/// \param[in,out] offset261/// Pointer to an offset in the data. On return the offset will be262/// advanced by the number of bytes read.263///264/// \return265/// True if the ELFSymbol was successfully read and false otherwise.266bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);267268void Dump(lldb_private::Stream *s, uint32_t idx,269const lldb_private::DataExtractor *strtab_data,270const lldb_private::SectionList *section_list);271};272273/// \class ELFDynamic274/// Represents an entry in an ELF dynamic table.275struct ELFDynamic {276elf_sxword d_tag; ///< Type of dynamic table entry.277union {278elf_xword d_val; ///< Integer value of the table entry.279elf_addr d_ptr; ///< Pointer value of the table entry.280};281282ELFDynamic();283284/// Parse an ELFDynamic entry from the given DataExtractor starting at285/// position \p offset. The address size of the DataExtractor determines if286/// a 32 or 64 bit object is to be parsed.287///288/// \param[in] data289/// The DataExtractor to read from. The address size of the extractor290/// determines if a 32 or 64 bit object should be read.291///292/// \param[in,out] offset293/// Pointer to an offset in the data. On return the offset will be294/// advanced by the number of bytes read.295///296/// \return297/// True if the ELFDynamic entry was successfully read and false298/// otherwise.299bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);300};301302/// \class ELFRel303/// Represents a relocation entry with an implicit addend.304struct ELFRel {305elf_addr r_offset; ///< Address of reference.306elf_xword r_info; ///< symbol index and type of relocation.307308ELFRel();309310/// Parse an ELFRel entry from the given DataExtractor starting at position311/// \p offset. The address size of the DataExtractor determines if a 32 or312/// 64 bit object is to be parsed.313///314/// \param[in] data315/// The DataExtractor to read from. The address size of the extractor316/// determines if a 32 or 64 bit object should be read.317///318/// \param[in,out] offset319/// Pointer to an offset in the data. On return the offset will be320/// advanced by the number of bytes read.321///322/// \return323/// True if the ELFRel entry was successfully read and false otherwise.324bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);325326/// Returns the type when the given entry represents a 32-bit relocation.327static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }328329/// Returns the type when the given entry represents a 64-bit relocation.330static unsigned RelocType64(const ELFRel &rel) {331return rel.r_info & 0xffffffff;332}333334/// Returns the symbol index when the given entry represents a 32-bit335/// relocation.336static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }337338/// Returns the symbol index when the given entry represents a 64-bit339/// relocation.340static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }341};342343/// \class ELFRela344/// Represents a relocation entry with an explicit addend.345struct ELFRela {346elf_addr r_offset; ///< Address of reference.347elf_xword r_info; ///< Symbol index and type of relocation.348elf_sxword r_addend; ///< Constant part of expression.349350ELFRela();351352/// Parse an ELFRela entry from the given DataExtractor starting at position353/// \p offset. The address size of the DataExtractor determines if a 32 or354/// 64 bit object is to be parsed.355///356/// \param[in] data357/// The DataExtractor to read from. The address size of the extractor358/// determines if a 32 or 64 bit object should be read.359///360/// \param[in,out] offset361/// Pointer to an offset in the data. On return the offset will be362/// advanced by the number of bytes read.363///364/// \return365/// True if the ELFRela entry was successfully read and false otherwise.366bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);367368/// Returns the type when the given entry represents a 32-bit relocation.369static unsigned RelocType32(const ELFRela &rela) {370return rela.r_info & 0x0ff;371}372373/// Returns the type when the given entry represents a 64-bit relocation.374static unsigned RelocType64(const ELFRela &rela) {375return rela.r_info & 0xffffffff;376}377378/// Returns the symbol index when the given entry represents a 32-bit379/// relocation.380static unsigned RelocSymbol32(const ELFRela &rela) {381return rela.r_info >> 8;382}383384/// Returns the symbol index when the given entry represents a 64-bit385/// relocation.386static unsigned RelocSymbol64(const ELFRela &rela) {387return rela.r_info >> 32;388}389};390391} // End namespace elf.392393#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H394395396