├── .github └── workflows │ ├── c.yml │ └── coverity.yml ├── LICENSE ├── Makefile ├── README.md ├── dat.h ├── elf.c ├── elf.h ├── fns.h ├── print.c └── str.c /.github/workflows/c.yml: -------------------------------------------------------------------------------- 1 | name: C 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: make nuke 17 | run: make nuke 18 | - name: make 19 | run: make 20 | -------------------------------------------------------------------------------- /.github/workflows/coverity.yml: -------------------------------------------------------------------------------- 1 | name: Coverity Scan 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | coverity: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: vapier/coverity-scan-action@v1 13 | with: 14 | email: ${{ secrets.COVERITY_SCAN_EMAIL }} 15 | token: ${{ secrets.COVERITY_SCAN_TOKEN }} 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 David du Colombier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 | OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | AR?=ar 2 | AS?=as 3 | RANLIB?=ranlib 4 | CC?=gcc 5 | LD?=gcc 6 | CFLAGS?=-Wall -Wextra -c -I./libbele -O3 7 | LDFLAGS?= 8 | 9 | LIB=libelf.a 10 | 11 | OFILES=\ 12 | elf.o\ 13 | print.o\ 14 | str.o\ 15 | 16 | HFILES=\ 17 | dat.h\ 18 | elf.h\ 19 | fns.h\ 20 | 21 | default: deps $(LIB) 22 | $(LIB): $(OFILES) $(HFILES) 23 | $(AR) r $(LIB) $(OFILES) 24 | $(RANLIB) $(LIB) 25 | 26 | deps: 27 | git clone -q https://github.com/0intro/libbele 28 | 29 | cleandeps: 30 | rm -rf libbele 31 | 32 | %.o: %.c 33 | $(CC) $(CFLAGS) $*.c 34 | 35 | clean: 36 | rm -f *.o 37 | 38 | nuke: clean cleandeps 39 | rm -f $(LIB) 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/0intro/libelf/workflows/C/badge.svg)](https://github.com/0intro/libelf/actions/workflows/c.yml) 2 | [![Coverity Scan Build Status](https://scan.coverity.com/projects/0intro-libelf/badge.svg)](https://scan.coverity.com/projects/0intro-libelf) 3 | 4 | libelf 5 | ====== 6 | 7 | Libelf is a simple library which provides functions to read ELF files. 8 | 9 | Headers 10 | ------- 11 | 12 | ``` 13 | #include 14 | #include 15 | ``` 16 | 17 | Structures 18 | ---------- 19 | 20 | ``` 21 | typedef struct Fhdr Fhdr; 22 | 23 | /* 24 | * Portable ELF file header 25 | */ 26 | struct Fhdr { 27 | /* Private */ 28 | ... 29 | 30 | /* ELF Identification */ 31 | uint8_t class; /* File class */ 32 | uint8_t data; /* Data encoding */ 33 | uint8_t elfversion; /* File version */ 34 | uint8_t osabi; /* Operating system/ABI identification */ 35 | uint8_t abiversion; /* ABI version */ 36 | 37 | /* ELF Header */ 38 | uint16_t type; 39 | uint16_t machine; 40 | uint32_t version; 41 | uint64_t entry; 42 | uint64_t phoff; 43 | uint64_t shoff; 44 | uint16_t ehsize; /* ELF Header size */ 45 | uint16_t phentsize; /* Section Header size */ 46 | uint16_t phnum; 47 | uint16_t shentsize; /* Program Header size */ 48 | uint16_t shnum; 49 | uint16_t shstrndx; 50 | 51 | /* Section Header */ 52 | uint32_t name; 53 | uint64_t offset; 54 | uint64_t size; 55 | 56 | /* String Table */ 57 | uint32_t strndxsize; /* String Table Size */ 58 | uint8_t *strndx; /* Copy of String Table */ 59 | }; 60 | ``` 61 | 62 | Functions 63 | --------- 64 | 65 | ``` 66 | /* Read */ 67 | int readelf(FILE *f, Fhdr *fp); 68 | uint8_t* readelfsection(FILE *f, char *name, uint64_t *size, Fhdr *fp); 69 | void freeelf(Fhdr *fp); 70 | 71 | /* Print */ 72 | void printelfhdr(Fhdr *fp); 73 | 74 | /* String */ 75 | char* elfclass(uint8_t class); 76 | char* elfdata(uint8_t data); 77 | char* elfosabi(uint8_t osabi); 78 | char* elftype(uint16_t type); 79 | char* elfmachine(uint16_t machine); 80 | char* elfversion(uint8_t version); 81 | ``` 82 | 83 | Example 84 | ------- 85 | 86 | ``` 87 | Fhdr fhdr; 88 | FILE *f; 89 | uint8_t *buf; 90 | uint64_t len; 91 | 92 | f = fopen("/bin/ls", "rb"); 93 | if (f == NULL) 94 | return -1; 95 | 96 | buf = readelfsection(f, ".text", &len, &fhdr); 97 | if (buf == NULL) 98 | return -1; 99 | 100 | // ... 101 | 102 | freeelf(&fhdr); 103 | ``` 104 | -------------------------------------------------------------------------------- /dat.h: -------------------------------------------------------------------------------- 1 | #define USED(x) if(x){}else{} 2 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) 3 | 4 | extern char *machinestr[]; 5 | 6 | #define EI_NIDENT 16 7 | 8 | enum { 9 | Eh32sz = 52, 10 | Sh32sz = 40, 11 | Ph32sz = 32, 12 | Eh64sz = 64, 13 | Sh64sz = 64, 14 | Ph64sz = 56, 15 | }; 16 | 17 | /* 18 | * ELF32 Header 19 | */ 20 | typedef struct { 21 | uint8_t ident[EI_NIDENT]; 22 | uint16_t type; 23 | uint16_t machine; 24 | uint32_t version; 25 | uint32_t entry; 26 | uint32_t phoff; 27 | uint32_t shoff; 28 | uint32_t flags; 29 | uint16_t ehsize; 30 | uint16_t phentsize; 31 | uint16_t phnum; 32 | uint16_t shentsize; 33 | uint16_t shnum; 34 | uint16_t shstrndx; 35 | } Elf32_Ehdr; 36 | 37 | /* 38 | * ELF64 Header 39 | */ 40 | typedef struct { 41 | uint8_t ident[EI_NIDENT]; 42 | uint16_t type; 43 | uint16_t machine; 44 | uint32_t version; 45 | uint64_t entry; 46 | uint64_t phoff; 47 | uint64_t shoff; 48 | uint32_t flags; 49 | uint16_t ehsize; 50 | uint16_t phentsize; 51 | uint16_t phnum; 52 | uint16_t shentsize; 53 | uint16_t shnum; 54 | uint16_t shstrndx; 55 | } Elf64_Ehdr; 56 | 57 | /* 58 | * ELF32 Section Header 59 | */ 60 | typedef struct { 61 | uint32_t name; 62 | uint32_t type; 63 | uint32_t flags; 64 | uint32_t addr; 65 | uint32_t offset; 66 | uint32_t size; 67 | uint32_t link; 68 | uint32_t info; 69 | uint32_t addralign; 70 | uint32_t entsize; 71 | } Elf32_Shdr; 72 | 73 | /* 74 | * ELF64 Section Header 75 | */ 76 | typedef struct { 77 | uint32_t name; 78 | uint32_t type; 79 | uint64_t flags; 80 | uint64_t addr; 81 | uint64_t offset; 82 | uint64_t size; 83 | uint32_t link; 84 | uint32_t info; 85 | uint64_t addralign; 86 | uint64_t entsize; 87 | } Elf64_Shdr; 88 | 89 | /* 90 | * ELF32 Program Header 91 | */ 92 | typedef struct { 93 | uint32_t type; 94 | uint32_t offset; 95 | uint32_t vaddr; 96 | uint32_t paddr; 97 | uint32_t filesz; 98 | uint32_t memsz; 99 | uint32_t flags; 100 | uint32_t align; 101 | } Elf32_Phdr; 102 | 103 | /* 104 | * ELF64 Program Header 105 | */ 106 | typedef struct { 107 | uint32_t type; 108 | uint32_t flags; 109 | uint64_t offset; 110 | uint64_t vaddr; 111 | uint64_t paddr; 112 | uint64_t filesz; 113 | uint64_t memsz; 114 | uint64_t align; 115 | } Elf64_Phdr; 116 | 117 | /* 118 | * Object file type 119 | */ 120 | enum { 121 | ET_NONE = 0, /* No file type */ 122 | ET_REL = 1, /* Relocatable file */ 123 | ET_EXEC = 2, /* Executable file */ 124 | ET_DYN = 3, /* Shared object file */ 125 | ET_CORE = 4, /* Core file */ 126 | ET_LOOS = 0xfe00, /* Operating system-specific */ 127 | ET_HIOS = 0xfeff, /* Operating system-specific */ 128 | ET_LOPROC = 0xff00, /* Processor-specific */ 129 | ET_HIPROC = 0xffff, /* Processor-specific */ 130 | }; 131 | 132 | /* 133 | * Architectures 134 | */ 135 | enum { 136 | EM_NONE = 0, /* No machine */ 137 | EM_M32 = 1, /* AT&T WE 32100 */ 138 | EM_SPARC = 2, /* SPARC */ 139 | EM_386 = 3, /* Intel 80386 */ 140 | EM_68K = 4, /* Motorola 68000 */ 141 | EM_88K = 5, /* Motorola 88000 */ 142 | EM_IAMCU = 6, /* Intel MCU */ 143 | EM_860 = 7, /* Intel 80860 */ 144 | EM_MIPS = 8, /* MIPS I Architecture */ 145 | EM_S370 = 9, /* IBM System/370 Processor */ 146 | EM_MIPS_RS3_LE = 10, /* MIPS RS3000 Little-endian */ 147 | /* 11-14 Reserved for future use */ 148 | EM_PARISC = 15, /* Hewlett-Packard PA-RISC */ 149 | reserved = 16, /* Reserved for future use */ 150 | EM_VPP500 = 17, /* Fujitsu VPP500 */ 151 | EM_SPARC32PLUS = 18, /* Enhanced instruction set SPARC */ 152 | EM_960 = 19, /* Intel 80960 */ 153 | EM_PPC = 20, /* PowerPC */ 154 | EM_PPC64 = 21, /* 64-bit PowerPC */ 155 | EM_S390 = 22, /* IBM System/390 Processor */ 156 | EM_SPU = 23, /* IBM SPU/SPC */ 157 | /* 24-35 Reserved for future use */ 158 | EM_V800 = 36, /* NEC V800 */ 159 | EM_FR20 = 37, /* Fujitsu FR20 */ 160 | EM_RH32 = 38, /* TRW RH-32 */ 161 | EM_RCE = 39, /* Motorola RCE */ 162 | EM_ARM = 40, /* ARM 32-bit architecture (AARCH32) */ 163 | EM_ALPHA = 41, /* Digital Alpha */ 164 | EM_SH = 42, /* Hitachi SH */ 165 | EM_SPARCV9 = 43, /* SPARC Version 9 */ 166 | EM_TRICORE = 44, /* Siemens TriCore embedded processor */ 167 | EM_ARC = 45, /* Argonaut RISC Core, Argonaut Technologies Inc. */ 168 | EM_H8_300 = 46, /* Hitachi H8/300 */ 169 | EM_H8_300H = 47, /* Hitachi H8/300H */ 170 | EM_H8S = 48, /* Hitachi H8S */ 171 | EM_H8_500 = 49, /* Hitachi H8/500 */ 172 | EM_IA_64 = 50, /* Intel IA-64 processor architecture */ 173 | EM_MIPS_X = 51, /* Stanford MIPS-X */ 174 | EM_COLDFIRE = 52, /* Motorola ColdFire */ 175 | EM_68HC12 = 53, /* Motorola M68HC12 */ 176 | EM_MMA = 54, /* Fujitsu MMA Multimedia Accelerator */ 177 | EM_PCP = 55, /* Siemens PCP */ 178 | EM_NCPU = 56, /* Sony nCPU embedded RISC processor */ 179 | EM_NDR1 = 57, /* Denso NDR1 microprocessor */ 180 | EM_STARCORE = 58, /* Motorola Star*Core processor */ 181 | EM_ME16 = 59, /* Toyota ME16 processor */ 182 | EM_ST100 = 60, /* STMicroelectronics ST100 processor */ 183 | EM_TINYJ = 61, /* Advanced Logic Corp. TinyJ embedded processor family */ 184 | EM_X86_64 = 62, /* AMD x86-64 architecture */ 185 | EM_PDSP = 63, /* Sony DSP Processor */ 186 | EM_PDP10 = 64, /* Digital Equipment Corp. PDP-10 */ 187 | EM_PDP11 = 65, /* Digital Equipment Corp. PDP-11 */ 188 | EM_FX66 = 66, /* Siemens FX66 microcontroller */ 189 | EM_ST9PLUS = 67, /* STMicroelectronics ST9+ 8/16 bit microcontroller */ 190 | EM_ST7 = 68, /* STMicroelectronics ST7 8-bit microcontroller */ 191 | EM_68HC16 = 69, /* Motorola MC68HC16 Microcontroller */ 192 | EM_68HC11 = 70, /* Motorola MC68HC11 Microcontroller */ 193 | EM_68HC08 = 71, /* Motorola MC68HC08 Microcontroller */ 194 | EM_68HC05 = 72, /* Motorola MC68HC05 Microcontroller */ 195 | EM_SVX = 73, /* Silicon Graphics SVx */ 196 | EM_ST19 = 74, /* STMicroelectronics ST19 8-bit microcontroller */ 197 | EM_VAX = 75, /* Digital VAX */ 198 | EM_CRIS = 76, /* Axis Communications 32-bit embedded processor */ 199 | EM_JAVELIN = 77, /* Infineon Technologies 32-bit embedded processor */ 200 | EM_FIREPATH = 78, /* Element 14 64-bit DSP Processor */ 201 | EM_ZSP = 79, /* LSI Logic 16-bit DSP Processor */ 202 | EM_MMIX = 80, /* Donald Knuth's educational 64-bit processor */ 203 | EM_HUANY = 81, /* Harvard University machine-independent object files */ 204 | EM_PRISM = 82, /* SiTera Prism */ 205 | EM_AVR = 83, /* Atmel AVR 8-bit microcontroller */ 206 | EM_FR30 = 84, /* Fujitsu FR30 */ 207 | EM_D10V = 85, /* Mitsubishi D10V */ 208 | EM_D30V = 86, /* Mitsubishi D30V */ 209 | EM_V850 = 87, /* NEC v850 */ 210 | EM_M32R = 88, /* Mitsubishi M32R */ 211 | EM_MN10300 = 89, /* Matsushita MN10300 */ 212 | EM_MN10200 = 90, /* Matsushita MN10200 */ 213 | EM_PJ = 91, /* picoJava */ 214 | EM_OPENRISC = 92, /* OpenRISC 32-bit embedded processor */ 215 | EM_ARC_COMPACT = 93, /* ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) */ 216 | EM_XTENSA = 94, /* Tensilica Xtensa Architecture */ 217 | EM_VIDEOCORE = 95, /* Alphamosaic VideoCore processor */ 218 | EM_TMM_GPP = 96, /* Thompson Multimedia General Purpose Processor */ 219 | EM_NS32K = 97, /* National Semiconductor 32000 series */ 220 | EM_TPC = 98, /* Tenor Network TPC processor */ 221 | EM_SNP1K = 99, /* Trebia SNP 1000 processor */ 222 | EM_ST200 = 100, /* STMicroelectronics (www.st.com) ST200 microcontroller */ 223 | EM_IP2K = 101, /* Ubicom IP2xxx microcontroller family */ 224 | EM_MAX = 102, /* MAX Processor */ 225 | EM_CR = 103, /* National Semiconductor CompactRISC microprocessor */ 226 | EM_F2MC16 = 104, /* Fujitsu F2MC16 */ 227 | EM_MSP430 = 105, /* Texas Instruments embedded microcontroller msp430 */ 228 | EM_BLACKFIN = 106, /* Analog Devices Blackfin (DSP) processor */ 229 | EM_SE_C33 = 107, /* S1C33 Family of Seiko Epson processors */ 230 | EM_SEP = 108, /* Sharp embedded microprocessor */ 231 | EM_ARCA = 109, /* Arca RISC Microprocessor */ 232 | EM_UNICORE = 110, /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University*/ 233 | EM_EXCESS = 111, /* eXcess: 16/32/64-bit configurable embedded CPU */ 234 | EM_DXP = 112, /* Icera Semiconductor Inc. Deep Execution Processor */ 235 | EM_ALTERA_NIOS2 = 113, /* Altera Nios II soft-core processor */ 236 | EM_CRX = 114, /* National Semiconductor CompactRISC CRX microprocessor */ 237 | EM_XGATE = 115, /* Motorola XGATE embedded processor */ 238 | EM_C166 = 116, /* Infineon C16x/XC16x processor */ 239 | EM_M16C = 117, /* Renesas M16C series microprocessors */ 240 | EM_DSPIC30F = 118, /* Microchip Technology dsPIC30F Digital Signal Controller */ 241 | EM_CE = 119, /* Freescale Communication Engine RISC core */ 242 | EM_M32C = 120, /* Renesas M32C series microprocessors */ 243 | /* 121-130 Reserved for future use */ 244 | EM_TSK3000 = 131, /* Altium TSK3000 core */ 245 | EM_RS08 = 132, /* Freescale RS08 embedded processor */ 246 | EM_SHARC = 133, /* Analog Devices SHARC family of 32-bit DSP processors */ 247 | EM_ECOG2 = 134, /* Cyan Technology eCOG2 microprocessor */ 248 | EM_SCORE7 = 135, /* Sunplus S+core7 RISC processor */ 249 | EM_DSP24 = 136, /* New Japan Radio (NJR) 24-bit DSP Processor */ 250 | EM_VIDEOCORE3 = 137, /* Broadcom VideoCore III processor */ 251 | EM_LATTICEMICO32 = 138, /* RISC processor for Lattice FPGA architecture */ 252 | EM_SE_C17 = 139, /* Seiko Epson C17 family */ 253 | EM_TI_C6000 = 140, /* The Texas Instruments TMS320C6000 DSP family */ 254 | EM_TI_C2000 = 141, /* The Texas Instruments TMS320C2000 DSP family */ 255 | EM_TI_C5500 = 142, /* The Texas Instruments TMS320C55x DSP family */ 256 | EM_TI_ARP32 = 143, /* Texas Instruments Application Specific RISC Processor, 32bit fetch */ 257 | EM_TI_PRU = 144, /* Texas Instruments Programmable Realtime Unit */ 258 | /* 145-159 Reserved for future use */ 259 | EM_MMDSP_PLUS = 160, /* STMicroelectronics 64bit VLIW Data Signal Processor */ 260 | EM_CYPRESS_M8C = 161, /* Cypress M8C microprocessor */ 261 | EM_R32C = 162, /* Renesas R32C series microprocessors */ 262 | EM_TRIMEDIA = 163, /* NXP Semiconductors TriMedia architecture family */ 263 | EM_QDSP6 = 164, /* QUALCOMM DSP6 Processor */ 264 | EM_8051 = 165, /* Intel 8051 and variants */ 265 | EM_STXP7X = 166, /* STMicroelectronics STxP7x family of configurable and extensible RISC processors */ 266 | EM_NDS32 = 167, /* Andes Technology compact code size embedded RISC processor family */ 267 | EM_ECOG1X = 168, /* Cyan Technology eCOG1X family */ 268 | EM_MAXQ30 = 169, /* Dallas Semiconductor MAXQ30 Core Micro-controllers */ 269 | EM_XIMO16 = 170, /* New Japan Radio (NJR) 16-bit DSP Processor */ 270 | EM_MANIK = 171, /* M2000 Reconfigurable RISC Microprocessor */ 271 | EM_CRAYNV2 = 172, /* Cray Inc. NV2 vector architecture */ 272 | EM_RX = 173, /* Renesas RX family */ 273 | EM_METAG = 174, /* Imagination Technologies META processor architecture */ 274 | EM_MCST_ELBRUS = 175, /* MCST Elbrus general purpose hardware architecture */ 275 | EM_ECOG16 = 176, /* Cyan Technology eCOG16 family */ 276 | EM_CR16 = 177, /* National Semiconductor CompactRISC CR16 16-bit microprocessor */ 277 | EM_ETPU = 178, /* Freescale Extended Time Processing Unit */ 278 | EM_SLE9X = 179, /* Infineon Technologies SLE9X core */ 279 | EM_L10M = 180, /* Intel L10M */ 280 | EM_K10M = 181, /* Intel K10M */ 281 | /* 182 Reserved for future Intel use */ 282 | EM_AARCH64 = 183, /* ARM 64-bit architecture (AARCH64) */ 283 | /* 184 Reserved for future ARM use */ 284 | EM_AVR32 = 185, /* Atmel Corporation 32-bit microprocessor family */ 285 | EM_STM8 = 186, /* STMicroeletronics STM8 8-bit microcontroller */ 286 | EM_TILE64 = 187, /* Tilera TILE64 multicore architecture family */ 287 | EM_TILEPRO = 188, /* Tilera TILEPro multicore architecture family */ 288 | EM_MICROBLAZE = 189, /* Xilinx MicroBlaze 32-bit RISC soft processor core */ 289 | EM_CUDA = 190, /* NVIDIA CUDA architecture */ 290 | EM_TILEGX = 191, /* Tilera TILE-Gx multicore architecture family */ 291 | EM_CLOUDSHIELD = 192, /* CloudShield architecture family */ 292 | EM_COREA_1ST = 193, /* KIPO-KAIST Core-A 1st generation processor family */ 293 | EM_COREA_2ND = 194, /* KIPO-KAIST Core-A 2nd generation processor family */ 294 | EM_ARC_COMPACT2 = 195, /* Synopsys ARCompact V2 */ 295 | EM_OPEN8 = 196, /* Open8 8-bit RISC soft processor core */ 296 | EM_RL78 = 197, /* Renesas RL78 family */ 297 | EM_VIDEOCORE5 = 198, /* Broadcom VideoCore V processor */ 298 | EM_78KOR = 199, /* Renesas 78KOR family */ 299 | EM_56800EX = 200, /* Freescale 56800EX Digital Signal Controller (DSC) */ 300 | EM_BA1 = 201, /* Beyond BA1 CPU architecture */ 301 | EM_BA2 = 202, /* Beyond BA2 CPU architecture */ 302 | EM_XCORE = 203, /* XMOS xCORE processor family */ 303 | EM_MCHP_PIC = 204, /* Microchip 8-bit PIC(r) family */ 304 | EM_INTEL205 = 205, /* Reserved by Intel */ 305 | EM_INTEL206 = 206, /* Reserved by Intel */ 306 | EM_INTEL207 = 207, /* Reserved by Intel */ 307 | EM_INTEL208 = 208, /* Reserved by Intel */ 308 | EM_INTEL209 = 209, /* Reserved by Intel */ 309 | EM_KM32 = 210, /* KM211 KM32 32-bit processor */ 310 | EM_KMX32 = 211, /* KM211 KMX32 32-bit processor */ 311 | EM_KMX16 = 212, /* KM211 KMX16 16-bit processor */ 312 | EM_KMX8 = 213, /* KM211 KMX8 8-bit processor */ 313 | EM_KVARC = 214, /* KM211 KVARC processor */ 314 | EM_CDP = 215, /* Paneve CDP architecture family */ 315 | EM_COGE = 216, /* Cognitive Smart Memory Processor */ 316 | EM_COOL = 217, /* Bluechip Systems CoolEngine */ 317 | EM_NORC = 218, /* Nanoradio Optimized RISC */ 318 | EM_CSR_KALIMBA = 219, /* CSR Kalimba architecture family */ 319 | EM_Z80 = 220, /* Zilog Z80 */ 320 | EM_VISIUM = 221, /* Controls and Data Services VISIUMcore processor */ 321 | EM_FT32 = 222, /* FTDI Chip FT32 high performance 32-bit RISC architecture */ 322 | EM_MOXIE = 223, /* Moxie processor family */ 323 | EM_AMDGPU = 224, /* AMD GPU architecture */ 324 | /* 225-242 */ 325 | EM_RISCV = 243, /* RISC-V */ 326 | }; 327 | 328 | /* 329 | * Object file version 330 | */ 331 | enum { 332 | EV_NONE = 0, /* Invalid */ 333 | EV_CURRENT = 1, /* Current */ 334 | }; 335 | 336 | /* 337 | * Identification 338 | */ 339 | enum { 340 | EI_MAG0 = 0, /* File identification */ 341 | EI_MAG1 = 1, /* File identification */ 342 | EI_MAG2 = 2, /* File identification */ 343 | EI_MAG3 = 3, /* File identification */ 344 | EI_CLASS = 4, /* File class */ 345 | EI_DATA = 5, /* Data encoding */ 346 | EI_VERSION = 6, /* File version */ 347 | EI_OSABI = 7, /* Operating system/ABI identification */ 348 | EI_ABIVERSION = 8, /* ABI version */ 349 | EI_PAD = 9, /* Start of padding bytes */ 350 | }; 351 | 352 | /* 353 | * ELF Magic Number 354 | */ 355 | enum { 356 | ELFMAG0 = 0x7f, /* e_ident[EI_MAG0] */ 357 | ELFMAG1 = 'E', /* e_ident[EI_MAG1] */ 358 | ELFMAG2 = 'L', /* e_ident[EI_MAG2] */ 359 | ELFMAG3 = 'F', /* e_ident[EI_MAG3] */ 360 | }; 361 | 362 | /* 363 | * File class 364 | */ 365 | enum { 366 | ELFCLASSNONE = 0, /* Invalid class */ 367 | ELFCLASS32 = 1, /* 32-bit objects */ 368 | ELFCLASS64 = 2, /* 64-bit objects */ 369 | }; 370 | 371 | /* 372 | * Data encoding 373 | */ 374 | enum { 375 | ELFDATANONE = 0, /* Invalid data encoding */ 376 | ELFDATA2LSB = 1, /* Litte-endian */ 377 | ELFDATA2MSB = 2, /* Big-endian */ 378 | }; 379 | 380 | /* 381 | * Operating system/ABI identification 382 | */ 383 | enum { 384 | ELFOSABI_NONE = 0, /* No extensions or unspecified */ 385 | ELFOSABI_HPUX = 1, /* Hewlett-Packard HP-UX */ 386 | ELFOSABI_NETBSD = 2, /* NetBSD */ 387 | ELFOSABI_GNU = 3, /* GNU */ 388 | ELFOSABI_SOLARIS = 6, /* Sun Solaris */ 389 | ELFOSABI_AIX = 7, /* AIX */ 390 | ELFOSABI_IRIX = 8, /* IRIX */ 391 | ELFOSABI_FREEBSD = 9, /* FreeBSD */ 392 | ELFOSABI_TRU64 = 10, /* Compaq TRU64 UNIX */ 393 | ELFOSABI_MODESTO = 11, /* Novell Modesto */ 394 | ELFOSABI_OPENBSD = 12, /* Open BSD */ 395 | ELFOSABI_OPENVMS = 13, /* Open VMS */ 396 | ELFOSABI_NSK = 14, /* Hewlett-Packard Non-Stop Kernel */ 397 | ELFOSABI_AROS = 15, /* Amiga Research OS */ 398 | ELFOSABI_FENIXOS = 16, /* The FenixOS highly scalable multi-core OS */ 399 | ELFOSABI_CLOUDABI = 17, /* Nuxi CloudABI */ 400 | ELFOSABI_OPENVOS = 18, /* Stratus Technologies OpenVOS */ 401 | /* 64-255 Architecture-specific value range */ 402 | }; 403 | 404 | /* 405 | * Special Section Indexes 406 | */ 407 | enum { 408 | SHN_UNDEF = 0, 409 | SHN_LORESERVE = 0xff00, 410 | SHN_LOPROC = 0xff00, 411 | SHN_HIPROC = 0xff1f, 412 | SHN_LOOS = 0xff20, 413 | SHN_HIOS = 0xff3f, 414 | SHN_ABS = 0xfff1, 415 | SHN_COMMON = 0xfff2, 416 | SHN_XINDEX = 0xffff, 417 | SHN_HIRESERVE = 0xffff, 418 | }; 419 | 420 | /* 421 | * Section Types 422 | */ 423 | enum { 424 | SHT_NULL = 0, 425 | SHT_PROGBITS = 1, 426 | SHT_SYMTAB = 2, 427 | SHT_STRTAB = 3, 428 | SHT_RELA = 4, 429 | SHT_HASH = 5, 430 | SHT_DYNAMIC = 6, 431 | SHT_NOTE = 7, 432 | SHT_NOBITS = 8, 433 | SHT_REL = 9, 434 | SHT_SHLIB = 10, 435 | SHT_DYNSYM = 11, 436 | SHT_INIT_ARRAY = 14, 437 | SHT_FINI_ARRAY = 15, 438 | SHT_PREINIT_ARRAY = 16, 439 | SHT_GROUP = 17, 440 | SHT_SYMTAB_SHNDX = 18, 441 | SHT_LOOS = 0x60000000, 442 | SHT_HIOS = 0x6fffffff, 443 | SHT_LOPROC = 0x70000000, 444 | SHT_HIPROC = 0x7fffffff, 445 | SHT_LOUSER = 0x80000000, 446 | SHT_HIUSER = 0xffffffff, 447 | }; 448 | 449 | /* 450 | * Section Attribute Flags 451 | */ 452 | enum { 453 | SHF_WRITE = 0x1, 454 | SHF_ALLOC = 0x2, 455 | SHF_EXECINSTR = 0x4, 456 | SHF_MERGE = 0x10, 457 | SHF_STRINGS = 0x20, 458 | SHF_INFO_LINK = 0x40, 459 | SHF_LINK_ORDER = 0x80, 460 | SHF_OS_NONCONFORMING = 0x100, 461 | SHF_GROUP = 0x200, 462 | SHF_TLS = 0x400, 463 | SHF_COMPRESSED = 0x800, 464 | SHF_MASKOS = 0x0ff00000, 465 | SHF_MASKPROC = 0xf0000000, 466 | }; 467 | 468 | /* 469 | * Section Attribute Flags 470 | */ 471 | enum { 472 | GRP_COMDAT = 0x1, 473 | GRP_MASKOS = 0x0ff00000, 474 | GRP_MASKPROC = 0xf0000000, 475 | }; 476 | -------------------------------------------------------------------------------- /elf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "bele.h" 8 | #include "elf.h" 9 | #include "dat.h" 10 | #include "fns.h" 11 | 12 | static int verbose; 13 | 14 | typedef struct Data Data; 15 | typedef struct Class Class; 16 | 17 | struct Data { 18 | int type; 19 | char *name; 20 | unsigned int (*get8)(void*, uint8_t*); 21 | unsigned int (*get16)(void*, uint16_t*); 22 | unsigned int (*get32)(void*, uint32_t*); 23 | unsigned int (*get64)(void*, uint64_t*); 24 | }; 25 | 26 | struct Class { 27 | int type; 28 | char *name; 29 | int ehsize; 30 | int shentsize; 31 | int phentsize; 32 | int (*readelfehdr)(FILE*, Fhdr*); 33 | int (*readelfshdr)(FILE*, Fhdr*); 34 | int (*readelfphdr)(FILE*, Fhdr*); 35 | int (*readelfstrndx)(FILE*, Fhdr*); 36 | }; 37 | 38 | static int readelf32ehdr(FILE*, Fhdr*); 39 | static int readelf32shdr(FILE*, Fhdr*); 40 | static int readelf32phdr(FILE*, Fhdr*); 41 | static int readelf32strndx(FILE*, Fhdr*); 42 | 43 | static int readelf64ehdr(FILE*, Fhdr*); 44 | static int readelf64shdr(FILE*, Fhdr*); 45 | static int readelf64phdr(FILE*, Fhdr*); 46 | static int readelf64strndx(FILE*, Fhdr*); 47 | 48 | static Data data[] = { 49 | { 50 | ELFDATANONE, 51 | "invalid", 52 | NULL, 53 | NULL, 54 | NULL, 55 | NULL 56 | }, 57 | { 58 | ELFDATA2LSB, 59 | "little-endian", 60 | le8get, 61 | le16get, 62 | le32get, 63 | le64get 64 | }, 65 | { 66 | ELFDATA2MSB, 67 | "big-endian", 68 | be8get, 69 | be16get, 70 | be32get, 71 | be64get 72 | } 73 | }; 74 | 75 | static Class class[] = { 76 | { 77 | ELFCLASSNONE, 78 | "invalid", 79 | 0, 80 | 0, 81 | 0, 82 | NULL, 83 | NULL, 84 | NULL, 85 | NULL, 86 | }, 87 | { 88 | ELFCLASS32, 89 | "32-bit", 90 | sizeof(Elf32_Ehdr), 91 | sizeof(Elf32_Shdr), 92 | sizeof(Elf32_Phdr), 93 | readelf32ehdr, 94 | readelf32shdr, 95 | readelf32phdr, 96 | readelf32strndx, 97 | }, 98 | { 99 | ELFCLASS64, 100 | "64-bit", 101 | sizeof(Elf64_Ehdr), 102 | sizeof(Elf64_Shdr), 103 | sizeof(Elf64_Phdr), 104 | readelf64ehdr, 105 | readelf64shdr, 106 | readelf64phdr, 107 | readelf64strndx, 108 | } 109 | }; 110 | 111 | /* 112 | * Read ELF32 Header 113 | */ 114 | static int 115 | readelf32ehdr(FILE *f, Fhdr *fp) 116 | { 117 | uint8_t buf[Eh32sz]; 118 | Elf32_Ehdr e; 119 | uint8_t *p; 120 | 121 | p = buf; 122 | 123 | if (fseek(f, 0, SEEK_SET) < 0) 124 | return -1; 125 | 126 | if (fread(p, fp->ehsize, 1, f) != 1) 127 | return -1; 128 | 129 | memmove(&e.ident, p, sizeof(e.ident)); 130 | p += sizeof(e.ident); 131 | p += fp->get16(p, &e.type); 132 | p += fp->get16(p, &e.machine); 133 | p += fp->get32(p, &e.version); 134 | p += fp->get32(p, &e.entry); 135 | p += fp->get32(p, &e.phoff); 136 | p += fp->get32(p, &e.shoff); 137 | p += fp->get32(p, &e.flags); 138 | p += fp->get16(p, &e.ehsize); 139 | p += fp->get16(p, &e.phentsize); 140 | p += fp->get16(p, &e.phnum); 141 | p += fp->get16(p, &e.shentsize); 142 | p += fp->get16(p, &e.shnum); 143 | p += fp->get16(p, &e.shstrndx); 144 | 145 | if (verbose) 146 | printelf32ehdr(&e, fp); 147 | 148 | if (e.type != ET_REL && e.type != ET_EXEC && e.type != ET_DYN && e.type != ET_CORE) { 149 | fprintf(stderr, "unsupported file type %d\n", e.type); 150 | return -1; 151 | } 152 | 153 | if (fp->ehsize != e.ehsize) { 154 | fprintf(stderr, "ehsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); 155 | return -1; 156 | } 157 | 158 | if (fp->shentsize != e.shentsize) { 159 | fprintf(stderr, "shentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); 160 | return -1; 161 | } 162 | 163 | if (fp->phentsize != e.phentsize) { 164 | fprintf(stderr, "phentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); 165 | return -1; 166 | } 167 | 168 | fp->type = e.type; 169 | fp->machine = e.machine; 170 | fp->version = e.version; 171 | fp->entry = e.entry; 172 | 173 | fp->shoff = e.shoff; 174 | fp->phoff = e.phoff; 175 | fp->phnum = e.phnum; 176 | fp->shnum = e.shnum; 177 | fp->shstrndx = e.shstrndx; 178 | 179 | return (int)(p - buf); 180 | } 181 | 182 | /* 183 | * Read ELF64 Header 184 | */ 185 | static int 186 | readelf64ehdr(FILE *f, Fhdr *fp) 187 | { 188 | uint8_t buf[Eh64sz]; 189 | Elf64_Ehdr e; 190 | uint8_t *p; 191 | 192 | p = buf; 193 | 194 | if (fseek(f, 0, SEEK_SET) < 0) 195 | return -1; 196 | 197 | if (fread(p, fp->ehsize , 1, f) != 1) 198 | return -1; 199 | 200 | memmove(&e.ident, p, sizeof(e.ident)); 201 | p += sizeof(e.ident); 202 | p += fp->get16(p, &e.type); 203 | p += fp->get16(p, &e.machine); 204 | p += fp->get32(p, &e.version); 205 | p += fp->get64(p, &e.entry); 206 | p += fp->get64(p, &e.phoff); 207 | p += fp->get64(p, &e.shoff); 208 | p += fp->get32(p, &e.flags); 209 | p += fp->get16(p, &e.ehsize); 210 | p += fp->get16(p, &e.phentsize); 211 | p += fp->get16(p, &e.phnum); 212 | p += fp->get16(p, &e.shentsize); 213 | p += fp->get16(p, &e.shnum); 214 | p += fp->get16(p, &e.shstrndx); 215 | 216 | if (verbose) 217 | printelf64ehdr(&e, fp); 218 | 219 | if (e.type != ET_REL && e.type != ET_EXEC && e.type != ET_DYN && e.type != ET_CORE) { 220 | fprintf(stderr, "unsupported file type %d\n", e.type); 221 | return -1; 222 | } 223 | 224 | if (fp->ehsize != e.ehsize) { 225 | fprintf(stderr, "ehsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); 226 | return -1; 227 | } 228 | 229 | if (fp->shentsize != e.shentsize) { 230 | fprintf(stderr, "shentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); 231 | return -1; 232 | } 233 | 234 | if (fp->phentsize != e.phentsize) { 235 | fprintf(stderr, "phentsize mismatch; want %u; got %u\n", fp->ehsize, e.ehsize); 236 | return -1; 237 | } 238 | 239 | fp->type = e.type; 240 | fp->machine = e.machine; 241 | fp->version = e.version; 242 | fp->entry = e.entry; 243 | 244 | fp->shoff = e.shoff; 245 | fp->phoff = e.phoff; 246 | fp->phnum = e.phnum; 247 | fp->shnum = e.shnum; 248 | fp->shstrndx = e.shstrndx; 249 | 250 | return (int)(p - buf); 251 | } 252 | 253 | /* 254 | * Unpack ELF32 Section Header 255 | */ 256 | int 257 | unpackelf32shdr(uint8_t *buf, int len, Elf32_Shdr *sh, Fhdr *fp) 258 | { 259 | uint8_t *p; 260 | 261 | if (len < Sh32sz) 262 | return -1; 263 | 264 | p = buf; 265 | 266 | p += fp->get32(p, &sh->name); 267 | p += fp->get32(p, &sh->type); 268 | p += fp->get32(p, &sh->flags); 269 | p += fp->get32(p, &sh->addr); 270 | p += fp->get32(p, &sh->offset); 271 | p += fp->get32(p, &sh->size); 272 | p += fp->get32(p, &sh->link); 273 | p += fp->get32(p, &sh->info); 274 | p += fp->get32(p, &sh->addralign); 275 | p += fp->get32(p, &sh->entsize); 276 | 277 | return p - buf; 278 | } 279 | 280 | /* 281 | * Read ELF32 Section Header 282 | */ 283 | static int 284 | readelf32shdr(FILE *f, Fhdr *fp) 285 | { 286 | uint8_t buf[Sh32sz]; 287 | Elf32_Shdr sh; 288 | 289 | if (fread(buf, fp->shentsize, 1, f) != 1) 290 | return -1; 291 | 292 | if (unpackelf32shdr(buf, sizeof(buf), &sh, fp) < 0) 293 | return -1; 294 | 295 | fp->name = sh.name; 296 | fp->offset = sh.offset; 297 | fp->size = sh.size; 298 | 299 | if (verbose) 300 | printelf32shdr(&sh, fp); 301 | 302 | return 0; 303 | } 304 | 305 | /* 306 | * Unpack ELF32 Program Header 307 | */ 308 | int 309 | unpackelf32phdr(uint8_t *buf, int len, Elf32_Phdr *ph, Fhdr *fp) 310 | { 311 | uint8_t *p; 312 | 313 | if (len < Ph32sz) 314 | return -1; 315 | 316 | p = buf; 317 | 318 | p += fp->get32(p, &ph->type); 319 | p += fp->get32(p, &ph->offset); 320 | p += fp->get32(p, &ph->vaddr); 321 | p += fp->get32(p, &ph->paddr); 322 | p += fp->get32(p, &ph->filesz); 323 | p += fp->get32(p, &ph->memsz); 324 | p += fp->get32(p, &ph->flags); 325 | p += fp->get32(p, &ph->align); 326 | 327 | return p - buf; 328 | } 329 | 330 | /* 331 | * Read ELF32 Program Header 332 | */ 333 | static int 334 | readelf32phdr(FILE *f, Fhdr *fp) 335 | { 336 | uint8_t buf[Ph32sz]; 337 | Elf32_Phdr ph; 338 | 339 | if (fread(buf, fp->phentsize, 1, f) != 1) 340 | return -1; 341 | 342 | if (unpackelf32phdr(buf, sizeof(buf), &ph, fp) < 0) 343 | return -1; 344 | 345 | if (verbose) 346 | printelf32phdr(&ph, fp); 347 | 348 | return 0; 349 | } 350 | 351 | /* 352 | * Unpack ELF64 Section Header 353 | */ 354 | int 355 | unpackelf64shdr(uint8_t *buf, int len, Elf64_Shdr *sh, Fhdr *fp) 356 | { 357 | uint8_t *p; 358 | 359 | if (len < Sh64sz) 360 | return -1; 361 | 362 | p = buf; 363 | 364 | p += fp->get32(p, &sh->name); 365 | p += fp->get32(p, &sh->type); 366 | p += fp->get64(p, &sh->flags); 367 | p += fp->get64(p, &sh->addr); 368 | p += fp->get64(p, &sh->offset); 369 | p += fp->get64(p, &sh->size); 370 | p += fp->get32(p, &sh->link); 371 | p += fp->get32(p, &sh->info); 372 | p += fp->get64(p, &sh->addralign); 373 | p += fp->get64(p, &sh->entsize); 374 | 375 | return p - buf; 376 | } 377 | 378 | /* 379 | * Read ELF64 Section Header 380 | */ 381 | static int 382 | readelf64shdr(FILE *f, Fhdr *fp) 383 | { 384 | uint8_t buf[Sh64sz]; 385 | Elf64_Shdr sh; 386 | 387 | if (fread(buf, fp->shentsize, 1, f) != 1) 388 | return -1; 389 | 390 | if (unpackelf64shdr(buf, sizeof(buf), &sh, fp) < 0) 391 | return -1; 392 | 393 | fp->name = sh.name; 394 | fp->offset = sh.offset; 395 | fp->size = sh.size; 396 | 397 | if (verbose) 398 | printelf64shdr(&sh, fp); 399 | 400 | return 0; 401 | } 402 | 403 | /* 404 | * Unpack ELF64 Program Header 405 | */ 406 | int 407 | unpackelf64phdr(uint8_t *buf, int len, Elf64_Phdr *ph, Fhdr *fp) 408 | { 409 | uint8_t *p; 410 | 411 | if (len < Ph64sz) 412 | return -1; 413 | 414 | p = buf; 415 | 416 | p += fp->get32(p, &ph->type); 417 | p += fp->get32(p, &ph->flags); 418 | p += fp->get64(p, &ph->offset); 419 | p += fp->get64(p, &ph->vaddr); 420 | p += fp->get64(p, &ph->paddr); 421 | p += fp->get64(p, &ph->filesz); 422 | p += fp->get64(p, &ph->memsz); 423 | p += fp->get64(p, &ph->align); 424 | 425 | return p - buf; 426 | } 427 | 428 | /* 429 | * Read ELF64 Program Header 430 | */ 431 | static int 432 | readelf64phdr(FILE *f, Fhdr *fp) 433 | { 434 | uint8_t buf[Ph64sz]; 435 | Elf64_Phdr ph; 436 | 437 | if (fread(buf, fp->phentsize, 1, f) != 1) 438 | return -1; 439 | 440 | if (unpackelf64phdr(buf, sizeof(buf), &ph, fp) < 0) 441 | return -1; 442 | 443 | if (verbose) 444 | printelf64phdr(&ph, fp); 445 | 446 | return 0; 447 | } 448 | 449 | /* 450 | * Read ELF ident 451 | */ 452 | int 453 | readident(FILE *f, Fhdr *fp) 454 | { 455 | uint8_t buf[EI_NIDENT]; 456 | unsigned int i; 457 | uint8_t *p; 458 | 459 | if (fseek(f, 0, SEEK_SET) < 0) 460 | return -1; 461 | 462 | p = buf; 463 | if (fread(p, EI_NIDENT, 1, f) != 1) 464 | return -1; 465 | 466 | p += EI_NIDENT; 467 | 468 | if (buf[EI_MAG0] != ELFMAG0) 469 | return -1; 470 | if (buf[EI_MAG1] != ELFMAG1) 471 | return -1; 472 | if (buf[EI_MAG2] != ELFMAG2) 473 | return -1; 474 | if (buf[EI_MAG3] != ELFMAG3) 475 | return -1; 476 | 477 | if(buf[EI_VERSION] != EV_CURRENT) { 478 | fprintf(stderr, "unsupported file version %d\n", buf[EI_VERSION]); 479 | return -1; 480 | } 481 | 482 | for (i = 0; i < nelem(class); i++) { 483 | if (buf[EI_CLASS] != class[i].type) 484 | continue; 485 | if (class[i].readelfehdr == NULL) 486 | return -1; 487 | fp->readelfehdr = class[i].readelfehdr; 488 | fp->readelfshdr = class[i].readelfshdr; 489 | fp->readelfphdr = class[i].readelfphdr; 490 | fp->readelfstrndx = class[i].readelfstrndx; 491 | fp->ehsize = class[i].ehsize; 492 | fp->shentsize = class[i].shentsize; 493 | fp->phentsize = class[i].phentsize; 494 | break; 495 | } 496 | 497 | if (i == nelem(class)) 498 | return -1; 499 | 500 | for (i = 0; i < nelem(data); i++) { 501 | if (buf[EI_DATA] != data[i].type) 502 | continue; 503 | if (data[i].get8 == NULL) 504 | return -1; 505 | fp->get8 = data[i].get8; 506 | fp->get16 = data[i].get16; 507 | fp->get32 = data[i].get32; 508 | fp->get64 = data[i].get64; 509 | break; 510 | } 511 | 512 | if (i == nelem(data)) 513 | return -1; 514 | 515 | fp->class = buf[EI_CLASS]; 516 | fp->data = buf[EI_DATA]; 517 | fp->elfversion = buf[EI_VERSION]; 518 | fp->osabi = buf[EI_OSABI]; 519 | fp->abiversion = buf[EI_ABIVERSION]; 520 | 521 | return (int)(p - buf); 522 | } 523 | 524 | /* 525 | * Read ELF Section Headers 526 | */ 527 | int 528 | readelfshdrs(FILE *f, Fhdr *fp) 529 | { 530 | unsigned int i; 531 | 532 | if (fseek(f, fp->shoff, SEEK_SET) < 0) 533 | return -1; 534 | 535 | for (i = 0; i < fp->shnum; i++) { 536 | if (fp->readelfshdr(f, fp) < 0) 537 | return -1; 538 | } 539 | 540 | return 0; 541 | } 542 | 543 | /* 544 | * Read ELF Program Headers 545 | */ 546 | int 547 | readelfphdrs(FILE *f, Fhdr *fp) 548 | { 549 | unsigned int i; 550 | 551 | if (fseek(f, fp->phoff, SEEK_SET) < 0) 552 | return -1; 553 | 554 | for (i = 0; i < fp->phnum; i++) { 555 | if (fp->readelfphdr(f, fp) < 0) 556 | return -1; 557 | } 558 | 559 | return 0; 560 | } 561 | 562 | /* 563 | * Read ELF32 String Table 564 | */ 565 | static int 566 | readelf32strndx(FILE *f, Fhdr *fp) 567 | { 568 | uint8_t buf[Sh32sz]; 569 | Elf32_Shdr sh; 570 | 571 | if (fseek(f, fp->shoff + (uint64_t)(fp->shstrndx * fp->shentsize), SEEK_SET) < 0) 572 | return -1; 573 | 574 | if (fread(buf, fp->shentsize, 1, f) != 1) 575 | return -1; 576 | 577 | if (unpackelf32shdr(buf, sizeof(buf), &sh, fp) < 0) 578 | return -1; 579 | 580 | fp->offset = sh.offset; 581 | fp->strndxsize = sh.size; 582 | 583 | return 0; 584 | } 585 | 586 | /* 587 | * Read ELF64 String Table 588 | */ 589 | static int 590 | readelf64strndx(FILE *f, Fhdr *fp) 591 | { 592 | uint8_t buf[Sh64sz]; 593 | Elf64_Shdr sh; 594 | 595 | if (fseek(f, fp->shoff + (uint64_t)(fp->shstrndx * fp->shentsize), SEEK_SET) < 0) 596 | return -1; 597 | 598 | if (fread(buf, fp->shentsize, 1, f) != 1) 599 | return -1; 600 | 601 | if (unpackelf64shdr(buf, sizeof(buf), &sh, fp) < 0) 602 | return -1; 603 | 604 | fp->offset = sh.offset; 605 | fp->strndxsize = sh.size; 606 | 607 | return 0; 608 | } 609 | 610 | static uint8_t* 611 | newsection(FILE *f, uint64_t offset, uint64_t size) 612 | { 613 | uint8_t *sect; 614 | 615 | sect = malloc(size); 616 | if (sect == NULL) 617 | return NULL; 618 | 619 | if (fseek(f, offset, SEEK_SET) < 0) { 620 | free(sect); 621 | return NULL; 622 | } 623 | 624 | if (fread(sect, size, 1, f) != 1) { 625 | free(sect); 626 | return NULL; 627 | } 628 | 629 | return sect; 630 | } 631 | 632 | /* 633 | * Read ELF String Table 634 | */ 635 | static int 636 | readelfstrndx(FILE *f, Fhdr *fp) 637 | { 638 | if (fp->shstrndx == SHN_UNDEF) { 639 | fprintf(stderr, "missing string table\n"); 640 | return -1; 641 | } 642 | 643 | if (fp->readelfstrndx(f, fp) < 0) 644 | return -1; 645 | 646 | fp->strndx = newsection(f, fp->offset, fp->strndxsize); 647 | if (fp->strndx == NULL) 648 | return -1; 649 | 650 | return 0; 651 | } 652 | 653 | /* 654 | * Get string from index in String Table 655 | */ 656 | char* getstr(Fhdr *fp, uint32_t i) 657 | { 658 | if (fp->strndx == NULL) 659 | return NULL; 660 | 661 | if (i >= fp->strndxsize) 662 | return NULL; 663 | 664 | return (char*)&fp->strndx[i]; 665 | } 666 | 667 | /* 668 | * Read ELF Section Headers 669 | */ 670 | uint8_t* 671 | readelfsect(FILE *f, char *name, Fhdr *fp) 672 | { 673 | unsigned int i; 674 | char *n; 675 | 676 | if (fseek(f, fp->shoff, SEEK_SET) < 0) 677 | return NULL; 678 | 679 | for (i = 0; i < fp->shnum; i++) { 680 | if (fp->readelfshdr(f, fp) < 0) 681 | return NULL; 682 | n = getstr(fp, fp->name); 683 | if (n == NULL) 684 | return NULL; 685 | if (strcmp(n, name) == 0) 686 | return newsection(f, fp->offset, fp->size); 687 | } 688 | 689 | fprintf(stderr, "section %s not found\n", name); 690 | 691 | return NULL; 692 | } 693 | 694 | /* 695 | * Read ELF File 696 | */ 697 | int 698 | readelf(FILE *f, Fhdr *fp) 699 | { 700 | memset(fp, 0, sizeof(*fp)); 701 | 702 | if (readident(f, fp) < 0) 703 | return -1; 704 | 705 | if (fp->readelfehdr(f, fp) < 0) 706 | return -1; 707 | 708 | if (readelfstrndx(f, fp) < 0) 709 | return -1; 710 | 711 | if (readelfshdrs(f, fp) < 0) 712 | return -1; 713 | 714 | if (readelfphdrs(f, fp) < 0) 715 | return -1; 716 | 717 | return 0; 718 | } 719 | 720 | /* 721 | * Read ELF Section 722 | */ 723 | uint8_t* 724 | readelfsection(FILE *f, char *name, uint64_t *size, Fhdr *fp) 725 | { 726 | uint8_t *sect; 727 | 728 | memset(fp, 0, sizeof(*fp)); 729 | 730 | if (readident(f, fp) < 0) 731 | return NULL; 732 | 733 | if (fp->readelfehdr(f, fp) < 0) 734 | return NULL; 735 | 736 | if (readelfstrndx(f, fp) < 0) 737 | return NULL; 738 | 739 | sect = readelfsect(f, name, fp); 740 | if (sect == NULL) 741 | return NULL; 742 | 743 | *size = fp->size; 744 | 745 | return sect; 746 | } 747 | 748 | 749 | void 750 | freeelf(Fhdr *fp) 751 | { 752 | if (fp->strndx != NULL) 753 | free(fp->strndx); 754 | } 755 | -------------------------------------------------------------------------------- /elf.h: -------------------------------------------------------------------------------- 1 | typedef struct Fhdr Fhdr; 2 | 3 | /* 4 | * Portable ELF file header 5 | */ 6 | struct Fhdr { 7 | /* ELF Data */ 8 | unsigned int (*get8)(void*, uint8_t*); 9 | unsigned int (*get16)(void*, uint16_t*); 10 | unsigned int (*get32)(void*, uint32_t*); 11 | unsigned int (*get64)(void*, uint64_t*); 12 | 13 | /* ELF Class */ 14 | int (*readelfehdr)(FILE*, Fhdr*); 15 | int (*readelfshdr)(FILE*, Fhdr*); 16 | int (*readelfphdr)(FILE*, Fhdr*); 17 | int (*readelfstrndx)(FILE*, Fhdr*); 18 | 19 | /* ELF Identification */ 20 | uint8_t class; /* File class */ 21 | uint8_t data; /* Data encoding */ 22 | uint8_t elfversion; /* File version */ 23 | uint8_t osabi; /* Operating system/ABI identification */ 24 | uint8_t abiversion; /* ABI version */ 25 | 26 | /* ELF Header */ 27 | uint16_t type; 28 | uint16_t machine; 29 | uint32_t version; 30 | uint64_t entry; 31 | uint64_t phoff; 32 | uint64_t shoff; 33 | uint16_t ehsize; /* ELF Header size */ 34 | uint16_t phentsize; /* Section Header size */ 35 | uint16_t phnum; 36 | uint16_t shentsize; /* Program Header size */ 37 | uint16_t shnum; 38 | uint16_t shstrndx; 39 | 40 | /* Section Header */ 41 | uint32_t name; 42 | uint64_t offset; 43 | uint64_t size; 44 | 45 | /* String Table */ 46 | uint32_t strndxsize; /* String Table size */ 47 | uint8_t *strndx; /* Copy of String Table */ 48 | }; 49 | 50 | /* Read */ 51 | int readelf(FILE*, Fhdr*); 52 | uint8_t* readelfsection(FILE*, char*, uint64_t*, Fhdr*); 53 | void freeelf(Fhdr*); 54 | 55 | /* Print */ 56 | void printelfhdr(Fhdr*); 57 | 58 | /* String */ 59 | char* elfclass(uint8_t); 60 | char* elfdata(uint8_t); 61 | char* elfosabi(uint8_t); 62 | char* elftype(uint16_t); 63 | char* elfmachine(uint16_t); 64 | char* elfversion(uint8_t); 65 | -------------------------------------------------------------------------------- /fns.h: -------------------------------------------------------------------------------- 1 | /* 2 | * print.c 3 | */ 4 | void printelf32ehdr(Elf32_Ehdr*, Fhdr*); 5 | void printelf64ehdr(Elf64_Ehdr*, Fhdr*); 6 | void printelf32shdr(Elf32_Shdr*, Fhdr*); 7 | void printelf64shdr(Elf64_Shdr*, Fhdr*); 8 | void printelf32phdr(Elf32_Phdr*, Fhdr*); 9 | void printelf64phdr(Elf64_Phdr*, Fhdr*); 10 | 11 | char* getstr(Fhdr*, uint32_t); 12 | -------------------------------------------------------------------------------- /print.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "elf.h" 6 | #include "dat.h" 7 | #include "fns.h" 8 | 9 | void 10 | printident(Fhdr *fp) 11 | { 12 | printf("class %s (0x%.2x)\n", elfclass(fp->class), fp->class); 13 | printf("data %s (0x%.2x)\n", elfdata(fp->data), fp->data); 14 | printf("version %s (%u)\n", elfversion(fp->version), fp->version); 15 | printf("os abi %s (0x%.2x)\n", elfosabi(fp->osabi), fp->osabi); 16 | printf("abi version %u\n", fp->abiversion); 17 | } 18 | 19 | void 20 | printelf32ehdr(Elf32_Ehdr *e, Fhdr *fp) 21 | { 22 | printf("ident %.2x %c %c %c %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", 23 | e->ident[0], e->ident[1], e->ident[2], e->ident[3], e->ident[4], e->ident[5], e->ident[6], e->ident[7], 24 | e->ident[8], e->ident[9], e->ident[10], e->ident[11], e->ident[12], e->ident[13], e->ident[14], e->ident[15]); 25 | printident(fp); 26 | printf("type %s (0x%.4x)\n", elftype(e->type), e->type); 27 | printf("machine %s (0x%.4x)\n", elfmachine(e->machine), e->machine); 28 | printf("version %s (%u)\n", elfversion(e->version), e->version); 29 | printf("entry 0x%.8x\n", e->entry); 30 | printf("phoff %u\n", e->phoff); 31 | printf("shoff %u\n", e->shoff); 32 | printf("flags 0x%.8x\n", e->flags); 33 | printf("ehsize %u\n", e->ehsize); 34 | printf("phentsize %u\n", e->phentsize); 35 | printf("phnum %u\n", e->phnum); 36 | printf("shentsize %u\n", e->shentsize); 37 | printf("shnum %u\n", e->shnum); 38 | printf("shstrndx %u\n", e->shstrndx); 39 | printf("\n"); 40 | } 41 | 42 | void 43 | printelf64ehdr(Elf64_Ehdr *e, Fhdr *fp) 44 | { 45 | printf("ident %.2x %c %c %c %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", 46 | e->ident[0], e->ident[1], e->ident[2], e->ident[3], e->ident[4], e->ident[5], e->ident[6], e->ident[7], 47 | e->ident[8], e->ident[9], e->ident[10], e->ident[11], e->ident[12], e->ident[13], e->ident[14], e->ident[15]); 48 | printident(fp); 49 | printf("type %s (0x%.4x)\n", elftype(e->type), e->type); 50 | printf("machine %s (0x%.4x)\n", elfmachine(e->machine), e->machine); 51 | printf("version %s (%u)\n", elfversion(e->version), e->version); 52 | printf("entry 0x%.16" PRIx64 "\n", e->entry); 53 | printf("phoff %" PRIu64 "\n", e->phoff); 54 | printf("shoff %" PRIu64 "\n", e->shoff); 55 | printf("flags 0x%.8x\n", e->flags); 56 | printf("ehsize %u\n", e->ehsize); 57 | printf("phentsize %u\n", e->phentsize); 58 | printf("phnum %u\n", e->phnum); 59 | printf("shentsize %u\n", e->shentsize); 60 | printf("shnum %u\n", e->shnum); 61 | printf("shstrndx %u\n", e->shstrndx); 62 | printf("\n"); 63 | } 64 | 65 | void 66 | printelf32shdr(Elf32_Shdr *sh, Fhdr *fp) 67 | { 68 | printf("section header\n"); 69 | printf("name %s (%u)\n", getstr(fp, sh->name), sh->name); 70 | printf("type %u\n", sh->type); 71 | printf("flags 0x%.8x\n", sh->flags); 72 | printf("addr 0x%.8x\n", sh->addr); 73 | printf("offset 0x%.8x\n", sh->offset); 74 | printf("size %u\n", sh->size); 75 | printf("link %u\n", sh->link); 76 | printf("info %u\n", sh->info); 77 | printf("addralign 0x%.8x\n", sh->addralign); 78 | printf("entsize %u\n", sh->entsize); 79 | printf("\n"); 80 | } 81 | 82 | void 83 | printelf32phdr(Elf32_Phdr *ph, Fhdr *fp) 84 | { 85 | USED(fp); 86 | printf("program header\n"); 87 | printf("type %u\n", ph->type); 88 | printf("offset 0x%.8x\n", ph->offset); 89 | printf("vaddr 0x%.8x\n", ph->vaddr); 90 | printf("paddr 0x%.8x\n", ph->paddr); 91 | printf("filesz %u\n", ph->filesz); 92 | printf("memsz %u\n", ph->memsz); 93 | printf("flags 0x%.8x\n", ph->flags); 94 | printf("align 0x%.8x\n", ph->align); 95 | printf("\n"); 96 | } 97 | 98 | void 99 | printelf64shdr(Elf64_Shdr *sh, Fhdr *fp) 100 | { 101 | printf("section header\n"); 102 | printf("name %s (%u)\n", getstr(fp, sh->name), sh->name); 103 | printf("type %u\n", sh->type); 104 | printf("flags 0x%.16" PRIx64 "\n", sh->flags); 105 | printf("addr 0x%.16" PRIx64 "\n", sh->addr); 106 | printf("offset 0x%.16" PRIx64 "\n", sh->offset); 107 | printf("size %" PRIu64 "\n", sh->size); 108 | printf("link %u\n", sh->link); 109 | printf("info %u\n", sh->info); 110 | printf("addralign 0x%.16" PRIx64 "\n", sh->addralign); 111 | printf("entsize %" PRIu64 "\n", sh->entsize); 112 | printf("\n"); 113 | } 114 | 115 | void 116 | printelf64phdr(Elf64_Phdr *ph, Fhdr *fp) 117 | { 118 | USED(fp); 119 | printf("program header\n"); 120 | printf("type %u\n", ph->type); 121 | printf("flags 0x%.8x\n", ph->flags); 122 | printf("offset 0x%.16" PRIx64 "\n", ph->offset); 123 | printf("vaddr 0x%.16" PRIx64 "\n", ph->vaddr); 124 | printf("paddr 0x%.16" PRIx64 "\n", ph->paddr); 125 | printf("filesz %" PRIu64 "\n", ph->filesz); 126 | printf("memsz %" PRIu64 "\n", ph->memsz); 127 | printf("align 0x%.16" PRIx64 "\n", ph->align); 128 | printf("\n"); 129 | } 130 | 131 | void 132 | printelfhdr(Fhdr *fp) 133 | { 134 | printident(fp); 135 | printf("type %s (0x%.4x)\n", elftype(fp->type), fp->type); 136 | printf("machine %s (0x%.4x)\n", elfmachine(fp->machine), fp->machine); 137 | printf("version %s (%u)\n", elfversion(fp->version), fp->version); 138 | if (fp->class == ELFCLASS32) 139 | printf("entry 0x%.4ux\n", (uint32_t)fp->entry); 140 | if (fp->class == ELFCLASS64) 141 | printf("entry 0x%.8" PRIx64 "\n", fp->entry); 142 | } 143 | -------------------------------------------------------------------------------- /str.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "dat.h" 4 | 5 | static char* classstr[] = { 6 | [ELFCLASSNONE] = "Invalid class", 7 | [ELFCLASS32] = "32-bit objects", 8 | [ELFCLASS64] = "64-bit objects", 9 | }; 10 | 11 | char* 12 | elfclass(uint8_t class) 13 | { 14 | if(class < nelem(classstr) && classstr[class]) 15 | return classstr[class]; 16 | 17 | return "Unknown class"; 18 | } 19 | 20 | static char* datastr[] = { 21 | [ELFDATANONE] = "Invalid data encoding", 22 | [ELFDATA2LSB] = "Litte-endian", 23 | [ELFDATA2MSB] = "Big-endian", 24 | }; 25 | 26 | char* 27 | elfdata(uint8_t data) 28 | { 29 | if(data < nelem(datastr) && datastr[data]) 30 | return datastr[data]; 31 | 32 | return "Unknown data"; 33 | } 34 | 35 | static char* osabistr[] = { 36 | [ELFOSABI_NONE] = "No extensions or unspecified", 37 | [ELFOSABI_HPUX] = "Hewlett-Packard HP-UX", 38 | [ELFOSABI_NETBSD] = "NetBSD", 39 | [ELFOSABI_GNU] = "GNU ", 40 | [ELFOSABI_SOLARIS] = "Sun Solaris", 41 | [ELFOSABI_AIX] = "AIX", 42 | [ELFOSABI_IRIX] = "IRIX", 43 | [ELFOSABI_FREEBSD] = "FreeBSD", 44 | [ELFOSABI_TRU64] = "Compaq TRU64 UNIX", 45 | [ELFOSABI_MODESTO] = "Novell Modesto", 46 | [ELFOSABI_OPENBSD] = "Open BSD", 47 | [ELFOSABI_OPENVMS] = "Open VMS", 48 | [ELFOSABI_NSK] = "Hewlett-Packard Non-Stop Kernel", 49 | [ELFOSABI_AROS] = "Amiga Research OS", 50 | [ELFOSABI_FENIXOS] = "The FenixOS highly scalable multi-core OS", 51 | [ELFOSABI_CLOUDABI] = "Nuxi CloudABI", 52 | [ELFOSABI_OPENVOS] = "Stratus Technologies OpenVOS", 53 | }; 54 | 55 | char* 56 | elfosabi(uint8_t data) 57 | { 58 | if(data < nelem(osabistr) && osabistr[data]) 59 | return osabistr[data]; 60 | 61 | return "Unknown osabi"; 62 | } 63 | 64 | char *machinestr[] = { 65 | [EM_NONE] = "No machine", 66 | [EM_M32] = "AT&T WE 32100", 67 | [EM_SPARC] = "SPARC", 68 | [EM_386] = "Intel 80386", 69 | [EM_68K] = "Motorola 68000", 70 | [EM_88K] = "Motorola 88000", 71 | [EM_IAMCU] = "Intel MCU", 72 | [EM_860] = "Intel 80860", 73 | [EM_MIPS] = "MIPS I Architecture", 74 | [EM_S370] = "IBM System/370 Processor", 75 | [EM_MIPS_RS3_LE] = "MIPS RS3000 Little-endian", 76 | [EM_PARISC] = "Hewlett-Packard PA-RISC", 77 | [EM_VPP500] = "Fujitsu VPP500", 78 | [EM_SPARC32PLUS] = "Enhanced instruction set SPARC", 79 | [EM_960] = "Intel 80960", 80 | [EM_PPC] = "PowerPC", 81 | [EM_PPC64] = "64-bit PowerPC", 82 | [EM_S390] = "IBM System/390 Processor", 83 | [EM_SPU] = "IBM SPU/SPC", 84 | [EM_V800] = "NEC V800", 85 | [EM_FR20] = "Fujitsu FR20", 86 | [EM_RH32] = "TRW RH-32", 87 | [EM_RCE] = "Motorola RCE", 88 | [EM_ARM] = "ARM 32-bit architecture (AARCH32)", 89 | [EM_ALPHA] = "Digital Alpha", 90 | [EM_SH] = "Hitachi SH", 91 | [EM_SPARCV9] = "SPARC Version 9", 92 | [EM_TRICORE] = "Siemens TriCore embedded processor", 93 | [EM_ARC] = "Argonaut RISC Core, Argonaut Technologies Inc.", 94 | [EM_H8_300] = "Hitachi H8/300", 95 | [EM_H8_300H] = "Hitachi H8/300H", 96 | [EM_H8S] = "Hitachi H8S", 97 | [EM_H8_500] = "Hitachi H8/500", 98 | [EM_IA_64] = "Intel IA-64 processor architecture", 99 | [EM_MIPS_X] = "Stanford MIPS-X", 100 | [EM_COLDFIRE] = "Motorola ColdFire", 101 | [EM_68HC12] = "Motorola M68HC12", 102 | [EM_MMA] = "Fujitsu MMA Multimedia Accelerator", 103 | [EM_PCP] = "Siemens PCP", 104 | [EM_NCPU] = "Sony nCPU embedded RISC processor", 105 | [EM_NDR1] = "Denso NDR1 microprocessor", 106 | [EM_STARCORE] = "Motorola Star*Core processor", 107 | [EM_ME16] = "Toyota ME16 processor", 108 | [EM_ST100] = "STMicroelectronics ST100 processor", 109 | [EM_TINYJ] = "Advanced Logic Corp. TinyJ embedded processor family", 110 | [EM_X86_64] = "AMD x86-64 architecture", 111 | [EM_PDSP] = "Sony DSP Processor", 112 | [EM_PDP10] = "Digital Equipment Corp. PDP-10", 113 | [EM_PDP11] = "Digital Equipment Corp. PDP-11", 114 | [EM_FX66] = "Siemens FX66 microcontroller", 115 | [EM_ST9PLUS] = "STMicroelectronics ST9+ 8/16 bit microcontroller", 116 | [EM_ST7] = "STMicroelectronics ST7 8-bit microcontroller", 117 | [EM_68HC16] = "Motorola MC68HC16 Microcontroller", 118 | [EM_68HC11] = "Motorola MC68HC11 Microcontroller", 119 | [EM_68HC08] = "Motorola MC68HC08 Microcontroller", 120 | [EM_68HC05] = "Motorola MC68HC05 Microcontroller", 121 | [EM_SVX] = "Silicon Graphics SVx", 122 | [EM_ST19] = "STMicroelectronics ST19 8-bit microcontroller", 123 | [EM_VAX] = "Digital VAX", 124 | [EM_CRIS] = "Axis Communications 32-bit embedded processor", 125 | [EM_JAVELIN] = "Infineon Technologies 32-bit embedded processor", 126 | [EM_FIREPATH] = "Element 14 64-bit DSP Processor", 127 | [EM_ZSP] = "LSI Logic 16-bit DSP Processor", 128 | [EM_MMIX] = "Donald Knuth's educational 64-bit processor", 129 | [EM_HUANY] = "Harvard University machine-independent object files", 130 | [EM_PRISM] = "SiTera Prism", 131 | [EM_AVR] = "Atmel AVR 8-bit microcontroller", 132 | [EM_FR30] = "Fujitsu FR30", 133 | [EM_D10V] = "Mitsubishi D10V", 134 | [EM_D30V] = "Mitsubishi D30V", 135 | [EM_V850] = "NEC v850", 136 | [EM_M32R] = "Mitsubishi M32R", 137 | [EM_MN10300] = "Matsushita MN10300", 138 | [EM_MN10200] = "Matsushita MN10200", 139 | [EM_PJ] = "picoJava", 140 | [EM_OPENRISC] = "OpenRISC 32-bit embedded processor", 141 | [EM_ARC_COMPACT] = "ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)", 142 | [EM_XTENSA] = "Tensilica Xtensa Architecture", 143 | [EM_VIDEOCORE] = "Alphamosaic VideoCore processor", 144 | [EM_TMM_GPP] = "Thompson Multimedia General Purpose Processor", 145 | [EM_NS32K] = "National Semiconductor 32000 series", 146 | [EM_TPC] = "Tenor Network TPC processor", 147 | [EM_SNP1K] = "Trebia SNP 1000 processor", 148 | [EM_ST200] = "STMicroelectronics (www.st.com) ST200 microcontroller", 149 | [EM_IP2K] = "Ubicom IP2xxx microcontroller family", 150 | [EM_MAX] = "MAX Processor", 151 | [EM_CR] = "National Semiconductor CompactRISC microprocessor", 152 | [EM_F2MC16] = "Fujitsu F2MC16", 153 | [EM_MSP430] = "Texas Instruments embedded microcontroller msp430", 154 | [EM_BLACKFIN] = "Analog Devices Blackfin (DSP) processor", 155 | [EM_SE_C33] = "S1C33 Family of Seiko Epson processors", 156 | [EM_SEP] = "Sharp embedded microprocessor", 157 | [EM_ARCA] = "Arca RISC Microprocessor", 158 | [EM_UNICORE] = "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University", 159 | [EM_EXCESS] = "eXcess: 16/32/64-bit configurable embedded CPU", 160 | [EM_DXP] = "Icera Semiconductor Inc. Deep Execution Processor", 161 | [EM_ALTERA_NIOS2] = "Altera Nios II soft-core processor", 162 | [EM_CRX] = "National Semiconductor CompactRISC CRX microprocessor", 163 | [EM_XGATE] = "Motorola XGATE embedded processor", 164 | [EM_C166] = "Infineon C16x/XC16x processor", 165 | [EM_M16C] = "Renesas M16C series microprocessors", 166 | [EM_DSPIC30F] = "Microchip Technology dsPIC30F Digital Signal Controller", 167 | [EM_CE] = "Freescale Communication Engine RISC core", 168 | [EM_M32C] = "Renesas M32C series microprocessors", 169 | [EM_TSK3000] = "Altium TSK3000 core", 170 | [EM_RS08] = "Freescale RS08 embedded processor", 171 | [EM_SHARC] = "Analog Devices SHARC family of 32-bit DSP processors", 172 | [EM_ECOG2] = "Cyan Technology eCOG2 microprocessor", 173 | [EM_SCORE7] = "Sunplus S+core7 RISC processor", 174 | [EM_DSP24] = "New Japan Radio (NJR) 24-bit DSP Processor", 175 | [EM_VIDEOCORE3] = "Broadcom VideoCore III processor", 176 | [EM_LATTICEMICO32] = "RISC processor for Lattice FPGA architecture", 177 | [EM_SE_C17] = "Seiko Epson C17 family", 178 | [EM_TI_C6000] = "The Texas Instruments TMS320C6000 DSP family", 179 | [EM_TI_C2000] = "The Texas Instruments TMS320C2000 DSP family", 180 | [EM_TI_C5500] = "The Texas Instruments TMS320C55x DSP family", 181 | [EM_TI_ARP32] = "Texas Instruments Application Specific RISC Processor, 32bit fetch", 182 | [EM_TI_PRU] = "Texas Instruments Programmable Realtime Unit", 183 | [EM_MMDSP_PLUS] = "STMicroelectronics 64bit VLIW Data Signal Processor", 184 | [EM_CYPRESS_M8C] = "Cypress M8C microprocessor", 185 | [EM_R32C] = "Renesas R32C series microprocessors", 186 | [EM_TRIMEDIA] = "NXP Semiconductors TriMedia architecture family", 187 | [EM_QDSP6] = "QUALCOMM DSP6 Processor", 188 | [EM_8051] = "Intel 8051 and variants", 189 | [EM_STXP7X] = "STMicroelectronics STxP7x family of configurable and extensible RISC processors", 190 | [EM_NDS32] = "Andes Technology compact code size embedded RISC processor family", 191 | [EM_ECOG1X] = "Cyan Technology eCOG1X family", 192 | [EM_MAXQ30] = "Dallas Semiconductor MAXQ30 Core Micro-controllers", 193 | [EM_XIMO16] = "New Japan Radio (NJR) 16-bit DSP Processor", 194 | [EM_MANIK] = "M2000 Reconfigurable RISC Microprocessor", 195 | [EM_CRAYNV2] = "Cray Inc. NV2 vector architecture", 196 | [EM_RX] = "Renesas RX family", 197 | [EM_METAG] = "Imagination Technologies META processor architecture", 198 | [EM_MCST_ELBRUS] = "MCST Elbrus general purpose hardware architecture", 199 | [EM_ECOG16] = "Cyan Technology eCOG16 family", 200 | [EM_CR16] = "National Semiconductor CompactRISC CR16 16-bit microprocessor", 201 | [EM_ETPU] = "Freescale Extended Time Processing Unit", 202 | [EM_SLE9X] = "Infineon Technologies SLE9X core", 203 | [EM_L10M] = "Intel L10M", 204 | [EM_K10M] = "Intel K10M", 205 | [EM_AARCH64] = "ARM 64-bit architecture (AARCH64)", 206 | [EM_AVR32] = "Atmel Corporation 32-bit microprocessor family", 207 | [EM_STM8] = "STMicroeletronics STM8 8-bit microcontroller", 208 | [EM_TILE64] = "Tilera TILE64 multicore architecture family", 209 | [EM_TILEPRO] = "Tilera TILEPro multicore architecture family", 210 | [EM_MICROBLAZE] = "Xilinx MicroBlaze 32-bit RISC soft processor core", 211 | [EM_CUDA] = "NVIDIA CUDA architecture", 212 | [EM_TILEGX] = "Tilera TILE-Gx multicore architecture family", 213 | [EM_CLOUDSHIELD] = "CloudShield architecture family", 214 | [EM_COREA_1ST] = "KIPO-KAIST Core-A 1st generation processor family", 215 | [EM_COREA_2ND] = "KIPO-KAIST Core-A 2nd generation processor family", 216 | [EM_ARC_COMPACT2] = "Synopsys ARCompact V2", 217 | [EM_OPEN8] = "Open8 8-bit RISC soft processor core", 218 | [EM_RL78] = "Renesas RL78 family", 219 | [EM_VIDEOCORE5] = "Broadcom VideoCore V processor", 220 | [EM_78KOR] = "Renesas 78KOR family", 221 | [EM_56800EX] = "Freescale 56800EX Digital Signal Controller (DSC)", 222 | [EM_BA1] = "Beyond BA1 CPU architecture", 223 | [EM_BA2] = "Beyond BA2 CPU architecture", 224 | [EM_XCORE] = "XMOS xCORE processor family", 225 | [EM_MCHP_PIC] = "Microchip 8-bit PIC(r) family", 226 | [EM_INTEL205] = "Reserved by Intel", 227 | [EM_INTEL206] = "Reserved by Intel", 228 | [EM_INTEL207] = "Reserved by Intel", 229 | [EM_INTEL208] = "Reserved by Intel", 230 | [EM_INTEL209] = "Reserved by Intel", 231 | [EM_KM32] = "KM211 KM32 32-bit processor", 232 | [EM_KMX32] = "KM211 KMX32 32-bit processor", 233 | [EM_KMX16] = "KM211 KMX16 16-bit processor", 234 | [EM_KMX8] = "KM211 KMX8 8-bit processor", 235 | [EM_KVARC] = "KM211 KVARC processor", 236 | [EM_CDP] = "Paneve CDP architecture family", 237 | [EM_COGE] = "Cognitive Smart Memory Processor", 238 | [EM_COOL] = "Bluechip Systems CoolEngine", 239 | [EM_NORC] = "Nanoradio Optimized RISC", 240 | [EM_CSR_KALIMBA] = "CSR Kalimba architecture family", 241 | [EM_Z80] = "Zilog Z80", 242 | [EM_VISIUM] = "Controls and Data Services VISIUMcore processor", 243 | [EM_FT32] = "FTDI Chip FT32 high performance 32-bit RISC architecture", 244 | [EM_MOXIE] = "Moxie processor family", 245 | [EM_AMDGPU] = "AMD GPU architecture", 246 | [EM_RISCV] = "RISC-V" 247 | }; 248 | 249 | char *typestr[] = { 250 | [ET_NONE] = "No file type", 251 | [ET_REL] = "Relocatable file", 252 | [ET_EXEC] = "Executable file", 253 | [ET_DYN] = "Shared object file", 254 | [ET_CORE] = "Core file", 255 | }; 256 | 257 | char* 258 | elftype(uint16_t type) 259 | { 260 | if(type < nelem(typestr) && typestr[type]) 261 | return typestr[type]; 262 | 263 | if (type >= ET_LOOS && type <= ET_HIOS) 264 | return "Operating system-specific"; 265 | 266 | if (type >= ET_LOPROC) 267 | return "Processor-specific"; 268 | 269 | return "Unknown type"; 270 | } 271 | 272 | char* 273 | elfmachine(uint16_t machine) 274 | { 275 | if(machine < nelem(machinestr) && machinestr[machine]) 276 | return machinestr[machine]; 277 | 278 | return "Unknown machine"; 279 | } 280 | 281 | char *versionstr[] = { 282 | [EV_NONE] = "Invalid", 283 | [EV_CURRENT] = "Current", 284 | }; 285 | 286 | char* 287 | elfversion(uint8_t version) 288 | { 289 | if(version < nelem(versionstr) && versionstr[version]) 290 | return versionstr[version]; 291 | 292 | return "Unknown version"; 293 | } 294 | --------------------------------------------------------------------------------