Bring ELF64 on par with ELF32, add a few magic constants and support ".dynamic"

section entries.

llvm-svn: 108221
This commit is contained in:
Stephen Wilson 2010-07-13 00:24:59 +00:00
parent 0a34e31d81
commit 08d1c71c94
1 changed files with 123 additions and 11 deletions

View File

@ -10,11 +10,10 @@
// This header contains common, non-processor-specific data structures and
// constants for the ELF file format.
//
// The details of the ELF32 bits in this file are largely based on
// the Tool Interface Standard (TIS) Executable and Linking Format
// (ELF) Specification Version 1.2, May 1995. The ELF64 stuff is not
// standardized, as far as I can tell. It was largely based on information
// I found in OpenBSD header files.
// The details of the ELF32 bits in this file are largely based on the Tool
// Interface Standard (TIS) Executable and Linking Format (ELF) Specification
// Version 1.2, May 1995. The ELF64 stuff is based on ELF-64 Object File Format
// Version 1.5, Draft 2, May 1998 as well as OpenBSD header files.
//
//===----------------------------------------------------------------------===//
@ -47,8 +46,23 @@ typedef uint16_t Elf64_Quarter;
// Object file magic string.
static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
// e_ident size and indices.
enum {
EI_MAG0 = 0, // File identification index.
EI_MAG1 = 1, // File identification index.
EI_MAG2 = 2, // File identification index.
EI_MAG3 = 3, // File identification index.
EI_CLASS = 4, // File class.
EI_DATA = 5, // Data encoding.
EI_VERSION = 6, // File version.
EI_OSABI = 7, // OS/ABI identification.
EI_ABIVERSION = 8, // ABI version.
EI_PAD = 9, // Start of padding bytes.
EI_NIDENT = 16 // Number of bytes in e_ident.
};
struct Elf32_Ehdr {
unsigned char e_ident[16]; // ELF Identification bytes
unsigned char e_ident[EI_NIDENT]; // ELF Identification bytes
Elf32_Half e_type; // Type of file (see ET_* below)
Elf32_Half e_machine; // Required architecture for this file (see EM_*)
Elf32_Word e_version; // Must be equal to 1
@ -65,14 +79,14 @@ struct Elf32_Ehdr {
bool checkMagic() const {
return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
}
unsigned char getFileClass() const { return e_ident[4]; }
unsigned char getDataEncoding() { return e_ident[5]; }
unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
};
// 64-bit ELF header. Fields are the same as for ELF32, but with different
// types (see above).
struct Elf64_Ehdr {
unsigned char e_ident[16];
unsigned char e_ident[EI_NIDENT];
Elf64_Quarter e_type;
Elf64_Quarter e_machine;
Elf64_Half e_version;
@ -86,6 +100,11 @@ struct Elf64_Ehdr {
Elf64_Quarter e_shentsize;
Elf64_Quarter e_shnum;
Elf64_Quarter e_shstrndx;
bool checkMagic() const {
return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
}
unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
};
// File types
@ -117,6 +136,7 @@ enum {
EM_860 = 7, // Intel 80860
EM_MIPS = 8, // MIPS R3000
EM_PPC = 20, // PowerPC
EM_PPC64 = 21, // PowerPC64
EM_ARM = 40, // ARM
EM_ALPHA = 41, // DEC Alpha
EM_SPARCV9 = 43, // SPARC V9
@ -131,6 +151,7 @@ enum {
// Object file byte orderings.
enum {
ELFDATANONE = 0, // Invalid data encoding.
ELFDATA2LSB = 1, // Little-endian object file
ELFDATA2MSB = 2 // Big-endian object file
};
@ -262,7 +283,7 @@ enum {
SHF_MASKPROC = 0xf0000000 // Bits indicating processor-specific flags.
};
// Symbol table entries.
// Symbol table entries for ELF32.
struct Elf32_Sym {
Elf32_Word st_name; // Symbol name (index into string table)
Elf32_Addr st_value; // Value or address associated with the symbol
@ -282,6 +303,26 @@ struct Elf32_Sym {
}
};
// Symbol table entries for ELF64.
struct Elf64_Sym {
Elf64_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
Elf64_Half st_shndx; // Which section (header table index) it's defined in
Elf64_Addr st_value; // Value or address associated with the symbol
Elf64_Xword st_size; // Size of the symbol
// These accessors and mutators are identical to those defined for ELF32
// symbol table entries.
unsigned char getBinding() const { return st_info >> 4; }
unsigned char getType() const { return st_info & 0x0f; }
void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
void setBindingAndType(unsigned char b, unsigned char t) {
st_info = (b << 4) + (t & 0x0f);
}
};
// Symbol bindings.
enum {
STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def
@ -372,7 +413,7 @@ struct Elf64_Rela {
};
};
// Program header.
// Program header for ELF32.
struct Elf32_Phdr {
Elf32_Word p_type; // Type of segment
Elf32_Off p_offset; // File offset where segment is located, in bytes
@ -384,6 +425,18 @@ struct Elf32_Phdr {
Elf32_Word p_align; // Segment alignment constraint
};
// Program header for ELF64.
struct Elf64_Phdr {
Elf64_Word p_type; // Type of segment
Elf64_Word p_flags; // Segment flags
Elf64_Off p_offset; // File offset where segment is located, in bytes
Elf64_Addr p_vaddr; // Virtual address of beginning of segment
Elf64_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
Elf64_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
Elf64_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
Elf64_Xword p_align; // Segment alignment constraint
};
// Segment types.
enum {
PT_NULL = 0, // Unused segment.
@ -405,6 +458,65 @@ enum {
PF_MASKPROC = 0xf0000000 // Unspecified
};
// Dynamic table entry for ELF32.
struct Elf32_Dyn
{
Elf32_Sword d_tag; // Type of dynamic table entry.
union
{
Elf32_Word d_val; // Integer value of entry.
Elf32_Addr d_ptr; // Pointer value of entry.
} d_un;
};
// Dynamic table entry for ELF64.
struct Elf64_Dyn
{
Elf64_Sxword d_tag; // Type of dynamic table entry.
union
{
Elf64_Xword d_val; // Integer value of entry.
Elf64_Addr d_ptr; // Pointer value of entry.
} d_un;
};
// Dynamic table entry tags.
enum {
DT_NULL = 0, // Marks end of dynamic array.
DT_NEEDED = 1, // String table offset of needed library.
DT_PLTRELSZ = 2, // Size of relocation entries in PLT.
DT_PLTGOT = 3, // Address associated with linkage table.
DT_HASH = 4, // Address of symbolic hash table.
DT_STRTAB = 5, // Address of dynamic string table.
DT_SYMTAB = 6, // Address of dynamic symbol table.
DT_RELA = 7, // Address of relocation table (Rela entries).
DT_RELASZ = 8, // Size of Rela relocation table.
DT_RELAENT = 9, // Size of a Rela relocation entry.
DT_STRSZ = 10, // Total size of the string table.
DT_SYMENT = 11, // Size of a symbol table entry.
DT_INIT = 12, // Address of initialization function.
DT_FINI = 13, // Address of termination function.
DT_SONAME = 14, // String table offset of a shared objects name.
DT_RPATH = 15, // String table offset of library search path.
DT_SYMBOLIC = 16, // Changes symbol resolution algorithm.
DT_REL = 17, // Address of relocation table (Rel entries).
DT_RELSZ = 18, // Size of Rel relocation table.
DT_RELENT = 19, // Size of a Rel relocation entry.
DT_PLTREL = 20, // Type of relocation entry used for linking.
DT_DEBUG = 21, // Reserved for debugger.
DT_TEXTREL = 22, // Relocations exist for non-writable segements.
DT_JMPREL = 23, // Address of relocations associated with PLT.
DT_BIND_NOW = 24, // Process all relocations before execution.
DT_INIT_ARRAY = 25, // Pointer to array of initialization functions.
DT_FINI_ARRAY = 26, // Pointer to array of termination functions.
DT_INIT_ARRAYSZ = 27, // Size of DT_INIT_ARRAY.
DT_FINI_ARRAYSZ = 28, // Size of DT_FINI_ARRAY.
DT_LOOS = 0x60000000, // Start of environment specific tags.
DT_HIOS = 0x6FFFFFFF, // End of environment specific tags.
DT_LOPROC = 0x70000000, // Start of processor specific tags.
DT_HIPROC = 0x7FFFFFFF // End of processor specific tags.
};
} // end namespace ELF
} // end namespace llvm