1 //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// @file 11 /// @brief Generic structures and typedefs for ELF files. 12 /// 13 /// This file provides definitions for the various entities comprising an ELF 14 /// file. The structures are generic in the sense that they do not correspond 15 /// to the exact binary layout of an ELF, but can be used to hold the 16 /// information present in both 32 and 64 bit variants of the format. Each 17 /// entity provides a \c Parse method which is capable of transparently reading 18 /// both 32 and 64 bit instances of the object. 19 //===----------------------------------------------------------------------===// 20 21 #ifndef liblldb_ELFHeader_h_ 22 #define liblldb_ELFHeader_h_ 23 24 #include "llvm/Support/ELF.h" 25 26 #include "lldb/lldb-enumerations.h" 27 #include "lldb/lldb-types.h" 28 29 namespace lldb_private { 30 class DataExtractor; 31 } // End namespace lldb_private. 32 33 namespace elf { 34 35 //------------------------------------------------------------------------------ 36 /// @name ELF type definitions. 37 /// 38 /// Types used to represent the various components of ELF structures. All types 39 /// are signed or unsigned integral types wide enough to hold values from both 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; 46 typedef int32_t elf_sword; 47 typedef uint64_t elf_size; 48 typedef uint64_t elf_xword; 49 typedef int64_t elf_sxword; 50 //@} 51 52 //------------------------------------------------------------------------------ 53 /// @class ELFHeader 54 /// @brief Generic representation of an ELF file header. 55 /// 56 /// This object is used to identify the general attributes on an ELF file and to 57 /// locate additional sections within the file. 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. 69 elf_half e_phnum_hdr; ///< Number of program header entries. 70 elf_half e_shentsize; ///< Size of a section header table entry. 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. 80 81 ELFHeader(); 82 83 //-------------------------------------------------------------------------- 84 /// Returns true if this is a 32 bit ELF file header. 85 /// 86 /// @return 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 } 91 92 //-------------------------------------------------------------------------- 93 /// Returns true if this is a 64 bit ELF file header. 94 /// 95 /// @return 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 } 100 101 //-------------------------------------------------------------------------- 102 /// The byte order of this ELF file header. 103 /// 104 /// @return 105 /// The byte order of this ELF file as described by the header. 106 lldb::ByteOrder GetByteOrder() const; 107 108 //-------------------------------------------------------------------------- 109 /// The jump slot relocation type of this ELF. 110 unsigned GetRelocationJumpSlotType() const; 111 112 //-------------------------------------------------------------------------- 113 /// Check if there should be header extension in section header #0 114 /// 115 /// @return 116 /// True if parsing the ELFHeader requires reading header extension 117 /// and false otherwise. 118 bool HasHeaderExtension() const; 119 120 //-------------------------------------------------------------------------- 121 /// Parse an ELFHeader entry starting at position \p offset and 122 /// update the data extractor with the address size and byte order 123 /// attributes as defined by the header. 124 /// 125 /// @param[in,out] data 126 /// The DataExtractor to read from. Updated with the address size and 127 /// byte order attributes appropriate to this header. 128 /// 129 /// @param[in,out] offset 130 /// Pointer to an offset in the data. On return the offset will be 131 /// advanced by the number of bytes read. 132 /// 133 /// @return 134 /// True if the ELFHeader was successfully read and false 135 /// otherwise. 136 bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); 137 138 //-------------------------------------------------------------------------- 139 /// Examines at most EI_NIDENT bytes starting from the given pointer and 140 /// determines if the magic ELF identification exists. 141 /// 142 /// @return 143 /// True if the given sequence of bytes identifies an ELF file. 144 static bool MagicBytesMatch(const uint8_t *magic); 145 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 /// 152 /// @return 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); 156 157 private: 158 159 //-------------------------------------------------------------------------- 160 /// Parse an ELFHeader header extension entry. This method is called 161 /// by Parse(). 162 /// 163 /// @param[in] data 164 /// The DataExtractor to read from. 165 void ParseHeaderExtension(lldb_private::DataExtractor &data); 166 }; 167 168 //------------------------------------------------------------------------------ 169 /// @class ELFSectionHeader 170 /// @brief Generic representation of an ELF section header. 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. 182 183 ELFSectionHeader(); 184 185 //-------------------------------------------------------------------------- 186 /// Parse an ELFSectionHeader entry from the given DataExtracter starting at 187 /// position \p offset. 188 /// 189 /// @param[in] data 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 /// 193 /// @param[in,out] offset 194 /// Pointer to an offset in the data. On return the offset will be 195 /// advanced by the number of bytes read. 196 /// 197 /// @return 198 /// True if the ELFSectionHeader was successfully read and false 199 /// otherwise. 200 bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 201 }; 202 203 //------------------------------------------------------------------------------ 204 /// @class ELFProgramHeader 205 /// @brief Generic representation of an ELF program header. 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. 215 216 ELFProgramHeader(); 217 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 /// 222 /// @param[in] data 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 /// 226 /// @param[in,out] offset 227 /// Pointer to an offset in the data. On return the offset will be 228 /// advanced by the number of bytes read. 229 /// 230 /// @return 231 /// True if the ELFProgramHeader was successfully read and false 232 /// otherwise. 233 bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 234 }; 235 236 //------------------------------------------------------------------------------ 237 /// @class ELFSymbol 238 /// @brief Represents a symbol within an ELF symbol table. 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. 246 247 ELFSymbol(); 248 249 /// Returns the binding attribute of the st_info member. 250 unsigned char getBinding() const { return st_info >> 4; } 251 252 /// Returns the type attribute of the st_info member. 253 unsigned char getType() const { return st_info & 0x0F; } 254 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 } 259 260 static const char *bindingToCString(unsigned char binding); 261 262 static const char *typeToCString(unsigned char type); 263 264 static const char * 265 sectionIndexToCString(elf_half shndx, 266 const lldb_private::SectionList *section_list); 267 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 /// 272 /// @param[in] data 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 /// 276 /// @param[in,out] offset 277 /// Pointer to an offset in the data. On return the offset will be 278 /// advanced by the number of bytes read. 279 /// 280 /// @return 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); 287 }; 288 289 //------------------------------------------------------------------------------ 290 /// @class ELFDynamic 291 /// @brief Represents an entry in an ELF dynamic table. 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 }; 298 299 ELFDynamic(); 300 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 /// 305 /// @param[in] data 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 /// 309 /// @param[in,out] offset 310 /// Pointer to an offset in the data. On return the offset will be 311 /// advanced by the number of bytes read. 312 /// 313 /// @return 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); 317 }; 318 319 //------------------------------------------------------------------------------ 320 /// @class ELFRel 321 /// @brief Represents a relocation entry with an implicit addend. 322 struct ELFRel { 323 elf_addr r_offset; ///< Address of reference. 324 elf_xword r_info; ///< symbol index and type of relocation. 325 326 ELFRel(); 327 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 /// 332 /// @param[in] data 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 /// 336 /// @param[in,out] offset 337 /// Pointer to an offset in the data. On return the offset will be 338 /// advanced by the number of bytes read. 339 /// 340 /// @return 341 /// True if the ELFRel entry was successfully read and false otherwise. 342 bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 343 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; } 346 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 } 351 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; } 355 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; } 359 }; 360 361 //------------------------------------------------------------------------------ 362 /// @class ELFRela 363 /// @brief Represents a relocation entry with an explicit addend. 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. 368 369 ELFRela(); 370 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 /// 375 /// @param[in] data 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 /// 379 /// @param[in,out] offset 380 /// Pointer to an offset in the data. On return the offset will be 381 /// advanced by the number of bytes read. 382 /// 383 /// @return 384 /// True if the ELFRela entry was successfully read and false otherwise. 385 bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 386 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 } 391 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 } 396 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 } 402 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 } 408 }; 409 410 } // End namespace elf. 411 412 #endif // #ifndef liblldb_ELFHeader_h_ 413