Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 1 | //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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-exception |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 9 | /// \file |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 10 | /// Generic structures and typedefs for ELF files. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 11 | /// |
| 12 | /// This file provides definitions for the various entities comprising an ELF |
| 13 | /// file. The structures are generic in the sense that they do not correspond |
| 14 | /// to the exact binary layout of an ELF, but can be used to hold the |
| 15 | /// information present in both 32 and 64 bit variants of the format. Each |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 16 | /// entity provides a \c Parse method which is capable of transparently |
| 17 | /// reading both 32 and 64 bit instances of the object. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 18 | //===----------------------------------------------------------------------===// |
| 19 | |
| 20 | #ifndef liblldb_ELFHeader_h_ |
| 21 | #define liblldb_ELFHeader_h_ |
| 22 | |
Zachary Turner | 264b5d9 | 2017-06-07 03:48:56 +0000 | [diff] [blame] | 23 | #include "llvm/BinaryFormat/ELF.h" |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 24 | |
| 25 | #include "lldb/lldb-enumerations.h" |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 26 | #include "lldb/lldb-types.h" |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 27 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 28 | namespace lldb_private { |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 29 | class DataExtractor; |
| 30 | } // End namespace lldb_private. |
| 31 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 32 | namespace elf { |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 33 | |
| 34 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 35 | /// \name ELF type definitions. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 36 | /// |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 37 | /// Types used to represent the various components of ELF structures. All |
| 38 | /// types are signed or unsigned integral types wide enough to hold values |
| 39 | /// from both |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 40 | /// 32 and 64 bit ELF variants. |
| 41 | //@{ |
| 42 | typedef uint64_t elf_addr; |
| 43 | typedef uint64_t elf_off; |
| 44 | typedef uint16_t elf_half; |
| 45 | typedef uint32_t elf_word; |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 46 | typedef int32_t elf_sword; |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 47 | typedef uint64_t elf_size; |
| 48 | typedef uint64_t elf_xword; |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 49 | typedef int64_t elf_sxword; |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 50 | //@} |
| 51 | |
| 52 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 53 | /// \class ELFHeader |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 54 | /// Generic representation of an ELF file header. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 55 | /// |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 56 | /// This object is used to identify the general attributes on an ELF file and |
| 57 | /// to locate additional sections within the file. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 58 | struct ELFHeader { |
| 59 | unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification. |
| 60 | elf_addr e_entry; ///< Virtual address program entry point. |
| 61 | elf_off e_phoff; ///< File offset of program header table. |
| 62 | elf_off e_shoff; ///< File offset of section header table. |
| 63 | elf_word e_flags; ///< Processor specific flags. |
| 64 | elf_word e_version; ///< Version of object file (always 1). |
| 65 | elf_half e_type; ///< Object file type. |
| 66 | elf_half e_machine; ///< Target architecture. |
| 67 | elf_half e_ehsize; ///< Byte size of the ELF header. |
| 68 | elf_half e_phentsize; ///< Size of a program header table entry. |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 69 | elf_half e_phnum_hdr; ///< Number of program header entries. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 70 | elf_half e_shentsize; ///< Size of a section header table entry. |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 71 | elf_half e_shnum_hdr; ///< Number of section header entries. |
| 72 | elf_half e_shstrndx_hdr; ///< String table section index. |
| 73 | |
| 74 | // In some cases these numbers do not fit in 16 bits and they are |
| 75 | // stored outside of the header in section #0. Here are the actual |
| 76 | // values. |
| 77 | elf_word e_phnum; ///< Number of program header entries. |
| 78 | elf_word e_shnum; ///< Number of section header entries. |
| 79 | elf_word e_shstrndx; ///< String table section index. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 80 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 81 | ELFHeader(); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 82 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 83 | //-------------------------------------------------------------------------- |
| 84 | /// Returns true if this is a 32 bit ELF file header. |
| 85 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 86 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 87 | /// True if this is a 32 bit ELF file header. |
| 88 | bool Is32Bit() const { |
| 89 | return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32; |
| 90 | } |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 91 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 92 | //-------------------------------------------------------------------------- |
| 93 | /// Returns true if this is a 64 bit ELF file header. |
| 94 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 95 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 96 | /// True if this is a 64 bit ELF file header. |
| 97 | bool Is64Bit() const { |
| 98 | return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; |
| 99 | } |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 100 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 101 | //-------------------------------------------------------------------------- |
| 102 | /// The byte order of this ELF file header. |
| 103 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 104 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 105 | /// The byte order of this ELF file as described by the header. |
| 106 | lldb::ByteOrder GetByteOrder() const; |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 107 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 108 | //-------------------------------------------------------------------------- |
| 109 | /// The jump slot relocation type of this ELF. |
| 110 | unsigned GetRelocationJumpSlotType() const; |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 111 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 112 | //-------------------------------------------------------------------------- |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 113 | /// Check if there should be header extension in section header #0 |
| 114 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 115 | /// \return |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 116 | /// True if parsing the ELFHeader requires reading header extension |
| 117 | /// and false otherwise. |
| 118 | bool HasHeaderExtension() const; |
| 119 | |
| 120 | //-------------------------------------------------------------------------- |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 121 | /// Parse an ELFHeader entry starting at position \p offset and update the |
| 122 | /// data extractor with the address size and byte order attributes as |
| 123 | /// defined by the header. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 124 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 125 | /// \param[in,out] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 126 | /// The DataExtractor to read from. Updated with the address size and |
| 127 | /// byte order attributes appropriate to this header. |
| 128 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 129 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 130 | /// Pointer to an offset in the data. On return the offset will be |
| 131 | /// advanced by the number of bytes read. |
| 132 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 133 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 134 | /// True if the ELFHeader was successfully read and false |
| 135 | /// otherwise. |
| 136 | bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 137 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 138 | //-------------------------------------------------------------------------- |
| 139 | /// Examines at most EI_NIDENT bytes starting from the given pointer and |
| 140 | /// determines if the magic ELF identification exists. |
| 141 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 142 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 143 | /// True if the given sequence of bytes identifies an ELF file. |
| 144 | static bool MagicBytesMatch(const uint8_t *magic); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 145 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 146 | //-------------------------------------------------------------------------- |
| 147 | /// Examines at most EI_NIDENT bytes starting from the given address and |
| 148 | /// determines the address size of the underlying ELF file. This function |
| 149 | /// should only be called on an pointer for which MagicBytesMatch returns |
| 150 | /// true. |
| 151 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 152 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 153 | /// The number of bytes forming an address in the ELF file (either 4 or |
| 154 | /// 8), else zero if the address size could not be determined. |
| 155 | static unsigned AddressSizeInBytes(const uint8_t *magic); |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 156 | |
| 157 | private: |
| 158 | |
| 159 | //-------------------------------------------------------------------------- |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 160 | /// Parse an ELFHeader header extension entry. This method is called by |
| 161 | /// Parse(). |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 162 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 163 | /// \param[in] data |
Pavel Labath | 23ccc29 | 2017-01-31 23:09:46 +0000 | [diff] [blame] | 164 | /// The DataExtractor to read from. |
| 165 | void ParseHeaderExtension(lldb_private::DataExtractor &data); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 166 | }; |
| 167 | |
| 168 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 169 | /// \class ELFSectionHeader |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 170 | /// Generic representation of an ELF section header. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 171 | struct ELFSectionHeader { |
| 172 | elf_word sh_name; ///< Section name string index. |
| 173 | elf_word sh_type; ///< Section type. |
| 174 | elf_xword sh_flags; ///< Section attributes. |
| 175 | elf_addr sh_addr; ///< Virtual address of the section in memory. |
| 176 | elf_off sh_offset; ///< Start of section from beginning of file. |
| 177 | elf_xword sh_size; ///< Number of bytes occupied in the file. |
| 178 | elf_word sh_link; ///< Index of associated section. |
| 179 | elf_word sh_info; ///< Extra section info (overloaded). |
| 180 | elf_xword sh_addralign; ///< Power of two alignment constraint. |
| 181 | elf_xword sh_entsize; ///< Byte size of each section entry. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 182 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 183 | ELFSectionHeader(); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 184 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 185 | //-------------------------------------------------------------------------- |
| 186 | /// Parse an ELFSectionHeader entry from the given DataExtracter starting at |
| 187 | /// position \p offset. |
| 188 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 189 | /// \param[in] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 190 | /// The DataExtractor to read from. The address size of the extractor |
| 191 | /// determines if a 32 or 64 bit object should be read. |
| 192 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 193 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 194 | /// Pointer to an offset in the data. On return the offset will be |
| 195 | /// advanced by the number of bytes read. |
| 196 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 197 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 198 | /// True if the ELFSectionHeader was successfully read and false |
| 199 | /// otherwise. |
| 200 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 201 | }; |
| 202 | |
| 203 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 204 | /// \class ELFProgramHeader |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 205 | /// Generic representation of an ELF program header. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 206 | struct ELFProgramHeader { |
| 207 | elf_word p_type; ///< Type of program segment. |
| 208 | elf_word p_flags; ///< Segment attributes. |
| 209 | elf_off p_offset; ///< Start of segment from beginning of file. |
| 210 | elf_addr p_vaddr; ///< Virtual address of segment in memory. |
| 211 | elf_addr p_paddr; ///< Physical address (for non-VM systems). |
| 212 | elf_xword p_filesz; ///< Byte size of the segment in file. |
| 213 | elf_xword p_memsz; ///< Byte size of the segment in memory. |
| 214 | elf_xword p_align; ///< Segment alignment constraint. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 215 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 216 | ELFProgramHeader(); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 217 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 218 | /// Parse an ELFProgramHeader entry from the given DataExtractor starting at |
| 219 | /// position \p offset. The address size of the DataExtractor determines if |
| 220 | /// a 32 or 64 bit object is to be parsed. |
| 221 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 222 | /// \param[in] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 223 | /// The DataExtractor to read from. The address size of the extractor |
| 224 | /// determines if a 32 or 64 bit object should be read. |
| 225 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 226 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 227 | /// Pointer to an offset in the data. On return the offset will be |
| 228 | /// advanced by the number of bytes read. |
| 229 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 230 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 231 | /// True if the ELFProgramHeader was successfully read and false |
| 232 | /// otherwise. |
| 233 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 234 | }; |
| 235 | |
| 236 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 237 | /// \class ELFSymbol |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 238 | /// Represents a symbol within an ELF symbol table. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 239 | struct ELFSymbol { |
| 240 | elf_addr st_value; ///< Absolute or relocatable address. |
| 241 | elf_xword st_size; ///< Size of the symbol or zero. |
| 242 | elf_word st_name; ///< Symbol name string index. |
| 243 | unsigned char st_info; ///< Symbol type and binding attributes. |
| 244 | unsigned char st_other; ///< Reserved for future use. |
| 245 | elf_half st_shndx; ///< Section to which this symbol applies. |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 246 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 247 | ELFSymbol(); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 248 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 249 | /// Returns the binding attribute of the st_info member. |
| 250 | unsigned char getBinding() const { return st_info >> 4; } |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 251 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 252 | /// Returns the type attribute of the st_info member. |
| 253 | unsigned char getType() const { return st_info & 0x0F; } |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 254 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 255 | /// Sets the binding and type of the st_info member. |
| 256 | void setBindingAndType(unsigned char binding, unsigned char type) { |
| 257 | st_info = (binding << 4) + (type & 0x0F); |
| 258 | } |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 259 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 260 | static const char *bindingToCString(unsigned char binding); |
Greg Clayton | 9594f4c | 2013-04-13 23:17:23 +0000 | [diff] [blame] | 261 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 262 | static const char *typeToCString(unsigned char type); |
Greg Clayton | 9594f4c | 2013-04-13 23:17:23 +0000 | [diff] [blame] | 263 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 264 | static const char * |
| 265 | sectionIndexToCString(elf_half shndx, |
| 266 | const lldb_private::SectionList *section_list); |
Greg Clayton | 9594f4c | 2013-04-13 23:17:23 +0000 | [diff] [blame] | 267 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 268 | /// Parse an ELFSymbol entry from the given DataExtractor starting at |
| 269 | /// position \p offset. The address size of the DataExtractor determines if |
| 270 | /// a 32 or 64 bit object is to be parsed. |
| 271 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 272 | /// \param[in] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 273 | /// The DataExtractor to read from. The address size of the extractor |
| 274 | /// determines if a 32 or 64 bit object should be read. |
| 275 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 276 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 277 | /// Pointer to an offset in the data. On return the offset will be |
| 278 | /// advanced by the number of bytes read. |
| 279 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 280 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 281 | /// True if the ELFSymbol was successfully read and false otherwise. |
| 282 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); |
| 283 | |
| 284 | void Dump(lldb_private::Stream *s, uint32_t idx, |
| 285 | const lldb_private::DataExtractor *strtab_data, |
| 286 | const lldb_private::SectionList *section_list); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 287 | }; |
| 288 | |
| 289 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 290 | /// \class ELFDynamic |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 291 | /// Represents an entry in an ELF dynamic table. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 292 | struct ELFDynamic { |
| 293 | elf_sxword d_tag; ///< Type of dynamic table entry. |
| 294 | union { |
| 295 | elf_xword d_val; ///< Integer value of the table entry. |
| 296 | elf_addr d_ptr; ///< Pointer value of the table entry. |
| 297 | }; |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 298 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 299 | ELFDynamic(); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 300 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 301 | /// Parse an ELFDynamic entry from the given DataExtractor starting at |
| 302 | /// position \p offset. The address size of the DataExtractor determines if |
| 303 | /// a 32 or 64 bit object is to be parsed. |
| 304 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 305 | /// \param[in] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 306 | /// The DataExtractor to read from. The address size of the extractor |
| 307 | /// determines if a 32 or 64 bit object should be read. |
| 308 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 309 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 310 | /// Pointer to an offset in the data. On return the offset will be |
| 311 | /// advanced by the number of bytes read. |
| 312 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 313 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 314 | /// True if the ELFDynamic entry was successfully read and false |
| 315 | /// otherwise. |
| 316 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 317 | }; |
| 318 | |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 319 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 320 | /// \class ELFRel |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 321 | /// Represents a relocation entry with an implicit addend. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 322 | struct ELFRel { |
| 323 | elf_addr r_offset; ///< Address of reference. |
| 324 | elf_xword r_info; ///< symbol index and type of relocation. |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 325 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 326 | ELFRel(); |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 327 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 328 | /// Parse an ELFRel entry from the given DataExtractor starting at position |
| 329 | /// \p offset. The address size of the DataExtractor determines if a 32 or |
| 330 | /// 64 bit object is to be parsed. |
| 331 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 332 | /// \param[in] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 333 | /// The DataExtractor to read from. The address size of the extractor |
| 334 | /// determines if a 32 or 64 bit object should be read. |
| 335 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 336 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 337 | /// Pointer to an offset in the data. On return the offset will be |
| 338 | /// advanced by the number of bytes read. |
| 339 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 340 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 341 | /// True if the ELFRel entry was successfully read and false otherwise. |
| 342 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 343 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 344 | /// Returns the type when the given entry represents a 32-bit relocation. |
| 345 | static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 346 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 347 | /// Returns the type when the given entry represents a 64-bit relocation. |
| 348 | static unsigned RelocType64(const ELFRel &rel) { |
| 349 | return rel.r_info & 0xffffffff; |
| 350 | } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 351 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 352 | /// Returns the symbol index when the given entry represents a 32-bit |
| 353 | /// relocation. |
| 354 | static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 355 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 356 | /// Returns the symbol index when the given entry represents a 64-bit |
| 357 | /// relocation. |
| 358 | static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 359 | }; |
| 360 | |
| 361 | //------------------------------------------------------------------------------ |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 362 | /// \class ELFRela |
Adrian Prantl | d8f460e | 2018-05-02 16:55:16 +0000 | [diff] [blame] | 363 | /// Represents a relocation entry with an explicit addend. |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 364 | struct ELFRela { |
| 365 | elf_addr r_offset; ///< Address of reference. |
| 366 | elf_xword r_info; ///< Symbol index and type of relocation. |
| 367 | elf_sxword r_addend; ///< Constant part of expression. |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 368 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 369 | ELFRela(); |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 370 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 371 | /// Parse an ELFRela entry from the given DataExtractor starting at position |
| 372 | /// \p offset. The address size of the DataExtractor determines if a 32 or |
| 373 | /// 64 bit object is to be parsed. |
| 374 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 375 | /// \param[in] data |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 376 | /// The DataExtractor to read from. The address size of the extractor |
| 377 | /// determines if a 32 or 64 bit object should be read. |
| 378 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 379 | /// \param[in,out] offset |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 380 | /// Pointer to an offset in the data. On return the offset will be |
| 381 | /// advanced by the number of bytes read. |
| 382 | /// |
Adrian Prantl | f05b42e | 2019-03-11 17:09:29 +0000 | [diff] [blame^] | 383 | /// \return |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 384 | /// True if the ELFRela entry was successfully read and false otherwise. |
| 385 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 386 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 387 | /// Returns the type when the given entry represents a 32-bit relocation. |
| 388 | static unsigned RelocType32(const ELFRela &rela) { |
| 389 | return rela.r_info & 0x0ff; |
| 390 | } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 391 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 392 | /// Returns the type when the given entry represents a 64-bit relocation. |
| 393 | static unsigned RelocType64(const ELFRela &rela) { |
| 394 | return rela.r_info & 0xffffffff; |
| 395 | } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 396 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 397 | /// Returns the symbol index when the given entry represents a 32-bit |
| 398 | /// relocation. |
| 399 | static unsigned RelocSymbol32(const ELFRela &rela) { |
| 400 | return rela.r_info >> 8; |
| 401 | } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 402 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 403 | /// Returns the symbol index when the given entry represents a 64-bit |
| 404 | /// relocation. |
| 405 | static unsigned RelocSymbol64(const ELFRela &rela) { |
| 406 | return rela.r_info >> 32; |
| 407 | } |
Stephen Wilson | 43fe645 | 2011-03-30 15:59:12 +0000 | [diff] [blame] | 408 | }; |
| 409 | |
Stephen Wilson | f325ba9 | 2010-07-13 23:07:23 +0000 | [diff] [blame] | 410 | } // End namespace elf. |
| 411 | |
| 412 | #endif // #ifndef liblldb_ELFHeader_h_ |