diff options
author | Etienne Pierre-Doray <etiennep@chromium.org> | 2018-07-25 20:16:02 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-07-25 20:33:17 -0700 |
commit | a88cad0485f1c73d63ba0a1bcfccc8a68bd300c6 (patch) | |
tree | a1e2e0302064526dd50280e84651979b656f0ad2 /type_elf.h | |
parent | ae27d8ed0116c53fb530b141e96df91e90c3671c (diff) | |
download | zucchini-a88cad0485f1c73d63ba0a1bcfccc8a68bd300c6.tar.gz |
[Zucchini] Create elf types and utils.
Creates types and utility class to manipulate ELF header format and relocation
references.
BufferView: :modify() was also added.
Change-Id: Iacec212a2fb2f8a6c85d551eed4b8e0a84926d89
Reviewed-on: https://chromium-review.googlesource.com/1136846
Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org>
Reviewed-by: Greg Thompson <grt@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578034}
NOKEYCHECK=True
GitOrigin-RevId: 320f7d9d2cff9702e632af296867bf6ce7b14f8b
Diffstat (limited to 'type_elf.h')
-rw-r--r-- | type_elf.h | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/type_elf.h b/type_elf.h new file mode 100644 index 0000000..99dcba2 --- /dev/null +++ b/type_elf.h @@ -0,0 +1,252 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ZUCCHINI_TYPE_ELF_H_ +#define COMPONENTS_ZUCCHINI_TYPE_ELF_H_ + +#include <stdint.h> + +namespace zucchini { + +// Structures and constants taken from linux/elf.h and following identical +// layout. This is used for parsing of Executable and Linkable Format (ELF). +namespace elf { +// Supported by MSVC, g++, and clang++. Ensures no gaps in packing. +#pragma pack(push, 1) + +// This header defines various types from the ELF file spec, but no code +// related to using them. + +typedef uint32_t Elf32_Addr; // Unsigned program address. +typedef uint16_t Elf32_Half; // Unsigned medium integer. +typedef uint32_t Elf32_Off; // Unsigned file offset. +typedef int32_t Elf32_Sword; // Signed large integer. +typedef uint32_t Elf32_Word; // Unsigned large integer. + +typedef uint64_t Elf64_Addr; // Unsigned program address. +typedef uint16_t Elf64_Half; // Unsigned medium integer. +typedef uint64_t Elf64_Off; // Unsigned file offset. +typedef int32_t Elf64_Sword; // Signed large integer. +typedef uint32_t Elf64_Word; // Unsigned large integer. +typedef int64_t Elf64_Sxword; // Signed extra large integer. +typedef uint64_t Elf64_Xword; // Unsigned extra large integer. + +// The header at the top of the file. +struct Elf32_Ehdr { + unsigned char e_ident[16]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +}; + +struct Elf64_Ehdr { + unsigned char e_ident[16]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +}; + +// Values for header->e_type. +enum e_type_values { + ET_NONE = 0, // No file type + ET_REL = 1, // Relocatable file + ET_EXEC = 2, // Executable file + ET_DYN = 3, // Shared object file + ET_CORE = 4, // Core file + ET_LOPROC = 0xFF00, // Processor-specific + ET_HIPROC = 0xFFFF // Processor-specific +}; + +// Values for header->e_machine. +enum e_machine_values { + EM_NONE = 0, // No machine. + EM_386 = 3, // Intel Architecture. + EM_ARM = 40, // ARM Architecture. + EM_X86_64 = 62, // Intel x86-64 Architecture. + EM_AARCH64 = 183, // ARM Architecture, 64-bit. + // Other values skipped. +}; + +// A section header in the section header table. +struct Elf32_Shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +}; + +struct Elf64_Shdr { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +}; + +// Values for the section type field in a section header. +enum sh_type_values { + SHT_NULL = 0, + SHT_PROGBITS = 1, + SHT_SYMTAB = 2, + SHT_STRTAB = 3, + SHT_RELA = 4, + SHT_HASH = 5, + SHT_DYNAMIC = 6, + SHT_NOTE = 7, + SHT_NOBITS = 8, + SHT_REL = 9, + SHT_SHLIB = 10, + SHT_DYNSYM = 11, + SHT_INIT_ARRAY = 14, + SHT_FINI_ARRAY = 15, + SHT_LOPROC = 0x70000000, + SHT_HIPROC = 0x7FFFFFFF, + SHT_LOUSER = 0x80000000, + SHT_HIUSER = 0xFFFFFFFF +}; + +enum sh_flag_masks { + SHF_WRITE = 1 << 0, + SHF_ALLOC = 1 << 1, + SHF_EXECINSTR = 1 << 2, +}; + +struct Elf32_Phdr { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +}; + +struct Elf64_Phdr { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +}; + +// Values for the segment type field in a program segment header. +enum ph_type_values { + PT_NULL = 0, + PT_LOAD = 1, + PT_DYNAMIC = 2, + PT_INTERP = 3, + PT_NOTE = 4, + PT_SHLIB = 5, + PT_PHDR = 6, + PT_LOPROC = 0x70000000, + PT_HIPROC = 0x7FFFFFFF +}; + +struct Elf32_Rel { + Elf32_Addr r_offset; + Elf32_Word r_info; +}; + +struct Elf64_Rel { + Elf64_Addr r_offset; + Elf64_Xword r_info; +}; + +struct Elf32_Rela { + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +}; + +struct Elf64_Rela { + Elf64_Addr r_offset; + Elf64_Xword r_info; + Elf64_Sxword r_addend; +}; + +enum elf32_rel_386_type_values { + R_386_NONE = 0, + R_386_32 = 1, + R_386_PC32 = 2, + R_386_GOT32 = 3, + R_386_PLT32 = 4, + R_386_COPY = 5, + R_386_GLOB_DAT = 6, + R_386_JMP_SLOT = 7, + R_386_RELATIVE = 8, + R_386_GOTOFF = 9, + R_386_GOTPC = 10, + R_386_TLS_TPOFF = 14, +}; + +enum elf32_rel_x86_64_type_values { + R_X86_64_NONE = 0, + R_X86_64_64 = 1, + R_X86_64_PC32 = 2, + R_X86_64_GOT32 = 3, + R_X86_64_PLT32 = 4, + R_X86_64_COPY = 5, + R_X86_64_GLOB_DAT = 6, + R_X86_64_JUMP_SLOT = 7, + R_X86_64_RELATIVE = 8, + R_X86_64_GOTPCREL = 9, + R_X86_64_32 = 10, + R_X86_64_32S = 11, + R_X86_64_16 = 12, + R_X86_64_PC16 = 13, + R_X86_64_8 = 14, + R_X86_64_PC8 = 15, +}; + +enum elf32_rel_arm_type_values { + R_ARM_RELATIVE = 23, +}; + +enum elf64_rel_aarch64_type_values { + R_AARCH64_GLOB_DAT = 0x401, + R_AARCH64_JUMP_SLOT = 0x402, + R_AARCH64_RELATIVE = 0x403, +}; + +#pragma pack(pop) + +} // namespace elf +} // namespace zucchini + +#endif // COMPONENTS_ZUCCHINI_TYPE_ELF_H_ |