diff elf.c @ 0:b8f7423e385c

import 0.13
author Peter Meerwald <pmeerw@pmeerw.net>
date Fri, 20 Jul 2012 01:51:24 +0200
parents
children bbbfb3f97919
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/elf.c	Fri Jul 20 01:51:24 2012 +0200
@@ -0,0 +1,130 @@
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <elf.h>
+#if defined(HAVE_SYS_LINK_H)
+#  include <sys/link.h> /* Find DT_RPATH on Solaris 2.6 */
+#endif /*  HAVE_SYS_LINK_H */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "protos.h"
+
+int
+elf_open(const char *filename, int flags, Elf_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] != ELFCLASS ||
+       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, SIZEOF_VOID_P * 8);
+     close(fd);
+     errno = ENOEXEC; /* Hm, is this the best errno code to use? */
+     return -1;
+   }
+
+   if (ehdr->e_phentsize != sizeof(Elf_Phdr))
+   {
+     fprintf(stderr, "section size was read as %d, not %d!\n",
+            ehdr->e_phentsize, sizeof(Elf_Phdr));
+     close(fd);
+     return -1;
+   }
+   return fd;
+}
+
+int
+elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_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;
+}
+
+void
+elf_close(int fd)
+{
+  close(fd);
+}
+
+const char *
+elf_tagname(int tag)
+{
+  switch (tag) {
+  case DT_RPATH:
+    return "RPATH";
+    break;
+#if defined(DT_RUNPATH)
+  case DT_RUNPATH:
+    return "RUNPATH";
+    break;
+#endif /* DT_RUNPATH */
+  }
+  return "UNKNOWN";
+}
+
+int
+elf_dynpath_tag(int tag)
+{
+  return ( tag == DT_RPATH
+#if defined(DT_RUNPATH)
+           || tag == DT_RUNPATH
+#endif /* DT_RUNPATH */
+           );
+}

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