brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.5 KiB · 963cc85 Raw
395 lines · c
1//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// Generic structures and typedefs for ELF files.11///12/// This file provides definitions for the various entities comprising an ELF13/// file.  The structures are generic in the sense that they do not correspond14/// to the exact binary layout of an ELF, but can be used to hold the15/// information present in both 32 and 64 bit variants of the format.  Each16/// entity provides a \c Parse method which is capable of transparently17/// reading both 32 and 64 bit instances of the object.18//===----------------------------------------------------------------------===//19 20#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H21#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H22 23#include "llvm/BinaryFormat/ELF.h"24 25#include "lldb/lldb-enumerations.h"26#include "lldb/lldb-types.h"27 28namespace lldb_private {29class DataExtractor;30} // End namespace lldb_private.31 32namespace elf {33 34/// \name ELF type definitions.35///36/// Types used to represent the various components of ELF structures.  All37/// types are signed or unsigned integral types wide enough to hold values38/// from both39/// 32 and 64 bit ELF variants.40//@{41typedef uint64_t elf_addr;42typedef uint64_t elf_off;43typedef uint16_t elf_half;44typedef uint32_t elf_word;45typedef int32_t elf_sword;46typedef uint64_t elf_size;47typedef uint64_t elf_xword;48typedef int64_t elf_sxword;49//@}50 51/// \class ELFHeader52/// Generic representation of an ELF file header.53///54/// This object is used to identify the general attributes on an ELF file and55/// to locate additional sections within the file.56struct ELFHeader {57  unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.58  elf_addr e_entry;     ///< Virtual address program entry point.59  elf_off e_phoff;      ///< File offset of program header table.60  elf_off e_shoff;      ///< File offset of section header table.61  elf_word e_flags;     ///< Processor specific flags.62  elf_word e_version;   ///< Version of object file (always 1).63  elf_half e_type;      ///< Object file type.64  elf_half e_machine;   ///< Target architecture.65  elf_half e_ehsize;    ///< Byte size of the ELF header.66  elf_half e_phentsize; ///< Size of a program header table entry.67  elf_half e_phnum_hdr; ///< Number of program header entries.68  elf_half e_shentsize; ///< Size of a section header table entry.69  elf_half e_shnum_hdr; ///< Number of section header entries.70  elf_half e_shstrndx_hdr; ///< String table section index.71 72  // In some cases these numbers do not fit in 16 bits and they are73  // stored outside of the header in section #0. Here are the actual74  // values.75  elf_word e_phnum;     ///< Number of program header entries.76  elf_word e_shnum;     ///< Number of section header entries.77  elf_word e_shstrndx;  ///< String table section index.78 79  ELFHeader();80 81  /// Returns true if this is a 32 bit ELF file header.82  ///83  /// \return84  ///    True if this is a 32 bit ELF file header.85  bool Is32Bit() const {86    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;87  }88 89  /// Returns true if this is a 64 bit ELF file header.90  ///91  /// \return92  ///   True if this is a 64 bit ELF file header.93  bool Is64Bit() const {94    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;95  }96 97  /// The byte order of this ELF file header.98  ///99  /// \return100  ///    The byte order of this ELF file as described by the header.101  lldb::ByteOrder GetByteOrder() const;102 103  /// The jump slot relocation type of this ELF.104  unsigned GetRelocationJumpSlotType() const;105 106  /// Check if there should be header extension in section header #0107  ///108  /// \return109  ///    True if parsing the ELFHeader requires reading header extension110  ///    and false otherwise.111  bool HasHeaderExtension() const;112 113  /// Parse an ELFHeader entry starting at position \p offset and update the114  /// data extractor with the address size and byte order attributes as115  /// defined by the header.116  ///117  /// \param[in,out] data118  ///    The DataExtractor to read from.  Updated with the address size and119  ///    byte order attributes appropriate to this header.120  ///121  /// \param[in,out] offset122  ///    Pointer to an offset in the data.  On return the offset will be123  ///    advanced by the number of bytes read.124  ///125  /// \return126  ///    True if the ELFHeader was successfully read and false127  ///    otherwise.128  bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);129 130  /// Examines at most EI_NIDENT bytes starting from the given pointer and131  /// determines if the magic ELF identification exists.132  ///133  /// \return134  ///    True if the given sequence of bytes identifies an ELF file.135  static bool MagicBytesMatch(const uint8_t *magic);136 137  /// Examines at most EI_NIDENT bytes starting from the given address and138  /// determines the address size of the underlying ELF file.  This function139  /// should only be called on an pointer for which MagicBytesMatch returns140  /// true.141  ///142  /// \return143  ///    The number of bytes forming an address in the ELF file (either 4 or144  ///    8), else zero if the address size could not be determined.145  static unsigned AddressSizeInBytes(const uint8_t *magic);146 147private:148 149  /// Parse an ELFHeader header extension entry.  This method is called by150  /// Parse().151  ///152  /// \param[in] data153  ///    The DataExtractor to read from.154  void ParseHeaderExtension(lldb_private::DataExtractor &data);155};156 157/// \class ELFSectionHeader158/// Generic representation of an ELF section header.159struct ELFSectionHeader {160  elf_word sh_name;       ///< Section name string index.161  elf_word sh_type;       ///< Section type.162  elf_xword sh_flags;     ///< Section attributes.163  elf_addr sh_addr;       ///< Virtual address of the section in memory.164  elf_off sh_offset;      ///< Start of section from beginning of file.165  elf_xword sh_size;      ///< Number of bytes occupied in the file.166  elf_word sh_link;       ///< Index of associated section.167  elf_word sh_info;       ///< Extra section info (overloaded).168  elf_xword sh_addralign; ///< Power of two alignment constraint.169  elf_xword sh_entsize;   ///< Byte size of each section entry.170 171  ELFSectionHeader();172 173  /// Parse an ELFSectionHeader entry from the given DataExtracter starting at174  /// position \p offset.175  ///176  /// \param[in] data177  ///    The DataExtractor to read from.  The address size of the extractor178  ///    determines if a 32 or 64 bit object should be read.179  ///180  /// \param[in,out] offset181  ///    Pointer to an offset in the data.  On return the offset will be182  ///    advanced by the number of bytes read.183  ///184  /// \return185  ///    True if the ELFSectionHeader was successfully read and false186  ///    otherwise.187  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);188};189 190/// \class ELFProgramHeader191/// Generic representation of an ELF program header.192struct ELFProgramHeader {193  elf_word p_type;    ///< Type of program segment.194  elf_word p_flags;   ///< Segment attributes.195  elf_off p_offset;   ///< Start of segment from beginning of file.196  elf_addr p_vaddr;   ///< Virtual address of segment in memory.197  elf_addr p_paddr;   ///< Physical address (for non-VM systems).198  elf_xword p_filesz; ///< Byte size of the segment in file.199  elf_xword p_memsz;  ///< Byte size of the segment in memory.200  elf_xword p_align;  ///< Segment alignment constraint.201 202  ELFProgramHeader();203 204  /// Parse an ELFProgramHeader entry from the given DataExtractor starting at205  /// position \p offset.  The address size of the DataExtractor determines if206  /// a 32 or 64 bit object is to be parsed.207  ///208  /// \param[in] data209  ///    The DataExtractor to read from.  The address size of the extractor210  ///    determines if a 32 or 64 bit object should be read.211  ///212  /// \param[in,out] offset213  ///    Pointer to an offset in the data.  On return the offset will be214  ///    advanced by the number of bytes read.215  ///216  /// \return217  ///    True if the ELFProgramHeader was successfully read and false218  ///    otherwise.219  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);220};221 222/// \class ELFSymbol223/// Represents a symbol within an ELF symbol table.224struct ELFSymbol {225  elf_addr st_value;      ///< Absolute or relocatable address.226  elf_xword st_size;      ///< Size of the symbol or zero.227  elf_word st_name;       ///< Symbol name string index.228  unsigned char st_info;  ///< Symbol type and binding attributes.229  unsigned char st_other; ///< Reserved for future use.230  elf_half st_shndx;      ///< Section to which this symbol applies.231 232  ELFSymbol();233 234  /// Returns the binding attribute of the st_info member.235  unsigned char getBinding() const { return st_info >> 4; }236 237  /// Returns the type attribute of the st_info member.238  unsigned char getType() const { return st_info & 0x0F; }239 240  /// Sets the binding and type of the st_info member.241  void setBindingAndType(unsigned char binding, unsigned char type) {242    st_info = (binding << 4) + (type & 0x0F);243  }244 245  static const char *bindingToCString(unsigned char binding);246 247  static const char *typeToCString(unsigned char type);248 249  static const char *250  sectionIndexToCString(elf_half shndx,251                        const lldb_private::SectionList *section_list);252 253  /// Parse an ELFSymbol entry from the given DataExtractor starting at254  /// position \p offset.  The address size of the DataExtractor determines if255  /// a 32 or 64 bit object is to be parsed.256  ///257  /// \param[in] data258  ///    The DataExtractor to read from.  The address size of the extractor259  ///    determines if a 32 or 64 bit object should be read.260  ///261  /// \param[in,out] offset262  ///    Pointer to an offset in the data.  On return the offset will be263  ///    advanced by the number of bytes read.264  ///265  /// \return266  ///    True if the ELFSymbol was successfully read and false otherwise.267  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);268 269  void Dump(lldb_private::Stream *s, uint32_t idx,270            const lldb_private::DataExtractor *strtab_data,271            const lldb_private::SectionList *section_list);272};273 274/// \class ELFDynamic275/// Represents an entry in an ELF dynamic table.276struct ELFDynamic {277  elf_sxword d_tag; ///< Type of dynamic table entry.278  union {279    elf_xword d_val; ///< Integer value of the table entry.280    elf_addr d_ptr;  ///< Pointer value of the table entry.281  };282 283  ELFDynamic();284 285  /// Parse an ELFDynamic entry from the given DataExtractor starting at286  /// position \p offset.  The address size of the DataExtractor determines if287  /// a 32 or 64 bit object is to be parsed.288  ///289  /// \param[in] data290  ///    The DataExtractor to read from.  The address size of the extractor291  ///    determines if a 32 or 64 bit object should be read.292  ///293  /// \param[in,out] offset294  ///    Pointer to an offset in the data.  On return the offset will be295  ///    advanced by the number of bytes read.296  ///297  /// \return298  ///    True if the ELFDynamic entry was successfully read and false299  ///    otherwise.300  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);301};302 303/// \class ELFRel304/// Represents a relocation entry with an implicit addend.305struct ELFRel {306  elf_addr r_offset; ///< Address of reference.307  elf_xword r_info;  ///< symbol index and type of relocation.308 309  ELFRel();310 311  /// Parse an ELFRel entry from the given DataExtractor starting at position312  /// \p offset.  The address size of the DataExtractor determines if a 32 or313  /// 64 bit object is to be parsed.314  ///315  /// \param[in] data316  ///    The DataExtractor to read from.  The address size of the extractor317  ///    determines if a 32 or 64 bit object should be read.318  ///319  /// \param[in,out] offset320  ///    Pointer to an offset in the data.  On return the offset will be321  ///    advanced by the number of bytes read.322  ///323  /// \return324  ///    True if the ELFRel entry was successfully read and false otherwise.325  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);326 327  /// Returns the type when the given entry represents a 32-bit relocation.328  static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }329 330  /// Returns the type when the given entry represents a 64-bit relocation.331  static unsigned RelocType64(const ELFRel &rel) {332    return rel.r_info & 0xffffffff;333  }334 335  /// Returns the symbol index when the given entry represents a 32-bit336  /// relocation.337  static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }338 339  /// Returns the symbol index when the given entry represents a 64-bit340  /// relocation.341  static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }342};343 344/// \class ELFRela345/// Represents a relocation entry with an explicit addend.346struct ELFRela {347  elf_addr r_offset;   ///< Address of reference.348  elf_xword r_info;    ///< Symbol index and type of relocation.349  elf_sxword r_addend; ///< Constant part of expression.350 351  ELFRela();352 353  /// Parse an ELFRela entry from the given DataExtractor starting at position354  /// \p offset.  The address size of the DataExtractor determines if a 32 or355  /// 64 bit object is to be parsed.356  ///357  /// \param[in] data358  ///    The DataExtractor to read from.  The address size of the extractor359  ///    determines if a 32 or 64 bit object should be read.360  ///361  /// \param[in,out] offset362  ///    Pointer to an offset in the data.  On return the offset will be363  ///    advanced by the number of bytes read.364  ///365  /// \return366  ///    True if the ELFRela entry was successfully read and false otherwise.367  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);368 369  /// Returns the type when the given entry represents a 32-bit relocation.370  static unsigned RelocType32(const ELFRela &rela) {371    return rela.r_info & 0x0ff;372  }373 374  /// Returns the type when the given entry represents a 64-bit relocation.375  static unsigned RelocType64(const ELFRela &rela) {376    return rela.r_info & 0xffffffff;377  }378 379  /// Returns the symbol index when the given entry represents a 32-bit380  /// relocation.381  static unsigned RelocSymbol32(const ELFRela &rela) {382    return rela.r_info >> 8;383  }384 385  /// Returns the symbol index when the given entry represents a 64-bit386  /// relocation.387  static unsigned RelocSymbol64(const ELFRela &rela) {388    return rela.r_info >> 32;389  }390};391 392} // End namespace elf.393 394#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H395