commit 6a366634ac8c865bc1504ded613c9c95b49bb5a7 Author: David du Colombier <0intro@gmail.com> Date: Mon Nov 21 22:11:53 2016 +0100 initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a686df6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 David du Colombier + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0bfabf8 --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +AR?=ar +AS?=as +RANLIB?=ranlib +CC?=gcc +LD?=gcc +CFLAGS?=-Wall -Wextra -c -I./libbele -O3 +LDFLAGS?= + +LIB=libelf.a + +OFILES=\ + elf.o\ + machines.o\ + print.o\ + +HFILES=\ + dat.h\ + elf.h\ + fns.h\ + +default: deps $(LIB) +$(LIB): $(OFILES) $(HFILES) + $(AR) r $(LIB) $(OFILES) + $(RANLIB) $(LIB) + +deps: + git clone -q https://github.com/0intro/libbele + +cleandeps: + rm -rf libbele + +%.o: %.c + $(CC) $(CFLAGS) $*.c + +clean: + rm -f *.o + +nuke: clean cleandeps + rm -f $(LIB) diff --git a/README.md b/README.md new file mode 100644 index 0000000..6366aa6 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +[![Build Status](https://drone.io/github.com/0intro/libelf/status.png)](https://drone.io/github.com/0intro/libelf/latest) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/0intro-libelf/badge.svg)](https://scan.coverity.com/projects/0intro-libelf) + +libelf +====== + +Libelf is a simple library which provides functions to read ELF files. + +Headers +------- + +``` +#include +#include +``` + +Structures +---------- + +``` +typedef struct Fhdr Fhdr; + +/* + * Portable ELF file header + */ +struct Fhdr { + /* Private */ + ... + + /* ELF Header */ + uint64_t phoff; + uint64_t shoff; + uint16_t ehsize; /* ELF Header size */ + uint16_t phentsize; /* Section Header size */ + uint16_t phnum; + uint16_t shentsize; /* Program Header size */ + uint16_t shnum; + uint16_t shstrndx; + + /* Section Header */ + uint32_t name; + uint64_t offset; + uint64_t size; + + /* String Table */ + uint32_t strndxsize; /* String Table Size */ + uint8_t *strndx; /* Copy of String Table */ +}; +``` + +Functions +--------- + +``` +int readelf(FILE *f, Fhdr *fp); +uint8_t* readelfsection(FILE *f, char *name, uint64_t *size, Fhdr *fp); +void freeelf(Fhdr *fp); +``` + +Example +------- + +``` +Fhdr fhdr; +FILE *f; +uint8_t *buf; +uint64_t len; + +f = fopen("/bin/ls", "rb"); +if (f == NULL) + return -1; + +buf = readelfsection(f, ".text", &len, &fhdr); +if (buf == NULL) + return -1; + +// ... + +freeelf(&fhdr); +``` diff --git a/dat.h b/dat.h new file mode 100644 index 0000000..0f39f2e --- /dev/null +++ b/dat.h @@ -0,0 +1,438 @@ +#define USED(x) if(x){}else{} +#define nelem(x) (sizeof(x)/sizeof((x)[0])) + +extern char *machines[]; + +#define EI_NIDENT 16 + +enum { + Eh32sz = 52, + Sh32sz = 40, + Ph32sz = 32, + Eh64sz = 64, + Sh64sz = 64, + Ph64sz = 56, +}; + +/* + * ELF32 Header + */ +typedef struct { + uint8_t ident[EI_NIDENT]; + uint16_t type; + uint16_t machine; + uint32_t version; + uint32_t entry; + uint32_t phoff; + uint32_t shoff; + uint32_t flags; + uint16_t ehsize; + uint16_t phentsize; + uint16_t phnum; + uint16_t shentsize; + uint16_t shnum; + uint16_t shstrndx; +} Elf32_Ehdr; + +/* + * ELF64 Header + */ +typedef struct { + uint8_t ident[EI_NIDENT]; + uint16_t type; + uint16_t machine; + uint32_t version; + uint64_t entry; + uint64_t phoff; + uint64_t shoff; + uint32_t flags; + uint16_t ehsize; + uint16_t phentsize; + uint16_t phnum; + uint16_t shentsize; + uint16_t shnum; + uint16_t shstrndx; +} Elf64_Ehdr; + +/* + * ELF32 Section Header + */ +typedef struct { + uint32_t name; + uint32_t type; + uint32_t flags; + uint32_t addr; + uint32_t offset; + uint32_t size; + uint32_t link; + uint32_t info; + uint32_t addralign; + uint32_t entsize; +} Elf32_Shdr; + +/* + * ELF64 Section Header + */ +typedef struct { + uint32_t name; + uint32_t type; + uint64_t flags; + uint64_t addr; + uint64_t offset; + uint64_t size; + uint32_t link; + uint32_t info; + uint64_t addralign; + uint64_t entsize; +} Elf64_Shdr; + +/* + * ELF32 Program Header + */ +typedef struct { + uint32_t type; + uint32_t offset; + uint32_t vaddr; + uint32_t paddr; + uint32_t filesz; + uint32_t memsz; + uint32_t flags; + uint32_t align; +} Elf32_Phdr; + +/* + * ELF64 Program Header + */ +typedef struct { + uint32_t type; + uint32_t flags; + uint64_t offset; + uint64_t vaddr; + uint64_t paddr; + uint64_t filesz; + uint64_t memsz; + uint64_t align; +} Elf64_Phdr; + +/* + * Object file type + */ +enum { + 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_LOOS = 0xfe00, /* Operating system-specific */ + ET_HIOS = 0xfeff, /* Operating system-specific */ + ET_LOPROC = 0xff00, /* Processor-specific */ + ET_HIPROC = 0xffff, /* Processor-specific */ +}; + +/* + * Architectures + */ +enum { + EM_NONE = 0, /* No machine */ + EM_M32 = 1, /* AT&T WE 32100 */ + EM_SPARC = 2, /* SPARC */ + EM_386 = 3, /* Intel 80386 */ + EM_68K = 4, /* Motorola 68000 */ + EM_88K = 5, /* Motorola 88000 */ + EM_IAMCU = 6, /* Intel MCU */ + EM_860 = 7, /* Intel 80860 */ + EM_MIPS = 8, /* MIPS I Architecture */ + EM_S370 = 9, /* IBM System/370 Processor */ + EM_MIPS_RS3_LE = 10, /* MIPS RS3000 Little-endian */ + /* 11-14 Reserved for future use */ + EM_PARISC = 15, /* Hewlett-Packard PA-RISC */ + reserved = 16, /* Reserved for future use */ + EM_VPP500 = 17, /* Fujitsu VPP500 */ + EM_SPARC32PLUS = 18, /* Enhanced instruction set SPARC */ + EM_960 = 19, /* Intel 80960 */ + EM_PPC = 20, /* PowerPC */ + EM_PPC64 = 21, /* 64-bit PowerPC */ + EM_S390 = 22, /* IBM System/390 Processor */ + EM_SPU = 23, /* IBM SPU/SPC */ + /* 24-35 Reserved for future use */ + EM_V800 = 36, /* NEC V800 */ + EM_FR20 = 37, /* Fujitsu FR20 */ + EM_RH32 = 38, /* TRW RH-32 */ + EM_RCE = 39, /* Motorola RCE */ + EM_ARM = 40, /* ARM 32-bit architecture (AARCH32) */ + EM_ALPHA = 41, /* Digital Alpha */ + EM_SH = 42, /* Hitachi SH */ + EM_SPARCV9 = 43, /* SPARC Version 9 */ + EM_TRICORE = 44, /* Siemens TriCore embedded processor */ + EM_ARC = 45, /* Argonaut RISC Core, Argonaut Technologies Inc. */ + EM_H8_300 = 46, /* Hitachi H8/300 */ + EM_H8_300H = 47, /* Hitachi H8/300H */ + EM_H8S = 48, /* Hitachi H8S */ + EM_H8_500 = 49, /* Hitachi H8/500 */ + EM_IA_64 = 50, /* Intel IA-64 processor architecture */ + EM_MIPS_X = 51, /* Stanford MIPS-X */ + EM_COLDFIRE = 52, /* Motorola ColdFire */ + EM_68HC12 = 53, /* Motorola M68HC12 */ + EM_MMA = 54, /* Fujitsu MMA Multimedia Accelerator */ + EM_PCP = 55, /* Siemens PCP */ + EM_NCPU = 56, /* Sony nCPU embedded RISC processor */ + EM_NDR1 = 57, /* Denso NDR1 microprocessor */ + EM_STARCORE = 58, /* Motorola Star*Core processor */ + EM_ME16 = 59, /* Toyota ME16 processor */ + EM_ST100 = 60, /* STMicroelectronics ST100 processor */ + EM_TINYJ = 61, /* Advanced Logic Corp. TinyJ embedded processor family */ + EM_X86_64 = 62, /* AMD x86-64 architecture */ + EM_PDSP = 63, /* Sony DSP Processor */ + EM_PDP10 = 64, /* Digital Equipment Corp. PDP-10 */ + EM_PDP11 = 65, /* Digital Equipment Corp. PDP-11 */ + EM_FX66 = 66, /* Siemens FX66 microcontroller */ + EM_ST9PLUS = 67, /* STMicroelectronics ST9+ 8/16 bit microcontroller */ + EM_ST7 = 68, /* STMicroelectronics ST7 8-bit microcontroller */ + EM_68HC16 = 69, /* Motorola MC68HC16 Microcontroller */ + EM_68HC11 = 70, /* Motorola MC68HC11 Microcontroller */ + EM_68HC08 = 71, /* Motorola MC68HC08 Microcontroller */ + EM_68HC05 = 72, /* Motorola MC68HC05 Microcontroller */ + EM_SVX = 73, /* Silicon Graphics SVx */ + EM_ST19 = 74, /* STMicroelectronics ST19 8-bit microcontroller */ + EM_VAX = 75, /* Digital VAX */ + EM_CRIS = 76, /* Axis Communications 32-bit embedded processor */ + EM_JAVELIN = 77, /* Infineon Technologies 32-bit embedded processor */ + EM_FIREPATH = 78, /* Element 14 64-bit DSP Processor */ + EM_ZSP = 79, /* LSI Logic 16-bit DSP Processor */ + EM_MMIX = 80, /* Donald Knuth's educational 64-bit processor */ + EM_HUANY = 81, /* Harvard University machine-independent object files */ + EM_PRISM = 82, /* SiTera Prism */ + EM_AVR = 83, /* Atmel AVR 8-bit microcontroller */ + EM_FR30 = 84, /* Fujitsu FR30 */ + EM_D10V = 85, /* Mitsubishi D10V */ + EM_D30V = 86, /* Mitsubishi D30V */ + EM_V850 = 87, /* NEC v850 */ + EM_M32R = 88, /* Mitsubishi M32R */ + EM_MN10300 = 89, /* Matsushita MN10300 */ + EM_MN10200 = 90, /* Matsushita MN10200 */ + EM_PJ = 91, /* picoJava */ + EM_OPENRISC = 92, /* OpenRISC 32-bit embedded processor */ + EM_ARC_COMPACT = 93, /* ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) */ + EM_XTENSA = 94, /* Tensilica Xtensa Architecture */ + EM_VIDEOCORE = 95, /* Alphamosaic VideoCore processor */ + EM_TMM_GPP = 96, /* Thompson Multimedia General Purpose Processor */ + EM_NS32K = 97, /* National Semiconductor 32000 series */ + EM_TPC = 98, /* Tenor Network TPC processor */ + EM_SNP1K = 99, /* Trebia SNP 1000 processor */ + EM_ST200 = 100, /* STMicroelectronics (www.st.com) ST200 microcontroller */ + EM_IP2K = 101, /* Ubicom IP2xxx microcontroller family */ + EM_MAX = 102, /* MAX Processor */ + EM_CR = 103, /* National Semiconductor CompactRISC microprocessor */ + EM_F2MC16 = 104, /* Fujitsu F2MC16 */ + EM_MSP430 = 105, /* Texas Instruments embedded microcontroller msp430 */ + EM_BLACKFIN = 106, /* Analog Devices Blackfin (DSP) processor */ + EM_SE_C33 = 107, /* S1C33 Family of Seiko Epson processors */ + EM_SEP = 108, /* Sharp embedded microprocessor */ + EM_ARCA = 109, /* Arca RISC Microprocessor */ + EM_UNICORE = 110, /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University*/ + EM_EXCESS = 111, /* eXcess: 16/32/64-bit configurable embedded CPU */ + EM_DXP = 112, /* Icera Semiconductor Inc. Deep Execution Processor */ + EM_ALTERA_NIOS2 = 113, /* Altera Nios II soft-core processor */ + EM_CRX = 114, /* National Semiconductor CompactRISC CRX microprocessor */ + EM_XGATE = 115, /* Motorola XGATE embedded processor */ + EM_C166 = 116, /* Infineon C16x/XC16x processor */ + EM_M16C = 117, /* Renesas M16C series microprocessors */ + EM_DSPIC30F = 118, /* Microchip Technology dsPIC30F Digital Signal Controller */ + EM_CE = 119, /* Freescale Communication Engine RISC core */ + EM_M32C = 120, /* Renesas M32C series microprocessors */ + /* 121-130 Reserved for future use */ + EM_TSK3000 = 131, /* Altium TSK3000 core */ + EM_RS08 = 132, /* Freescale RS08 embedded processor */ + EM_SHARC = 133, /* Analog Devices SHARC family of 32-bit DSP processors */ + EM_ECOG2 = 134, /* Cyan Technology eCOG2 microprocessor */ + EM_SCORE7 = 135, /* Sunplus S+core7 RISC processor */ + EM_DSP24 = 136, /* New Japan Radio (NJR) 24-bit DSP Processor */ + EM_VIDEOCORE3 = 137, /* Broadcom VideoCore III processor */ + EM_LATTICEMICO32 = 138, /* RISC processor for Lattice FPGA architecture */ + EM_SE_C17 = 139, /* Seiko Epson C17 family */ + EM_TI_C6000 = 140, /* The Texas Instruments TMS320C6000 DSP family */ + EM_TI_C2000 = 141, /* The Texas Instruments TMS320C2000 DSP family */ + EM_TI_C5500 = 142, /* The Texas Instruments TMS320C55x DSP family */ + EM_TI_ARP32 = 143, /* Texas Instruments Application Specific RISC Processor, 32bit fetch */ + EM_TI_PRU = 144, /* Texas Instruments Programmable Realtime Unit */ + /* 145-159 Reserved for future use */ + EM_MMDSP_PLUS = 160, /* STMicroelectronics 64bit VLIW Data Signal Processor */ + EM_CYPRESS_M8C = 161, /* Cypress M8C microprocessor */ + EM_R32C = 162, /* Renesas R32C series microprocessors */ + EM_TRIMEDIA = 163, /* NXP Semiconductors TriMedia architecture family */ + EM_QDSP6 = 164, /* QUALCOMM DSP6 Processor */ + EM_8051 = 165, /* Intel 8051 and variants */ + EM_STXP7X = 166, /* STMicroelectronics STxP7x family of configurable and extensible RISC processors */ + EM_NDS32 = 167, /* Andes Technology compact code size embedded RISC processor family */ + EM_ECOG1X = 168, /* Cyan Technology eCOG1X family */ + EM_MAXQ30 = 169, /* Dallas Semiconductor MAXQ30 Core Micro-controllers */ + EM_XIMO16 = 170, /* New Japan Radio (NJR) 16-bit DSP Processor */ + EM_MANIK = 171, /* M2000 Reconfigurable RISC Microprocessor */ + EM_CRAYNV2 = 172, /* Cray Inc. NV2 vector architecture */ + EM_RX = 173, /* Renesas RX family */ + EM_METAG = 174, /* Imagination Technologies META processor architecture */ + EM_MCST_ELBRUS = 175, /* MCST Elbrus general purpose hardware architecture */ + EM_ECOG16 = 176, /* Cyan Technology eCOG16 family */ + EM_CR16 = 177, /* National Semiconductor CompactRISC CR16 16-bit microprocessor */ + EM_ETPU = 178, /* Freescale Extended Time Processing Unit */ + EM_SLE9X = 179, /* Infineon Technologies SLE9X core */ + EM_L10M = 180, /* Intel L10M */ + EM_K10M = 181, /* Intel K10M */ + /* 182 Reserved for future Intel use */ + EM_AARCH64 = 183, /* ARM 64-bit architecture (AARCH64) */ + /* 184 Reserved for future ARM use */ + EM_AVR32 = 185, /* Atmel Corporation 32-bit microprocessor family */ + EM_STM8 = 186, /* STMicroeletronics STM8 8-bit microcontroller */ + EM_TILE64 = 187, /* Tilera TILE64 multicore architecture family */ + EM_TILEPRO = 188, /* Tilera TILEPro multicore architecture family */ + EM_MICROBLAZE = 189, /* Xilinx MicroBlaze 32-bit RISC soft processor core */ + EM_CUDA = 190, /* NVIDIA CUDA architecture */ + EM_TILEGX = 191, /* Tilera TILE-Gx multicore architecture family */ + EM_CLOUDSHIELD = 192, /* CloudShield architecture family */ + EM_COREA_1ST = 193, /* KIPO-KAIST Core-A 1st generation processor family */ + EM_COREA_2ND = 194, /* KIPO-KAIST Core-A 2nd generation processor family */ + EM_ARC_COMPACT2 = 195, /* Synopsys ARCompact V2 */ + EM_OPEN8 = 196, /* Open8 8-bit RISC soft processor core */ + EM_RL78 = 197, /* Renesas RL78 family */ + EM_VIDEOCORE5 = 198, /* Broadcom VideoCore V processor */ + EM_78KOR = 199, /* Renesas 78KOR family */ + EM_56800EX = 200, /* Freescale 56800EX Digital Signal Controller (DSC) */ + EM_BA1 = 201, /* Beyond BA1 CPU architecture */ + EM_BA2 = 202, /* Beyond BA2 CPU architecture */ + EM_XCORE = 203, /* XMOS xCORE processor family */ + EM_MCHP_PIC = 204, /* Microchip 8-bit PIC(r) family */ + EM_INTEL205 = 205, /* Reserved by Intel */ + EM_INTEL206 = 206, /* Reserved by Intel */ + EM_INTEL207 = 207, /* Reserved by Intel */ + EM_INTEL208 = 208, /* Reserved by Intel */ + EM_INTEL209 = 209, /* Reserved by Intel */ + EM_KM32 = 210, /* KM211 KM32 32-bit processor */ + EM_KMX32 = 211, /* KM211 KMX32 32-bit processor */ + EM_KMX16 = 212, /* KM211 KMX16 16-bit processor */ + EM_KMX8 = 213, /* KM211 KMX8 8-bit processor */ + EM_KVARC = 214, /* KM211 KVARC processor */ + EM_CDP = 215, /* Paneve CDP architecture family */ + EM_COGE = 216, /* Cognitive Smart Memory Processor */ + EM_COOL = 217, /* Bluechip Systems CoolEngine */ + EM_NORC = 218, /* Nanoradio Optimized RISC */ + EM_CSR_KALIMBA = 219, /* CSR Kalimba architecture family */ + EM_Z80 = 220, /* Zilog Z80 */ + EM_VISIUM = 221, /* Controls and Data Services VISIUMcore processor */ + EM_FT32 = 222, /* FTDI Chip FT32 high performance 32-bit RISC architecture */ + EM_MOXIE = 223, /* Moxie processor family */ + EM_AMDGPU = 224, /* AMD GPU architecture */ + /* 225-242 */ + EM_RISCV = 243, /* RISC-V */ +}; + +/* + * Object file version + */ +enum { + EV_NONE = 0, /* Invalid*/ + EV_CURRENT = 1, /* Current*/ +}; + +/* + * Identification + */ +enum { + EI_MAG0 = 0, /* File identification */ + EI_MAG1 = 1, /* File identification */ + EI_MAG2 = 2, /* File identification */ + EI_MAG3 = 3, /* File identification */ + EI_CLASS = 4, /* File class */ + EI_DATA = 5, /* Data encoding */ + EI_VERSION = 6, /* File version */ + EI_OSABI = 7, /* Operating system/ABI identification */ + EI_ABIVERSION = 8, /* ABI version */ + EI_PAD = 9, /* Start of padding bytes */ +}; + +enum { + ELFMAG0 = 0x7f, /* e_ident[EI_MAG0] */ + ELFMAG1 = 'E', /* e_ident[EI_MAG1] */ + ELFMAG2 = 'L', /* e_ident[EI_MAG2] */ + ELFMAG3 = 'F', /* e_ident[EI_MAG3] */ + + ELFCLASSNONE = 0, /* Invalid class */ + ELFCLASS32 = 1, /* 32-bit objects */ + ELFCLASS64 = 2, /* 64-bit objects */ + + ELFDATANONE = 0, /* Invalid data encoding */ + ELFDATA2LSB = 1, /* Litte-endian */ + ELFDATA2MSB = 2, /* Big-endian */ +}; + +/* + * Special Section Indexes + */ +enum { + SHN_UNDEF = 0, + SHN_LORESERVE = 0xff00, + SHN_LOPROC = 0xff00, + SHN_HIPROC = 0xff1f, + SHN_LOOS = 0xff20, + SHN_HIOS = 0xff3f, + SHN_ABS = 0xfff1, + SHN_COMMON = 0xfff2, + SHN_XINDEX = 0xffff, + SHN_HIRESERVE = 0xffff, +}; + +/* + * Section Types + */ +enum { + 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_PREINIT_ARRAY = 16, + SHT_GROUP = 17, + SHT_SYMTAB_SHNDX = 18, + SHT_LOOS = 0x60000000, + SHT_HIOS = 0x6fffffff, + SHT_LOPROC = 0x70000000, + SHT_HIPROC = 0x7fffffff, + SHT_LOUSER = 0x80000000, + SHT_HIUSER = 0xffffffff, +}; + +/* + * Section Attribute Flags + */ +enum { + SHF_WRITE = 0x1, + SHF_ALLOC = 0x2, + SHF_EXECINSTR = 0x4, + SHF_MERGE = 0x10, + SHF_STRINGS = 0x20, + SHF_INFO_LINK = 0x40, + SHF_LINK_ORDER = 0x80, + SHF_OS_NONCONFORMING = 0x100, + SHF_GROUP = 0x200, + SHF_TLS = 0x400, + SHF_COMPRESSED = 0x800, + SHF_MASKOS = 0x0ff00000, + SHF_MASKPROC = 0xf0000000, +}; + +/* + * Section Attribute Flags + */ +enum { + GRP_COMDAT = 0x1, + GRP_MASKOS = 0x0ff00000, + GRP_MASKPROC = 0xf0000000, +}; diff --git a/elf.c b/elf.c new file mode 100644 index 0000000..36c17d4 --- /dev/null +++ b/elf.c @@ -0,0 +1,727 @@ +#include +#include +#include +#include +#include + +#include "bele.h" +#include "elf.h" +#include "dat.h" +#include "fns.h" + +static int verbose; + +typedef struct Data Data; +typedef struct Class Class; + +struct Data { + int type; + char *name; + unsigned int (*get8)(void*, uint8_t*); + unsigned int (*get16)(void*, uint16_t*); + unsigned int (*get32)(void*, uint32_t*); + unsigned int (*get64)(void*, uint64_t*); +}; + +struct Class { + int type; + char *name; + int ehsize; + int shentsize; + int phentsize; + int (*readelfehdr)(FILE*, Fhdr*); + int (*readelfshdr)(FILE*, Fhdr*); + int (*readelfphdr)(FILE*, Fhdr*); + int (*readelfstrndx)(FILE*, Fhdr*); +}; + +static int readelf32ehdr(FILE*, Fhdr*); +static int readelf32shdr(FILE*, Fhdr*); +static int readelf32phdr(FILE*, Fhdr*); +static int readelf32strndx(FILE*, Fhdr*); + +static int readelf64ehdr(FILE*, Fhdr*); +static int readelf64shdr(FILE*, Fhdr*); +static int readelf64phdr(FILE*, Fhdr*); +static int readelf64strndx(FILE*, Fhdr*); + +static Data data[] = { + { + ELFDATANONE, + "invalid", + NULL, + NULL, + NULL, + NULL + }, + { + ELFDATA2LSB, + "little-endian", + le8get, + le16get, + le32get, + le64get + }, + { + ELFDATA2MSB, + "big-endian", + be8get, + be16get, + be32get, + be64get + } +}; + +static Class class[] = { + { + ELFCLASSNONE, + "invalid", + 0, + 0, + 0, + NULL, + NULL, + NULL, + NULL, + }, + { + ELFCLASS32, + "32-bit", + sizeof(Elf32_Ehdr), + sizeof(Elf32_Shdr), + sizeof(Elf32_Phdr), + readelf32ehdr, + readelf32shdr, + readelf32phdr, + readelf32strndx, + }, + { + ELFCLASS64, + "64-bit", + sizeof(Elf64_Ehdr), + sizeof(Elf64_Shdr), + sizeof(Elf64_Phdr), + readelf64ehdr, + readelf64shdr, + readelf64phdr, + readelf64strndx, + } +}; + +/* + * Read ELF32 Header + */ +static int +readelf32ehdr(FILE *f, Fhdr *fp) +{ + uint8_t buf[Eh32sz]; + Elf32_Ehdr e; + uint8_t *p; + + p = buf; + + fseek(f, 0, SEEK_SET); + + if (fread(p, fp->ehsize, 1, f) != 1) + return -1; + + memmove(&e.ident, p, sizeof(e.ident)); + p += sizeof(e.ident); + p += fp->get16(p, &e.type); + p += fp->get16(p, &e.machine); + p += fp->get32(p, &e.version); + p += fp->get32(p, &e.entry); + p += fp->get32(p, &e.phoff); + p += fp->get32(p, &e.shoff); + p += fp->get32(p, &e.flags); + p += fp->get16(p, &e.ehsize); + p += fp->get16(p, &e.phentsize); + p += fp->get16(p, &e.phnum); + p += fp->get16(p, &e.shentsize); + p += fp->get16(p, &e.shnum); + p += fp->get16(p, &e.shstrndx); + + if (verbose) + printelf32ehdr(&e, fp); + + if (e.type != ET_REL && e.type != ET_EXEC) { + fprintf(stderr, "unsupported file type %d\n", e.type); + return -1; + } + + if (fp->ehsize != e.ehsize) { + fprintf(stderr, "ehsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); + return -1; + } + + if (fp->shentsize != e.shentsize) { + fprintf(stderr, "shentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); + return -1; + } + + if (fp->phentsize != e.phentsize) { + fprintf(stderr, "phentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); + return -1; + } + + fp->shoff = e.shoff; + fp->phoff = e.phoff; + fp->phnum = e.phnum; + fp->shnum = e.shnum; + fp->shstrndx = e.shstrndx; + + return p - buf; +} + +/* + * Read ELF64 Header + */ +static int +readelf64ehdr(FILE *f, Fhdr *fp) +{ + uint8_t buf[Eh64sz]; + Elf64_Ehdr e; + uint8_t *p; + + p = buf; + + fseek(f, 0, SEEK_SET); + + if (fread(p, fp->ehsize , 1, f) != 1) + return -1; + + memmove(&e.ident, p, sizeof(e.ident)); + p += sizeof(e.ident); + p += fp->get16(p, &e.type); + p += fp->get16(p, &e.machine); + p += fp->get32(p, &e.version); + p += fp->get64(p, &e.entry); + p += fp->get64(p, &e.phoff); + p += fp->get64(p, &e.shoff); + p += fp->get32(p, &e.flags); + p += fp->get16(p, &e.ehsize); + p += fp->get16(p, &e.phentsize); + p += fp->get16(p, &e.phnum); + p += fp->get16(p, &e.shentsize); + p += fp->get16(p, &e.shnum); + p += fp->get16(p, &e.shstrndx); + + if (verbose) + printelf64ehdr(&e, fp); + + if (e.type != ET_REL && e.type != ET_EXEC) { + fprintf(stderr, "unsupported file type %d\n", e.type); + return -1; + } + + if (fp->ehsize != e.ehsize) { + fprintf(stderr, "ehsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); + return -1; + } + + if (fp->shentsize != e.shentsize) { + fprintf(stderr, "shentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); + return -1; + } + + if (fp->phentsize != e.phentsize) { + fprintf(stderr, "phentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); + return -1; + } + + fp->shoff = e.shoff; + fp->phoff = e.phoff; + fp->phnum = e.phnum; + fp->shnum = e.shnum; + fp->shstrndx = e.shstrndx; + + return p - buf; +} + +/* + * Unpack ELF32 Section Header + */ +int +unpackelf32shdr(uint8_t *buf, int len, Elf32_Shdr *sh, Fhdr *fp) +{ + uint8_t *p; + + if (len < Sh32sz) + return -1; + + p = buf; + + p += fp->get32(p, &sh->name); + p += fp->get32(p, &sh->type); + p += fp->get32(p, &sh->flags); + p += fp->get32(p, &sh->addr); + p += fp->get32(p, &sh->offset); + p += fp->get32(p, &sh->size); + p += fp->get32(p, &sh->link); + p += fp->get32(p, &sh->info); + p += fp->get32(p, &sh->addralign); + p += fp->get32(p, &sh->entsize); + + return p - buf; +} + +/* + * Read ELF32 Section Header + */ +static int +readelf32shdr(FILE *f, Fhdr *fp) +{ + uint8_t buf[Sh32sz]; + Elf32_Shdr sh; + + if (fread(buf, fp->shentsize, 1, f) != 1) + return -1; + + if (unpackelf32shdr(buf, sizeof(buf), &sh, fp) < 0) + return -1; + + fp->name = sh.name; + fp->offset = sh.offset; + fp->size = sh.size; + + if (verbose) + printelf32shdr(&sh, fp); + + return 0; +} + +/* + * Unpack ELF32 Program Header + */ +int +unpackelf32phdr(uint8_t *buf, int len, Elf32_Phdr *ph, Fhdr *fp) +{ + uint8_t *p; + + if (len < Ph32sz) + return -1; + + p = buf; + + p += fp->get32(p, &ph->type); + p += fp->get32(p, &ph->offset); + p += fp->get32(p, &ph->vaddr); + p += fp->get32(p, &ph->paddr); + p += fp->get32(p, &ph->filesz); + p += fp->get32(p, &ph->memsz); + p += fp->get32(p, &ph->flags); + p += fp->get32(p, &ph->align); + + return p - buf; +} + +/* + * Read ELF32 Program Header + */ +static int +readelf32phdr(FILE *f, Fhdr *fp) +{ + uint8_t buf[Ph32sz]; + Elf32_Phdr ph; + + if (fread(buf, fp->phentsize, 1, f) != 1) + return -1; + + if (unpackelf32phdr(buf, sizeof(buf), &ph, fp) < 0) + return -1; + + if (verbose) + printelf32phdr(&ph, fp); + + return 0; +} + +/* + * Unpack ELF64 Section Header + */ +int +unpackelf64shdr(uint8_t *buf, int len, Elf64_Shdr *sh, Fhdr *fp) +{ + uint8_t *p; + + if (len < Sh64sz) + return -1; + + p = buf; + + p += fp->get32(p, &sh->name); + p += fp->get32(p, &sh->type); + p += fp->get64(p, &sh->flags); + p += fp->get64(p, &sh->addr); + p += fp->get64(p, &sh->offset); + p += fp->get64(p, &sh->size); + p += fp->get32(p, &sh->link); + p += fp->get32(p, &sh->info); + p += fp->get64(p, &sh->addralign); + p += fp->get64(p, &sh->entsize); + + return p - buf; +} + +/* + * Read ELF64 Section Header + */ +static int +readelf64shdr(FILE *f, Fhdr *fp) +{ + uint8_t buf[Sh64sz]; + Elf64_Shdr sh; + + if (fread(buf, fp->shentsize, 1, f) != 1) + return -1; + + if (unpackelf64shdr(buf, sizeof(buf), &sh, fp) < 0) + return -1; + + fp->name = sh.name; + fp->offset = sh.offset; + fp->size = sh.size; + + if (verbose) + printelf64shdr(&sh, fp); + + return 0; +} + +/* + * Unpack ELF64 Program Header + */ +int +unpackelf64phdr(uint8_t *buf, int len, Elf64_Phdr *ph, Fhdr *fp) +{ + uint8_t *p; + + if (len < Ph64sz) + return -1; + + p = buf; + + p += fp->get32(p, &ph->type); + p += fp->get32(p, &ph->flags); + p += fp->get64(p, &ph->offset); + p += fp->get64(p, &ph->vaddr); + p += fp->get64(p, &ph->paddr); + p += fp->get64(p, &ph->filesz); + p += fp->get64(p, &ph->memsz); + p += fp->get64(p, &ph->align); + + return p - buf; +} + +/* + * Read ELF64 Program Header + */ +static int +readelf64phdr(FILE *f, Fhdr *fp) +{ + uint8_t buf[Ph64sz]; + Elf64_Phdr ph; + + if (fread(buf, fp->phentsize, 1, f) != 1) + return -1; + + if (unpackelf64phdr(buf, sizeof(buf), &ph, fp) < 0) + return -1; + + if (verbose) + printelf64phdr(&ph, fp); + + return 0; +} + +/* + * Read ELF ident + */ +int +readident(FILE *f, Fhdr *fp) +{ + uint8_t buf[EI_NIDENT]; + unsigned int i; + uint8_t *p; + + p = buf; + if (fread(p, EI_NIDENT, 1, f) != 1) + return -1; + + p += EI_NIDENT; + + if (buf[EI_MAG0] != ELFMAG0) + return -1; + if (buf[EI_MAG1] != ELFMAG1) + return -1; + if (buf[EI_MAG2] != ELFMAG2) + return -1; + if (buf[EI_MAG3] != ELFMAG3) + return -1; + + if(buf[EI_VERSION] != EV_CURRENT) { + fprintf(stderr, "unsupported file version %d\n", buf[EI_VERSION]); + return -1; + } + + for (i = 0; i < nelem(class); i++) { + if (buf[EI_CLASS] != class[i].type) + continue; + printf("class: %s\n", class[i].name); + if (class[i].readelfehdr == NULL) + return -1; + fp->readelfehdr = class[i].readelfehdr; + fp->readelfshdr = class[i].readelfshdr; + fp->readelfphdr = class[i].readelfphdr; + fp->readelfstrndx = class[i].readelfstrndx; + fp->ehsize = class[i].ehsize; + fp->shentsize = class[i].shentsize; + fp->phentsize = class[i].phentsize; + break; + } + + if (i == nelem(class)) + return -1; + + for (i = 0; i < nelem(data); i++) { + if (buf[EI_DATA] != data[i].type) + continue; + printf("data encoding: %s\n", data[i].name); + if (data[i].get8 == NULL) + return -1; + fp->get8 = data[i].get8; + fp->get16 = data[i].get16; + fp->get32 = data[i].get32; + fp->get64 = data[i].get64; + break; + } + + if (i == nelem(data)) + return -1; + + return p - buf; +} + +/* + * Read ELF Section Headers + */ +int +readelfshdrs(FILE *f, Fhdr *fp) +{ + unsigned int i; + + fseek(f, fp->shoff, SEEK_SET); + + for (i = 0; i < fp->shnum; i++) { + if (fp->readelfshdr(f, fp) < 0) + return -1; + } + + return 0; +} + +/* + * Read ELF Program Headers + */ +int +readelfphdrs(FILE *f, Fhdr *fp) +{ + unsigned int i; + + fseek(f, fp->phoff, SEEK_SET); + + for (i = 0; i < fp->phnum; i++) { + if (fp->readelfphdr(f, fp) < 0) + return -1; + } + + return 0; +} + +/* + * Read ELF32 String Table + */ +static int +readelf32strndx(FILE *f, Fhdr *fp) +{ + uint8_t buf[Sh32sz]; + Elf32_Shdr sh; + + fseek(f, fp->shoff + fp->shstrndx * fp->shentsize, SEEK_SET); + + if (fread(buf, fp->shentsize, 1, f) != 1) + return -1; + + if (unpackelf32shdr(buf, sizeof(buf), &sh, fp) < 0) + return -1; + + fp->offset = sh.offset; + fp->strndxsize = sh.size; + + return 0; +} + +/* + * Read ELF64 String Table + */ +static int +readelf64strndx(FILE *f, Fhdr *fp) +{ + uint8_t buf[Sh64sz]; + Elf64_Shdr sh; + + fseek(f, fp->shoff + fp->shstrndx * fp->shentsize, SEEK_SET); + + if (fread(buf, fp->shentsize, 1, f) != 1) + return -1; + + if (unpackelf64shdr(buf, sizeof(buf), &sh, fp) < 0) + return -1; + + fp->offset = sh.offset; + fp->strndxsize = sh.size; + + return 0; +} + +static uint8_t* +newsection(FILE *f, uint64_t offset, uint64_t size) +{ + uint8_t *sect; + + sect = malloc(size); + if (sect == NULL) + return NULL; + + fseek(f, offset, SEEK_SET); + + if (fread(sect, size, 1, f) != 1) { + free(sect); + return NULL; + } + + return sect; +} + +/* + * Read ELF String Table + */ +static int +readelfstrndx(FILE *f, Fhdr *fp) +{ + if (fp->shstrndx == SHN_UNDEF) { + fprintf(stderr, "missing string table\n"); + return -1; + } + + if (fp->readelfstrndx(f, fp) < 0) + return -1; + + fp->strndx = newsection(f, fp->offset, fp->strndxsize); + if (fp->strndx == NULL) + return -1; + + return 0; +} + +/* + * Get string from index in String Table + */ +char* getstr(Fhdr *fp, uint32_t i) +{ + if (fp->strndx == NULL) + return NULL; + + if (i >= fp->strndxsize) + return NULL; + + return (char*)&fp->strndx[i]; +} + +/* + * Read ELF Section Headers + */ +uint8_t* +readelfsect(FILE *f, char *name, Fhdr *fp) +{ + unsigned int i; + char *n; + + fseek(f, fp->shoff, SEEK_SET); + + for (i = 0; i < fp->shnum; i++) { + if (fp->readelfshdr(f, fp) < 0) + return NULL; + n = getstr(fp, fp->name); + if (n == NULL) + return NULL; + if (strcmp(n, name) == 0) + return newsection(f, fp->offset, fp->size); + } + + fprintf(stderr, "section %s not found\n", name); + + return NULL; +} + +/* + * Read ELF File + */ +int +readelf(FILE *f, Fhdr *fp) +{ + memset(fp, 0, sizeof(*fp)); + + if (readident(f, fp) < 0) + return -1; + + if (fp->readelfehdr(f, fp) < 0) + return -1; + + if (readelfstrndx(f, fp) < 0) + return -1; + + if (readelfshdrs(f, fp) < 0) + return -1; + + if (readelfphdrs(f, fp) < 0) + return -1; + + return 0; +} + +/* + * Read ELF Section + */ +uint8_t* +readelfsection(FILE *f, char *name, uint64_t *size, Fhdr *fp) +{ + uint8_t *sect; + + memset(fp, 0, sizeof(*fp)); + + if (readident(f, fp) < 0) + return NULL; + + if (fp->readelfehdr(f, fp) < 0) + return NULL; + + if (readelfstrndx(f, fp) < 0) + return NULL; + + sect = readelfsect(f, name, fp); + if (sect == NULL) + return NULL; + + *size = fp->size; + + return sect; +} + + +void +freeelf(Fhdr *fp) +{ + if (fp->strndx != NULL) + free(fp->strndx); +} diff --git a/elf.h b/elf.h new file mode 100644 index 0000000..7a045f5 --- /dev/null +++ b/elf.h @@ -0,0 +1,41 @@ +typedef struct Fhdr Fhdr; + +/* + * Portable ELF file header + */ +struct Fhdr { + /* ELF Data */ + unsigned int (*get8)(void*, uint8_t*); + unsigned int (*get16)(void*, uint16_t*); + unsigned int (*get32)(void*, uint32_t*); + unsigned int (*get64)(void*, uint64_t*); + + /* ELF Class */ + int (*readelfehdr)(FILE*, Fhdr*); + int (*readelfshdr)(FILE*, Fhdr*); + int (*readelfphdr)(FILE*, Fhdr*); + int (*readelfstrndx)(FILE*, Fhdr*); + + /* ELF Header */ + uint64_t phoff; + uint64_t shoff; + uint16_t ehsize; /* ELF Header size */ + uint16_t phentsize; /* Section Header size */ + uint16_t phnum; + uint16_t shentsize; /* Program Header size */ + uint16_t shnum; + uint16_t shstrndx; + + /* Section Header */ + uint32_t name; + uint64_t offset; + uint64_t size; + + /* String Table */ + uint32_t strndxsize; /* String Table size */ + uint8_t *strndx; /* Copy of String Table */ +}; + +int readelf(FILE*, Fhdr*); +uint8_t* readelfsection(FILE*, char*, uint64_t*, Fhdr*); +void freeelf(Fhdr*); diff --git a/fns.h b/fns.h new file mode 100644 index 0000000..41b19d0 --- /dev/null +++ b/fns.h @@ -0,0 +1,11 @@ +/* + * print.c + */ +void printelf32ehdr(Elf32_Ehdr*, Fhdr*); +void printelf64ehdr(Elf64_Ehdr*, Fhdr*); +void printelf32shdr(Elf32_Shdr*, Fhdr*); +void printelf64shdr(Elf64_Shdr*, Fhdr*); +void printelf32phdr(Elf32_Phdr*, Fhdr*); +void printelf64phdr(Elf64_Phdr*, Fhdr*); + +char* getstr(Fhdr*, uint32_t); diff --git a/machines.c b/machines.c new file mode 100644 index 0000000..19f3760 --- /dev/null +++ b/machines.c @@ -0,0 +1,188 @@ +#include + +#include "dat.h" + +char *machines[] = { + [EM_NONE] = "No machine", + [EM_M32] = "AT&T WE 32100", + [EM_SPARC] = "SPARC", + [EM_386] = "Intel 80386", + [EM_68K] = "Motorola 68000", + [EM_88K] = "Motorola 88000", + [EM_IAMCU] = "Intel MCU", + [EM_860] = "Intel 80860", + [EM_MIPS] = "MIPS I Architecture", + [EM_S370] = "IBM System/370 Processor", + [EM_MIPS_RS3_LE] = "MIPS RS3000 Little-endian", + [EM_PARISC] = "Hewlett-Packard PA-RISC", + [EM_VPP500] = "Fujitsu VPP500", + [EM_SPARC32PLUS] = "Enhanced instruction set SPARC", + [EM_960] = "Intel 80960", + [EM_PPC] = "PowerPC", + [EM_PPC64] = "64-bit PowerPC", + [EM_S390] = "IBM System/390 Processor", + [EM_SPU] = "IBM SPU/SPC", + [EM_V800] = "NEC V800", + [EM_FR20] = "Fujitsu FR20", + [EM_RH32] = "TRW RH-32", + [EM_RCE] = "Motorola RCE", + [EM_ARM] = "ARM 32-bit architecture (AARCH32)", + [EM_ALPHA] = "Digital Alpha", + [EM_SH] = "Hitachi SH", + [EM_SPARCV9] = "SPARC Version 9", + [EM_TRICORE] = "Siemens TriCore embedded processor", + [EM_ARC] = "Argonaut RISC Core, Argonaut Technologies Inc.", + [EM_H8_300] = "Hitachi H8/300", + [EM_H8_300H] = "Hitachi H8/300H", + [EM_H8S] = "Hitachi H8S", + [EM_H8_500] = "Hitachi H8/500", + [EM_IA_64] = "Intel IA-64 processor architecture", + [EM_MIPS_X] = "Stanford MIPS-X", + [EM_COLDFIRE] = "Motorola ColdFire", + [EM_68HC12] = "Motorola M68HC12", + [EM_MMA] = "Fujitsu MMA Multimedia Accelerator", + [EM_PCP] = "Siemens PCP", + [EM_NCPU] = "Sony nCPU embedded RISC processor", + [EM_NDR1] = "Denso NDR1 microprocessor", + [EM_STARCORE] = "Motorola Star*Core processor", + [EM_ME16] = "Toyota ME16 processor", + [EM_ST100] = "STMicroelectronics ST100 processor", + [EM_TINYJ] = "Advanced Logic Corp. TinyJ embedded processor family", + [EM_X86_64] = "AMD x86-64 architecture", + [EM_PDSP] = "Sony DSP Processor", + [EM_PDP10] = "Digital Equipment Corp. PDP-10", + [EM_PDP11] = "Digital Equipment Corp. PDP-11", + [EM_FX66] = "Siemens FX66 microcontroller", + [EM_ST9PLUS] = "STMicroelectronics ST9+ 8/16 bit microcontroller", + [EM_ST7] = "STMicroelectronics ST7 8-bit microcontroller", + [EM_68HC16] = "Motorola MC68HC16 Microcontroller", + [EM_68HC11] = "Motorola MC68HC11 Microcontroller", + [EM_68HC08] = "Motorola MC68HC08 Microcontroller", + [EM_68HC05] = "Motorola MC68HC05 Microcontroller", + [EM_SVX] = "Silicon Graphics SVx", + [EM_ST19] = "STMicroelectronics ST19 8-bit microcontroller", + [EM_VAX] = "Digital VAX", + [EM_CRIS] = "Axis Communications 32-bit embedded processor", + [EM_JAVELIN] = "Infineon Technologies 32-bit embedded processor", + [EM_FIREPATH] = "Element 14 64-bit DSP Processor", + [EM_ZSP] = "LSI Logic 16-bit DSP Processor", + [EM_MMIX] = "Donald Knuth's educational 64-bit processor", + [EM_HUANY] = "Harvard University machine-independent object files", + [EM_PRISM] = "SiTera Prism", + [EM_AVR] = "Atmel AVR 8-bit microcontroller", + [EM_FR30] = "Fujitsu FR30", + [EM_D10V] = "Mitsubishi D10V", + [EM_D30V] = "Mitsubishi D30V", + [EM_V850] = "NEC v850", + [EM_M32R] = "Mitsubishi M32R", + [EM_MN10300] = "Matsushita MN10300", + [EM_MN10200] = "Matsushita MN10200", + [EM_PJ] = "picoJava", + [EM_OPENRISC] = "OpenRISC 32-bit embedded processor", + [EM_ARC_COMPACT] = "ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)", + [EM_XTENSA] = "Tensilica Xtensa Architecture", + [EM_VIDEOCORE] = "Alphamosaic VideoCore processor", + [EM_TMM_GPP] = "Thompson Multimedia General Purpose Processor", + [EM_NS32K] = "National Semiconductor 32000 series", + [EM_TPC] = "Tenor Network TPC processor", + [EM_SNP1K] = "Trebia SNP 1000 processor", + [EM_ST200] = "STMicroelectronics (www.st.com) ST200 microcontroller", + [EM_IP2K] = "Ubicom IP2xxx microcontroller family", + [EM_MAX] = "MAX Processor", + [EM_CR] = "National Semiconductor CompactRISC microprocessor", + [EM_F2MC16] = "Fujitsu F2MC16", + [EM_MSP430] = "Texas Instruments embedded microcontroller msp430", + [EM_BLACKFIN] = "Analog Devices Blackfin (DSP) processor", + [EM_SE_C33] = "S1C33 Family of Seiko Epson processors", + [EM_SEP] = "Sharp embedded microprocessor", + [EM_ARCA] = "Arca RISC Microprocessor", + [EM_UNICORE] = "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University", + [EM_EXCESS] = "eXcess: 16/32/64-bit configurable embedded CPU", + [EM_DXP] = "Icera Semiconductor Inc. Deep Execution Processor", + [EM_ALTERA_NIOS2] = "Altera Nios II soft-core processor", + [EM_CRX] = "National Semiconductor CompactRISC CRX microprocessor", + [EM_XGATE] = "Motorola XGATE embedded processor", + [EM_C166] = "Infineon C16x/XC16x processor", + [EM_M16C] = "Renesas M16C series microprocessors", + [EM_DSPIC30F] = "Microchip Technology dsPIC30F Digital Signal Controller", + [EM_CE] = "Freescale Communication Engine RISC core", + [EM_M32C] = "Renesas M32C series microprocessors", + [EM_TSK3000] = "Altium TSK3000 core", + [EM_RS08] = "Freescale RS08 embedded processor", + [EM_SHARC] = "Analog Devices SHARC family of 32-bit DSP processors", + [EM_ECOG2] = "Cyan Technology eCOG2 microprocessor", + [EM_SCORE7] = "Sunplus S+core7 RISC processor", + [EM_DSP24] = "New Japan Radio (NJR) 24-bit DSP Processor", + [EM_VIDEOCORE3] = "Broadcom VideoCore III processor", + [EM_LATTICEMICO32] = "RISC processor for Lattice FPGA architecture", + [EM_SE_C17] = "Seiko Epson C17 family", + [EM_TI_C6000] = "The Texas Instruments TMS320C6000 DSP family", + [EM_TI_C2000] = "The Texas Instruments TMS320C2000 DSP family", + [EM_TI_C5500] = "The Texas Instruments TMS320C55x DSP family", + [EM_TI_ARP32] = "Texas Instruments Application Specific RISC Processor, 32bit fetch", + [EM_TI_PRU] = "Texas Instruments Programmable Realtime Unit", + [EM_MMDSP_PLUS] = "STMicroelectronics 64bit VLIW Data Signal Processor", + [EM_CYPRESS_M8C] = "Cypress M8C microprocessor", + [EM_R32C] = "Renesas R32C series microprocessors", + [EM_TRIMEDIA] = "NXP Semiconductors TriMedia architecture family", + [EM_QDSP6] = "QUALCOMM DSP6 Processor", + [EM_8051] = "Intel 8051 and variants", + [EM_STXP7X] = "STMicroelectronics STxP7x family of configurable and extensible RISC processors", + [EM_NDS32] = "Andes Technology compact code size embedded RISC processor family", + [EM_ECOG1X] = "Cyan Technology eCOG1X family", + [EM_MAXQ30] = "Dallas Semiconductor MAXQ30 Core Micro-controllers", + [EM_XIMO16] = "New Japan Radio (NJR) 16-bit DSP Processor", + [EM_MANIK] = "M2000 Reconfigurable RISC Microprocessor", + [EM_CRAYNV2] = "Cray Inc. NV2 vector architecture", + [EM_RX] = "Renesas RX family", + [EM_METAG] = "Imagination Technologies META processor architecture", + [EM_MCST_ELBRUS] = "MCST Elbrus general purpose hardware architecture", + [EM_ECOG16] = "Cyan Technology eCOG16 family", + [EM_CR16] = "National Semiconductor CompactRISC CR16 16-bit microprocessor", + [EM_ETPU] = "Freescale Extended Time Processing Unit", + [EM_SLE9X] = "Infineon Technologies SLE9X core", + [EM_L10M] = "Intel L10M", + [EM_K10M] = "Intel K10M", + [EM_AARCH64] = "ARM 64-bit architecture (AARCH64)", + [EM_AVR32] = "Atmel Corporation 32-bit microprocessor family", + [EM_STM8] = "STMicroeletronics STM8 8-bit microcontroller", + [EM_TILE64] = "Tilera TILE64 multicore architecture family", + [EM_TILEPRO] = "Tilera TILEPro multicore architecture family", + [EM_MICROBLAZE] = "Xilinx MicroBlaze 32-bit RISC soft processor core", + [EM_CUDA] = "NVIDIA CUDA architecture", + [EM_TILEGX] = "Tilera TILE-Gx multicore architecture family", + [EM_CLOUDSHIELD] = "CloudShield architecture family", + [EM_COREA_1ST] = "KIPO-KAIST Core-A 1st generation processor family", + [EM_COREA_2ND] = "KIPO-KAIST Core-A 2nd generation processor family", + [EM_ARC_COMPACT2] = "Synopsys ARCompact V2", + [EM_OPEN8] = "Open8 8-bit RISC soft processor core", + [EM_RL78] = "Renesas RL78 family", + [EM_VIDEOCORE5] = "Broadcom VideoCore V processor", + [EM_78KOR] = "Renesas 78KOR family", + [EM_56800EX] = "Freescale 56800EX Digital Signal Controller (DSC)", + [EM_BA1] = "Beyond BA1 CPU architecture", + [EM_BA2] = "Beyond BA2 CPU architecture", + [EM_XCORE] = "XMOS xCORE processor family", + [EM_MCHP_PIC] = "Microchip 8-bit PIC(r) family", + [EM_INTEL205] = "Reserved by Intel", + [EM_INTEL206] = "Reserved by Intel", + [EM_INTEL207] = "Reserved by Intel", + [EM_INTEL208] = "Reserved by Intel", + [EM_INTEL209] = "Reserved by Intel", + [EM_KM32] = "KM211 KM32 32-bit processor", + [EM_KMX32] = "KM211 KMX32 32-bit processor", + [EM_KMX16] = "KM211 KMX16 16-bit processor", + [EM_KMX8] = "KM211 KMX8 8-bit processor", + [EM_KVARC] = "KM211 KVARC processor", + [EM_CDP] = "Paneve CDP architecture family", + [EM_COGE] = "Cognitive Smart Memory Processor", + [EM_COOL] = "Bluechip Systems CoolEngine", + [EM_NORC] = "Nanoradio Optimized RISC", + [EM_CSR_KALIMBA] = "CSR Kalimba architecture family", + [EM_Z80] = "Zilog Z80", + [EM_VISIUM] = "Controls and Data Services VISIUMcore processor", + [EM_FT32] = "FTDI Chip FT32 high performance 32-bit RISC architecture", + [EM_MOXIE] = "Moxie processor family", + [EM_AMDGPU] = "AMD GPU architecture", + [EM_RISCV] = "RISC-V" +}; diff --git a/print.c b/print.c new file mode 100644 index 0000000..69249d3 --- /dev/null +++ b/print.c @@ -0,0 +1,125 @@ +#include +#include +#include + +#include "elf.h" +#include "dat.h" +#include "fns.h" + +void +printelf32ehdr(Elf32_Ehdr *e, Fhdr *fp) +{ + USED(fp); + printf("ident %.2x %c %c %c %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + e->ident[0], e->ident[1], e->ident[2], e->ident[3], e->ident[4], e->ident[5], e->ident[6], e->ident[7], + e->ident[8], e->ident[9], e->ident[10], e->ident[11], e->ident[12], e->ident[13], e->ident[14], e->ident[15]); + printf("type %u\n", e->type); + if (machines[e->machine] != NULL) + printf("machine %s (0x%.4x)\n", machines[e->machine], e->machine); + else + printf("machine 0x%.4x\n", e->machine); + printf("version %u\n", e->version); + printf("entry 0x%.8x\n", e->entry); + printf("phoff %u\n", e->phoff); + printf("shoff %u\n", e->shoff); + printf("flags 0x%.8x\n", e->flags); + printf("ehsize %u\n", e->ehsize); + printf("phentsize %u\n", e->phentsize); + printf("phnum %u\n", e->phnum); + printf("shentsize %u\n", e->shentsize); + printf("shnum %u\n", e->shnum); + printf("shstrndx %u\n", e->shstrndx); + printf("\n"); +} + +void +printelf64ehdr(Elf64_Ehdr *e, Fhdr *fp) +{ + USED(fp); + printf("ident %.2x %c %c %c %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + e->ident[0], e->ident[1], e->ident[2], e->ident[3], e->ident[4], e->ident[5], e->ident[6], e->ident[7], + e->ident[8], e->ident[9], e->ident[10], e->ident[11], e->ident[12], e->ident[13], e->ident[14], e->ident[15]); + printf("type %u\n", e->type); + if (machines[e->machine] != NULL) + printf("machine %s (0x%.4x)\n", machines[e->machine], e->machine); + else + printf("machine 0x%.4x\n", e->machine); + printf("version %u\n", e->version); + printf("entry 0x%.16" PRIx64 "\n", e->entry); + printf("phoff %" PRIu64 "\n", e->phoff); + printf("shoff %" PRIu64 "\n", e->shoff); + printf("flags 0x%.8x\n", e->flags); + printf("ehsize %u\n", e->ehsize); + printf("phentsize %u\n", e->phentsize); + printf("phnum %u\n", e->phnum); + printf("shentsize %u\n", e->shentsize); + printf("shnum %u\n", e->shnum); + printf("shstrndx %u\n", e->shstrndx); + printf("\n"); +} + +void +printelf32shdr(Elf32_Shdr *sh, Fhdr *fp) +{ + printf("section header\n"); + printf("name %s (%u)\n", getstr(fp, sh->name), sh->name); + printf("type %u\n", sh->type); + printf("flags 0x%.8x\n", sh->flags); + printf("addr 0x%.8x\n", sh->addr); + printf("offset 0x%.8x\n", sh->offset); + printf("size %u\n", sh->size); + printf("link %u\n", sh->link); + printf("info %u\n", sh->info); + printf("addralign 0x%.8x\n", sh->addralign); + printf("entsize %u\n", sh->entsize); + printf("\n"); +} + +void +printelf32phdr(Elf32_Phdr *ph, Fhdr *fp) +{ + USED(fp); + printf("program header\n"); + printf("type %u\n", ph->type); + printf("offset 0x%.8x\n", ph->offset); + printf("vaddr 0x%.8x\n", ph->vaddr); + printf("paddr 0x%.8x\n", ph->paddr); + printf("filesz %u\n", ph->filesz); + printf("memsz %u\n", ph->memsz); + printf("flags 0x%.8x\n", ph->flags); + printf("align 0x%.8x\n", ph->align); + printf("\n"); +} + +void +printelf64shdr(Elf64_Shdr *sh, Fhdr *fp) +{ + printf("section header\n"); + printf("name %s (%u)\n", getstr(fp, sh->name), sh->name); + printf("type %u\n", sh->type); + printf("flags 0x%.16" PRIx64 "\n", sh->flags); + printf("addr 0x%.16" PRIx64 "\n", sh->addr); + printf("offset 0x%.16" PRIx64 "\n", sh->offset); + printf("size %" PRIu64 "\n", sh->size); + printf("link %u\n", sh->link); + printf("info %u\n", sh->info); + printf("addralign 0x%.16" PRIx64 "\n", sh->addralign); + printf("entsize %" PRIu64 "\n", sh->entsize); + printf("\n"); +} + +void +printelf64phdr(Elf64_Phdr *ph, Fhdr *fp) +{ + USED(fp); + printf("program header\n"); + printf("type %u\n", ph->type); + printf("flags 0x%.8x\n", ph->flags); + printf("offset 0x%.16" PRIx64 "\n", ph->offset); + printf("vaddr 0x%.16" PRIx64 "\n", ph->vaddr); + printf("paddr 0x%.16" PRIx64 "\n", ph->paddr); + printf("filesz %" PRIu64 "\n", ph->filesz); + printf("memsz %" PRIu64 "\n", ph->memsz); + printf("align 0x%.16" PRIx64 "\n", ph->align); + printf("\n"); +}