1254721Semaste//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste// 10254721Semaste/// @file 11254721Semaste/// @brief Generic structures and typedefs for ELF files. 12254721Semaste/// 13254721Semaste/// This file provides definitions for the various entities comprising an ELF 14254721Semaste/// file. The structures are generic in the sense that they do not correspond 15254721Semaste/// to the exact binary layout of an ELF, but can be used to hold the 16254721Semaste/// information present in both 32 and 64 bit variants of the format. Each 17254721Semaste/// entity provides a \c Parse method which is capable of transparently reading 18254721Semaste/// both 32 and 64 bit instances of the object. 19254721Semaste//===----------------------------------------------------------------------===// 20254721Semaste 21254721Semaste#ifndef liblldb_ELFHeader_h_ 22254721Semaste#define liblldb_ELFHeader_h_ 23254721Semaste 24254721Semaste#include "llvm/Support/ELF.h" 25254721Semaste 26254721Semaste#include "lldb/lldb-enumerations.h" 27254721Semaste 28254721Semastenamespace lldb_private 29254721Semaste{ 30254721Semasteclass DataExtractor; 31254721Semaste} // End namespace lldb_private. 32254721Semaste 33254721Semastenamespace elf 34254721Semaste{ 35254721Semaste 36254721Semaste//------------------------------------------------------------------------------ 37254721Semaste/// @name ELF type definitions. 38254721Semaste/// 39254721Semaste/// Types used to represent the various components of ELF structures. All types 40254721Semaste/// are signed or unsigned integral types wide enough to hold values from both 41254721Semaste/// 32 and 64 bit ELF variants. 42254721Semaste//@{ 43254721Semastetypedef uint64_t elf_addr; 44254721Semastetypedef uint64_t elf_off; 45254721Semastetypedef uint16_t elf_half; 46254721Semastetypedef uint32_t elf_word; 47254721Semastetypedef int32_t elf_sword; 48254721Semastetypedef uint64_t elf_size; 49254721Semastetypedef uint64_t elf_xword; 50254721Semastetypedef int64_t elf_sxword; 51254721Semaste//@} 52254721Semaste 53254721Semaste//------------------------------------------------------------------------------ 54254721Semaste/// @class ELFHeader 55254721Semaste/// @brief Generic representation of an ELF file header. 56254721Semaste/// 57254721Semaste/// This object is used to identify the general attributes on an ELF file and to 58254721Semaste/// locate additional sections within the file. 59254721Semastestruct ELFHeader 60254721Semaste{ 61254721Semaste unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification. 62254721Semaste elf_addr e_entry; ///< Virtual address program entry point. 63254721Semaste elf_off e_phoff; ///< File offset of program header table. 64254721Semaste elf_off e_shoff; ///< File offset of section header table. 65254721Semaste elf_word e_flags; ///< Processor specific flags. 66254721Semaste elf_word e_version; ///< Version of object file (always 1). 67254721Semaste elf_half e_type; ///< Object file type. 68254721Semaste elf_half e_machine; ///< Target architecture. 69254721Semaste elf_half e_ehsize; ///< Byte size of the ELF header. 70254721Semaste elf_half e_phentsize; ///< Size of a program header table entry. 71254721Semaste elf_half e_phnum; ///< Number of program header entries. 72254721Semaste elf_half e_shentsize; ///< Size of a section header table entry. 73254721Semaste elf_half e_shnum; ///< Number of section header entries. 74254721Semaste elf_half e_shstrndx; ///< String table section index. 75254721Semaste 76254721Semaste ELFHeader(); 77254721Semaste 78254721Semaste //-------------------------------------------------------------------------- 79254721Semaste /// Returns true if this is a 32 bit ELF file header. 80254721Semaste /// 81254721Semaste /// @return 82254721Semaste /// True if this is a 32 bit ELF file header. 83254721Semaste bool Is32Bit() const { 84254721Semaste return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32; 85254721Semaste } 86254721Semaste 87254721Semaste //-------------------------------------------------------------------------- 88254721Semaste /// Returns true if this is a 64 bit ELF file header. 89254721Semaste /// 90254721Semaste /// @return 91254721Semaste /// True if this is a 64 bit ELF file header. 92254721Semaste bool Is64Bit() const { 93254721Semaste return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; 94254721Semaste } 95254721Semaste 96254721Semaste //-------------------------------------------------------------------------- 97254721Semaste /// The byte order of this ELF file header. 98254721Semaste /// 99254721Semaste /// @return 100254721Semaste /// The byte order of this ELF file as described by the header. 101254721Semaste lldb::ByteOrder 102254721Semaste GetByteOrder() const; 103254721Semaste 104254721Semaste //-------------------------------------------------------------------------- 105254721Semaste /// The jump slot relocation type of this ELF. 106254721Semaste unsigned 107254721Semaste GetRelocationJumpSlotType() const; 108254721Semaste 109254721Semaste //-------------------------------------------------------------------------- 110254721Semaste /// Parse an ELFHeader entry starting at position \p offset and 111254721Semaste /// update the data extractor with the address size and byte order 112254721Semaste /// attributes as defined by the header. 113254721Semaste /// 114254721Semaste /// @param[in,out] data 115254721Semaste /// The DataExtractor to read from. Updated with the address size and 116254721Semaste /// byte order attributes appropriate to this header. 117254721Semaste /// 118254721Semaste /// @param[in,out] offset 119254721Semaste /// Pointer to an offset in the data. On return the offset will be 120254721Semaste /// advanced by the number of bytes read. 121254721Semaste /// 122254721Semaste /// @return 123254721Semaste /// True if the ELFHeader was successfully read and false 124254721Semaste /// otherwise. 125254721Semaste bool 126254721Semaste Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); 127254721Semaste 128254721Semaste //-------------------------------------------------------------------------- 129254721Semaste /// Examines at most EI_NIDENT bytes starting from the given pointer and 130254721Semaste /// determines if the magic ELF identification exists. 131254721Semaste /// 132254721Semaste /// @return 133254721Semaste /// True if the given sequence of bytes identifies an ELF file. 134254721Semaste static bool 135254721Semaste MagicBytesMatch(const uint8_t *magic); 136254721Semaste 137254721Semaste //-------------------------------------------------------------------------- 138254721Semaste /// Examines at most EI_NIDENT bytes starting from the given address and 139254721Semaste /// determines the address size of the underlying ELF file. This function 140254721Semaste /// should only be called on an pointer for which MagicBytesMatch returns 141254721Semaste /// true. 142254721Semaste /// 143254721Semaste /// @return 144254721Semaste /// The number of bytes forming an address in the ELF file (either 4 or 145254721Semaste /// 8), else zero if the address size could not be determined. 146254721Semaste static unsigned 147254721Semaste AddressSizeInBytes(const uint8_t *magic); 148254721Semaste}; 149254721Semaste 150254721Semaste//------------------------------------------------------------------------------ 151254721Semaste/// @class ELFSectionHeader 152254721Semaste/// @brief Generic representation of an ELF section header. 153254721Semastestruct ELFSectionHeader 154254721Semaste{ 155254721Semaste elf_word sh_name; ///< Section name string index. 156254721Semaste elf_word sh_type; ///< Section type. 157254721Semaste elf_xword sh_flags; ///< Section attributes. 158254721Semaste elf_addr sh_addr; ///< Virtual address of the section in memory. 159254721Semaste elf_off sh_offset; ///< Start of section from beginning of file. 160254721Semaste elf_xword sh_size; ///< Number of bytes occupied in the file. 161254721Semaste elf_word sh_link; ///< Index of associated section. 162254721Semaste elf_word sh_info; ///< Extra section info (overloaded). 163254721Semaste elf_xword sh_addralign; ///< Power of two alignment constraint. 164254721Semaste elf_xword sh_entsize; ///< Byte size of each section entry. 165254721Semaste 166254721Semaste ELFSectionHeader(); 167254721Semaste 168254721Semaste //-------------------------------------------------------------------------- 169254721Semaste /// Parse an ELFSectionHeader entry from the given DataExtracter starting at 170254721Semaste /// position \p offset. 171254721Semaste /// 172254721Semaste /// @param[in] data 173254721Semaste /// The DataExtractor to read from. The address size of the extractor 174254721Semaste /// determines if a 32 or 64 bit object should be read. 175254721Semaste /// 176254721Semaste /// @param[in,out] offset 177254721Semaste /// Pointer to an offset in the data. On return the offset will be 178254721Semaste /// advanced by the number of bytes read. 179254721Semaste /// 180254721Semaste /// @return 181254721Semaste /// True if the ELFSectionHeader was successfully read and false 182254721Semaste /// otherwise. 183254721Semaste bool 184254721Semaste Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 185254721Semaste}; 186254721Semaste 187254721Semaste//------------------------------------------------------------------------------ 188254721Semaste/// @class ELFProgramHeader 189254721Semaste/// @brief Generic representation of an ELF program header. 190254721Semastestruct ELFProgramHeader 191254721Semaste{ 192254721Semaste elf_word p_type; ///< Type of program segment. 193254721Semaste elf_word p_flags; ///< Segment attributes. 194254721Semaste elf_off p_offset; ///< Start of segment from beginning of file. 195254721Semaste elf_addr p_vaddr; ///< Virtual address of segment in memory. 196254721Semaste elf_addr p_paddr; ///< Physical address (for non-VM systems). 197254721Semaste elf_xword p_filesz; ///< Byte size of the segment in file. 198254721Semaste elf_xword p_memsz; ///< Byte size of the segment in memory. 199254721Semaste elf_xword p_align; ///< Segment alignment constraint. 200254721Semaste 201254721Semaste ELFProgramHeader(); 202254721Semaste 203254721Semaste /// Parse an ELFProgramHeader entry from the given DataExtractor starting at 204254721Semaste /// position \p offset. The address size of the DataExtractor determines if 205254721Semaste /// a 32 or 64 bit object is to be parsed. 206254721Semaste /// 207254721Semaste /// @param[in] data 208254721Semaste /// The DataExtractor to read from. The address size of the extractor 209254721Semaste /// determines if a 32 or 64 bit object should be read. 210254721Semaste /// 211254721Semaste /// @param[in,out] offset 212254721Semaste /// Pointer to an offset in the data. On return the offset will be 213254721Semaste /// advanced by the number of bytes read. 214254721Semaste /// 215254721Semaste /// @return 216254721Semaste /// True if the ELFProgramHeader was successfully read and false 217254721Semaste /// otherwise. 218254721Semaste bool 219254721Semaste Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 220254721Semaste}; 221254721Semaste 222254721Semaste//------------------------------------------------------------------------------ 223254721Semaste/// @class ELFSymbol 224254721Semaste/// @brief Represents a symbol within an ELF symbol table. 225254721Semastestruct ELFSymbol 226254721Semaste{ 227254721Semaste elf_addr st_value; ///< Absolute or relocatable address. 228254721Semaste elf_xword st_size; ///< Size of the symbol or zero. 229254721Semaste elf_word st_name; ///< Symbol name string index. 230254721Semaste unsigned char st_info; ///< Symbol type and binding attributes. 231254721Semaste unsigned char st_other; ///< Reserved for future use. 232254721Semaste elf_half st_shndx; ///< Section to which this symbol applies. 233254721Semaste 234254721Semaste ELFSymbol(); 235254721Semaste 236254721Semaste /// Returns the binding attribute of the st_info member. 237254721Semaste unsigned char getBinding() const { return st_info >> 4; } 238254721Semaste 239254721Semaste /// Returns the type attribute of the st_info member. 240254721Semaste unsigned char getType() const { return st_info & 0x0F; } 241254721Semaste 242254721Semaste /// Sets the binding and type of the st_info member. 243254721Semaste void setBindingAndType(unsigned char binding, unsigned char type) { 244254721Semaste st_info = (binding << 4) + (type & 0x0F); 245254721Semaste } 246254721Semaste 247254721Semaste static const char * 248254721Semaste bindingToCString(unsigned char binding); 249254721Semaste 250254721Semaste static const char * 251254721Semaste typeToCString(unsigned char type); 252254721Semaste 253254721Semaste static const char * 254254721Semaste sectionIndexToCString(elf_half shndx, 255254721Semaste const lldb_private::SectionList *section_list); 256254721Semaste 257254721Semaste /// Parse an ELFSymbol entry from the given DataExtractor starting at 258254721Semaste /// position \p offset. The address size of the DataExtractor determines if 259254721Semaste /// a 32 or 64 bit object is to be parsed. 260254721Semaste /// 261254721Semaste /// @param[in] data 262254721Semaste /// The DataExtractor to read from. The address size of the extractor 263254721Semaste /// determines if a 32 or 64 bit object should be read. 264254721Semaste /// 265254721Semaste /// @param[in,out] offset 266254721Semaste /// Pointer to an offset in the data. On return the offset will be 267254721Semaste /// advanced by the number of bytes read. 268254721Semaste /// 269254721Semaste /// @return 270254721Semaste /// True if the ELFSymbol was successfully read and false otherwise. 271254721Semaste bool 272254721Semaste Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 273254721Semaste 274254721Semaste void 275254721Semaste Dump (lldb_private::Stream *s, 276254721Semaste uint32_t idx, 277254721Semaste const lldb_private::DataExtractor *strtab_data, 278254721Semaste const lldb_private::SectionList *section_list); 279254721Semaste}; 280254721Semaste 281254721Semaste//------------------------------------------------------------------------------ 282254721Semaste/// @class ELFDynamic 283254721Semaste/// @brief Represents an entry in an ELF dynamic table. 284254721Semastestruct ELFDynamic 285254721Semaste{ 286254721Semaste elf_sxword d_tag; ///< Type of dynamic table entry. 287254721Semaste union 288254721Semaste { 289254721Semaste elf_xword d_val; ///< Integer value of the table entry. 290254721Semaste elf_addr d_ptr; ///< Pointer value of the table entry. 291254721Semaste }; 292254721Semaste 293254721Semaste ELFDynamic(); 294254721Semaste 295254721Semaste /// Parse an ELFDynamic entry from the given DataExtractor starting at 296254721Semaste /// position \p offset. The address size of the DataExtractor determines if 297254721Semaste /// a 32 or 64 bit object is to be parsed. 298254721Semaste /// 299254721Semaste /// @param[in] data 300254721Semaste /// The DataExtractor to read from. The address size of the extractor 301254721Semaste /// determines if a 32 or 64 bit object should be read. 302254721Semaste /// 303254721Semaste /// @param[in,out] offset 304254721Semaste /// Pointer to an offset in the data. On return the offset will be 305254721Semaste /// advanced by the number of bytes read. 306254721Semaste /// 307254721Semaste /// @return 308254721Semaste /// True if the ELFDynamic entry was successfully read and false 309254721Semaste /// otherwise. 310254721Semaste bool 311254721Semaste Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 312254721Semaste}; 313254721Semaste 314254721Semaste//------------------------------------------------------------------------------ 315254721Semaste/// @class ELFRel 316254721Semaste/// @brief Represents a relocation entry with an implicit addend. 317254721Semastestruct ELFRel 318254721Semaste{ 319254721Semaste elf_addr r_offset; ///< Address of reference. 320254721Semaste elf_xword r_info; ///< symbol index and type of relocation. 321254721Semaste 322254721Semaste ELFRel(); 323254721Semaste 324254721Semaste /// Parse an ELFRel entry from the given DataExtractor starting at position 325254721Semaste /// \p offset. The address size of the DataExtractor determines if a 32 or 326254721Semaste /// 64 bit object is to be parsed. 327254721Semaste /// 328254721Semaste /// @param[in] data 329254721Semaste /// The DataExtractor to read from. The address size of the extractor 330254721Semaste /// determines if a 32 or 64 bit object should be read. 331254721Semaste /// 332254721Semaste /// @param[in,out] offset 333254721Semaste /// Pointer to an offset in the data. On return the offset will be 334254721Semaste /// advanced by the number of bytes read. 335254721Semaste /// 336254721Semaste /// @return 337254721Semaste /// True if the ELFRel entry was successfully read and false otherwise. 338254721Semaste bool 339254721Semaste Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 340254721Semaste 341254721Semaste /// Returns the type when the given entry represents a 32-bit relocation. 342254721Semaste static unsigned 343254721Semaste RelocType32(const ELFRel &rel) 344254721Semaste { 345254721Semaste return rel.r_info & 0x0ff; 346254721Semaste } 347254721Semaste 348254721Semaste /// Returns the type when the given entry represents a 64-bit relocation. 349254721Semaste static unsigned 350254721Semaste RelocType64(const ELFRel &rel) 351254721Semaste { 352254721Semaste return rel.r_info & 0xffffffff; 353254721Semaste } 354254721Semaste 355254721Semaste /// Returns the symbol index when the given entry represents a 32-bit 356254721Semaste /// reloction. 357254721Semaste static unsigned 358254721Semaste RelocSymbol32(const ELFRel &rel) 359254721Semaste { 360254721Semaste return rel.r_info >> 8; 361254721Semaste } 362254721Semaste 363254721Semaste /// Returns the symbol index when the given entry represents a 64-bit 364254721Semaste /// reloction. 365254721Semaste static unsigned 366254721Semaste RelocSymbol64(const ELFRel &rel) 367254721Semaste { 368254721Semaste return rel.r_info >> 32; 369254721Semaste } 370254721Semaste}; 371254721Semaste 372254721Semaste//------------------------------------------------------------------------------ 373254721Semaste/// @class ELFRela 374254721Semaste/// @brief Represents a relocation entry with an explicit addend. 375254721Semastestruct ELFRela 376254721Semaste{ 377254721Semaste elf_addr r_offset; ///< Address of reference. 378254721Semaste elf_xword r_info; ///< Symbol index and type of relocation. 379254721Semaste elf_sxword r_addend; ///< Constant part of expression. 380254721Semaste 381254721Semaste ELFRela(); 382254721Semaste 383254721Semaste /// Parse an ELFRela entry from the given DataExtractor starting at position 384254721Semaste /// \p offset. The address size of the DataExtractor determines if a 32 or 385254721Semaste /// 64 bit object is to be parsed. 386254721Semaste /// 387254721Semaste /// @param[in] data 388254721Semaste /// The DataExtractor to read from. The address size of the extractor 389254721Semaste /// determines if a 32 or 64 bit object should be read. 390254721Semaste /// 391254721Semaste /// @param[in,out] offset 392254721Semaste /// Pointer to an offset in the data. On return the offset will be 393254721Semaste /// advanced by the number of bytes read. 394254721Semaste /// 395254721Semaste /// @return 396254721Semaste /// True if the ELFRela entry was successfully read and false otherwise. 397254721Semaste bool 398254721Semaste Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 399254721Semaste 400254721Semaste /// Returns the type when the given entry represents a 32-bit relocation. 401254721Semaste static unsigned 402254721Semaste RelocType32(const ELFRela &rela) 403254721Semaste { 404254721Semaste return rela.r_info & 0x0ff; 405254721Semaste } 406254721Semaste 407254721Semaste /// Returns the type when the given entry represents a 64-bit relocation. 408254721Semaste static unsigned 409254721Semaste RelocType64(const ELFRela &rela) 410254721Semaste { 411254721Semaste return rela.r_info & 0xffffffff; 412254721Semaste } 413254721Semaste 414254721Semaste /// Returns the symbol index when the given entry represents a 32-bit 415254721Semaste /// reloction. 416254721Semaste static unsigned 417254721Semaste RelocSymbol32(const ELFRela &rela) 418254721Semaste { 419254721Semaste return rela.r_info >> 8; 420254721Semaste } 421254721Semaste 422254721Semaste /// Returns the symbol index when the given entry represents a 64-bit 423254721Semaste /// reloction. 424254721Semaste static unsigned 425254721Semaste RelocSymbol64(const ELFRela &rela) 426254721Semaste { 427254721Semaste return rela.r_info >> 32; 428254721Semaste } 429254721Semaste}; 430254721Semaste 431254721Semaste} // End namespace elf. 432254721Semaste 433254721Semaste#endif // #ifndef liblldb_ELFHeader_h_ 434