diff elf.c @ 1:bbbfb3f97919

implement 32 and 64 bit support
author Peter Meerwald <p.meerwald@bct-electronic.com>
date Fri, 20 Jul 2012 11:26:24 +0200
parents b8f7423e385c
children
line wrap: on
line diff
--- a/elf.c	Fri Jul 20 01:51:24 2012 +0200
+++ b/elf.c	Fri Jul 20 11:26:24 2012 +0200
@@ -17,7 +17,7 @@
 #include "protos.h"
 
 int
-elf_open(const char *filename, int flags, Elf_Ehdr *ehdr)
+elf32_open(const char *filename, int flags, Elf32_Ehdr *ehdr)
 {
    int fd;
 
@@ -36,7 +36,7 @@
    }
 
    if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) ||
-       ehdr->e_ident[EI_CLASS] != ELFCLASS ||
+       ehdr->e_ident[EI_CLASS] != ELFCLASS32 ||
        ehdr->e_ident[EI_DATA] != ELFDATA2 ||
        ehdr->e_ident[EI_VERSION] != EV_CURRENT)
    {
@@ -46,16 +46,18 @@
 #else /* not WORD_BIGENDIAN */
              "`%s' probably isn't a %d-bit LSB-first ELF file.\n",
 #endif /* not WORD_BIGENDIAN */
-             filename, SIZEOF_VOID_P * 8);
+             filename, 32);
      close(fd);
      errno = ENOEXEC; /* Hm, is this the best errno code to use? */
      return -1;
    }
 
-   if (ehdr->e_phentsize != sizeof(Elf_Phdr))
+   printf("32-bit ELF file\n");
+
+   if (ehdr->e_phentsize != sizeof(Elf32_Phdr))
    {
-     fprintf(stderr, "section size was read as %d, not %d!\n",
-            ehdr->e_phentsize, sizeof(Elf_Phdr));
+     fprintf(stderr, "section size was read as %d, not %lu!\n",
+            ehdr->e_phentsize, sizeof(Elf32_Phdr));
      close(fd);
      return -1;
    }
@@ -63,7 +65,90 @@
 }
 
 int
-elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr)
+elf64_open(const char *filename, int flags, Elf64_Ehdr *ehdr)
+{
+   int fd;
+
+   fd = open(filename, flags);
+   if (fd == -1)
+   {
+     perror ("open");
+     return -1;
+   }
+
+   if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr))
+   {
+     perror ("reading header");
+     close(fd);
+     return -1;
+   }
+
+   if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) ||
+       ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
+       ehdr->e_ident[EI_DATA] != ELFDATA2 ||
+       ehdr->e_ident[EI_VERSION] != EV_CURRENT)
+   {
+     fprintf(stderr,
+#ifdef WORDS_BIGENDIAN
+             "`%s' probably isn't a %d-bit MSB-first ELF file.\n",
+#else /* not WORD_BIGENDIAN */
+             "`%s' probably isn't a %d-bit LSB-first ELF file.\n",
+#endif /* not WORD_BIGENDIAN */
+             filename, 64);
+     close(fd);
+     errno = ENOEXEC; /* Hm, is this the best errno code to use? */
+     return -1;
+   }
+
+   printf("64-bit ELF file\n");
+
+   if (ehdr->e_phentsize != sizeof(Elf64_Phdr))
+   {
+     fprintf(stderr, "section size was read as %d, not %lu!\n",
+            ehdr->e_phentsize, sizeof(Elf64_Phdr));
+     close(fd);
+     return -1;
+   }
+   return fd;
+}
+
+int
+elf32_find_dynamic_section(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr)
+{
+  int i;
+  if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1)
+  {
+    perror ("positioning for sections");
+    return 1;
+  }
+
+  for (i = 0; i < ehdr->e_phnum; i++)
+  {
+    if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr))
+    {
+      perror ("reading section header");
+      return 1;
+    }
+    if (phdr->p_type == PT_DYNAMIC)
+      break;
+  }
+  if (i == ehdr->e_phnum)
+    {
+      fprintf (stderr, "No dynamic section found.\n");
+      return 2;
+    }
+
+  if (0 == phdr->p_filesz)
+    {
+      fprintf (stderr, "Length of dynamic section is zero.\n");
+      return 3;
+    }
+
+  return 0;
+}
+
+int
+elf64_find_dynamic_section(int fd, Elf64_Ehdr *ehdr, Elf64_Phdr *phdr)
 {
   int i;
   if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1)

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.