aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--misc/elf-abi/elf-abi.c281
1 files changed, 130 insertions, 151 deletions
diff --git a/misc/elf-abi/elf-abi.c b/misc/elf-abi/elf-abi.c
index aa383c4..6b3a9c2 100644
--- a/misc/elf-abi/elf-abi.c
+++ b/misc/elf-abi/elf-abi.c
@@ -7,15 +7,15 @@
*
* Supported identifiers:
*
- * alpha_32
- * arm_{oabi32,32,64}
- * hppa_32,64
- * ia_64
- * m68k_32
+ * alpha_{32,64}
+ * arm_{32,64}
+ * hppa_{32,64}
+ * ia_{32,64}
+ * m68k_{32,64}
* mips_{n32,n64,o32}
* ppc_{32,64}
- * s390_32
- * sh_32
+ * s390_{32,64}
+ * sh_{32,64}
* sparc_{32,64}
* x86_{32,x32,64}
*
@@ -35,7 +35,6 @@
*
* http://www.sco.com/developers/gabi/2000-07-17/ch4.eheader.html
*
- *
* Copyright 2015 Anthony G. Basile - <blueness@gentoo.org>
* Copyright 2015 Zac Medico - <zmedico@gentoo.org>
*
@@ -102,64 +101,91 @@ E_MIPS_ABI_EABI64 = 0x00004000
#define EF_ARM_NEW_ABI 0x80
#define EF_ARM_OLD_ABI 0x100
-/*
-def compute_suffix_mips(elf_header):
- name = None
- mips_abi = elf_header.e_flags & EF_MIPS_ABI
- if mips_abi:
- if mips_abi == E_MIPS_ABI_O32:
- name = "o32"
- elif mips_abi == E_MIPS_ABI_O64:
- name = "o64"
- elif mips_abi == E_MIPS_ABI_EABI32:
- name = "eabi32"
- elif mips_abi == E_MIPS_ABI_EABI64:
- name = "eabi64"
-
- elif elf_header.e_flags & EF_MIPS_ABI2:
- name = "n32"
- elif elf_header.ei_class == ELFCLASS64:
- name = "n64"
- return name
-
-def compute_multilib_id(elf_header):
- prefix = machine_prefix_map.get(elf_header.e_machine)
- suffix = None
+int
+get_wordsize(uint8_t ei_class)
+{
+ switch (ei_class) {
+ case ELFCLASS32:
+ return 32;
+ case ELFCLASS64:
+ return 64;
+ default:
+ return 0;
+ }
+}
- if prefix == "mips":
- suffix = compute_suffix_mips(elf_header)
- elif elf_header.ei_class == ELFCLASS64:
- suffix = "64"
- elif elf_header.ei_class == ELFCLASS32:
- if elf_header.e_machine == EM_X86_64:
- suffix = "x32"
- else:
- suffix = "32"
- if prefix is None or suffix is None:
- multilib_id = None
- else:
- multilib_id = "%s_%s" % (prefix, suffix)
+int
+get_endian(uint8_t ei_data)
+{
+ switch (ei_data) {
+ case ELFDATA2LSB:
+ return -1;
+ case ELFDATA2MSB:
+ return 1;
+ default:
+ return 0;
+ }
+}
- return multilib_id
-*/
-#define MAX_IDENT 32
+char *
+get_abi(uint16_t e_machine, int width, uint32_t e_flags)
+{
+ switch(e_machine) {
+ case EM_ALPHA:
+ case EM_FAKE_ALPHA:
+ return "alpha";
+ case EM_X86_64:
+ return "amd64";
+ case EM_ARM:
+ return "arm";
+ case EM_AARCH64:
+ return "arm64";
+ case EM_68K:
+ return "m68k";
+ case EM_MIPS_RS3_LE:
+ case EM_MIPS:
+ return "mips";
+ case EM_IA_64:
+ return "ia64";
+ case EM_PARISC:
+ return "hppa";
+ case EM_PPC:
+ return "ppc";
+ case EM_PPC64:
+ return "ppc64";
+ case EM_S390:
+ return "s390";
+ case EM_SH:
+ return "sh";
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ case EM_SPARC:
+ return "sparc";
+ case EM_386:
+ return "x86";
+ default:
+ return "unknown_arch";
+ }
+}
int
main(int argc, char* argv[])
{
- char ident[MAX_IDENT]; /* The Gentoo standard arch_abi identifier. */
- char *arch; /* The Gentoo architecture identifier. */
- int fd;
- struct stat s;
+ int width; /* Machine word size. Either 32 or 64 bits. */
+ int endian; /* Endian, -1 = little, 1 = big */
+ char *abi; /* Abi name from glibc's <bits/syscall.h> */
+
+ int fd; /* file descriptor for opened Elf object. */
+ struct stat s; /* stat on opened Elf object. */
char magic[4]; /* magic number at the begining of the file */
- uint8_t ei_class, width; /* width = 8 bytes for 32-bits, 16 bytes for 64-bits. */
- uint8_t ei_data, endian; /* endian = 0 for little, 1 for big endian. */
+ uint8_t ei_class; /* ei_class is one byte of e_ident[] */
+ uint8_t ei_data; /* ei_data is one byte of e_ident[] */
uint16_t e_machine; /* Size is Elf32_Half or Elf64_Half. Both are 2 bytes. */
uint32_t e_flags; /* Size is Elf32_Word or Elf64_Word. Both are 4 bytes. */
- uint64_t e_flags_offset; /* Wide enough for either 32 or 64 bits. */
+ uint64_t e_machine_offset, e_flags_offset; /* Wide enough for either 32 or 64 bits. */
/* Is the second parameter a regular file? */
if (argc != 2)
@@ -177,120 +203,73 @@ main(int argc, char* argv[])
if (strncmp(magic, ELFMAG, 4) != 0)
errx(1, "%s is not an ELF object", argv[1]);
-
/* 32 or 64 bits? */
if (read(fd, &ei_class, 1) == -1)
err(1, "read() ei_class failed");
- switch (ei_class) {
- case ELFCLASS32:
- width = 4;
- printf("32 bit\n");
- break;
- case ELFCLASS64:
- width = 8;
- printf("64 bit\n");
- break;
- default:
- width = 0;
- printf("Unknown bit\n");
- }
+ width = get_wordsize(ei_class);
/* Little or Big Endian? */
if (read(fd, &ei_data, 1) == -1)
err(1, "read() ei_data failed");
- switch (ei_data) {
- case ELFDATA2LSB:
- endian = 0;
- printf("Little Endian\n");
- break;
- case ELFDATA2MSB:
- endian = 1;
- printf("Big Endian\n");
- break;
- default:
- endian = -1;
- printf("Unknown Endian\n");
- }
+ endian = get_endian(ei_data);
- /* Seek to e_macine = 16 bytes (e_ident[])) + 2 bytes (e_type which is Elf32_Half/Elf64_Half) */
- if (lseek(fd, 18, SEEK_SET) == -1)
- err(1, "lseek() e_machine failed");
+ /*
+ All Elf files begin with the following Elf header:
+ unsigned char e_ident[EI_NIDENT]; - 16 bytes
+ Elf32_Half e_type; - 2 bytes
+ Elf32_Half e_machine; - 2 bytes
+ Elf32_Word e_version; - 4 bytes
+ Elf32_Addr e_entry; - 4 bytes or 8 bytes for Elf64
+ Elf32_Off e_phoff; - 4 bytes or 8 bytes for Elf64
+ Elf32_Off e_shoff; - 4 bytes or 8 bytes for Elf64
+ Elf32_Word e_flags; - 4 bytes
+
+ Seek to e_machine = 18 bytes.
+ Seek to e_flags = 36 bytes (Elf32) or 48 bytes (Elf64)
+ */
+ e_machine_offset = 18;
+ if (width == 32)
+ e_flags_offset = 36;
+ else
+ e_flags_offset = 48;
- /* What is the arch? */
+ /* What is the abi? */
+ if (lseek(fd, e_machine_offset, SEEK_SET) == -1)
+ err(1, "lseek() e_machine failed");
if (read(fd, &e_machine, 2) == -1)
err(1, "read() e_machine failed");
- switch(e_machine) {
- case EM_ALPHA:
- case EM_FAKE_ALPHA:
- arch = "alpha";
- break;
- case EM_X86_64:
- arch = "amd64";
- break;
- case EM_ARM:
- arch = "arm";
- break;
- case EM_AARCH64:
- arch = "arm64";
- break;
- case EM_68K:
- arch = "m68k";
- break;
- case EM_MIPS_RS3_LE:
- case EM_MIPS:
- arch = "mips";
- break;
- case EM_IA_64:
- arch = "ia64";
- break;
- case EM_PARISC:
- arch = "hppa";
- break;
- case EM_PPC:
- arch = "ppc";
- break;
- case EM_PPC64:
- arch = "ppc64";
- break;
- case EM_S390:
- arch = "s390";
- break;
- case EM_SH:
- arch = "sh";
- break;
- case EM_SPARC32PLUS:
- case EM_SPARCV9:
- case EM_SPARC:
- arch = "sparc";
- break;
- case EM_386:
- arch = "x86";
- break;
- default:
- arch = "unknown";
- }
- printf("%s\n", arch);
- /*
- e_data_offset =
- if (lseek(fd, 18, SEEK_SET) == -1)
- err(1, "lseek() e_machine failed");
+ if (lseek(fd, e_flags_offset, SEEK_SET) == -1)
+ err(1, "lseek() e_flags failed");
if (read(fd, &e_flags, 2) == -1)
- err(1, "read() e_machine failed");
- */
- /*
- # E_ENTRY + 3 * sizeof(uintN)
- e_flags_offset = E_ENTRY + 3 * width // 8
- f.seek(e_flags_offset)
- e_flags = uint32(f.read(4))
+ err(1, "read() e_flags failed");
- return _elf_header(ei_class, ei_data, e_machine, e_flags)
+ abi = get_abi(e_machine, width, e_flags);
- multilib_id = compute_multilib_id(elf_header)
- */
+ printf("%s\n", abi);
- memset(ident, 0, MAX_IDENT);
+/*
+ if (!strcmp(arch, "mips")) ;
+ switch (e_flags & EF_MIPS_ABI) {
+ case E_MIPS_ABI_O32:
+ abi = "o32";
+ break;
+
+ if mips_abi == E_MIPS_ABI_O32:
+ name = "o32"
+ elif mips_abi == E_MIPS_ABI_O64:
+ name = "o64"
+ elif mips_abi == E_MIPS_ABI_EABI32:
+ name = "eabi32"
+ elif mips_abi == E_MIPS_ABI_EABI64:
+ name = "eabi64"
+ elif elf_header.e_flags & EF_MIPS_ABI2:
+ name = "n32"
+ elif elf_header.ei_class == ELFCLASS64:
+ name = "n64"
+ }
+*/
close(fd);
exit(EXIT_SUCCESS);
}