commit 71539b6717e562995e294b8b2d0173cd38885354
parent 5d5161359e267f3f6dc4979fa46fe4a351acc884
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 28 Jan 2025 12:46:29 +0100
libmach: Rewrite elf support
This rewrite was needed to support any elf file,
independently of the target machine, and without
worring about 32 or 64 bit elf version.
Diffstat:
47 files changed, 2026 insertions(+), 1554 deletions(-)
diff --git a/include/bits/scc/elf.h b/include/bits/scc/elf.h
@@ -0,0 +1,107 @@
+#define EI_NIDENT 16
+
+typedef struct elf Elf;
+typedef struct elfhdr Elfhdr;
+typedef struct elfphdr Elfphdr;
+typedef struct elfsec Elfsec;
+typedef struct elfsym Elfsym;
+typedef struct elfpack Elfpack;
+typedef struct elfunpack Elfunpack;
+typedef struct elfrel Elfrel;
+
+struct elfhdr {
+ unsigned char ident[EI_NIDENT];
+ unsigned short type;
+ unsigned short machine;
+ unsigned long version;
+ unsigned long long entry;
+ unsigned long long phoff;
+ unsigned long long shoff;
+ unsigned long flags;
+ unsigned short ehsize;
+
+ unsigned short phentsize;
+ unsigned short phnum;
+
+ unsigned short shentsize;
+ unsigned short shnum;
+ unsigned short shstrndx;
+};
+
+struct elfphdr {
+ unsigned long type;
+ unsigned long flags;
+ unsigned long long offset;
+
+ unsigned long long vaddr;
+ unsigned long long paddr;
+
+ unsigned long long filesz;
+ unsigned long long memsz;
+ unsigned long long align;
+};
+
+struct elfsec {
+ char *name;
+ char *strtbl;
+
+ unsigned long sh_name;
+ unsigned long type;
+ unsigned long long flags;
+ unsigned long long addr;
+ unsigned long long offset;
+ unsigned long long size;
+ unsigned long link;
+ unsigned long info;
+ unsigned long long addralign;
+ unsigned long long entsize;
+};
+
+struct elfrel {
+ Elfsym *sym;
+ Elfsec *sec;
+
+ unsigned long long off;
+ unsigned long info;
+ long addend;
+};
+
+struct elfsym {
+ char *name;
+ Elfsec *symsec;
+
+ unsigned long st_name;
+ unsigned char info;
+ unsigned char other;
+ unsigned short shndx;
+ unsigned long long value;
+ unsigned long long size;
+};
+
+struct elf {
+ Elfhdr hdr;
+ Elfphdr *phdr;
+
+ Elfsec *secs;
+ int nsec;
+ int secstrtbl;
+
+ Elfsym *syms;
+ int nsym;
+
+ Elfrel *rels;
+ int nrel;
+
+ Elfpack *pack;
+ Elfunpack *unpack;
+};
+
+struct arch {
+ char *name;
+ int mach;
+ int endian;
+ int type;
+};
+
+/* globals */
+extern struct arch elfarchs[];
diff --git a/include/bits/scc/elf/elfent.h b/include/bits/scc/elf/elfent.h
@@ -4,13 +4,17 @@
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
-#define ELF32_ST_BIND(x) ((x) >> 4)
-#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
-#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
+#define ELF_ST_BIND(x) ((x) >> 4)
+#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
+#define ELF_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
-#define ELF64_ST_BIND(x) ((x) >> 4)
-#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf)
-#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
+#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
+#define ELF32_ST_INFO(b,t) ELF_ST_INFO(b, t)
+
+#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
+#define ELF64_ST_INFO(b,t) ELF_ST_INFO(b, t)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
diff --git a/include/bits/scc/elf/elfhdr.h b/include/bits/scc/elf/elfhdr.h
@@ -261,7 +261,7 @@
/* Magic for e_phnum: get real value from sh_info of first section header */
#define PN_XNUM 0xffff
-#define ELFH32SZ 54
+#define ELFH32SZ 52
#define ELFH64SZ 64
typedef struct elfhdr32 Elf32_Ehdr;
diff --git a/include/bits/scc/elf64.h b/include/bits/scc/elf64.h
@@ -4,8 +4,6 @@
#include <scc/elf/elfshdr.h>
#include <scc/elf/elfent.h>
-#define ELF_ST_BIND ELF64_ST_BIND
-#define ELF_ST_TYPE ELF64_ST_TYPE
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Phdr Elf64_Phdr
#define Elf_Shdr Elf64_Shdr
diff --git a/include/bits/scc/mach.h b/include/bits/scc/mach.h
@@ -21,7 +21,7 @@ typedef struct mapsec Mapsec;
enum objformat {
COFF32,
- ELF64,
+ ELF,
NFORMATS,
};
@@ -32,6 +32,8 @@ enum objarch {
ARCHZ80,
ARCHARM32,
ARCHARM64,
+ ARCHUNK32,
+ ARCHUNK64,
};
enum order {
diff --git a/src/cmd/scc-objdump/Makefile b/src/cmd/scc-objdump/Makefile
@@ -6,7 +6,7 @@ include $(PROJECTDIR)/scripts/rules.mk
OBJS =\
main.o\
coff32.o\
- elf64.o\
+ elf.o\
TARGET = scc-objdump
MORE_LDLIBS = -lmach -lscc
diff --git a/src/cmd/scc-objdump/elf.c b/src/cmd/scc-objdump/elf.c
@@ -0,0 +1,738 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/mach.h>
+#include <scc/elf/elftypes.h>
+#include <scc/elf/elfhdr.h>
+#include <scc/elf/elfphdr.h>
+#include <scc/elf/elfshdr.h>
+#include <scc/elf/elfent.h>
+#include <scc/elf.h>
+
+#include "objdump.h"
+
+enum elfsecflags {
+ ELF_WRITE = 0,
+ ELF_ALLOC = 1,
+ ELF_EXEC = 2,
+ ELF_MERGE = 3,
+ ELF_STRINGS = 4,
+ ELF_INFO_LINK = 5,
+ ELF_LINK_ORDER = 6,
+ ELF_OS_NONCONFOR = 7,
+ ELF_GROUP = 8,
+ ELF_TLS = 9,
+ ELF_COMPRESSED = 10,
+ ELF_NR_FLAGS = 11,
+};
+
+enum phdrflags {
+ FLAG_X = 0,
+ FLAG_W = 1,
+ FLAG_R = 2,
+ NR_RIGHTS = 3,
+};
+
+int
+elfhasrelloc(Obj *obj, Section *sec)
+{
+ size_t i;
+ Elf *elf = obj->data;
+ Elfsec *shdr;
+
+ for (i = 0; i < elf->nsec; i++) {
+ shdr = &elf->secs[i];
+ if (shdr->type != SHT_RELA && shdr->type != SHT_REL)
+ continue;
+ if (shdr->info == sec->index)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+printents(Obj *obj)
+{
+ int n;
+ size_t i;
+ Section sec;
+ Elfsym *ent;
+ Elf *elf = obj->data;
+ char *sbind, *stype, *svis, *ssec;
+ unsigned info, bind, type, vis, nsec;
+
+ static char *binds[] = {
+ [STB_LOCAL] = "Local symbol",
+ [STB_GLOBAL] = "Global symbol",
+ [STB_WEAK] = "like global - lower precedence",
+ [STB_NUM] = "number of symbol bindings",
+ [STB_LOPROC] = "reserved range for processor",
+ [STB_HIPROC] = " specific symbol bindings",
+ };
+ static char *types[] = {
+ [STT_NOTYPE] = "not specified",
+ [STT_OBJECT] = "data object",
+ [STT_FUNC] = "function",
+ [STT_SECTION] = "section",
+ [STT_FILE] = "file",
+ [STT_COMMON] = "common symbol",
+ [STT_TLS] = "thread local storage",
+ [STT_LOPROC] = "reserved range for processor",
+ [STT_HIPROC] = " specific symbol types",
+ };
+ static char *visibilities[] = {
+ [STV_DEFAULT] = "Visibility set by binding type",
+ [STV_INTERNAL] = "OS specific version of STV_HIDDEN",
+ [STV_HIDDEN] = "can only be seen inside own .so",
+ [STV_PROTECTED] = "HIDDEN inside, DEFAULT outside",
+ };
+
+ for (i = 0; i < elf->nsym; i++) {
+ ent = &elf->syms[i];
+
+ info = ent->info;
+ bind = ELF_ST_BIND(info);
+ type = ELF_ST_TYPE(info);
+ vis = ELF_ST_VISIBILITY(ent->other);
+ nsec = ent->shndx;
+
+ sbind = (bind <= STB_HIPROC) ? binds[bind] : "Unknown";
+ stype = (type <= STT_HIPROC) ? types[type] : "Unknown";
+ svis = (vis <= STV_PROTECTED) ? visibilities[vis] : "Unknown";
+ if (!sbind)
+ sbind = "Unknown";
+ if (!stype)
+ stype = "Unknown";
+ if (!svis)
+ svis = "Unknown";
+
+ switch (nsec) {
+ case SHN_ABS:
+ ssec = "*ABS*";
+ break;
+ case SHN_COMMON:
+ ssec = "*COM*";
+ break;
+ default:
+ n = nsec;
+ ssec = "*UNK*";
+ if (getsec(obj, &n, &sec))
+ ssec = sec.name;
+ }
+
+ printf("Symbol %zu:\n"
+ "\tst_name: %lu '%s'\n"
+ "\tst_info: %u\n"
+ "\t\tst_bind: %u %s\n"
+ "\t\tst_type: %u %s\n"
+ "\tst_other: %u %s\n"
+ "\tst_shndx: %u %s\n"
+ "\tst_value: %#llx\n"
+ "\tst_size: %llu\n"
+ "\n",
+ i,
+ (long) ent->st_name, ent->name,
+ info,
+ bind, sbind,
+ type, stype,
+ vis, svis,
+ nsec, ssec,
+ (unsigned long long) ent->value,
+ (unsigned long long) ent->size);
+ }
+}
+
+static void
+printstbl(Obj *obj)
+{
+ int n;
+ size_t i;
+ Symbol sym;
+ Section sec;
+ Elfsym *ent;
+ Elfsec *shdr;
+ Elf *elf = obj->data;
+ unsigned info, bind, type;
+ char cbind, cweak, cctor, cwarn, cindir, cdebug, ctype;
+
+ if (elf->nsym == 0) {
+ puts("no symbols");
+ return;
+ }
+
+ for (i = 1; i < elf->nsym; i++) {
+ ent = &elf->syms[i];
+ shdr =&elf->secs[ent->shndx];
+ n = i;
+ getsym(obj, &n, &sym);
+ n = ent->shndx;
+ getsec(obj, &n, &sec);
+
+ info = ent->info;
+ bind = ELF64_ST_BIND(info);
+ type = ELF64_ST_TYPE(info);
+
+ cbind = (bind == STB_LOCAL) ? 'l' : 'g';
+ cweak = (bind == STB_WEAK) ? 'w' : ' ';
+ cctor = ' ';
+ cwarn = ' ';
+ cindir = ' ';
+
+ switch (sym.type) {
+ case 'N':
+ case 'n':
+ cdebug = 'd';
+ break;
+ case 'U':
+ cdebug = ' ';
+ cbind = ' ';
+ break;
+ default:
+ cdebug = (ent->symsec->type == SHT_DYNAMIC) ? 'D' : ' ';
+ }
+
+ switch (type) {
+ case STT_OBJECT:
+ ctype = 'O';
+ break;
+ case STT_FUNC:
+ ctype = 'F';
+ break;
+ case STT_FILE:
+ ctype = 'f';
+ cdebug = 'd';
+ break;
+ default:
+ ctype = ' ';
+ break;
+ }
+
+ printf("%016llx %c%c%c%c%c%c%c %-15s %08llu %-20s [%4zu]\n",
+ (long long) ent->value,
+ cbind,
+ cweak,
+ cctor,
+ cwarn,
+ cindir,
+ cdebug,
+ ctype,
+ sec.name,
+ (long long) ent->size,
+ sym.name,
+ i);
+ }
+}
+
+void
+elfsyms(Obj *obj)
+{
+ printstbl(obj);
+
+ if (pflag)
+ printents(obj);
+}
+
+void
+elfscns(Obj *obj)
+{
+ size_t i;
+ Elf *elf = obj->data;
+ Elfsec *shdr;
+ static char *types[] = {
+ [SHT_NULL] = "inactive",
+ [SHT_PROGBITS] = "program defined information",
+ [SHT_SYMTAB] = "symbol table section",
+ [SHT_STRTAB] = "string table section",
+ [SHT_RELA] = "relocation section with addends",
+ [SHT_HASH] = "symbol hash table section",
+ [SHT_DYNAMIC] = "dynamic section",
+ [SHT_NOTE] = "note section",
+ [SHT_NOBITS] = "no space section",
+ [SHT_REL] = "relation section without addends",
+ [SHT_SHLIB] = "reserved - purpose unknown",
+ [SHT_DYNSYM] = "dynamic symbol table section",
+ [SHT_NUM] = "number of section types",
+ [SHT_INIT_ARRAY] = "pointers to init functions",
+ [SHT_FINI_ARRAY] = "pointers to termination functions",
+ [SHT_PREINIT_ARRAY] = "ptrs to funcs called before init",
+ [SHT_GROUP] = "defines a section group",
+ [SHT_SYMTAB_SHNDX] = "Section indexes (see SHN_XINDEX).",
+ };
+ static Flags f = {
+ .nr = ELF_NR_FLAGS,
+ .text = {
+ [ELF_WRITE] = "WRITE",
+ [ELF_ALLOC] = "ALLOC",
+ [ELF_EXEC] = "EXEC",
+ [ELF_MERGE] = "MERGE",
+ [ELF_STRINGS] = "STRINGS",
+ [ELF_INFO_LINK] = "INFO_LINK",
+ [ELF_LINK_ORDER] = "LINK_ORDER",
+ [ELF_OS_NONCONFOR] = "OS_NONCONFORMING",
+ [ELF_GROUP] = "GROUP",
+ [ELF_TLS] = "TLS",
+ [ELF_COMPRESSED] = "COMPRESSED",
+ }
+ };
+
+ for (i = 0; i < elf->nsec; i++) {
+ long type;
+ char *stype;
+ shdr = &elf->secs[i];
+
+ type = shdr->type;
+ if (type <= SHT_SYMTAB_SHNDX) {
+ stype = types[type];
+ } else {
+ switch (type) {
+ case SHT_SUNW_dof:
+ stype = "SHT_SUNW_dof";
+ break;
+ case SHT_GNU_LIBLIST:
+ stype = "SHT_GNU_LIBLIST";
+ break;
+ case SHT_SUNW_move:
+ stype = "SHT_SUNW_move";
+ break;
+ case SHT_SUNW_syminfo:
+ stype = "SHT_SUNW_syminfo";
+ break;
+ case SHT_GNU_VERDEF:
+ stype = "SHT_GNU_VERDEF";
+ break;
+ case SHT_GNU_VERNEED:
+ stype = "SHT_GNU_VERNEED";
+ break;
+ case SHT_GNU_VERSYM:
+ stype = "SHT_GNU_VERSYM";
+ break;
+ default:
+ stype = NULL;
+ }
+ }
+
+ if (!stype)
+ stype = "Unknown";
+
+ f.flags = shdr->flags;
+
+ printf("Section %zu:\n"
+ "\tsh_name: %lu %s\n"
+ "\tsh_type: %lu %s\n"
+ "\tsh_flags: %#llx\n"
+ "\tsh_addr: %#llx\n"
+ "\tsh_offset: %#llx\n"
+ "\tsh_size: %#llx\n"
+ "\tsh_link: %lu\n"
+ "\tsh_info: %lu\n"
+ "\tsh_addralign: %llu\n"
+ "\tsh_entsize: %llu\n",
+ i,
+ (long) shdr->sh_name, shdr->name,
+ type, stype,
+ (long long) shdr->flags,
+ (long long) shdr->addr,
+ (long long) shdr->offset,
+ (long long) shdr->size,
+ (long) shdr->link,
+ (long) shdr->info,
+ (long long) shdr->addralign,
+ (long long) shdr->entsize);
+
+ putchar('\t');
+ printflags(&f);
+ putchar('\n');
+ }
+}
+
+static void
+printfhdr(Elfhdr *hdr)
+{
+ unsigned long version;
+ unsigned class, data, abi, type, mach;
+ char *sclass, *sdata, *sabi, *stype, *smach, *sversion;
+
+ static char *abis[] = {
+ [ELFOSABI_SYSV] = "UNIX System V ABI",
+ [ELFOSABI_HPUX] = "HP-UX operating system",
+ [ELFOSABI_NETBSD] = "NetBSD",
+ [ELFOSABI_LINUX] = "GNU/Linux",
+ [ELFOSABI_HURD] = "GNU/Hurd",
+ [ELFOSABI_86OPEN] = "86Open common IA32 ABI",
+ [ELFOSABI_SOLARIS] = "Solaris",
+ [ELFOSABI_MONTEREY] = "Monterey",
+ [ELFOSABI_IRIX] = "IRIX",
+ [ELFOSABI_FREEBSD] = "FreeBSD",
+ [ELFOSABI_TRU64] = "TRU64 UNIX",
+ [ELFOSABI_MODESTO] = "Novell Modesto",
+ [ELFOSABI_OPENBSD] = "OpenBSD",
+ [ELFOSABI_OPENVMS] = "Open VMS",
+ [ELFOSABI_NSK] = "Hewlett-Packard Non-Stop Kernel",
+ [ELFOSABI_AROS] = "Amiga Research OS",
+ [ELFOSABI_FENIXOS] = "The FenixOS multi-core OS",
+ [ELFOSABI_CLOUDABI] = "Nuxi CloudABI",
+ [ELFOSABI_OPENVOS] = "Stratus Technologies OpenVOS",
+ [ELFOSABI_ARM] = "ARM",
+ [ELFOSABI_STANDALONE] = "Standalone (embedded) application",
+ };
+ static char *classes[] = {
+ [ELFCLASSNONE] = "invalid",
+ [ELFCLASS32] = "32-bit objs",
+ [ELFCLASS64] = "64-bit objs",
+ };
+ static char *datas[] = {
+ [ELFDATANONE] = "invalid",
+ [ELFDATA2LSB] = "Little-Endian",
+ [ELFDATA2MSB] = "Big-Endian",
+ };
+ static char *types[] = {
+ [ET_NONE] = "No file type",
+ [ET_REL] = "Relocatable file",
+ [ET_EXEC] = "Executable file",
+ [ET_DYN] = "Shared object file",
+ [ET_CORE] = "Core file",
+ };
+ static char *machs[] = {
+ [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",
+ [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 AARCH32",
+ [EM_ALPHA] = "Digital Alpha",
+ [EM_SH] = "Hitachi SH",
+ [EM_SPARCV9] = "SPARC Version 9",
+ [EM_TRICORE] = "Siemens TriCore",
+ [EM_ARC] = "Argonaut RISC Core",
+ [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",
+ [EM_MIPS_X] = "Stanford MIPS-X",
+ [EM_COLDFIRE] = "Motorola ColdFire",
+ [EM_68HC12] = "Motorola M68HC12",
+ [EM_MMA] = "Fujitsu MMA",
+ [EM_PCP] = "Siemens PCP",
+ [EM_NCPU] = "Sony nCPU",
+ [EM_NDR1] = "Denso NDR1",
+ [EM_STARCORE] = "Motorola Star*Core",
+ [EM_ME16] = "Toyota ME16",
+ [EM_ST100] = "STMicroelectronics ST100",
+ [EM_TINYJ] = "Advanced Logic Corp. TinyJ",
+ [EM_X86_64] = "AMD x86-64",
+ [EM_PDSP] = "Sony DSP Processor",
+ [EM_PDP10] = "DEC PDP-10",
+ [EM_PDP11] = "DEC PDP-11",
+ [EM_FX66] = "Siemens FX66",
+ [EM_ST9PLUS] = "STMicroelectronics ST9+",
+ [EM_ST7] = "STMicroelectronics ST7",
+ [EM_68HC16] = "Motorola MC68HC16",
+ [EM_68HC11] = "Motorola MC68HC11",
+ [EM_68HC08] = "Motorola MC68HC08",
+ [EM_68HC05] = "Motorola MC68HC05",
+ [EM_SVX] = "Silicon Graphics SVx",
+ [EM_ST19] = "STMicroelectronics ST19",
+ [EM_VAX] = "Digital VAX",
+ [EM_CRIS] = "Axis Communications 32-bit",
+ [EM_JAVELIN] = "Infineon Technologies 32-bit",
+ [EM_FIREPATH] = "Element 14 64-bit DSP Processor",
+ [EM_ZSP] = "LSI Logic 16-bit DSP Processor",
+ [EM_MMIX] = "Donald Knuth's educational 64-bit",
+ [EM_HUANY] = "Harvard machine-independent",
+ [EM_PRISM] = "SiTera Prism",
+ [EM_AVR] = "Atmel AVR 8-bit",
+ [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",
+ [EM_ARC_A5] = "ARC ARCompact",
+ [EM_ARC_COMPACT] = "ARC ARCompact",
+ [EM_XTENSA] = "Tensilica Xtensa",
+ [EM_VIDEOCORE] = "Alphamosaic VideoCore",
+ [EM_TMM_GPP] = "Thompson Multimedia GPP",
+ [EM_NS32K] = "National 32000 series",
+ [EM_TPC] = "Tenor Network TPC",
+ [EM_SNP1K] = "Trebia SNP 1000",
+ [EM_ST200] = "STMicroelectronics ST200",
+ [EM_IP2K] = "Ubicom IP2xxx",
+ [EM_MAX] = "MAX Processor",
+ [EM_CR] = "National CompactRISC",
+ [EM_F2MC16] = "Fujitsu F2MC16",
+ [EM_MSP430] = "Texas msp430",
+ [EM_BLACKFIN] = "Analog Devices Blackfin",
+ [EM_SE_C33] = "S1C33 of Seiko Epson",
+ [EM_SEP] = "Sharp embedded",
+ [EM_ARCA] = "Arca RISC",
+ [EM_UNICORE] = "PKU-Unity Ltd. and MPRC",
+ [EM_EXCESS] = "eXcess CPU",
+ [EM_DXP] = "Deep Execution Processor",
+ [EM_ALTERA_NIOS2] = "Altera Nios II",
+ [EM_CRX] = "National CompactRISC CRX",
+ [EM_XGATE] = "Motorola XGATE",
+ [EM_C166] = "Infineon C16x/XC16x",
+ [EM_M16C] = "Renesas M16C",
+ [EM_DSPIC30F] = "Microchip dsPIC30F",
+ [EM_CE] = "Freescale Communication Engine",
+ [EM_M32C] = "Renesas M32C",
+ [EM_TSK3000] = "Altium TSK3000 core",
+ [EM_RS08] = "Freescale RS08",
+ [EM_SHARC] = "Analog Devices SHARC",
+ [EM_ECOG2] = "Cyan Technology eCOG2",
+ [EM_SCORE7] = "Sunplus S+core7",
+ [EM_DSP24] = "NJR 24-bit DSP",
+ [EM_VIDEOCORE3] = "Broadcom VideoCore III",
+ [EM_LATTICEMICO3] = "RISC processor for Lattice FPGA",
+ [EM_SE_C17] = "Seiko Epson C17",
+ [EM_TI_C6000] = "TMS320C6000 DSP family",
+ [EM_TI_C2000] = "TMS320C2000 DSP family",
+ [EM_TI_C5500] = "TMS320C55x DSP family",
+ [EM_TI_ARP32] = "Texas Application Specific RISC",
+ [EM_TI_PRU] = "Texas Programmable Realtime Unit",
+ [EM_MMDSP_PLUS] = "STMicroelectronics 64bit VLIW",
+ [EM_CYPRESS_M8C] = "Cypress M8C microprocessor",
+ [EM_R32C] = "Renesas R32C series",
+ [EM_TRIMEDIA] = "NXP Semiconductors TriMedia",
+ [EM_QDSP6] = "QUALCOMM DSP6 Processor",
+ [EM_8051] = "Intel 8051 and variants",
+ [EM_STXP7X] = "STMicroelectronics STxP7x",
+ [EM_NDS32] = "Andes Technology embedded RISC",
+ [EM_ECOG1] = "Cyan Technology eCOG1X family",
+ [EM_ECOG1X] = "Cyan Technology eCOG1X family",
+ [EM_MAXQ30] = "MAXQ30 Core Micro-controllers",
+ [EM_XIMO16] = "NJR 16-bit DSP Processor",
+ [EM_MANIK] = "M2000 Reconfigurable RISC",
+ [EM_CRAYNV2] = "Cray Inc. NV2 vector architecture",
+ [EM_RX] = "Renesas RX family",
+ [EM_METAG] = "Imagination Technologies META",
+ [EM_MCST_ELBRUS] = "MCST Elbrus",
+ [EM_ECOG16] = "Cyan Technology eCOG16 family",
+ [EM_CR16] = "National CompactRISC CR16",
+ [EM_ETPU] = "Freescale Extended Time Unit",
+ [EM_SLE9X] = "Infineon Technologies SLE9X core",
+ [EM_L10M] = "Intel L10M",
+ [EM_K10M] = "Intel K10M",
+ [EM_AARCH64] = "ARM AARCH64",
+ [EM_AVR32] = "Atmel 32-bit",
+ [EM_STM8] = "STMicroeletronics STM8 ",
+ [EM_TILE64] = "Tilera TILE64",
+ [EM_TILEPRO] = "Tilera TILEPro",
+ [EM_MICROBLAZE] = "Xilinx MicroBlaze 32-bit",
+ [EM_CUDA] = "NVIDIA CUDA architecture",
+ [EM_TILEGX] = "Tilera TILE-Gx family",
+ [EM_CLOUDSHIELD] = "CloudShield architecture family",
+ [EM_COREA_1ST] = "KIPO-KAIST Core-A 1st gen family",
+ [EM_COREA_2ND] = "KIPO-KAIST Core-A 2nd gen 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 (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_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] = "VISIUMcore processor",
+ [EM_FT32] = "FTDI Chip FT32",
+ [EM_MOXIE] = "Moxie processor family",
+ [EM_AMDGPU] = "AMD GPU architecture",
+ [EM_RISCV] = "RISC-V",
+ [EM_BPF] = "Linux BPF",
+ [EM_CSKY] = "C-SKY",
+ };
+ static char *versions[] = {
+ [EV_NONE] = "Invalid",
+ [EV_CURRENT] = "Current",
+ };
+
+ class = hdr->ident[EI_CLASS];
+ data = hdr->ident[EI_DATA];
+ abi = hdr->ident[EI_OSABI];
+ type = hdr->type;
+ mach = hdr->machine;
+ version = hdr->version;
+
+ sclass = (class <= ELFCLASS64) ? classes[class] : "Unknown";
+ sdata = (data <= ELFDATA2MSB) ? datas[data] : "Unknown";
+ stype = (type <= ET_CORE) ? types[type] : "Unknown";
+ smach = (mach <= EM_CSKY) ? machs[mach] : "Unknown";
+ if (!smach)
+ smach = "Unknown";
+ sversion = (version <= EV_CURRENT) ? versions[version] : "Unknown";
+
+ switch (abi) {
+ case ELFOSABI_ARM:
+ sabi = "ARM";
+ break;
+ case ELFOSABI_STANDALONE:
+ sabi = "Standalone (embedded) application";
+ break;
+ default:
+ sabi = (abi <= ELFOSABI_OPENVOS) ? abis[abi] : "Unknown";
+ }
+
+ printf("elfhdr:\n"
+ "\tei_class: %u, %s\n"
+ "\tei_data: %u, %s\n"
+ "\tei_version: %u\n"
+ "\tei_osabi: %u, %s\n"
+ "\tei_abiversion: %u\n"
+ "\te_type: %u, %s\n"
+ "\te_machine: %u, %s\n"
+ "\te_version: %lu, %s\n"
+ "\te_entry: 0x%08llx\n"
+ "\te_phoff: %llu\n"
+ "\te_shoff: %llu\n"
+ "\te_flags: %#lx\n"
+ "\te_ehsize: %lu\n"
+ "\te_phentsize: %lu\n"
+ "\te_phnum: %lu\n"
+ "\te_shentsize: %lu\n"
+ "\te_shnum: %lu\n"
+ "\te_shstrndx: %lu\n"
+ "\n",
+ class, sclass,
+ data, sdata,
+ hdr->ident[EI_VERSION],
+ abi, sabi,
+ hdr->ident[EI_ABIVERSION],
+ type, stype,
+ mach, smach,
+ version, sversion,
+ (long long) hdr->entry,
+ (long long) hdr->phoff,
+ (long long) hdr->shoff,
+ (long) hdr->flags,
+ (long) hdr->ehsize,
+ (long) hdr->phentsize,
+ (long) hdr->phnum,
+ (long) hdr->shentsize,
+ (long) hdr->shnum,
+ (long) hdr->shstrndx);
+}
+
+static void
+printphdr(Elfphdr *phdr, unsigned long n)
+{
+ unsigned long i;
+ static char *types[] = {
+ [PT_NULL] = "unused",
+ [PT_LOAD] = "loadable segment",
+ [PT_DYNAMIC] = "dynamic linking section",
+ [PT_INTERP] = "the RTLD",
+ [PT_NOTE] = "auxiliary information",
+ [PT_SHLIB] = "reserved - purpose undefined",
+ [PT_PHDR] = "program header",
+ [PT_TLS] = "thread local storage",
+ };
+ static Flags f ={
+ .nr = NR_RIGHTS,
+ .text = {
+ [FLAG_X] = "Executable",
+ [FLAG_W] = "Writable",
+ [FLAG_R] = "Readable",
+ }
+ };
+
+ for (i = 0; i < n; i++) {
+ unsigned long type;
+ char *stype;
+
+ type = phdr->type;
+ stype = (type <= PT_TLS) ? types[type] : "Unknown";
+ f.flags = phdr->flags;
+
+ printf("Program header %ld\n"
+ "\tp_type: %#lx, %s\n"
+ "\tp_flags: %#lx\n"
+ "\tp_offset: %#08llx\n"
+ "\tp_vaddr: %#08llx\n"
+ "\tp_paddr: %#08llx\n"
+ "\tp_filesz: %#08llx\n"
+ "\tp_memsz: %#08llx\n"
+ "\tp_align: %#08llx\n",
+ i,
+ type, stype,
+ (long) phdr->flags,
+ (long long) phdr->offset,
+ (long long) phdr->vaddr,
+ (long long) phdr->paddr,
+ (long long) phdr->filesz,
+ (long long) phdr->memsz,
+ (long long) phdr->align);
+
+ putchar('\t');
+ printflags(&f);
+ putchar('\n');
+ ++phdr;
+ }
+}
+
+void
+elffhdr(Obj *obj, unsigned long long *start, Flags *f)
+{
+ size_t i;
+ char *name;
+ Elf *elf = obj->data;
+ Elfhdr *hdr = &elf->hdr;
+ Elfsec *shdr;
+
+ *start = hdr->entry;
+
+ for (i = 0; i < elf->nsec; i++) {
+ shdr = &elf->secs[i];
+ name = shdr->name;
+ setflag(f, strncmp(name, ".debug", 6) == 0, HAS_DEBUG);
+ setflag(f, strncmp(name, ".line", 5) == 0, HAS_LINENO);
+ setflag(f, strcmp(name, ".debug_line") == 0, HAS_LINENO);
+ setflag(f, shdr->type == SHT_RELA, HAS_RELOC);
+ setflag(f, shdr->type == SHT_REL, HAS_RELOC);
+ }
+
+ setflag(f, hdr->type == ET_EXEC, EXEC_P);
+ setflag(f, hdr->type == ET_DYN, DYNAMIC);
+ setflag(f, elf->nsym > 0, HAS_SYMS);
+
+ if (!pflag)
+ return;
+
+ printfhdr(hdr);
+ printphdr(elf->phdr, hdr->phnum);
+}
diff --git a/src/cmd/scc-objdump/elf64.c b/src/cmd/scc-objdump/elf64.c
@@ -1,734 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "objdump.h"
-
-enum elfsecflags {
- ELF_WRITE = 0,
- ELF_ALLOC = 1,
- ELF_EXEC = 2,
- ELF_MERGE = 3,
- ELF_STRINGS = 4,
- ELF_INFO_LINK = 5,
- ELF_LINK_ORDER = 6,
- ELF_OS_NONCONFOR = 7,
- ELF_GROUP = 8,
- ELF_TLS = 9,
- ELF_COMPRESSED = 10,
- ELF_NR_FLAGS = 11,
-};
-
-enum phdrflags {
- FLAG_X = 0,
- FLAG_W = 1,
- FLAG_R = 2,
- NR_RIGHTS = 3,
-};
-
-int
-elf64hasrelloc(Obj *obj, Section *sec)
-{
- size_t i;
- Elf64 *elf = obj->data;
- Elf_Shdr *shdr;
-
- for (i = 0; i < elf->nsec; i++) {
- shdr = &elf->shdr[i];
- if (shdr->sh_type != SHT_RELA && shdr->sh_type != SHT_REL)
- continue;
- if (shdr->sh_info == sec->index)
- return 1;
- }
-
- return 0;
-}
-
-static void
-printents(Obj *obj)
-{
- int n;
- size_t i;
- Section sec;
- Elf_Sym *ent;
- Elf64 *elf = obj->data;
- char *sbind, *stype, *svis, *ssec;
- unsigned info, bind, type, vis, nsec;
-
- static char *binds[] = {
- [STB_LOCAL] = "Local symbol",
- [STB_GLOBAL] = "Global symbol",
- [STB_WEAK] = "like global - lower precedence",
- [STB_NUM] = "number of symbol bindings",
- [STB_LOPROC] = "reserved range for processor",
- [STB_HIPROC] = " specific symbol bindings",
- };
- static char *types[] = {
- [STT_NOTYPE] = "not specified",
- [STT_OBJECT] = "data object",
- [STT_FUNC] = "function",
- [STT_SECTION] = "section",
- [STT_FILE] = "file",
- [STT_COMMON] = "common symbol",
- [STT_TLS] = "thread local storage",
- [STT_LOPROC] = "reserved range for processor",
- [STT_HIPROC] = " specific symbol types",
- };
- static char *visibilities[] = {
- [STV_DEFAULT] = "Visibility set by binding type",
- [STV_INTERNAL] = "OS specific version of STV_HIDDEN",
- [STV_HIDDEN] = "can only be seen inside own .so",
- [STV_PROTECTED] = "HIDDEN inside, DEFAULT outside",
- };
-
- for (i = 0; i < elf->nsym; i++) {
- ent = &elf->syms[i];
-
- info = ent->st_info;
- bind = ELF64_ST_BIND(info);
- type = ELF64_ST_TYPE(info);
- vis = ELF_ST_VISIBILITY(ent->st_other);
- nsec = ent->st_shndx;
-
- sbind = (bind <= STB_HIPROC) ? binds[bind] : "Unknown";
- stype = (type <= STT_HIPROC) ? types[type] : "Unknown";
- svis = (vis <= STV_PROTECTED) ? visibilities[vis] : "Unknown";
- if (!sbind)
- sbind = "Unknown";
- if (!stype)
- stype = "Unknown";
- if (!svis)
- svis = "Unknown";
-
- switch (nsec) {
- case SHN_ABS:
- ssec = "*ABS*";
- break;
- case SHN_COMMON:
- ssec = "*COM*";
- break;
- default:
- n = nsec;
- ssec = "*UNK*";
- if (getsec(obj, &n, &sec))
- ssec = sec.name;
- }
-
- printf("Symbol %zu:\n"
- "\tst_name: %lu '%s'\n"
- "\tst_info: %u\n"
- "\t\tst_bind: %u %s\n"
- "\t\tst_type: %u %s\n"
- "\tst_other: %u %s\n"
- "\tst_shndx: %u %s\n"
- "\tst_value: %llu\n"
- "\tst_size: %llu\n"
- "\n",
- i,
- (long) ent->st_name,
- elf64str(obj, SYM_STRTBL, ent->st_name),
- info,
- bind, sbind,
- type, stype,
- vis, svis,
- nsec, ssec,
- (unsigned long long) ent->st_value,
- (unsigned long long) ent->st_size);
- }
-}
-
-static void
-printstbl(Obj *obj)
-{
- int n;
- size_t i;
- Symbol sym;
- Section sec;
- Elf_Sym *ent;
- Elf_Shdr *shdr;
- Elf64 *elf = obj->data;
- unsigned info, bind, type;
- char cbind, cweak, cctor, cwarn, cindir, cdebug, ctype;
-
- if (elf->nsym == 0) {
- puts("no symbols");
- return;
- }
-
- for (i = 1; i < elf->nsym; i++) {
- ent = &elf->syms[i];
- shdr =&elf->shdr[ent->st_shndx];
- n = i;
- getsym(obj, &n, &sym);
- n = ent->st_shndx;
- getsec(obj, &n, &sec);
-
- info = ent->st_info;
- bind = ELF64_ST_BIND(info);
- type = ELF64_ST_TYPE(info);
-
- cbind = (bind == STB_LOCAL) ? 'l' : 'g';
- cweak = (bind == STB_WEAK) ? 'w' : ' ';
- cctor = ' ';
- cwarn = ' ';
- cindir = ' ';
-
- switch (sym.type) {
- case 'N':
- case 'n':
- cdebug = 'd';
- break;
- case 'U':
- cdebug = ' ';
- cbind = ' ';
- break;
- default:
- cdebug = (elf->symtab->sh_type == SHT_DYNAMIC) ? 'D' : ' ';
- }
-
- switch (type) {
- case STT_OBJECT:
- ctype = 'O';
- break;
- case STT_FUNC:
- ctype = 'F';
- break;
- case STT_FILE:
- ctype = 'f';
- cdebug = 'd';
- break;
- default:
- ctype = ' ';
- break;
- }
-
- printf("%016llx %c%c%c%c%c%c%c %-15s %08llu %-20s [%4zu]\n",
- (long long) ent->st_value,
- cbind,
- cweak,
- cctor,
- cwarn,
- cindir,
- cdebug,
- ctype,
- sec.name,
- (long long) ent->st_size,
- sym.name,
- i);
- }
-}
-
-void
-elf64syms(Obj *obj)
-{
- printstbl(obj);
-
- if (pflag)
- printents(obj);
-}
-
-void
-elf64scns(Obj *obj)
-{
- size_t i;
- Elf64 *elf = obj->data;
- Elf_Shdr *shdr;
- static char *types[] = {
- [SHT_NULL] = "inactive",
- [SHT_PROGBITS] = "program defined information",
- [SHT_SYMTAB] = "symbol table section",
- [SHT_STRTAB] = "string table section",
- [SHT_RELA] = "relocation section with addends",
- [SHT_HASH] = "symbol hash table section",
- [SHT_DYNAMIC] = "dynamic section",
- [SHT_NOTE] = "note section",
- [SHT_NOBITS] = "no space section",
- [SHT_REL] = "relation section without addends",
- [SHT_SHLIB] = "reserved - purpose unknown",
- [SHT_DYNSYM] = "dynamic symbol table section",
- [SHT_NUM] = "number of section types",
- [SHT_INIT_ARRAY] = "pointers to init functions",
- [SHT_FINI_ARRAY] = "pointers to termination functions",
- [SHT_PREINIT_ARRAY] = "ptrs to funcs called before init",
- [SHT_GROUP] = "defines a section group",
- [SHT_SYMTAB_SHNDX] = "Section indexes (see SHN_XINDEX).",
- };
- static Flags f = {
- .nr = ELF_NR_FLAGS,
- .text = {
- [ELF_WRITE] = "WRITE",
- [ELF_ALLOC] = "ALLOC",
- [ELF_EXEC] = "EXEC",
- [ELF_MERGE] = "MERGE",
- [ELF_STRINGS] = "STRINGS",
- [ELF_INFO_LINK] = "INFO_LINK",
- [ELF_LINK_ORDER] = "LINK_ORDER",
- [ELF_OS_NONCONFOR] = "OS_NONCONFORMING",
- [ELF_GROUP] = "GROUP",
- [ELF_TLS] = "TLS",
- [ELF_COMPRESSED] = "COMPRESSED",
- }
- };
-
- for (i = 0; i < elf->nsec; i++) {
- long type;
- char *stype;
- shdr = &elf->shdr[i];
-
- type = shdr->sh_type;
- if (type <= SHT_SYMTAB_SHNDX) {
- stype = types[type];
- } else {
- switch (type) {
- case SHT_SUNW_dof:
- stype = "SHT_SUNW_dof";
- break;
- case SHT_GNU_LIBLIST:
- stype = "SHT_GNU_LIBLIST";
- break;
- case SHT_SUNW_move:
- stype = "SHT_SUNW_move";
- break;
- case SHT_SUNW_syminfo:
- stype = "SHT_SUNW_syminfo";
- break;
- case SHT_GNU_VERDEF:
- stype = "SHT_GNU_VERDEF";
- break;
- case SHT_GNU_VERNEED:
- stype = "SHT_GNU_VERNEED";
- break;
- case SHT_GNU_VERSYM:
- stype = "SHT_GNU_VERSYM";
- break;
- default:
- stype = NULL;
- }
- }
-
- if (!stype)
- stype = "Unknown";
-
- f.flags = shdr->sh_flags;
-
- printf("Section %zu:\n"
- "\tsh_name: %lu\n"
- "\tsh_type: %lu %s\n"
- "\tsh_flags: %#llx\n"
- "\tsh_addr: %#llx\n"
- "\tsh_offset: %#llx\n"
- "\tsh_size: %#llx\n"
- "\tsh_link: %lu\n"
- "\tsh_info: %lu\n"
- "\tsh_addralign: %llu\n"
- "\tsh_entsize: %llu\n",
- i,
- (long) shdr->sh_name,
- type, stype,
- (long long) shdr->sh_flags,
- (long long) shdr->sh_addr,
- (long long) shdr->sh_offset,
- (long long) shdr->sh_size,
- (long) shdr->sh_link,
- (long) shdr->sh_info,
- (long long) shdr->sh_addralign,
- (long long) shdr->sh_entsize);
-
- putchar('\t');
- printflags(&f);
- putchar('\n');
- }
-}
-
-static void
-printfhdr(Elf_Ehdr *hdr)
-{
- unsigned long version;
- unsigned class, data, abi, type, mach;
- char *sclass, *sdata, *sabi, *stype, *smach, *sversion;
-
- static char *abis[] = {
- [ELFOSABI_SYSV] = "UNIX System V ABI",
- [ELFOSABI_HPUX] = "HP-UX operating system",
- [ELFOSABI_NETBSD] = "NetBSD",
- [ELFOSABI_LINUX] = "GNU/Linux",
- [ELFOSABI_HURD] = "GNU/Hurd",
- [ELFOSABI_86OPEN] = "86Open common IA32 ABI",
- [ELFOSABI_SOLARIS] = "Solaris",
- [ELFOSABI_MONTEREY] = "Monterey",
- [ELFOSABI_IRIX] = "IRIX",
- [ELFOSABI_FREEBSD] = "FreeBSD",
- [ELFOSABI_TRU64] = "TRU64 UNIX",
- [ELFOSABI_MODESTO] = "Novell Modesto",
- [ELFOSABI_OPENBSD] = "OpenBSD",
- [ELFOSABI_OPENVMS] = "Open VMS",
- [ELFOSABI_NSK] = "Hewlett-Packard Non-Stop Kernel",
- [ELFOSABI_AROS] = "Amiga Research OS",
- [ELFOSABI_FENIXOS] = "The FenixOS multi-core OS",
- [ELFOSABI_CLOUDABI] = "Nuxi CloudABI",
- [ELFOSABI_OPENVOS] = "Stratus Technologies OpenVOS",
- [ELFOSABI_ARM] = "ARM",
- [ELFOSABI_STANDALONE] = "Standalone (embedded) application",
- };
- static char *classes[] = {
- [ELFCLASSNONE] = "invalid",
- [ELFCLASS32] = "32-bit objs",
- [ELFCLASS64] = "64-bit objs",
- };
- static char *datas[] = {
- [ELFDATANONE] = "invalid",
- [ELFDATA2LSB] = "Little-Endian",
- [ELFDATA2MSB] = "Big-Endian",
- };
- static char *types[] = {
- [ET_NONE] = "No file type",
- [ET_REL] = "Relocatable file",
- [ET_EXEC] = "Executable file",
- [ET_DYN] = "Shared object file",
- [ET_CORE] = "Core file",
- };
- static char *machs[] = {
- [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",
- [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 AARCH32",
- [EM_ALPHA] = "Digital Alpha",
- [EM_SH] = "Hitachi SH",
- [EM_SPARCV9] = "SPARC Version 9",
- [EM_TRICORE] = "Siemens TriCore",
- [EM_ARC] = "Argonaut RISC Core",
- [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",
- [EM_MIPS_X] = "Stanford MIPS-X",
- [EM_COLDFIRE] = "Motorola ColdFire",
- [EM_68HC12] = "Motorola M68HC12",
- [EM_MMA] = "Fujitsu MMA",
- [EM_PCP] = "Siemens PCP",
- [EM_NCPU] = "Sony nCPU",
- [EM_NDR1] = "Denso NDR1",
- [EM_STARCORE] = "Motorola Star*Core",
- [EM_ME16] = "Toyota ME16",
- [EM_ST100] = "STMicroelectronics ST100",
- [EM_TINYJ] = "Advanced Logic Corp. TinyJ",
- [EM_X86_64] = "AMD x86-64",
- [EM_PDSP] = "Sony DSP Processor",
- [EM_PDP10] = "DEC PDP-10",
- [EM_PDP11] = "DEC PDP-11",
- [EM_FX66] = "Siemens FX66",
- [EM_ST9PLUS] = "STMicroelectronics ST9+",
- [EM_ST7] = "STMicroelectronics ST7",
- [EM_68HC16] = "Motorola MC68HC16",
- [EM_68HC11] = "Motorola MC68HC11",
- [EM_68HC08] = "Motorola MC68HC08",
- [EM_68HC05] = "Motorola MC68HC05",
- [EM_SVX] = "Silicon Graphics SVx",
- [EM_ST19] = "STMicroelectronics ST19",
- [EM_VAX] = "Digital VAX",
- [EM_CRIS] = "Axis Communications 32-bit",
- [EM_JAVELIN] = "Infineon Technologies 32-bit",
- [EM_FIREPATH] = "Element 14 64-bit DSP Processor",
- [EM_ZSP] = "LSI Logic 16-bit DSP Processor",
- [EM_MMIX] = "Donald Knuth's educational 64-bit",
- [EM_HUANY] = "Harvard machine-independent",
- [EM_PRISM] = "SiTera Prism",
- [EM_AVR] = "Atmel AVR 8-bit",
- [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",
- [EM_ARC_A5] = "ARC ARCompact",
- [EM_ARC_COMPACT] = "ARC ARCompact",
- [EM_XTENSA] = "Tensilica Xtensa",
- [EM_VIDEOCORE] = "Alphamosaic VideoCore",
- [EM_TMM_GPP] = "Thompson Multimedia GPP",
- [EM_NS32K] = "National 32000 series",
- [EM_TPC] = "Tenor Network TPC",
- [EM_SNP1K] = "Trebia SNP 1000",
- [EM_ST200] = "STMicroelectronics ST200",
- [EM_IP2K] = "Ubicom IP2xxx",
- [EM_MAX] = "MAX Processor",
- [EM_CR] = "National CompactRISC",
- [EM_F2MC16] = "Fujitsu F2MC16",
- [EM_MSP430] = "Texas msp430",
- [EM_BLACKFIN] = "Analog Devices Blackfin",
- [EM_SE_C33] = "S1C33 of Seiko Epson",
- [EM_SEP] = "Sharp embedded",
- [EM_ARCA] = "Arca RISC",
- [EM_UNICORE] = "PKU-Unity Ltd. and MPRC",
- [EM_EXCESS] = "eXcess CPU",
- [EM_DXP] = "Deep Execution Processor",
- [EM_ALTERA_NIOS2] = "Altera Nios II",
- [EM_CRX] = "National CompactRISC CRX",
- [EM_XGATE] = "Motorola XGATE",
- [EM_C166] = "Infineon C16x/XC16x",
- [EM_M16C] = "Renesas M16C",
- [EM_DSPIC30F] = "Microchip dsPIC30F",
- [EM_CE] = "Freescale Communication Engine",
- [EM_M32C] = "Renesas M32C",
- [EM_TSK3000] = "Altium TSK3000 core",
- [EM_RS08] = "Freescale RS08",
- [EM_SHARC] = "Analog Devices SHARC",
- [EM_ECOG2] = "Cyan Technology eCOG2",
- [EM_SCORE7] = "Sunplus S+core7",
- [EM_DSP24] = "NJR 24-bit DSP",
- [EM_VIDEOCORE3] = "Broadcom VideoCore III",
- [EM_LATTICEMICO3] = "RISC processor for Lattice FPGA",
- [EM_SE_C17] = "Seiko Epson C17",
- [EM_TI_C6000] = "TMS320C6000 DSP family",
- [EM_TI_C2000] = "TMS320C2000 DSP family",
- [EM_TI_C5500] = "TMS320C55x DSP family",
- [EM_TI_ARP32] = "Texas Application Specific RISC",
- [EM_TI_PRU] = "Texas Programmable Realtime Unit",
- [EM_MMDSP_PLUS] = "STMicroelectronics 64bit VLIW",
- [EM_CYPRESS_M8C] = "Cypress M8C microprocessor",
- [EM_R32C] = "Renesas R32C series",
- [EM_TRIMEDIA] = "NXP Semiconductors TriMedia",
- [EM_QDSP6] = "QUALCOMM DSP6 Processor",
- [EM_8051] = "Intel 8051 and variants",
- [EM_STXP7X] = "STMicroelectronics STxP7x",
- [EM_NDS32] = "Andes Technology embedded RISC",
- [EM_ECOG1] = "Cyan Technology eCOG1X family",
- [EM_ECOG1X] = "Cyan Technology eCOG1X family",
- [EM_MAXQ30] = "MAXQ30 Core Micro-controllers",
- [EM_XIMO16] = "NJR 16-bit DSP Processor",
- [EM_MANIK] = "M2000 Reconfigurable RISC",
- [EM_CRAYNV2] = "Cray Inc. NV2 vector architecture",
- [EM_RX] = "Renesas RX family",
- [EM_METAG] = "Imagination Technologies META",
- [EM_MCST_ELBRUS] = "MCST Elbrus",
- [EM_ECOG16] = "Cyan Technology eCOG16 family",
- [EM_CR16] = "National CompactRISC CR16",
- [EM_ETPU] = "Freescale Extended Time Unit",
- [EM_SLE9X] = "Infineon Technologies SLE9X core",
- [EM_L10M] = "Intel L10M",
- [EM_K10M] = "Intel K10M",
- [EM_AARCH64] = "ARM AARCH64",
- [EM_AVR32] = "Atmel 32-bit",
- [EM_STM8] = "STMicroeletronics STM8 ",
- [EM_TILE64] = "Tilera TILE64",
- [EM_TILEPRO] = "Tilera TILEPro",
- [EM_MICROBLAZE] = "Xilinx MicroBlaze 32-bit",
- [EM_CUDA] = "NVIDIA CUDA architecture",
- [EM_TILEGX] = "Tilera TILE-Gx family",
- [EM_CLOUDSHIELD] = "CloudShield architecture family",
- [EM_COREA_1ST] = "KIPO-KAIST Core-A 1st gen family",
- [EM_COREA_2ND] = "KIPO-KAIST Core-A 2nd gen 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 (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_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] = "VISIUMcore processor",
- [EM_FT32] = "FTDI Chip FT32",
- [EM_MOXIE] = "Moxie processor family",
- [EM_AMDGPU] = "AMD GPU architecture",
- [EM_RISCV] = "RISC-V",
- [EM_BPF] = "Linux BPF",
- [EM_CSKY] = "C-SKY",
- };
- static char *versions[] = {
- [EV_NONE] = "Invalid",
- [EV_CURRENT] = "Current",
- };
-
- class = hdr->e_ident[EI_CLASS];
- data = hdr->e_ident[EI_DATA];
- abi = hdr->e_ident[EI_OSABI];
- type = hdr->e_type;
- mach = hdr->e_machine;
- version = hdr->e_version;
-
- sclass = (class <= ELFCLASS64) ? classes[class] : "Unknown";
- sdata = (data <= ELFDATA2MSB) ? datas[data] : "Unknown";
- stype = (type <= ET_CORE) ? types[type] : "Unknown";
- smach = (mach <= EM_CSKY) ? machs[mach] : "Unknown";
- if (!smach)
- smach = "Unknown";
- sversion = (version <= EV_CURRENT) ? versions[version] : "Unknown";
-
- switch (abi) {
- case ELFOSABI_ARM:
- sabi = "ARM";
- break;
- case ELFOSABI_STANDALONE:
- sabi = "Standalone (embedded) application";
- break;
- default:
- sabi = (abi <= ELFOSABI_OPENVOS) ? abis[abi] : "Unknown";
- }
-
- printf("elfhdr64:\n"
- "\tei_class: %u, %s\n"
- "\tei_data: %u, %s\n"
- "\tei_version: %u\n"
- "\tei_osabi: %u, %s\n"
- "\tei_abiversion: %u\n"
- "\te_type: %u, %s\n"
- "\te_machine: %u, %s\n"
- "\te_version: %lu, %s\n"
- "\te_entry: 0x%08llx\n"
- "\te_phoff: %llu\n"
- "\te_shoff: %llu\n"
- "\te_flags: %#lx\n"
- "\te_ehsize: %lu\n"
- "\te_phentsize: %lu\n"
- "\te_phnum: %lu\n"
- "\te_shentsize: %lu\n"
- "\te_shnum: %lu\n"
- "\te_shstrndx: %lu\n"
- "\n",
- class, sclass,
- data, sdata,
- hdr->e_ident[EI_VERSION],
- abi, sabi,
- hdr->e_ident[EI_ABIVERSION],
- type, stype,
- mach, smach,
- version, sversion,
- (long long) hdr->e_entry,
- (long long) hdr->e_phoff,
- (long long) hdr->e_shoff,
- (long) hdr->e_flags,
- (long) hdr->e_ehsize,
- (long) hdr->e_phentsize,
- (long) hdr->e_phnum,
- (long) hdr->e_shentsize,
- (long) hdr->e_shnum,
- (long) hdr->e_shstrndx);
-}
-
-static void
-printphdr(Elf_Phdr *phdr, unsigned long n)
-{
- unsigned long i;
- static char *types[] = {
- [PT_NULL] = "unused",
- [PT_LOAD] = "loadable segment",
- [PT_DYNAMIC] = "dynamic linking section",
- [PT_INTERP] = "the RTLD",
- [PT_NOTE] = "auxiliary information",
- [PT_SHLIB] = "reserved - purpose undefined",
- [PT_PHDR] = "program header",
- [PT_TLS] = "thread local storage",
- };
- static Flags f ={
- .nr = NR_RIGHTS,
- .text = {
- [FLAG_X] = "Executable",
- [FLAG_W] = "Writable",
- [FLAG_R] = "Readable",
- }
- };
-
- for (i = 0; i < n; i++) {
- unsigned long type;
- char *stype;
-
- type = phdr->p_type;
- stype = (type <= PT_TLS) ? types[type] : "Unknown";
- f.flags = phdr->p_flags;
-
- printf("Program header %ld\n"
- "\tp_type: %#lx, %s\n"
- "\tp_flags: %#lx\n"
- "\tp_offset: %#08llx\n"
- "\tp_vaddr: %#08llx\n"
- "\tp_paddr: %#08llx\n"
- "\tp_filesz: %#08llx\n"
- "\tp_memsz: %#08llx\n"
- "\tp_align: %#08llx\n",
- i,
- type, stype,
- (long) phdr->p_flags,
- (long long) phdr->p_offset,
- (long long) phdr->p_vaddr,
- (long long) phdr->p_paddr,
- (long long) phdr->p_filesz,
- (long long) phdr->p_memsz,
- (long long) phdr->p_align);
-
- putchar('\t');
- printflags(&f);
- putchar('\n');
- ++phdr;
- }
-}
-
-void
-elf64fhdr(Obj *obj, unsigned long long *start, Flags *f)
-{
- size_t i;
- char *name;
- Elf64 *elf = obj->data;
- Elf_Ehdr *hdr = &elf->hdr;
- Elf_Shdr *shdr;
-
- *start = hdr->e_entry;
-
- for (i = 0; i < elf->nsec; i++) {
- shdr = &elf->shdr[i];
- name = elf64str(obj, SEC_STRTBL, shdr->sh_name);
- setflag(f, strncmp(name, ".debug", 6) == 0, HAS_DEBUG);
- setflag(f, strncmp(name, ".line", 5) == 0, HAS_LINENO);
- setflag(f, strcmp(name, ".debug_line") == 0, HAS_LINENO);
- setflag(f, shdr->sh_type == SHT_RELA, HAS_RELOC);
- setflag(f, shdr->sh_type == SHT_REL, HAS_RELOC);
- }
-
- setflag(f, hdr->e_type == ET_EXEC, EXEC_P);
- setflag(f, hdr->e_type == ET_DYN, DYNAMIC);
- setflag(f, elf->nsym > 0, HAS_SYMS);
-
- if (!pflag)
- return;
-
- printfhdr(hdr);
- printphdr(elf->phdr, hdr->e_phnum);
-}
diff --git a/src/cmd/scc-objdump/main.c b/src/cmd/scc-objdump/main.c
@@ -34,11 +34,11 @@ static struct binops *op, ops[NFORMATS] = {
.dumpfhdr = coff32fhdr,
.hasrelloc = coff32hasrelloc,
},
- [ELF64] = {
- .dumpsyms = elf64syms,
- .dumpsecs = elf64scns,
- .dumpfhdr = elf64fhdr,
- .hasrelloc = elf64hasrelloc,
+ [ELF] = {
+ .dumpsyms = elfsyms,
+ .dumpsecs = elfscns,
+ .dumpfhdr = elffhdr,
+ .hasrelloc = elfhasrelloc,
},
};
diff --git a/src/cmd/scc-objdump/objdump.h b/src/cmd/scc-objdump/objdump.h
@@ -36,10 +36,10 @@ extern void coff32fhdr(Obj *, unsigned long long *, Flags *);
extern int coff32hasrelloc(Obj *, Section *);
/* elf64.c */
-extern void elf64syms(Obj *);
-extern void elf64scns(Obj *);
-extern void elf64fhdr(Obj *, unsigned long long *, Flags *);
-extern int elf64hasrelloc(Obj *, Section *);
+extern void elfsyms(Obj *);
+extern void elfscns(Obj *);
+extern void elffhdr(Obj *, unsigned long long *, Flags *);
+extern int elfhasrelloc(Obj *, Section *);
/* main.c */
extern void error(char *, ...);
diff --git a/src/libmach/Makefile b/src/libmach/Makefile
@@ -1,7 +1,7 @@
.POSIX:
DIRS =\
- elf64\
+ elf\
coff32\
PROJECTDIR =../..
@@ -45,4 +45,4 @@ $(TARGET): $(OBJS)
cp $@ $(LIBDIR)/scc
dep:
- ./mkdep elf64 coff32
+ ./mkdep elf coff32
diff --git a/src/libmach/delobj.c b/src/libmach/delobj.c
@@ -5,12 +5,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static void (*ops[NFORMATS])(Obj *) = {
[COFF32] = coff32del,
- [ELF64] = elf64del,
+ [ELF] = elfdel,
};
void
diff --git a/src/libmach/elf/Makefile b/src/libmach/elf/Makefile
@@ -0,0 +1,25 @@
+.POSIX:
+
+PROJECTDIR =../../..
+include $(PROJECTDIR)/scripts/rules.mk
+
+OBJS =\
+ elfarchs.o\
+ elfdel.o\
+ elfgetsec.o\
+ elfgetsym.o\
+ elfnew.o\
+ elfprobe.o\
+ elfread.o\
+ elftype.o\
+
+all: $(OBJS)
+
+dep:
+ @(printf 'ELFOBJS=\\';\
+ echo;\
+ echo $(OBJS) |\
+ sed -E 's@ *([^ ]*)@\telf/\1\\\n@g') > deps.mk
+
+distclean:
+ rm -f deps.mk
diff --git a/src/libmach/elf/elfarchs.c b/src/libmach/elf/elfarchs.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+
+#include <scc/mach.h>
+#include <scc/elf/elftypes.h>
+#include <scc/elf/elfhdr.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+
+struct arch elfarchs[] = {
+ {
+ .name = "elf-amd64",
+ .mach = EM_X86_64,
+ .endian = ELFDATA2LSB,
+ .type = OBJ(ELF, ARCHAMD64, LITTLE_ENDIAN),
+ },
+ NULL,
+};
diff --git a/src/libmach/elf/elfdel.c b/src/libmach/elf/elfdel.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <scc/mach.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+void
+elfdel(Obj *obj)
+{
+ struct elf *elf = obj->data;
+
+ if (elf) {
+ free(elf->phdr);
+ free(elf->secs);
+ free(elf->syms);
+ free(elf->rels);
+ }
+ free(obj->data);
+ obj->data = NULL;
+}
diff --git a/src/libmach/elf/elfgetsec.c b/src/libmach/elf/elfgetsec.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+#include <scc/elf/elftypes.h>
+#include <scc/elf/elfshdr.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+Section *
+elfgetsec(Obj *obj, int *idx, Section *sec)
+{
+ int stype, n = *idx;
+ unsigned long flags, type;
+ unsigned sflags;
+ Elf *elf = obj->data;
+ Elfsec *shdr;
+
+ if (n >= elf->nsec) {
+ if (n == SHN_ABS)
+ sec->name = "*ABS";
+ else if (n == SHN_COMMON)
+ sec->name = "*COM*";
+ else
+ sec->name = "*UNK*";
+ return NULL;
+ }
+
+ shdr = &elf->secs[n];
+ flags = shdr->flags;
+ type = shdr->type;
+
+ if (flags & SHF_ALLOC) {
+ if (type == SHT_NOBITS)
+ stype = 'B';
+ else if (flags & SHF_WRITE)
+ stype = 'D';
+ else
+ stype = 'T';
+ } else {
+ stype = 'N';
+ }
+
+ sflags = 0;
+ if (flags & SHF_WRITE)
+ sflags |= SWRITE;
+ if (flags & SHF_EXECINSTR)
+ sflags |= SEXEC;
+ if (flags & SHF_ALLOC)
+ sflags |= SLOAD|SREAD;
+ if (type != SHT_NOBITS)
+ sflags |= SALLOC;
+ if (stype == 'T' || stype == 'D')
+ sflags |= SRELOC;
+
+ /*
+ * We cannot differentiate between load and base address
+ * in a section, while we can use the physical address
+ * for that when dealing with segments.
+ */
+ if (n == SHN_UNDEF)
+ sec->name = "*UND*";
+ else
+ sec->name = shdr->name;
+
+ sec->index = n;
+ sec->size = shdr->size;
+ sec->base = shdr->addr;
+ sec->load = shdr->addr;
+ sec->offset = shdr->offset;
+ sec->type = stype;
+ sec->flags = sflags;
+ sec->align = shdr->addralign;
+
+ return sec;
+}
diff --git a/src/libmach/elf/elfgetsym.c b/src/libmach/elf/elfgetsym.c
@@ -0,0 +1,123 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/mach.h>
+#include <scc/elf/elftypes.h>
+#include <scc/elf/elfent.h>
+#include <scc/elf/elfshdr.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+static int
+typeof(Elf *elf, Elfsym *ent, char *name)
+{
+ int c, bind, weak;
+ unsigned long flags, type;
+ Elfsec *shdr;
+
+ weak = ELF_ST_BIND(ent->info) == STB_WEAK;
+
+ switch (ent->shndx) {
+ case SHN_UNDEF:
+ c = 'U';
+ break;
+ case SHN_ABS:
+ c = 'a';
+ break;
+ case SHN_COMMON:
+ c = 'C';
+ break;
+ case SHN_XINDEX:
+ abort();
+ default:
+ shdr = &elf->secs[ent->shndx];
+ flags = shdr->flags;
+ type = shdr->type;
+
+ if (ELF_ST_BIND(ent->info) == STB_WEAK) {
+ c = (flags & SHF_EXECINSTR) ? 'W' : 'V';
+ } else {
+ if (flags & SHF_ALLOC) {
+ if (type == SHT_NOBITS)
+ c = 'b';
+ else if (flags & SHF_WRITE)
+ c = 'd';
+ else if (flags & SHF_EXECINSTR)
+ c = 't';
+ else
+ c = 'r';
+ } else if (strncmp(name, ".debug", 6) == 0) {
+ c = 'N';
+ } else if (strcmp(name, ".comment") == 0) {
+ c = 'N';
+ } else if (strcmp(name, ".line") == 0) {
+ c = 'N';
+ } else if (strcmp(name, ".stab") == 0) {
+ c = 'N';
+ } else {
+ c = '?';
+ }
+ if (ELF_ST_BIND(ent->info) != STB_LOCAL)
+ c = toupper(c);
+ }
+ }
+
+ return c;
+}
+
+static int
+stypeof(Elfsym *ent)
+{
+ switch (ELF_ST_TYPE(ent->info)) {
+ case STT_OBJECT:
+ return SYMOBJECT;
+ case STT_FUNC:
+ return SYMFUNC;
+ case STT_SECTION:
+ return SYMSECTION;
+ case STT_FILE:
+ return SYMFILE;
+ case STT_COMMON:
+ return SYMCOMMON;
+ default:
+ case STT_NOTYPE:
+ return SYMNOTYPE;
+ }
+}
+
+#include <assert.h>
+
+Symbol *
+elfgetsym(Obj *obj, int *idx, Symbol *sym)
+{
+ int n = *idx;
+ Elfsym *ent;
+ Elf *elf = obj->data;
+
+ if (n == 0)
+ n++;
+
+ if (!elf->syms || n >= elf->nsym)
+ return NULL;
+ ent = &elf->syms[n];
+
+ if (ELF_ST_TYPE(ent->info) == STT_SECTION) {
+ Elfsec *shdr = &elf->secs[ent->shndx];
+ sym->name = shdr->name;
+ } else {
+ sym->name = ent->name;
+ }
+
+ // assert(strlen(sym->name) > 0);
+ sym->type = typeof(elf, ent, sym->name);
+ sym->stype = stypeof(ent);
+ sym->value = ent->value;
+ sym->size = ent->size;
+ sym->index = *idx = n;
+
+ return sym;
+}
diff --git a/src/libmach/elf/elfnew.c b/src/libmach/elf/elfnew.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <scc/mach.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+int
+elfnew(Obj *obj, int type)
+{
+ struct elf *elf;
+
+ if ((elf = calloc(1, sizeof(*elf))) == NULL)
+ return -1;
+ obj->data = elf;
+ obj->index = "/";
+ return 0;
+}
diff --git a/src/libmach/elf/elfprobe.c b/src/libmach/elf/elfprobe.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+#include <scc/elf/elftypes.h>
+#include <scc/elf/elfhdr.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+int
+elfprobe(unsigned char *buf, char **name)
+{
+ int arch, data, endian;
+ struct elfhdr32 hdr;
+ struct arch *ap;
+
+ data = buf[EI_DATA];
+ endian = (data == ELFDATA2LSB) ? LITTLE_ENDIAN : BIG_ENDIAN;
+ arch = (buf[EI_CLASS] == ELFCLASS32) ? ARCHUNK32 : ARCHUNK64;
+
+ unpack(endian,
+ buf,
+ "'16sss",
+ hdr.e_ident,
+ &hdr.e_type,
+ &hdr.e_machine,
+ &hdr.e_version);
+
+ if (!IS_ELF(hdr)
+ || buf[EI_VERSION] != EV_CURRENT
+ || hdr.e_version != EV_CURRENT
+ || buf[EI_CLASS] != ELFCLASS32 && buf[EI_CLASS] != ELFCLASS64
+ || (data != ELFDATA2LSB && data != ELFDATA2MSB)) {
+ return -1;
+ }
+
+ for (ap = elfarchs; ap->name; ap++) {
+ if (ap->mach == hdr.e_machine && ap->endian == data) {
+ if (name)
+ *name = ap->name;
+ return ap->type;
+ }
+ }
+
+ return OBJ(ELF, arch, endian);
+}
diff --git a/src/libmach/elf/elfread.c b/src/libmach/elf/elfread.c
@@ -0,0 +1,761 @@
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/mach.h>
+#include <scc/elf.h>
+
+#include <scc/elf/elftypes.h>
+#include <scc/elf/elfhdr.h>
+#include <scc/elf/elfphdr.h>
+#include <scc/elf/elfshdr.h>
+#include <scc/elf/elfent.h>
+#include <scc/elf/elfrel.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+struct elfunpack {
+ void (*hdr)(int, unsigned char *, Elfhdr *);
+ void (*phdr)(int, unsigned char *, Elfphdr *);
+ void (*sec)(int, unsigned char *, Elfsec *);
+ void (*sym)(int, unsigned char *, Elfsym *);
+ void (*rel)(int, unsigned char *, Elfrel *);
+ void (*rela)(int, unsigned char *, Elfrel *);
+
+ int hdrsiz;
+ int phdrsiz;
+ int shentsiz;
+ int symsiz;
+ int relsiz;
+ int relasiz;
+};
+
+struct elfunpack unpack64;
+struct elfunpack unpack32;
+
+static void
+unpack_hdr64(int order, unsigned char *buf, Elfhdr *hdr)
+{
+ Elf64_Ehdr ehdr;
+ int n;
+
+ n = unpack(order,
+ buf,
+ "'16sslqqqlssssss",
+ ehdr.e_ident,
+ &ehdr.e_type,
+ &ehdr.e_machine,
+ &ehdr.e_version,
+ &ehdr.e_entry,
+ &ehdr.e_phoff,
+ &ehdr.e_shoff,
+ &ehdr.e_flags,
+ &ehdr.e_ehsize,
+ &ehdr.e_phentsize,
+ &ehdr.e_phnum,
+ &ehdr.e_shentsize,
+ &ehdr.e_shnum,
+ &ehdr.e_shstrndx);
+
+ assert(n == ELFH64SZ);
+
+ memcpy(hdr->ident, ehdr.e_ident, EI_NIDENT);
+ hdr->type = ehdr.e_type;
+ hdr->machine = ehdr.e_machine;
+ hdr->version = ehdr.e_version;
+ hdr->entry = ehdr.e_entry;
+ hdr->phoff = ehdr.e_phoff;
+ hdr->shoff = ehdr.e_shoff;
+ hdr->flags = ehdr.e_flags;
+ hdr->ehsize = ehdr.e_ehsize;
+ hdr->phentsize = ehdr.e_phentsize;
+ hdr->phnum = ehdr.e_phnum;
+ hdr->shentsize = ehdr.e_shentsize;
+ hdr->shnum = ehdr.e_shnum;
+ hdr->shstrndx = ehdr.e_shstrndx;
+}
+
+static void
+unpack_hdr32(int order, unsigned char *buf, Elfhdr *hdr)
+{
+ Elf32_Ehdr ehdr;
+ int n;
+
+ n = unpack(order,
+ buf,
+ "'16sslllllssssss",
+ ehdr.e_ident,
+ &ehdr.e_type,
+ &ehdr.e_machine,
+ &ehdr.e_version,
+ &ehdr.e_entry,
+ &ehdr.e_phoff,
+ &ehdr.e_shoff,
+ &ehdr.e_flags,
+ &ehdr.e_ehsize,
+ &ehdr.e_phentsize,
+ &ehdr.e_phnum,
+ &ehdr.e_shentsize,
+ &ehdr.e_shnum,
+ &ehdr.e_shstrndx);
+
+ assert(n == ELFH32SZ);
+
+ memcpy(hdr->ident, ehdr.e_ident, EI_NIDENT);
+ hdr->type = ehdr.e_type;
+ hdr->machine = ehdr.e_machine;
+ hdr->version = ehdr.e_version;
+ hdr->entry = ehdr.e_entry;
+ hdr->phoff = ehdr.e_phoff;
+ hdr->shoff = ehdr.e_shoff;
+ hdr->flags = ehdr.e_flags;
+ hdr->ehsize = ehdr.e_ehsize;
+ hdr->phentsize = ehdr.e_phentsize;
+ hdr->phnum = ehdr.e_phnum;
+ hdr->shentsize = ehdr.e_shentsize;
+ hdr->shnum = ehdr.e_shnum;
+ hdr->shstrndx = ehdr.e_shstrndx;
+}
+
+static void
+unpack_phdr64(int order, unsigned char *buf, Elfphdr *hdr)
+{
+ int n;
+ Elf64_Phdr phdr;
+
+ n = unpack(order,
+ buf,
+ "llqqqqqq",
+ &phdr.p_type,
+ &phdr.p_flags,
+ &phdr.p_offset,
+ &phdr.p_vaddr,
+ &phdr.p_paddr,
+ &phdr.p_filesz,
+ &phdr.p_memsz,
+ &phdr.p_align);
+
+ assert(n == ELFP64SZ);
+
+ hdr->type = phdr.p_type;
+ hdr->flags = phdr.p_flags;
+ hdr->offset = phdr.p_offset;
+ hdr->vaddr = phdr.p_vaddr;
+ hdr->paddr = phdr.p_paddr;
+ hdr->filesz = phdr.p_filesz;
+ hdr->memsz = phdr.p_memsz;
+ hdr->align = phdr.p_align;
+}
+
+static void
+unpack_phdr32(int order, unsigned char *buf, Elfphdr *hdr)
+{
+ int n;
+ Elf32_Phdr phdr;
+
+ n = unpack(order,
+ buf,
+ "llllllll",
+ &phdr.p_type,
+ &phdr.p_offset,
+ &phdr.p_vaddr,
+ &phdr.p_paddr,
+ &phdr.p_filesz,
+ &phdr.p_memsz,
+ &phdr.p_flags,
+ &phdr.p_align);
+
+ assert(n == ELFP32SZ);
+
+ hdr->type = phdr.p_type;
+ hdr->flags = phdr.p_flags;
+ hdr->offset = phdr.p_offset;
+ hdr->vaddr = phdr.p_vaddr;
+ hdr->paddr = phdr.p_paddr;
+ hdr->filesz = phdr.p_filesz;
+ hdr->memsz = phdr.p_memsz;
+ hdr->align = phdr.p_align;
+}
+
+static void
+unpack_shdr64(int order, unsigned char *buf, Elfsec *sec)
+{
+ int n;
+ Elf64_Shdr shdr;
+
+ n = unpack(order,
+ buf,
+ "llqqqqllqq",
+ &shdr.sh_name,
+ &shdr.sh_type,
+ &shdr.sh_flags,
+ &shdr.sh_addr,
+ &shdr.sh_offset,
+ &shdr.sh_size,
+ &shdr.sh_link,
+ &shdr.sh_info,
+ &shdr.sh_addralign,
+ &shdr.sh_entsize);
+
+ assert(n == ELFS64SZ);
+
+ sec->sh_name = shdr.sh_name;
+ sec->type = shdr.sh_type;
+ sec->flags = shdr.sh_flags;
+ sec->addr = shdr.sh_addr;
+ sec->offset = shdr.sh_offset;
+ sec->size = shdr.sh_size;
+ sec->link = shdr.sh_link;
+ sec->info = shdr.sh_info;
+ sec->addralign = shdr.sh_addralign;
+ sec->entsize = shdr.sh_entsize;
+}
+
+static void
+unpack_shdr32(int order, unsigned char *buf, Elfsec *sec)
+{
+ int n;
+ Elf32_Shdr shdr;
+
+ n = unpack(order,
+ buf,
+ "llllllllll",
+ &shdr.sh_name,
+ &shdr.sh_type,
+ &shdr.sh_flags,
+ &shdr.sh_addr,
+ &shdr.sh_offset,
+ &shdr.sh_size,
+ &shdr.sh_link,
+ &shdr.sh_info,
+ &shdr.sh_addralign,
+ &shdr.sh_entsize);
+
+ assert(n == ELFS32SZ);
+
+ sec->sh_name = shdr.sh_name;
+ sec->type = shdr.sh_type;
+ sec->flags = shdr.sh_flags;
+ sec->addr = shdr.sh_addr;
+ sec->offset = shdr.sh_offset;
+ sec->size = shdr.sh_size;
+ sec->link = shdr.sh_link;
+ sec->info = shdr.sh_info;
+ sec->addralign = shdr.sh_addralign;
+ sec->entsize = shdr.sh_entsize;
+}
+
+static void
+unpack_sym64(int order, unsigned char *buf, Elfsym *sym)
+{
+ int n;
+ Elf64_Sym ent;
+
+ n = unpack(order,
+ buf,
+ "lccsqq",
+ &ent.st_name,
+ &ent.st_info,
+ &ent.st_other,
+ &ent.st_shndx,
+ &ent.st_value,
+ &ent.st_size);
+
+ assert(n == ELFE64SZ);
+
+ sym->st_name = ent.st_name;
+ sym->info = ent.st_info;
+ sym->other = ent.st_other;
+ sym->shndx = ent.st_shndx;
+ sym->value = ent.st_value;
+ sym->size = ent.st_size;
+}
+
+static void
+unpack_sym32(int order, unsigned char *buf, Elfsym *sym)
+{
+ int n;
+ Elf32_Sym ent;
+
+ n = unpack(order,
+ buf,
+ "lllccs",
+ &ent.st_name,
+ &ent.st_value,
+ &ent.st_size,
+ &ent.st_info,
+ &ent.st_other,
+ &ent.st_shndx);
+
+ assert(n == ELFE32SZ);
+
+ sym->st_name = ent.st_name;
+ sym->info = ent.st_info;
+ sym->other = ent.st_other;
+ sym->shndx = ent.st_shndx;
+ sym->value = ent.st_value;
+ sym->size = ent.st_size;
+}
+
+static void
+unpack_rel64(int order, unsigned char *buf, Elfrel *rp)
+{
+ int n;
+ Elf64_Rel r;
+
+ n = unpack(order,
+ buf,
+ "qq",
+ &r.r_offset,
+ &r.r_info);
+
+ assert(n == ELFR64SZ);
+
+ rp->off = r.r_offset;
+ rp->info = r.r_info;
+ rp->addend = 0;
+}
+
+static void
+unpack_rel32(int order, unsigned char *buf, Elfrel *rp)
+{
+ int n;
+ Elf32_Rel r;
+
+ n = unpack(order,
+ buf,
+ "ll",
+ &r.r_offset,
+ &r.r_info);
+
+ assert(n == ELFR32SZ);
+
+ rp->off = r.r_offset;
+ rp->info = r.r_info;
+ rp->addend = 0;
+}
+
+static void
+unpack_rela64(int order, unsigned char *buf, Elfrel *rp)
+{
+ int n;
+ Elf64_Rela r;
+
+ n = unpack(order,
+ buf,
+ "qqq",
+ &r.r_offset,
+ &r.r_info,
+ &r.r_addend);
+
+ assert(n == ELFRA64SZ);
+
+ rp->off = r.r_offset;
+ rp->info = r.r_info;
+ rp->addend = r.r_addend;
+}
+
+static void
+unpack_rela32(int order, unsigned char *buf, Elfrel *rp)
+{
+ int n;
+ Elf32_Rela r;
+
+ n = unpack(order,
+ buf,
+ "lll",
+ &r.r_offset,
+ &r.r_info,
+ &r.r_addend);
+
+ assert(n == ELFRA32SZ);
+
+ rp->off = r.r_offset;
+ rp->info = r.r_info;
+ rp->addend = r.r_addend;
+}
+
+static int
+readhdr(Obj *obj, FILE *fp)
+{
+ Elf *elf = obj->data;
+ Elfhdr *hdr = &elf->hdr;
+ Elfunpack *u = elf->unpack;
+ unsigned char buf[ELFH64SZ];
+
+ if (fread(buf, u->hdrsiz, 1, fp) != 1)
+ return 0;
+ (*u->hdr)(ORDER(obj->type), buf, hdr);
+
+ if (hdr->shnum > INT_MAX || hdr->phnum > INT_MAX)
+ return 0;
+
+ switch (hdr->type) {
+ case ET_REL:
+ case ET_EXEC:
+ case ET_DYN:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+readphdr(Obj *obj, FILE *fp)
+{
+ int i, r;
+ Elfphdr *phdr;
+ Elf *elf = obj->data;
+ Elfhdr *hdr = &elf->hdr;
+ Elfunpack *u = elf->unpack;
+ unsigned char *buf;
+
+ r = 0;
+ if (hdr->phnum > 0
+ && (hdr->phoff == 0 || hdr->phentsize < u->phdrsiz)) {
+ errno = ERANGE;
+ goto err0;
+ }
+ if (hdr->phoff == 0 || hdr->phnum == 0)
+ return 1;
+
+ if ((buf = malloc(hdr->phentsize)) == NULL)
+ goto err0;
+ if ((phdr = calloc(hdr->phnum, sizeof(*phdr))) == NULL)
+ goto err1;
+ elf->phdr = phdr;
+
+ if (!objpos(obj, fp, hdr->phoff))
+ goto err1;
+
+ for (i = 0; i < hdr->phnum; i++) {
+ if (fread(buf, hdr->phentsize, 1, fp) != 1)
+ goto err1;
+ (*u->phdr)(ORDER(obj->type), buf, &phdr[i]);
+ }
+ r = 1;
+
+err1:
+ free(buf);
+err0:
+ return r;
+}
+
+static int
+readshdr(Obj *obj, FILE *fp)
+{
+ int r, nsec;
+ Elfsec *sec;
+ Elf *elf = obj->data;
+ Elfhdr *hdr = &elf->hdr;
+ Elfunpack *u = elf->unpack;
+ unsigned char *buf;
+
+ if (hdr->shoff == 0)
+ return 1;
+
+ if (!objpos(obj, fp, hdr->shoff))
+ return 0;
+
+ if (hdr->shnum != SHN_UNDEF) {
+ if (hdr->shnum > INT_MAX)
+ return 0;
+ nsec = hdr->shnum;
+ } else {
+ Elfsec sec0;
+ fpos_t pos;
+ unsigned char buf0[ELFS64SZ];
+
+ fgetpos(fp, &pos);
+ fread(buf0, u->shentsiz, 1, fp);
+ fsetpos(fp, &pos);
+
+ if (ferror(fp))
+ return 0;
+
+ (*u->sec)(ORDER(obj->type), buf0, &sec0);
+ if (sec0.size > INT_MAX)
+ return 0;
+ nsec = sec0.size;
+ }
+
+ if (nsec == 0)
+ return 1;
+
+ r = 0;
+ if ((buf = malloc(hdr->shentsize)) == NULL)
+ return 0;
+ if ((sec = calloc(nsec, sizeof(*sec))) == NULL)
+ goto err;
+ elf->secs = sec;
+ elf->nsec = nsec;
+
+ for ( ; nsec-- > 0; ++sec) {
+ if (fread(buf, hdr->shentsize, 1, fp) != 1)
+ goto err;
+ (*u->sec)(ORDER(obj->type), buf, sec);
+ }
+ r = 1;
+err:
+ free(buf);
+ return r;
+}
+
+static int
+readstrtbl(Obj *obj, FILE *fp)
+{
+ char *s;
+ int idx;
+ Elfsec *tbl, *sec;
+ Elf *elf = obj->data;
+ Elfhdr *hdr = &elf->hdr;
+
+ if (hdr->shstrndx != SHN_XINDEX) {
+ idx = hdr->shstrndx;
+ } else {
+ if (hdr->shnum == 0)
+ return 0;
+ sec = elf->secs;
+ if (sec->link > INT_MAX)
+ return 0;
+ idx = sec->link;
+ }
+ if (idx > elf->nsec || elf->secs[idx].type != SHT_STRTAB)
+ return 0;
+ elf->secstrtbl = idx;
+
+ for (sec = elf->secs; sec < &elf->secs[elf->nsec]; ++sec) {
+ if (sec->type != SHT_STRTAB)
+ continue;
+
+ if (sec->size > SIZE_MAX)
+ return 0;
+ if ((s = malloc(sec->size)) == NULL)
+ return 0;
+ sec->strtbl = s;
+
+ if (!objpos(obj, fp, sec->offset))
+ return 0;
+ if (fread(s, sec->size, 1, fp) != 1)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+secsize(Elfsec *sec, int onent, int entsiz)
+{
+ unsigned long long nent;
+
+ if (sec->entsize == 0 || sec->entsize < entsiz)
+ return -1;
+ nent = sec->size / sec->entsize;
+ if (nent > INT_MAX - onent)
+ return -1;
+
+ return nent;
+}
+
+static int
+readsyms(Obj *obj, Elfsec *sec, FILE *fp)
+{
+ int r = 0, n, oldn;
+ Elfsym *sym;
+ Elfsec *tbl;
+ Elf *elf = obj->data;
+ Elfunpack *u = elf->unpack;
+ Elfhdr *hdr = &elf->hdr;
+ unsigned char *buf;
+
+ if ((n = secsize(sec, elf->nsym, u->symsiz)) <= 0)
+ return n;
+ if ((buf = malloc(sec->entsize)) == NULL)
+ return 0;
+
+ oldn = elf->nsym;
+ sym = realloc(elf->syms, (oldn + n) * sizeof(Elfsym));
+ if (!sym)
+ goto err;
+ elf->syms = sym;
+ elf->nsym += n;
+
+ if (!objpos(obj, fp, sec->offset))
+ goto err;
+
+ if (sec->link >= hdr->shnum)
+ goto err;
+ tbl = &elf->secs[sec->link];
+ if (tbl->type != SHT_STRTAB)
+ goto err;
+
+ for (sym = &elf->syms[oldn] ; n-- > 0 ; ++sym) {
+ if (fread(buf, sec->entsize, 1, fp) != 1)
+ goto err;
+ (*u->sym)(ORDER(obj->type), buf, sym);
+ sym->symsec = sec;
+ if (sym->st_name >= tbl->size)
+ goto err;
+ sym->name = &tbl->strtbl[sym->st_name];
+
+ switch (sym->shndx) {
+ case SHN_XINDEX:
+ /*
+ * Elf supports an extension mechanism to allow
+ * indexes bigger than 4 bytes. We don't care
+ * and we reject elf files using this feature.
+ */
+ goto err;
+ case SHN_UNDEF:
+ case SHN_ABS:
+ case SHN_COMMON:
+ break;
+ default:
+ if (sym->shndx >= elf->nsec)
+ goto err;
+ break;
+ }
+ }
+ r = 1;
+
+err:
+ free(buf);
+ return r;
+}
+
+static int
+readrels(Obj *obj, Elfsec *sec, FILE *fp)
+{
+ int r = 0, oldn, n, min;
+ Elf *elf = obj->data;
+ Elfunpack *u = elf->unpack;
+ Elfrel *rp;
+ void (*fn)(int, unsigned char *, Elfrel *);
+ unsigned char *buf;
+
+ if (sec->type == SHT_RELA) {
+ fn = u->rela;
+ min = u->relasiz;
+ } else {
+ fn = u->rel;
+ min = u->relsiz;
+ }
+
+ if (!objpos(obj, fp, sec->offset))
+ goto err;
+
+ if ((n = secsize(sec, elf->nrel, min)) <= 0)
+ return n;
+ if ((buf = malloc(sec->entsize)) == NULL)
+ return 0;
+
+ oldn = elf->nrel;
+ rp = realloc(elf->rels, (oldn + n) * sizeof(Elfrel));
+ if (!rp)
+ goto err;
+ elf->rels = rp;
+ elf->nrel += n;
+
+ for (rp = &elf->rels[oldn]; n-- > 0; ++rp) {
+ if (fread(buf, sec->entsize, 1, fp) != 1)
+ goto err;
+ (*fn)(ORDER(obj->type), buf, rp);
+ }
+ r = 1;
+
+err:
+ free(buf);
+ return r;
+}
+
+static int
+procsecs(Obj *obj, FILE *fp)
+{
+ Elf *elf = obj->data;
+ Elfsec *tbl, *sec;
+
+ tbl = &elf->secs[elf->secstrtbl];
+ for (sec = elf->secs; sec < &elf->secs[elf->nsec]; ++sec) {
+ if (sec->sh_name >= tbl->size)
+ return 0;
+ sec->name = &tbl->strtbl[sec->sh_name];
+
+ switch (sec->type) {
+ case SHT_DYNSYM:
+ case SHT_SYMTAB:
+ if (!readsyms(obj, sec, fp))
+ return 0;
+ break;
+ case SHT_RELA:
+ case SHT_REL:
+ if (!readrels(obj, sec, fp))
+ return 0;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+int
+elfread(Obj *obj, FILE *fp)
+{
+ fpos_t pos;
+ Elf *elf = obj->data;
+ unsigned char buf[EI_CLASS+1];
+
+ fgetpos(fp, &pos);
+ fread(buf, sizeof(buf), 1, fp);
+ fsetpos(fp, &pos);
+
+ elf->unpack = (buf[EI_CLASS] == ELFCLASS64) ? &unpack64 : &unpack32;
+
+ if (!readhdr(obj, fp))
+ return -1;
+ if (!readphdr(obj, fp))
+ return -1;
+ if (!readshdr(obj, fp))
+ return -1;
+ if (!readstrtbl(obj, fp))
+ return -1;
+ if (!procsecs(obj, fp))
+ return -1;
+
+ return 0;
+}
+
+struct elfunpack unpack64 = {
+ .hdr = unpack_hdr64,
+ .phdr = unpack_phdr64,
+ .sec = unpack_shdr64,
+ .sym = unpack_sym64,
+ .rel = unpack_rel64,
+ .rela = unpack_rela64,
+
+ .hdrsiz = ELFH64SZ,
+ .phdrsiz = ELFP64SZ,
+ .shentsiz = ELFS64SZ,
+ .symsiz = ELFE64SZ,
+ .relsiz = ELFR64SZ,
+ .relasiz = ELFRA64SZ,
+};
+
+struct elfunpack unpack32 = {
+ .hdr = unpack_hdr32,
+ .phdr = unpack_phdr32,
+ .sec = unpack_shdr32,
+ .sym = unpack_sym32,
+ .rel = unpack_rel32,
+ .rela = unpack_rela32,
+
+ .hdrsiz = ELFH32SZ,
+ .phdrsiz = ELFP32SZ,
+ .shentsiz = ELFS32SZ,
+ .symsiz = ELFE32SZ,
+ .relsiz = ELFR32SZ,
+ .relasiz = ELFRA32SZ,
+};
diff --git a/src/libmach/elf/elftype.c b/src/libmach/elf/elftype.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <scc/mach.h>
+#include <scc/elf.h>
+
+#include "../libmach.h"
+#include "fun.h"
+
+int
+elftype(char *name)
+{
+ struct arch *ap;
+
+ for (ap = elfarchs; ap ->name; ap++) {
+ if (strcmp(ap->name, name) == 0)
+ return ap->type;
+ }
+
+ return -1;
+}
diff --git a/src/libmach/elf/fun.h b/src/libmach/elf/fun.h
@@ -0,0 +1,17 @@
+extern int elfnew(Obj *, int);
+extern int elfread(Obj *, FILE *);
+extern int elfsetidx(long, char **, long *, FILE *);
+extern int elfgetidx(long *, char ***, long **, FILE *);
+extern int elfpc2line(Obj *, unsigned long long , char *, int *);
+extern int elfstrip(Obj *);
+extern void elfdel(Obj *);
+extern int elfwrite(Obj *, Map *, FILE *);
+extern int elfprobe(unsigned char *, char **);
+extern int elftype(char *);
+
+extern int elfxsetidx(int long , char *[], long [], FILE *);
+extern int elfxgetidx(int, long *, char ***, long **, FILE *);
+
+extern Symbol *elfgetsym(Obj *, int *, Symbol *);
+extern Section *elfgetsec(Obj *, int *, Section *);
+extern Map *elfloadmap(Obj *, FILE *);
diff --git a/src/libmach/elf64/Makefile b/src/libmach/elf64/Makefile
@@ -1,35 +0,0 @@
-.POSIX:
-
-PROJECTDIR =../../..
-include $(PROJECTDIR)/scripts/rules.mk
-
-OBJS =\
- elf64.o\
- elf64archs.o\
- elf64del.o\
- elf64getsec.o\
- elf64getsym.o\
- elf64new.o\
- elf64probe.o\
- elf64read.o\
- elf64type.o\
-
-ELFHDRS =\
- $(INCDIR)/bits/scc/elf/elfent.h\
- $(INCDIR)/bits/scc/elf/elfhdr.h\
- $(INCDIR)/bits/scc/elf/elfphdr.h\
- $(INCDIR)/bits/scc/elf/elfshdr.h\
- $(INCDIR)/bits/scc/elf/elftypes.h\
-
-all: $(OBJS)
-
-$(OBJS): $(ELFHDRS)
-
-dep:
- @(printf 'ELF64OBJS=\\';\
- echo;\
- echo $(OBJS) |\
- sed -E 's@ *([^ ]*)@\telf64/\1\\\n@g') > deps.mk
-
-distclean:
- rm -f deps.mk
diff --git a/src/libmach/elf64/elf64.c b/src/libmach/elf64/elf64.c
@@ -1,24 +0,0 @@
-#include <stdio.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-char *
-elf64str(Obj *obj, int n, long stroff)
-{
- char *tbl;
- size_t siz;
- struct elf64 *elf;
-
- elf = obj->data;
-
- tbl = elf->strtbl[n];
- siz = elf->strsiz[n];
-
- if (!tbl || siz < stroff)
- return "";
- return &tbl[stroff];
-}
diff --git a/src/libmach/elf64/elf64archs.c b/src/libmach/elf64/elf64archs.c
@@ -1,16 +0,0 @@
-#include <stdio.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-
-struct arch elf64archs[] = {
- {
- .name = "elf-amd64",
- .mach = EM_X86_64,
- .endian = ELFDATA2LSB,
- .type = OBJ(ELF64, ARCHAMD64, LITTLE_ENDIAN),
- },
- NULL,
-};
diff --git a/src/libmach/elf64/elf64del.c b/src/libmach/elf64/elf64del.c
@@ -1,24 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-void
-elf64del(Obj *obj)
-{
- struct elf64 *elf = obj->data;
-
- if (elf) {
- free(elf->phdr);
- free(elf->shdr);
- free(elf->syms);
- free(elf->strtbl[0]);
- free(elf->strtbl[1]);
- }
- free(obj->data);
- obj->data = NULL;
-}
diff --git a/src/libmach/elf64/elf64getsec.c b/src/libmach/elf64/elf64getsec.c
@@ -1,76 +0,0 @@
-#include <stdio.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-Section *
-elf64getsec(Obj *obj, int *idx, Section *sec)
-{
- int stype, n = *idx;
- unsigned long flags, type;
- unsigned sflags;
- Elf64 *elf = obj->data;
- Elf_Ehdr *hdr = &elf->hdr;
- Elf_Shdr *shdr;
-
- if (n >= elf->nsec) {
- if (n == SHN_ABS)
- sec->name = "*ABS";
- else if (n == SHN_COMMON)
- sec->name = "*COM*";
- else
- sec->name = "*UNK*";
- return NULL;
- }
-
- shdr = &elf->shdr[n];
- flags = shdr->sh_flags;
- type = shdr->sh_type;
-
- if (flags & SHF_ALLOC) {
- if (type == SHT_NOBITS)
- stype = 'B';
- else if (flags & SHF_WRITE)
- stype = 'D';
- else
- stype = 'T';
- } else {
- stype = 'N';
- }
-
- sflags = 0;
- if (flags & SHF_WRITE)
- sflags |= SWRITE;
- if (flags & SHF_EXECINSTR)
- sflags |= SEXEC;
- if (flags & SHF_ALLOC)
- sflags |= SLOAD|SREAD;
- if (type != SHT_NOBITS)
- sflags |= SALLOC;
- if (stype == 'T' || stype == 'D')
- sflags |= SRELOC;
-
- /*
- * We cannot differentiate between load and base address
- * in a section, while we can use the physical address
- * for that when dealing with segments.
- */
- if (n == SHN_UNDEF)
- sec->name = "*UND*";
- else
- sec->name = elf64str(obj, SEC_STRTBL, shdr->sh_name);
-
- sec->index = n;
- sec->size = shdr->sh_size;
- sec->base = shdr->sh_addr;
- sec->load = shdr->sh_addr;
- sec->offset = shdr->sh_offset;
- sec->type = stype;
- sec->flags = sflags;
- sec->align = shdr->sh_addralign;
-
- return sec;
-}
diff --git a/src/libmach/elf64/elf64getsym.c b/src/libmach/elf64/elf64getsym.c
@@ -1,112 +0,0 @@
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-static int
-typeof(Elf64 *elf, Elf_Sym *ent, char *name)
-{
- int c, bind;
- unsigned long flags, type;
- Elf_Shdr *shdr;
-
- switch (ent->st_shndx) {
- case SHN_UNDEF:
- c = 'U';
- break;
- case SHN_ABS:
- c = 'a';
- break;
- case SHN_COMMON:
- c = 'C';
- break;
- case SHN_XINDEX:
- abort();
- default:
- shdr = &elf->shdr[ent->st_shndx];
- flags = shdr->sh_flags;
- type = shdr->sh_type;
-
- if (flags & SHF_ALLOC) {
- if (type == SHT_NOBITS)
- c = 'b';
- else if (flags & SHF_WRITE)
- c = 'd';
- else if (flags & SHF_EXECINSTR)
- c = 't';
- else
- c = 'r';
- } else if (strncmp(name, ".debug", 6) == 0) {
- c = 'N';
- } else if (strcmp(name, ".comment") == 0) {
- c = 'N';
- } else if (strcmp(name, ".line") == 0) {
- c = 'N';
- } else if (strcmp(name, ".stab") == 0) {
- c = 'N';
- } else {
- c = '?';
- }
- }
-
- if (ELF_ST_BIND(ent->st_info) != STB_LOCAL)
- c = toupper(c);
-
- return c;
-}
-
-static int
-stypeof(Elf_Sym *ent)
-{
- switch (ELF_ST_TYPE(ent->st_info)) {
- case STT_OBJECT:
- return SYMOBJECT;
- case STT_FUNC:
- return SYMFUNC;
- case STT_SECTION:
- return SYMSECTION;
- case STT_FILE:
- return SYMFILE;
- case STT_COMMON:
- return SYMCOMMON;
- default:
- case STT_NOTYPE:
- return SYMNOTYPE;
- }
-}
-
-Symbol *
-elf64getsym(Obj *obj, int *idx, Symbol *sym)
-{
- int n = *idx;
- Elf_Sym *ent;
- Elf64 *elf = obj->data;
-
- if (n == 0)
- n++;
-
- if (!elf->symtab || n >= elf->nsym)
- return NULL;
- ent = &elf->syms[n];
-
- if (ELF_ST_TYPE(ent->st_info) == STT_SECTION) {
- Elf_Shdr *shdr = &elf->shdr[ent->st_shndx];
- sym->name = elf64str(obj, SEC_STRTBL, shdr->sh_name);
- } else {
- sym->name = elf64str(obj, SYM_STRTBL, ent->st_name);
- }
-
- sym->type = typeof(elf, ent, sym->name);
- sym->stype = stypeof(ent);
- sym->value = ent->st_value;
- sym->size = ent->st_size;
- sym->index = *idx = n;
-
- return sym;
-}
diff --git a/src/libmach/elf64/elf64new.c b/src/libmach/elf64/elf64new.c
@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-int
-elf64new(Obj *obj, int type)
-{
- struct elf64 *elf;
-
- if ((elf = calloc(1, sizeof(*elf))) == NULL)
- return -1;
- obj->data = elf;
- obj->index = "/";
- return 0;
-}
diff --git a/src/libmach/elf64/elf64probe.c b/src/libmach/elf64/elf64probe.c
@@ -1,45 +0,0 @@
-#include <stdio.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-int
-elf64probe(unsigned char *buf, char **name)
-{
- int endian;
- Elf_Ehdr hdr;
- struct arch *ap;
-
- unpack(buf[EI_DATA] == ELFDATA2LSB ? LITTLE_ENDIAN : BIG_ENDIAN,
- buf,
- "'16sss",
- hdr.e_ident,
- &hdr.e_type,
- &hdr.e_machine,
- &hdr.e_version);
-
- if (!IS_ELF(hdr)
- || buf[EI_CLASS] != ELFCLASS64
- || buf[EI_DATA] == ELFDATANONE
- || buf[EI_VERSION] != EV_CURRENT
- || (buf[EI_DATA] != ELFDATA2LSB && buf[EI_DATA] != ELFDATA2MSB)) {
- return -1;
- }
-
- if (hdr.e_version != EV_CURRENT)
- return -1;
-
- endian = hdr.e_ident[EI_DATA];
- for (ap = elf64archs; ap->name; ap++) {
- if (ap->mach == hdr.e_machine && ap->endian == endian) {
- if (name)
- *name = ap->name;
- return ap->type;
- }
- }
-
- return -1;
-}
diff --git a/src/libmach/elf64/elf64read.c b/src/libmach/elf64/elf64read.c
@@ -1,386 +0,0 @@
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-static int
-unpack_hdr(int order, unsigned char *buf, Elf_Ehdr *hdr)
-{
- int n;
-
- n = unpack(order,
- buf,
- "'16sslqqqlssssss",
- hdr->e_ident,
- &hdr->e_type,
- &hdr->e_machine,
- &hdr->e_version,
- &hdr->e_entry,
- &hdr->e_phoff,
- &hdr->e_shoff,
- &hdr->e_flags,
- &hdr->e_ehsize,
- &hdr->e_phentsize,
- &hdr->e_phnum,
- &hdr->e_shentsize,
- &hdr->e_shnum,
- &hdr->e_shstrndx);
-
- assert(n == ELFHSZ);
-
- return n;
-}
-
-static int
-unpack_phdr(int order, unsigned char *buf, Elf_Phdr *phdr)
-{
- int n;
-
- n = unpack(order,
- buf,
- "llqqqqqq",
- &phdr->p_type,
- &phdr->p_flags,
- &phdr->p_offset,
- &phdr->p_vaddr,
- &phdr->p_paddr,
- &phdr->p_filesz,
- &phdr->p_memsz,
- &phdr->p_align);
-
- assert(n == ELFPSZ);
-
- return n;
-}
-
-static int
-unpack_shdr(int order, unsigned char *buf, Elf_Shdr *shdr)
-{
- int n;
-
- n = unpack(order,
- buf,
- "llqqqqllqq",
- &shdr->sh_name,
- &shdr->sh_type,
- &shdr->sh_flags,
- &shdr->sh_addr,
- &shdr->sh_offset,
- &shdr->sh_size,
- &shdr->sh_link,
- &shdr->sh_info,
- &shdr->sh_addralign,
- &shdr->sh_entsize);
-
- assert(n == ELFSSZ);
-
- return n;
-}
-
-static int
-unpack_sym(int order, unsigned char *buf, Elf_Sym *sym)
-{
- int n;
-
- n = unpack(order,
- buf,
- "lccsqq",
- &sym->st_name,
- &sym->st_info,
- &sym->st_other,
- &sym->st_shndx,
- &sym->st_value,
- &sym->st_size);
- assert(n == ELFESZ);
-
- return n;
-}
-
-static int
-readhdr(Obj *obj, FILE *fp)
-{
- Elf64 *elf;
- Elf_Ehdr *hdr;
- unsigned char buf[ELFHSZ];
-
- elf = obj->data;
- hdr = &elf->hdr;
-
- if (fread(buf, ELFHSZ, 1, fp) != 1)
- return 0;
- unpack_hdr(ORDER(obj->type), buf, hdr);
-
- switch (hdr->e_type) {
- case ET_REL:
- case ET_EXEC:
- case ET_DYN:
- return 1;
- default:
- return 0;
- }
-}
-
-static int
-readphdr(Obj *obj, FILE *fp)
-{
- long long i;
- Elf_Ehdr *hdr;
- Elf_Phdr *phdr;
- Elf64 *elf;
- unsigned char buf[ELFPSZ];
-
- elf = obj->data;
- hdr = &elf->hdr;
-
- if (hdr->e_phoff == 0 || hdr->e_phnum == 0)
- return 1;
-
- phdr = calloc(hdr->e_phnum, sizeof(*phdr));
- if (!phdr)
- return 0;
- elf->phdr = phdr;
-
- if (!objpos(obj, fp, hdr->e_phoff))
- return 0;
- for (i = 0; i < hdr->e_phnum; i++) {
- if (fread(buf, ELFPSZ, 1, fp) != 1)
- return 0;
- unpack_phdr(ORDER(obj->type), buf, &phdr[i]);
- }
-
- return 1;
-}
-
-static int
-readshdr(Obj *obj, FILE *fp)
-{
- unsigned long long i, nsec;
- Elf_Ehdr *hdr;
- Elf_Shdr *shdr;
- Elf64 *elf;
- unsigned char buf[ELFSSZ + ELFHSZ];
-
- elf = obj->data;
- hdr = &elf->hdr;
- elf->nsec = 0;
- elf->shdr = NULL;
-
- if (hdr->e_shoff == 0)
- return 1;
-
- if (!objpos(obj, fp, hdr->e_shoff))
- return 0;
-
- if (hdr->e_shnum != SHN_UNDEF) {
- nsec = hdr->e_shnum;
- } else {
- Elf_Shdr sec0;
- fpos_t pos;
-
- fgetpos(fp, &pos);
- fread(buf, ELFHSZ, 1, fp);
- fsetpos(fp, &pos);
-
- if (ferror(fp))
- return 0;
-
- unpack_shdr(ORDER(obj->type), buf, &sec0);
- nsec = sec0.sh_size;
- }
-
- if (nsec > SIZE_MAX)
- return 0;
- if (nsec == 0)
- return 1;
-
- shdr = calloc(nsec, sizeof(*shdr));
- if (!shdr)
- return 0;
- elf->shdr = shdr;
- elf->nsec = nsec;
-
- for (i = 0; i < nsec; i++) {
- if (fread(buf, ELFSSZ, 1, fp) != 1)
- return 0;
- unpack_shdr(ORDER(obj->type), buf, &shdr[i]);
- if (shdr[i].sh_type == SHT_SYMTAB) {
- /*
- * elf supports multiple symbol table, but we don't
- * care and we only support one, and we reject elf
- * files with more of one symbol table.
- */
- if (elf->symtab)
- return 0;
- elf->symtab = &shdr[i];
- }
- }
-
- return 1;
-}
-
-static int
-readsecstr(Obj *obj, FILE *fp)
-{
- long idx;
- size_t siz;
- char *str;
- Elf_Shdr *shdr;
- Elf64 *elf;
- Elf_Ehdr *hdr;
-
- elf = obj->data;
- hdr = &elf->hdr;
- idx = hdr->e_shstrndx;
- if (idx == SHN_UNDEF)
- return 0;
- if (idx == SHN_XINDEX) {
- if (hdr->e_shnum == 0)
- return 0;
- idx = elf->shdr[0].sh_link;
- }
-
- if (idx >= hdr->e_shnum)
- return 0;
- shdr = &elf->shdr[idx];
-
- if (shdr->sh_size > SIZE_MAX)
- return 0;
-
- siz = shdr->sh_size;
- if (siz == 0)
- return 1;
- str = malloc(siz);
- if (!str)
- return 0;
-
- elf->strtbl[SEC_STRTBL] = str;
- elf->strsiz[SEC_STRTBL] = siz;
-
- if (!objpos(obj, fp, shdr->sh_offset))
- return 0;
- if (fread(str, siz, 1, fp) != 1)
- return 0;
-
- return 1;
-}
-
-static int
-readsymstr(Obj *obj, FILE *fp)
-{
- long idx;
- size_t siz;
- char *str;
- Elf64 *elf;
- Elf_Shdr *shdr;
-
- elf = obj->data;
- if (!elf->symtab)
- return 1;
-
- idx = elf->symtab->sh_link;
- if (idx >= elf->nsec)
- return 0;
- shdr = &elf->shdr[idx];
-
- if (shdr->sh_size > SIZE_MAX)
- return 0;
-
- siz = shdr->sh_size;
- if (siz == 0)
- return 1;
- str = malloc(siz);
- if (!str)
- return 0;
-
- elf->strtbl[SYM_STRTBL] = str;
- elf->strsiz[SYM_STRTBL] = siz;
-
- if (!objpos(obj, fp, shdr->sh_offset))
- return 0;
- if (fread(str, siz, 1, fp) != 1)
- return 0;
-
- return 1;
-}
-
-static int
-readsym(Obj *obj, FILE *fp)
-{
- long nsym, i;
- int sec;
- Elf64 *elf;
- Elf_Sym *syms;
- Elf_Shdr *shdr;
- unsigned char buf[ELFSSZ];
-
- elf = obj->data;
- if (!elf->symtab)
- return 1;
- shdr = elf->symtab;
-
- assert(shdr->sh_type == SHT_SYMTAB);
-
- nsym = shdr->sh_size / shdr->sh_entsize;
- if (nsym >= SIZE_MAX)
- return 0;
-
- syms = calloc(nsym, sizeof(*syms));
- if (!syms)
- return 0;
- elf->syms = syms;
- elf->nsym = nsym;
-
- if (!objpos(obj, fp, shdr->sh_offset))
- return 0;
-
- for (i = 0; i < nsym; i++) {
- if (fread(buf, ELFESZ, 1, fp) != 1)
- return 0;
- unpack_sym(ORDER(obj->type), buf, &syms[i]);
-
- sec = syms[i].st_shndx;
- switch (sec) {
- case SHN_XINDEX:
- /*
- * Elf supports an extension mechanism to allow
- * indexes bigger than 4 bytes. We don't care
- * and we reject elf files using this feature.
- */
- return 0;
- case SHN_UNDEF:
- case SHN_ABS:
- case SHN_COMMON:
- break;
- default:
- if (sec >= elf->nsec)
- return 0;
- break;
- }
- }
-
- return 1;
-}
-
-int
-elf64read(Obj *obj, FILE *fp)
-{
- if (!readhdr(obj, fp))
- return -1;
- if (!readphdr(obj, fp))
- return -1;
- if (!readshdr(obj, fp))
- return -1;
- if (!readsym(obj, fp))
- return -1;
- if (!readsecstr(obj, fp))
- return -1;
- if (!readsymstr(obj, fp))
- return -1;
-
- return 0;
-}
diff --git a/src/libmach/elf64/elf64type.c b/src/libmach/elf64/elf64type.c
@@ -1,21 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include <scc/mach.h>
-#include <scc/elf64.h>
-
-#include "../libmach.h"
-#include "fun.h"
-
-int
-elf64type(char *name)
-{
- struct arch *ap;
-
- for (ap = elf64archs; ap ->name; ap++) {
- if (strcmp(ap->name, name) == 0)
- return ap->type;
- }
-
- return -1;
-}
diff --git a/src/libmach/elf64/fun.h b/src/libmach/elf64/fun.h
@@ -1,17 +0,0 @@
-extern int elf64new(Obj *, int);
-extern int elf64read(Obj *, FILE *);
-extern int elf64setidx(long, char **, long *, FILE *);
-extern int elf64getidx(long *, char ***, long **, FILE *);
-extern int elf64pc2line(Obj *, unsigned long long , char *, int *);
-extern int elf64strip(Obj *);
-extern void elf64del(Obj *);
-extern int elf64write(Obj *, Map *, FILE *);
-extern int elf64probe(unsigned char *, char **);
-extern int elf64type(char *);
-
-extern int elf64xsetidx(int long , char *[], long [], FILE *);
-extern int elf64xgetidx(int, long *, char ***, long **, FILE *);
-
-extern Symbol *elf64getsym(Obj *, int *, Symbol *);
-extern Section *elf64getsec(Obj *, int *, Section *);
-extern Map *elf64loadmap(Obj *, FILE *);
diff --git a/src/libmach/getindex.c b/src/libmach/getindex.c
@@ -5,7 +5,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(long *, char ***, long **, FILE *) = {
diff --git a/src/libmach/getsec.c b/src/libmach/getsec.c
@@ -4,12 +4,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static Section *(*ops[NFORMATS])(Obj *, int *, Section *) = {
[COFF32] = coff32getsec,
- [ELF64] = elf64getsec,
+ [ELF] = elfgetsec,
};
Section *
diff --git a/src/libmach/getsym.c b/src/libmach/getsym.c
@@ -4,12 +4,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static Symbol *(*ops[NFORMATS])(Obj *, int *, Symbol *) = {
[COFF32] = coff32getsym,
- [ELF64] = elf64getsym,
+ [ELF] = elfgetsym,
};
Symbol *
diff --git a/src/libmach/loadmap.c b/src/libmach/loadmap.c
@@ -4,7 +4,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static Map *(*ops[NFORMATS])(Obj *, FILE *) = {
diff --git a/src/libmach/newobj.c b/src/libmach/newobj.c
@@ -7,12 +7,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(Obj *, int) = {
[COFF32] = coff32new,
- [ELF64] = elf64new,
+ [ELF] = elfnew,
};
Obj *
diff --git a/src/libmach/objprobe.c b/src/libmach/objprobe.c
@@ -4,12 +4,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(unsigned char *, char **) = {
[COFF32] = coff32probe,
- [ELF64] = elf64probe,
+ [ELF] = elfprobe,
};
int
diff --git a/src/libmach/objtype.c b/src/libmach/objtype.c
@@ -4,12 +4,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(char *) = {
[COFF32] = coff32type,
- [ELF64] = elf64type,
+ [ELF] = elftype,
};
int
diff --git a/src/libmach/pc2line.c b/src/libmach/pc2line.c
@@ -4,7 +4,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(Obj *, unsigned long long , char *, int *) = {
diff --git a/src/libmach/readobj.c b/src/libmach/readobj.c
@@ -4,12 +4,12 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(Obj *, FILE *) = {
[COFF32] = coff32read,
- [ELF64] = elf64read,
+ [ELF] = elfread,
};
int
diff --git a/src/libmach/setindex.c b/src/libmach/setindex.c
@@ -5,7 +5,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(long, char **, long *, FILE *) = {
diff --git a/src/libmach/setsec.c b/src/libmach/setsec.c
@@ -4,7 +4,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static Section *(*ops[NFORMATS])(Obj *, int *, Section *) = {
diff --git a/src/libmach/setsym.c b/src/libmach/setsym.c
@@ -4,7 +4,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static Symbol *(*ops[NFORMATS])(Obj *, int *, Symbol *) = {
diff --git a/src/libmach/strip.c b/src/libmach/strip.c
@@ -4,7 +4,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(Obj *) = {
diff --git a/src/libmach/writeobj.c b/src/libmach/writeobj.c
@@ -4,7 +4,7 @@
#include "libmach.h"
-#include "elf64/fun.h"
+#include "elf/fun.h"
#include "coff32/fun.h"
static int (*ops[NFORMATS])(Obj *, Map *, FILE *) = {