Mercurial > hg > chrpath
annotate elf.c @ 2:7bf4a164d5bb default tip
fix bug: long_options have to be zero terminated
| author | Peter Meerwald <p.meerwald@bct-electronic.com> |
|---|---|
| date | Fri, 20 Jul 2012 11:28:30 +0200 |
| parents | bbbfb3f97919 |
| children |
| rev | line source |
|---|---|
| 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 | |
|
1
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
20 elf32_open(const char *filename, int flags, Elf32_Ehdr *ehdr) |
| 0 | 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) || | |
|
1
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
39 ehdr->e_ident[EI_CLASS] != ELFCLASS32 || |
| 0 | 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 */ | |
|
1
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
49 filename, 32); |
| 0 | 50 close(fd); |
| 51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | |
| 52 return -1; | |
| 53 } | |
| 54 | |
|
1
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
55 printf("32-bit ELF file\n"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
56 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
57 if (ehdr->e_phentsize != sizeof(Elf32_Phdr)) |
| 0 | 58 { |
|
1
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
59 fprintf(stderr, "section size was read as %d, not %lu!\n", |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
60 ehdr->e_phentsize, sizeof(Elf32_Phdr)); |
| 0 | 61 close(fd); |
| 62 return -1; | |
| 63 } | |
| 64 return fd; | |
| 65 } | |
| 66 | |
| 67 int | |
|
1
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
68 elf64_open(const char *filename, int flags, Elf64_Ehdr *ehdr) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
69 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
70 int fd; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
71 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
72 fd = open(filename, flags); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
73 if (fd == -1) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
74 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
75 perror ("open"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
76 return -1; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
77 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
78 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
79 if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
80 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
81 perror ("reading header"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
82 close(fd); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
83 return -1; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
84 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
85 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
86 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
87 ehdr->e_ident[EI_CLASS] != ELFCLASS64 || |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
88 ehdr->e_ident[EI_DATA] != ELFDATA2 || |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
89 ehdr->e_ident[EI_VERSION] != EV_CURRENT) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
90 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
91 fprintf(stderr, |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
92 #ifdef WORDS_BIGENDIAN |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
93 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
94 #else /* not WORD_BIGENDIAN */ |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
95 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
96 #endif /* not WORD_BIGENDIAN */ |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
97 filename, 64); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
98 close(fd); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
99 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
100 return -1; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
101 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
102 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
103 printf("64-bit ELF file\n"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
104 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
105 if (ehdr->e_phentsize != sizeof(Elf64_Phdr)) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
106 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
107 fprintf(stderr, "section size was read as %d, not %lu!\n", |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
108 ehdr->e_phentsize, sizeof(Elf64_Phdr)); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
109 close(fd); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
110 return -1; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
111 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
112 return fd; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
113 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
114 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
115 int |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
116 elf32_find_dynamic_section(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
117 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
118 int i; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
119 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
120 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
121 perror ("positioning for sections"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
122 return 1; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
123 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
124 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
125 for (i = 0; i < ehdr->e_phnum; i++) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
126 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
127 if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
128 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
129 perror ("reading section header"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
130 return 1; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
131 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
132 if (phdr->p_type == PT_DYNAMIC) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
133 break; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
134 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
135 if (i == ehdr->e_phnum) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
136 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
137 fprintf (stderr, "No dynamic section found.\n"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
138 return 2; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
139 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
140 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
141 if (0 == phdr->p_filesz) |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
142 { |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
143 fprintf (stderr, "Length of dynamic section is zero.\n"); |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
144 return 3; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
145 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
146 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
147 return 0; |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
148 } |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
149 |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
150 int |
|
bbbfb3f97919
implement 32 and 64 bit support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
0
diff
changeset
|
151 elf64_find_dynamic_section(int fd, Elf64_Ehdr *ehdr, Elf64_Phdr *phdr) |
| 0 | 152 { |
| 153 int i; | |
| 154 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | |
| 155 { | |
| 156 perror ("positioning for sections"); | |
| 157 return 1; | |
| 158 } | |
| 159 | |
| 160 for (i = 0; i < ehdr->e_phnum; i++) | |
| 161 { | |
| 162 if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) | |
| 163 { | |
| 164 perror ("reading section header"); | |
| 165 return 1; | |
| 166 } | |
| 167 if (phdr->p_type == PT_DYNAMIC) | |
| 168 break; | |
| 169 } | |
| 170 if (i == ehdr->e_phnum) | |
| 171 { | |
| 172 fprintf (stderr, "No dynamic section found.\n"); | |
| 173 return 2; | |
| 174 } | |
| 175 | |
| 176 if (0 == phdr->p_filesz) | |
| 177 { | |
| 178 fprintf (stderr, "Length of dynamic section is zero.\n"); | |
| 179 return 3; | |
| 180 } | |
| 181 | |
| 182 return 0; | |
| 183 } | |
| 184 | |
| 185 void | |
| 186 elf_close(int fd) | |
| 187 { | |
| 188 close(fd); | |
| 189 } | |
| 190 | |
| 191 const char * | |
| 192 elf_tagname(int tag) | |
| 193 { | |
| 194 switch (tag) { | |
| 195 case DT_RPATH: | |
| 196 return "RPATH"; | |
| 197 break; | |
| 198 #if defined(DT_RUNPATH) | |
| 199 case DT_RUNPATH: | |
| 200 return "RUNPATH"; | |
| 201 break; | |
| 202 #endif /* DT_RUNPATH */ | |
| 203 } | |
| 204 return "UNKNOWN"; | |
| 205 } | |
| 206 | |
| 207 int | |
| 208 elf_dynpath_tag(int tag) | |
| 209 { | |
| 210 return ( tag == DT_RPATH | |
| 211 #if defined(DT_RUNPATH) | |
| 212 || tag == DT_RUNPATH | |
| 213 #endif /* DT_RUNPATH */ | |
| 214 ); | |
| 215 } |
