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