annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
1
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
2 #ifdef HAVE_CONFIG_H
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
3 # include "config.h"
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
4 #endif
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
5
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
6 #include <elf.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
7 #if defined(HAVE_SYS_LINK_H)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
8 # include <sys/link.h> /* Find DT_RPATH on Solaris 2.6 */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
9 #endif /* HAVE_SYS_LINK_H */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
10 #include <stdio.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
11 #include <string.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
12 #include <unistd.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
13 #include <sys/types.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
14 #include <sys/stat.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
15 #include <errno.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
16 #include <fcntl.h>
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
17 #include "protos.h"
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
18
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
19 int
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
20 elf_open(const char *filename, int flags, Elf_Ehdr *ehdr)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
21 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
22 int fd;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
23
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
24 fd = open(filename, flags);
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
25 if (fd == -1)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
26 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
27 perror ("open");
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
28 return -1;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
29 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
30
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
31 if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr))
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
32 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
33 perror ("reading header");
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
34 close(fd);
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
35 return -1;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
36 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
37
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
38 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) ||
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
39 ehdr->e_ident[EI_CLASS] != ELFCLASS ||
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
40 ehdr->e_ident[EI_DATA] != ELFDATA2 ||
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
41 ehdr->e_ident[EI_VERSION] != EV_CURRENT)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
42 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
43 fprintf(stderr,
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
44 #ifdef WORDS_BIGENDIAN
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
45 "`%s' probably isn't a %d-bit MSB-first ELF file.\n",
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
46 #else /* not WORD_BIGENDIAN */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
47 "`%s' probably isn't a %d-bit LSB-first ELF file.\n",
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
48 #endif /* not WORD_BIGENDIAN */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
49 filename, SIZEOF_VOID_P * 8);
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
50 close(fd);
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
52 return -1;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
53 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
54
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
55 if (ehdr->e_phentsize != sizeof(Elf_Phdr))
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
56 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
57 fprintf(stderr, "section size was read as %d, not %d!\n",
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
58 ehdr->e_phentsize, sizeof(Elf_Phdr));
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
59 close(fd);
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
60 return -1;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
61 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
62 return fd;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
63 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
64
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
65 int
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
66 elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
67 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
68 int i;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
69 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
70 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
71 perror ("positioning for sections");
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
72 return 1;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
73 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
74
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
75 for (i = 0; i < ehdr->e_phnum; i++)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
76 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
77 if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr))
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
78 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
79 perror ("reading section header");
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
80 return 1;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
81 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
82 if (phdr->p_type == PT_DYNAMIC)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
83 break;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
84 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
85 if (i == ehdr->e_phnum)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
86 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
87 fprintf (stderr, "No dynamic section found.\n");
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
88 return 2;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
89 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
90
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
91 if (0 == phdr->p_filesz)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
92 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
93 fprintf (stderr, "Length of dynamic section is zero.\n");
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
94 return 3;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
95 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
96
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
97 return 0;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
98 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
99
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
100 void
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
101 elf_close(int fd)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
102 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
103 close(fd);
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
104 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
105
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
106 const char *
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
107 elf_tagname(int tag)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
108 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
109 switch (tag) {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
110 case DT_RPATH:
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
111 return "RPATH";
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
112 break;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
113 #if defined(DT_RUNPATH)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
114 case DT_RUNPATH:
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
115 return "RUNPATH";
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
116 break;
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
117 #endif /* DT_RUNPATH */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
118 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
119 return "UNKNOWN";
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
120 }
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
121
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
122 int
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
123 elf_dynpath_tag(int tag)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
124 {
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
125 return ( tag == DT_RPATH
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
126 #if defined(DT_RUNPATH)
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
127 || tag == DT_RUNPATH
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
128 #endif /* DT_RUNPATH */
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
129 );
b8f7423e385c import 0.13
Peter Meerwald <pmeerw@pmeerw.net>
parents:
diff changeset
130 }

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