Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: source/libvpx/build/make/obj_int_extract.c

Issue 11555023: libvpx: Add VP9 decoder. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 11
12 #include <stdarg.h> 12 #include <stdarg.h>
13 #include <stdio.h> 13 #include <stdio.h>
14 #include <stdlib.h> 14 #include <stdlib.h>
15 #include <string.h> 15 #include <string.h>
16 16
17 #include "vpx_config.h" 17 #include "vpx_config.h"
18 #include "vpx/vpx_integer.h" 18 #include "vpx/vpx_integer.h"
19 19
20 typedef enum 20 typedef enum {
21 { 21 OUTPUT_FMT_PLAIN,
22 OUTPUT_FMT_PLAIN, 22 OUTPUT_FMT_RVDS,
23 OUTPUT_FMT_RVDS, 23 OUTPUT_FMT_GAS,
24 OUTPUT_FMT_GAS,
25 } output_fmt_t; 24 } output_fmt_t;
26 25
27 int log_msg(const char *fmt, ...) 26 int log_msg(const char *fmt, ...) {
28 { 27 int res;
29 int res; 28 va_list ap;
30 va_list ap; 29 va_start(ap, fmt);
31 va_start(ap, fmt); 30 res = vfprintf(stderr, fmt, ap);
32 res = vfprintf(stderr, fmt, ap); 31 va_end(ap);
33 va_end(ap); 32 return res;
34 return res;
35 } 33 }
36 34
37 #if defined(__GNUC__) && __GNUC__ 35 #if defined(__GNUC__) && __GNUC__
38 #if defined(__MACH__) 36 #if defined(__MACH__)
39 37
40 #include <mach-o/loader.h> 38 #include <mach-o/loader.h>
41 #include <mach-o/nlist.h> 39 #include <mach-o/nlist.h>
42 40
43 int parse_macho(uint8_t *base_buf, size_t sz) 41 int parse_macho(uint8_t *base_buf, size_t sz) {
44 { 42 int i, j;
45 int i, j; 43 struct mach_header header;
46 struct mach_header header; 44 uint8_t *buf = base_buf;
47 uint8_t *buf = base_buf; 45 int base_data_section = 0;
48 int base_data_section = 0; 46 int bits = 0;
49 int bits = 0;
50 47
51 /* We can read in mach_header for 32 and 64 bit architectures 48 /* We can read in mach_header for 32 and 64 bit architectures
52 * because it's identical to mach_header_64 except for the last 49 * because it's identical to mach_header_64 except for the last
53 * element (uint32_t reserved), which we don't use. Then, when 50 * element (uint32_t reserved), which we don't use. Then, when
54 * we know which architecture we're looking at, increment buf 51 * we know which architecture we're looking at, increment buf
55 * appropriately. 52 * appropriately.
56 */ 53 */
57 memcpy(&header, buf, sizeof(struct mach_header)); 54 memcpy(&header, buf, sizeof(struct mach_header));
58 55
59 if (header.magic == MH_MAGIC) 56 if (header.magic == MH_MAGIC) {
60 { 57 if (header.cputype == CPU_TYPE_ARM
61 if (header.cputype == CPU_TYPE_ARM 58 || header.cputype == CPU_TYPE_X86) {
62 || header.cputype == CPU_TYPE_X86) 59 bits = 32;
63 { 60 buf += sizeof(struct mach_header);
64 bits = 32; 61 } else {
65 buf += sizeof(struct mach_header); 62 log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_[ ARM|X86].\n");
63 goto bail;
64 }
65 } else if (header.magic == MH_MAGIC_64) {
66 if (header.cputype == CPU_TYPE_X86_64) {
67 bits = 64;
68 buf += sizeof(struct mach_header_64);
69 } else {
70 log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_X 86_64.\n");
71 goto bail;
72 }
73 } else {
74 log_msg("Bad magic number for object file. 0x%x or 0x%x expected, 0x%x found .\n",
75 MH_MAGIC, MH_MAGIC_64, header.magic);
76 goto bail;
77 }
78
79 if (header.filetype != MH_OBJECT) {
80 log_msg("Bad filetype for object file. Currently only tested for MH_OBJECT.\ n");
81 goto bail;
82 }
83
84 for (i = 0; i < header.ncmds; i++) {
85 struct load_command lc;
86
87 memcpy(&lc, buf, sizeof(struct load_command));
88
89 if (lc.cmd == LC_SEGMENT) {
90 uint8_t *seg_buf = buf;
91 struct section s;
92 struct segment_command seg_c;
93
94 memcpy(&seg_c, seg_buf, sizeof(struct segment_command));
95 seg_buf += sizeof(struct segment_command);
96
97 /* Although each section is given it's own offset, nlist.n_value
98 * references the offset of the first section. This isn't
99 * apparent without debug information because the offset of the
100 * data section is the same as the first section. However, with
101 * debug sections mixed in, the offset of the debug section
102 * increases but n_value still references the first section.
103 */
104 if (seg_c.nsects < 1) {
105 log_msg("Not enough sections\n");
106 goto bail;
107 }
108
109 memcpy(&s, seg_buf, sizeof(struct section));
110 base_data_section = s.offset;
111 } else if (lc.cmd == LC_SEGMENT_64) {
112 uint8_t *seg_buf = buf;
113 struct section_64 s;
114 struct segment_command_64 seg_c;
115
116 memcpy(&seg_c, seg_buf, sizeof(struct segment_command_64));
117 seg_buf += sizeof(struct segment_command_64);
118
119 /* Explanation in LG_SEGMENT */
120 if (seg_c.nsects < 1) {
121 log_msg("Not enough sections\n");
122 goto bail;
123 }
124
125 memcpy(&s, seg_buf, sizeof(struct section_64));
126 base_data_section = s.offset;
127 } else if (lc.cmd == LC_SYMTAB) {
128 if (base_data_section != 0) {
129 struct symtab_command sc;
130 uint8_t *sym_buf = base_buf;
131 uint8_t *str_buf = base_buf;
132
133 memcpy(&sc, buf, sizeof(struct symtab_command));
134
135 if (sc.cmdsize != sizeof(struct symtab_command)) {
136 log_msg("Can't find symbol table!\n");
137 goto bail;
66 } 138 }
67 else 139
68 { 140 sym_buf += sc.symoff;
69 log_msg("Bad cputype for object file. Currently only tested for CPU_ TYPE_[ARM|X86].\n"); 141 str_buf += sc.stroff;
70 goto bail; 142
143 for (j = 0; j < sc.nsyms; j++) {
144 /* Location of string is cacluated each time from the
145 * start of the string buffer. On darwin the symbols
146 * are prefixed by "_", so we bump the pointer by 1.
147 * The target value is defined as an int in asm_*_offsets.c,
148 * which is 4 bytes on all targets we currently use.
149 */
150 if (bits == 32) {
151 struct nlist nl;
152 int val;
153
154 memcpy(&nl, sym_buf, sizeof(struct nlist));
155 sym_buf += sizeof(struct nlist);
156
157 memcpy(&val, base_buf + base_data_section + nl.n_value,
158 sizeof(val));
159 printf("%-40s EQU %5d\n",
160 str_buf + nl.n_un.n_strx + 1, val);
161 } else { /* if (bits == 64) */
162 struct nlist_64 nl;
163 int val;
164
165 memcpy(&nl, sym_buf, sizeof(struct nlist_64));
166 sym_buf += sizeof(struct nlist_64);
167
168 memcpy(&val, base_buf + base_data_section + nl.n_value,
169 sizeof(val));
170 printf("%-40s EQU %5d\n",
171 str_buf + nl.n_un.n_strx + 1, val);
172 }
71 } 173 }
72 } 174 }
73 else if (header.magic == MH_MAGIC_64)
74 {
75 if (header.cputype == CPU_TYPE_X86_64)
76 {
77 bits = 64;
78 buf += sizeof(struct mach_header_64);
79 }
80 else
81 {
82 log_msg("Bad cputype for object file. Currently only tested for CPU_ TYPE_X86_64.\n");
83 goto bail;
84 }
85 }
86 else
87 {
88 log_msg("Bad magic number for object file. 0x%x or 0x%x expected, 0x%x f ound.\n",
89 MH_MAGIC, MH_MAGIC_64, header.magic);
90 goto bail;
91 } 175 }
92 176
93 if (header.filetype != MH_OBJECT) 177 buf += lc.cmdsize;
94 { 178 }
95 log_msg("Bad filetype for object file. Currently only tested for MH_OBJE CT.\n");
96 goto bail;
97 }
98 179
99 for (i = 0; i < header.ncmds; i++) 180 return 0;
100 {
101 struct load_command lc;
102
103 memcpy(&lc, buf, sizeof(struct load_command));
104
105 if (lc.cmd == LC_SEGMENT)
106 {
107 uint8_t *seg_buf = buf;
108 struct section s;
109 struct segment_command seg_c;
110
111 memcpy(&seg_c, seg_buf, sizeof(struct segment_command));
112 seg_buf += sizeof(struct segment_command);
113
114 /* Although each section is given it's own offset, nlist.n_value
115 * references the offset of the first section. This isn't
116 * apparent without debug information because the offset of the
117 * data section is the same as the first section. However, with
118 * debug sections mixed in, the offset of the debug section
119 * increases but n_value still references the first section.
120 */
121 if (seg_c.nsects < 1)
122 {
123 log_msg("Not enough sections\n");
124 goto bail;
125 }
126
127 memcpy(&s, seg_buf, sizeof(struct section));
128 base_data_section = s.offset;
129 }
130 else if (lc.cmd == LC_SEGMENT_64)
131 {
132 uint8_t *seg_buf = buf;
133 struct section_64 s;
134 struct segment_command_64 seg_c;
135
136 memcpy(&seg_c, seg_buf, sizeof(struct segment_command_64));
137 seg_buf += sizeof(struct segment_command_64);
138
139 /* Explanation in LG_SEGMENT */
140 if (seg_c.nsects < 1)
141 {
142 log_msg("Not enough sections\n");
143 goto bail;
144 }
145
146 memcpy(&s, seg_buf, sizeof(struct section_64));
147 base_data_section = s.offset;
148 }
149 else if (lc.cmd == LC_SYMTAB)
150 {
151 if (base_data_section != 0)
152 {
153 struct symtab_command sc;
154 uint8_t *sym_buf = base_buf;
155 uint8_t *str_buf = base_buf;
156
157 memcpy(&sc, buf, sizeof(struct symtab_command));
158
159 if (sc.cmdsize != sizeof(struct symtab_command))
160 {
161 log_msg("Can't find symbol table!\n");
162 goto bail;
163 }
164
165 sym_buf += sc.symoff;
166 str_buf += sc.stroff;
167
168 for (j = 0; j < sc.nsyms; j++)
169 {
170 /* Location of string is cacluated each time from the
171 * start of the string buffer. On darwin the symbols
172 * are prefixed by "_", so we bump the pointer by 1.
173 * The target value is defined as an int in asm_*_offsets.c,
174 * which is 4 bytes on all targets we currently use.
175 */
176 if (bits == 32)
177 {
178 struct nlist nl;
179 int val;
180
181 memcpy(&nl, sym_buf, sizeof(struct nlist));
182 sym_buf += sizeof(struct nlist);
183
184 memcpy(&val, base_buf + base_data_section + nl.n_value,
185 sizeof(val));
186 printf("%-40s EQU %5d\n",
187 str_buf + nl.n_un.n_strx + 1, val);
188 }
189 else /* if (bits == 64) */
190 {
191 struct nlist_64 nl;
192 int val;
193
194 memcpy(&nl, sym_buf, sizeof(struct nlist_64));
195 sym_buf += sizeof(struct nlist_64);
196
197 memcpy(&val, base_buf + base_data_section + nl.n_value,
198 sizeof(val));
199 printf("%-40s EQU %5d\n",
200 str_buf + nl.n_un.n_strx + 1, val);
201 }
202 }
203 }
204 }
205
206 buf += lc.cmdsize;
207 }
208
209 return 0;
210 bail: 181 bail:
211 return 1; 182 return 1;
212 183
213 } 184 }
214 185
215 #elif defined(__ELF__) 186 #elif defined(__ELF__)
216 #include "elf.h" 187 #include "elf.h"
217 188
218 #define COPY_STRUCT(dst, buf, ofst, sz) do {\ 189 #define COPY_STRUCT(dst, buf, ofst, sz) do {\
219 if(ofst + sizeof((*(dst))) > sz) goto bail;\ 190 if(ofst + sizeof((*(dst))) > sz) goto bail;\
220 memcpy(dst, buf+ofst, sizeof((*(dst))));\ 191 memcpy(dst, buf+ofst, sizeof((*(dst))));\
221 } while(0) 192 } while(0)
222 193
223 #define ENDIAN_ASSIGN(val, memb) do {\ 194 #define ENDIAN_ASSIGN(val, memb) do {\
224 if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail;}\ 195 if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail ;}\
225 (val) = (memb);\ 196 (val) = (memb);\
226 } while(0) 197 } while(0)
227 198
228 #define ENDIAN_ASSIGN_IN_PLACE(memb) do {\ 199 #define ENDIAN_ASSIGN_IN_PLACE(memb) do {\
229 ENDIAN_ASSIGN(memb, memb);\ 200 ENDIAN_ASSIGN(memb, memb);\
230 } while(0) 201 } while(0)
231 202
232 typedef struct 203 typedef struct {
233 { 204 uint8_t *buf; /* Buffer containing ELF data */
234 uint8_t *buf; /* Buffer containing ELF data */ 205 size_t sz; /* Buffer size */
235 size_t sz; /* Buffer size */ 206 int le_data; /* Data is little-endian */
236 int le_data; /* Data is little-endian */ 207 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
237 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ 208 int bits; /* 32 or 64 */
238 int bits; /* 32 or 64 */ 209 Elf32_Ehdr hdr32;
239 Elf32_Ehdr hdr32; 210 Elf64_Ehdr hdr64;
240 Elf64_Ehdr hdr64;
241 } elf_obj_t; 211 } elf_obj_t;
242 212
243 int parse_elf_header(elf_obj_t *elf) 213 int parse_elf_header(elf_obj_t *elf) {
244 { 214 int res;
245 int res; 215 /* Verify ELF Magic numbers */
246 /* Verify ELF Magic numbers */ 216 COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz);
247 COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz); 217 res = elf->e_ident[EI_MAG0] == ELFMAG0;
248 res = elf->e_ident[EI_MAG0] == ELFMAG0; 218 res &= elf->e_ident[EI_MAG1] == ELFMAG1;
249 res &= elf->e_ident[EI_MAG1] == ELFMAG1; 219 res &= elf->e_ident[EI_MAG2] == ELFMAG2;
250 res &= elf->e_ident[EI_MAG2] == ELFMAG2; 220 res &= elf->e_ident[EI_MAG3] == ELFMAG3;
251 res &= elf->e_ident[EI_MAG3] == ELFMAG3; 221 res &= elf->e_ident[EI_CLASS] == ELFCLASS32
252 res &= elf->e_ident[EI_CLASS] == ELFCLASS32 222 || elf->e_ident[EI_CLASS] == ELFCLASS64;
253 || elf->e_ident[EI_CLASS] == ELFCLASS64; 223 res &= elf->e_ident[EI_DATA] == ELFDATA2LSB;
254 res &= elf->e_ident[EI_DATA] == ELFDATA2LSB; 224
255 225 if (!res) goto bail;
256 if (!res) goto bail; 226
257 227 elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB;
258 elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB; 228
259 229 /* Read in relevant values */
260 /* Read in relevant values */ 230 if (elf->e_ident[EI_CLASS] == ELFCLASS32) {
261 if (elf->e_ident[EI_CLASS] == ELFCLASS32) 231 elf->bits = 32;
262 { 232 COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz);
263 elf->bits = 32; 233
264 COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz); 234 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type);
265 235 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine);
266 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type); 236 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version);
267 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine); 237 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry);
268 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version); 238 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff);
269 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry); 239 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff);
270 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff); 240 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags);
271 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff); 241 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize);
272 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags); 242 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize);
273 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize); 243 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum);
274 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize); 244 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize);
275 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum); 245 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum);
276 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize); 246 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx);
277 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum); 247 } else { /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */
278 ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx); 248 elf->bits = 64;
279 } 249 COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz);
280 else /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */ 250
281 { 251 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type);
282 elf->bits = 64; 252 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine);
283 COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz); 253 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version);
284 254 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry);
285 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type); 255 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff);
286 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine); 256 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff);
287 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version); 257 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags);
288 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry); 258 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize);
289 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff); 259 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize);
290 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff); 260 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum);
291 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags); 261 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize);
292 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize); 262 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum);
293 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize); 263 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx);
294 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum); 264 }
295 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize); 265
296 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum); 266 return 0;
297 ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx);
298 }
299
300 return 0;
301 bail: 267 bail:
302 log_msg("Failed to parse ELF file header"); 268 log_msg("Failed to parse ELF file header");
303 return 1; 269 return 1;
304 } 270 }
305 271
306 int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hd r64) 272 int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hd r64) {
307 { 273 if (hdr32) {
308 if (hdr32) 274 if (idx >= elf->hdr32.e_shnum)
309 { 275 goto bail;
310 if (idx >= elf->hdr32.e_shnum) 276
311 goto bail; 277 COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsi ze,
312 278 elf->sz);
313 COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_she ntsize, 279 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name);
314 elf->sz); 280 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type);
315 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name); 281 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags);
316 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type); 282 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr);
317 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags); 283 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset);
318 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr); 284 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size);
319 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset); 285 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link);
320 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size); 286 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info);
321 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link); 287 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign);
322 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info); 288 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize);
323 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign); 289 } else { /* if (hdr64) */
324 ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize); 290 if (idx >= elf->hdr64.e_shnum)
325 } 291 goto bail;
326 else /* if (hdr64) */ 292
327 { 293 COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_shentsi ze,
328 if (idx >= elf->hdr64.e_shnum) 294 elf->sz);
329 goto bail; 295 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name);
330 296 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type);
331 COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_she ntsize, 297 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags);
332 elf->sz); 298 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr);
333 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name); 299 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset);
334 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type); 300 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size);
335 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags); 301 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link);
336 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr); 302 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info);
337 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset); 303 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign);
338 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size); 304 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize);
339 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link); 305 }
340 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info); 306
341 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign); 307 return 0;
342 ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize);
343 }
344
345 return 0;
346 bail: 308 bail:
347 return 1; 309 return 1;
348 } 310 }
349 311
350 char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) 312 char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) {
351 { 313 if (elf->bits == 32) {
352 if (elf->bits == 32) 314 Elf32_Shdr shdr;
353 { 315
354 Elf32_Shdr shdr; 316 if (parse_elf_section(elf, s_idx, &shdr, NULL)) {
355 317 log_msg("Failed to parse ELF string table: section %d, index %d\n",
356 if (parse_elf_section(elf, s_idx, &shdr, NULL)) 318 s_idx, idx);
357 { 319 return "";
358 log_msg("Failed to parse ELF string table: section %d, index %d\n", 320 }
359 s_idx, idx); 321
360 return ""; 322 return (char *)(elf->buf + shdr.sh_offset + idx);
323 } else { /* if (elf->bits == 64) */
324 Elf64_Shdr shdr;
325
326 if (parse_elf_section(elf, s_idx, NULL, &shdr)) {
327 log_msg("Failed to parse ELF string table: section %d, index %d\n",
328 s_idx, idx);
329 return "";
330 }
331
332 return (char *)(elf->buf + shdr.sh_offset + idx);
333 }
334 }
335
336 int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_ Sym *sym64) {
337 if (sym32) {
338 COPY_STRUCT(sym32, elf->buf, ofst, elf->sz);
339 ENDIAN_ASSIGN_IN_PLACE(sym32->st_name);
340 ENDIAN_ASSIGN_IN_PLACE(sym32->st_value);
341 ENDIAN_ASSIGN_IN_PLACE(sym32->st_size);
342 ENDIAN_ASSIGN_IN_PLACE(sym32->st_info);
343 ENDIAN_ASSIGN_IN_PLACE(sym32->st_other);
344 ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx);
345 } else { /* if (sym64) */
346 COPY_STRUCT(sym64, elf->buf, ofst, elf->sz);
347 ENDIAN_ASSIGN_IN_PLACE(sym64->st_name);
348 ENDIAN_ASSIGN_IN_PLACE(sym64->st_value);
349 ENDIAN_ASSIGN_IN_PLACE(sym64->st_size);
350 ENDIAN_ASSIGN_IN_PLACE(sym64->st_info);
351 ENDIAN_ASSIGN_IN_PLACE(sym64->st_other);
352 ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx);
353 }
354 return 0;
355 bail:
356 return 1;
357 }
358
359 int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode) {
360 elf_obj_t elf;
361 unsigned int ofst;
362 int i;
363 Elf32_Off strtab_off32;
364 Elf64_Off strtab_off64; /* save String Table offset for later use */
365
366 memset(&elf, 0, sizeof(elf));
367 elf.buf = buf;
368 elf.sz = sz;
369
370 /* Parse Header */
371 if (parse_elf_header(&elf))
372 goto bail;
373
374 if (elf.bits == 32) {
375 Elf32_Shdr shdr;
376 for (i = 0; i < elf.hdr32.e_shnum; i++) {
377 parse_elf_section(&elf, i, &shdr, NULL);
378
379 if (shdr.sh_type == SHT_STRTAB) {
380 char strtsb_name[128];
381
382 strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
383
384 if (!(strcmp(strtsb_name, ".shstrtab"))) {
385 /* log_msg("found section: %s\n", strtsb_name); */
386 strtab_off32 = shdr.sh_offset;
387 break;
361 } 388 }
362 389 }
363 return (char *)(elf->buf + shdr.sh_offset + idx); 390 }
364 } 391 } else { /* if (elf.bits == 64) */
365 else /* if (elf->bits == 64) */ 392 Elf64_Shdr shdr;
366 { 393 for (i = 0; i < elf.hdr64.e_shnum; i++) {
367 Elf64_Shdr shdr; 394 parse_elf_section(&elf, i, NULL, &shdr);
368 395
369 if (parse_elf_section(elf, s_idx, NULL, &shdr)) 396 if (shdr.sh_type == SHT_STRTAB) {
370 { 397 char strtsb_name[128];
371 log_msg("Failed to parse ELF string table: section %d, index %d\n", 398
372 s_idx, idx); 399 strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
373 return ""; 400
401 if (!(strcmp(strtsb_name, ".shstrtab"))) {
402 /* log_msg("found section: %s\n", strtsb_name); */
403 strtab_off64 = shdr.sh_offset;
404 break;
374 } 405 }
375 406 }
376 return (char *)(elf->buf + shdr.sh_offset + idx); 407 }
377 } 408 }
409
410 /* Parse all Symbol Tables */
411 if (elf.bits == 32) {
412 Elf32_Shdr shdr;
413 for (i = 0; i < elf.hdr32.e_shnum; i++) {
414 parse_elf_section(&elf, i, &shdr, NULL);
415
416 if (shdr.sh_type == SHT_SYMTAB) {
417 for (ofst = shdr.sh_offset;
418 ofst < shdr.sh_offset + shdr.sh_size;
419 ofst += shdr.sh_entsize) {
420 Elf32_Sym sym;
421
422 parse_elf_symbol(&elf, ofst, &sym, NULL);
423
424 /* For all OBJECTS (data objects), extract the value from the
425 * proper data segment.
426 */
427 /* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
428 log_msg("found data object %s\n",
429 parse_elf_string_table(&elf,
430 shdr.sh_link,
431 sym.st_name));
432 */
433
434 if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
435 && sym.st_size == 4) {
436 Elf32_Shdr dhdr;
437 int val = 0;
438 char section_name[128];
439
440 parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL);
441
442 /* For explanition - refer to _MSC_VER version of code */
443 strcpy(section_name, (char *)(elf.buf + strtab_off32 + dhdr.sh_name) );
444 /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhd r.sh_type); */
445
446 if (strcmp(section_name, ".bss")) {
447 if (sizeof(val) != sym.st_size) {
448 /* The target value is declared as an int in
449 * asm_*_offsets.c, which is 4 bytes on all
450 * targets we currently use. Complain loudly if
451 * this is not true.
452 */
453 log_msg("Symbol size is wrong\n");
454 goto bail;
455 }
456
457 memcpy(&val,
458 elf.buf + dhdr.sh_offset + sym.st_value,
459 sym.st_size);
460 }
461
462 if (!elf.le_data) {
463 log_msg("Big Endian data not supported yet!\n");
464 goto bail;
465 }
466
467 switch (mode) {
468 case OUTPUT_FMT_RVDS:
469 printf("%-40s EQU %5d\n",
470 parse_elf_string_table(&elf,
471 shdr.sh_link,
472 sym.st_name),
473 val);
474 break;
475 case OUTPUT_FMT_GAS:
476 printf(".equ %-40s, %5d\n",
477 parse_elf_string_table(&elf,
478 shdr.sh_link,
479 sym.st_name),
480 val);
481 break;
482 default:
483 printf("%s = %d\n",
484 parse_elf_string_table(&elf,
485 shdr.sh_link,
486 sym.st_name),
487 val);
488 }
489 }
490 }
491 }
492 }
493 } else { /* if (elf.bits == 64) */
494 Elf64_Shdr shdr;
495 for (i = 0; i < elf.hdr64.e_shnum; i++) {
496 parse_elf_section(&elf, i, NULL, &shdr);
497
498 if (shdr.sh_type == SHT_SYMTAB) {
499 for (ofst = shdr.sh_offset;
500 ofst < shdr.sh_offset + shdr.sh_size;
501 ofst += shdr.sh_entsize) {
502 Elf64_Sym sym;
503
504 parse_elf_symbol(&elf, ofst, NULL, &sym);
505
506 /* For all OBJECTS (data objects), extract the value from the
507 * proper data segment.
508 */
509 /* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
510 log_msg("found data object %s\n",
511 parse_elf_string_table(&elf,
512 shdr.sh_link,
513 sym.st_name));
514 */
515
516 if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT
517 && sym.st_size == 4) {
518 Elf64_Shdr dhdr;
519 int val = 0;
520 char section_name[128];
521
522 parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr);
523
524 /* For explanition - refer to _MSC_VER version of code */
525 strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name) );
526 /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhd r.sh_type); */
527
528 if ((strcmp(section_name, ".bss"))) {
529 if (sizeof(val) != sym.st_size) {
530 /* The target value is declared as an int in
531 * asm_*_offsets.c, which is 4 bytes on all
532 * targets we currently use. Complain loudly if
533 * this is not true.
534 */
535 log_msg("Symbol size is wrong\n");
536 goto bail;
537 }
538
539 memcpy(&val,
540 elf.buf + dhdr.sh_offset + sym.st_value,
541 sym.st_size);
542 }
543
544 if (!elf.le_data) {
545 log_msg("Big Endian data not supported yet!\n");
546 goto bail;
547 }
548
549 switch (mode) {
550 case OUTPUT_FMT_RVDS:
551 printf("%-40s EQU %5d\n",
552 parse_elf_string_table(&elf,
553 shdr.sh_link,
554 sym.st_name),
555 val);
556 break;
557 case OUTPUT_FMT_GAS:
558 printf(".equ %-40s, %5d\n",
559 parse_elf_string_table(&elf,
560 shdr.sh_link,
561 sym.st_name),
562 val);
563 break;
564 default:
565 printf("%s = %d\n",
566 parse_elf_string_table(&elf,
567 shdr.sh_link,
568 sym.st_name),
569 val);
570 }
571 }
572 }
573 }
574 }
575 }
576
577 if (mode == OUTPUT_FMT_RVDS)
578 printf(" END\n");
579
580 return 0;
581 bail:
582 log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n");
583 return 1;
378 } 584 }
379 585
380 int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_ Sym *sym64)
381 {
382 if (sym32)
383 {
384 COPY_STRUCT(sym32, elf->buf, ofst, elf->sz);
385 ENDIAN_ASSIGN_IN_PLACE(sym32->st_name);
386 ENDIAN_ASSIGN_IN_PLACE(sym32->st_value);
387 ENDIAN_ASSIGN_IN_PLACE(sym32->st_size);
388 ENDIAN_ASSIGN_IN_PLACE(sym32->st_info);
389 ENDIAN_ASSIGN_IN_PLACE(sym32->st_other);
390 ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx);
391 }
392 else /* if (sym64) */
393 {
394 COPY_STRUCT(sym64, elf->buf, ofst, elf->sz);
395 ENDIAN_ASSIGN_IN_PLACE(sym64->st_name);
396 ENDIAN_ASSIGN_IN_PLACE(sym64->st_value);
397 ENDIAN_ASSIGN_IN_PLACE(sym64->st_size);
398 ENDIAN_ASSIGN_IN_PLACE(sym64->st_info);
399 ENDIAN_ASSIGN_IN_PLACE(sym64->st_other);
400 ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx);
401 }
402 return 0;
403 bail:
404 return 1;
405 }
406
407 int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode)
408 {
409 elf_obj_t elf;
410 unsigned int ofst;
411 int i;
412 Elf32_Off strtab_off32;
413 Elf64_Off strtab_off64; /* save String Table offset for later use */
414
415 memset(&elf, 0, sizeof(elf));
416 elf.buf = buf;
417 elf.sz = sz;
418
419 /* Parse Header */
420 if (parse_elf_header(&elf))
421 goto bail;
422
423 if (elf.bits == 32)
424 {
425 Elf32_Shdr shdr;
426 for (i = 0; i < elf.hdr32.e_shnum; i++)
427 {
428 parse_elf_section(&elf, i, &shdr, NULL);
429
430 if (shdr.sh_type == SHT_STRTAB)
431 {
432 char strtsb_name[128];
433
434 strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_ name));
435
436 if (!(strcmp(strtsb_name, ".shstrtab")))
437 {
438 /* log_msg("found section: %s\n", strtsb_name); */
439 strtab_off32 = shdr.sh_offset;
440 break;
441 }
442 }
443 }
444 }
445 else /* if (elf.bits == 64) */
446 {
447 Elf64_Shdr shdr;
448 for (i = 0; i < elf.hdr64.e_shnum; i++)
449 {
450 parse_elf_section(&elf, i, NULL, &shdr);
451
452 if (shdr.sh_type == SHT_STRTAB)
453 {
454 char strtsb_name[128];
455
456 strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_ name));
457
458 if (!(strcmp(strtsb_name, ".shstrtab")))
459 {
460 /* log_msg("found section: %s\n", strtsb_name); */
461 strtab_off64 = shdr.sh_offset;
462 break;
463 }
464 }
465 }
466 }
467
468 /* Parse all Symbol Tables */
469 if (elf.bits == 32)
470 {
471 Elf32_Shdr shdr;
472 for (i = 0; i < elf.hdr32.e_shnum; i++)
473 {
474 parse_elf_section(&elf, i, &shdr, NULL);
475
476 if (shdr.sh_type == SHT_SYMTAB)
477 {
478 for (ofst = shdr.sh_offset;
479 ofst < shdr.sh_offset + shdr.sh_size;
480 ofst += shdr.sh_entsize)
481 {
482 Elf32_Sym sym;
483
484 parse_elf_symbol(&elf, ofst, &sym, NULL);
485
486 /* For all OBJECTS (data objects), extract the value from th e
487 * proper data segment.
488 */
489 /* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_na me)
490 log_msg("found data object %s\n",
491 parse_elf_string_table(&elf,
492 shdr.sh_link,
493 sym.st_name));
494 */
495
496 if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
497 && sym.st_size == 4)
498 {
499 Elf32_Shdr dhdr;
500 int val = 0;
501 char section_name[128];
502
503 parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL);
504
505 /* For explanition - refer to _MSC_VER version of code * /
506 strcpy(section_name, (char *)(elf.buf + strtab_off32 + d hdr.sh_name));
507 /* log_msg("Section_name: %s, Section_type: %d\n", secti on_name, dhdr.sh_type); */
508
509 if (strcmp(section_name, ".bss"))
510 {
511 if (sizeof(val) != sym.st_size)
512 {
513 /* The target value is declared as an int in
514 * asm_*_offsets.c, which is 4 bytes on all
515 * targets we currently use. Complain loudly if
516 * this is not true.
517 */
518 log_msg("Symbol size is wrong\n");
519 goto bail;
520 }
521
522 memcpy(&val,
523 elf.buf + dhdr.sh_offset + sym.st_value,
524 sym.st_size);
525 }
526
527 if (!elf.le_data)
528 {
529 log_msg("Big Endian data not supported yet!\n");
530 goto bail;
531 }
532
533 switch (mode)
534 {
535 case OUTPUT_FMT_RVDS:
536 printf("%-40s EQU %5d\n",
537 parse_elf_string_table(&elf,
538 shdr.sh_link,
539 sym.st_name),
540 val);
541 break;
542 case OUTPUT_FMT_GAS:
543 printf(".equ %-40s, %5d\n",
544 parse_elf_string_table(&elf,
545 shdr.sh_link,
546 sym.st_name),
547 val);
548 break;
549 default:
550 printf("%s = %d\n",
551 parse_elf_string_table(&elf,
552 shdr.sh_link,
553 sym.st_name),
554 val);
555 }
556 }
557 }
558 }
559 }
560 }
561 else /* if (elf.bits == 64) */
562 {
563 Elf64_Shdr shdr;
564 for (i = 0; i < elf.hdr64.e_shnum; i++)
565 {
566 parse_elf_section(&elf, i, NULL, &shdr);
567
568 if (shdr.sh_type == SHT_SYMTAB)
569 {
570 for (ofst = shdr.sh_offset;
571 ofst < shdr.sh_offset + shdr.sh_size;
572 ofst += shdr.sh_entsize)
573 {
574 Elf64_Sym sym;
575
576 parse_elf_symbol(&elf, ofst, NULL, &sym);
577
578 /* For all OBJECTS (data objects), extract the value from th e
579 * proper data segment.
580 */
581 /* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_na me)
582 log_msg("found data object %s\n",
583 parse_elf_string_table(&elf,
584 shdr.sh_link,
585 sym.st_name));
586 */
587
588 if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT
589 && sym.st_size == 4)
590 {
591 Elf64_Shdr dhdr;
592 int val = 0;
593 char section_name[128];
594
595 parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr);
596
597 /* For explanition - refer to _MSC_VER version of code * /
598 strcpy(section_name, (char *)(elf.buf + strtab_off64 + d hdr.sh_name));
599 /* log_msg("Section_name: %s, Section_type: %d\n", secti on_name, dhdr.sh_type); */
600
601 if ((strcmp(section_name, ".bss")))
602 {
603 if (sizeof(val) != sym.st_size)
604 {
605 /* The target value is declared as an int in
606 * asm_*_offsets.c, which is 4 bytes on all
607 * targets we currently use. Complain loudly if
608 * this is not true.
609 */
610 log_msg("Symbol size is wrong\n");
611 goto bail;
612 }
613
614 memcpy(&val,
615 elf.buf + dhdr.sh_offset + sym.st_value,
616 sym.st_size);
617 }
618
619 if (!elf.le_data)
620 {
621 log_msg("Big Endian data not supported yet!\n");
622 goto bail;
623 }
624
625 switch (mode)
626 {
627 case OUTPUT_FMT_RVDS:
628 printf("%-40s EQU %5d\n",
629 parse_elf_string_table(&elf,
630 shdr.sh_link,
631 sym.st_name),
632 val);
633 break;
634 case OUTPUT_FMT_GAS:
635 printf(".equ %-40s, %5d\n",
636 parse_elf_string_table(&elf,
637 shdr.sh_link,
638 sym.st_name),
639 val);
640 break;
641 default:
642 printf("%s = %d\n",
643 parse_elf_string_table(&elf,
644 shdr.sh_link,
645 sym.st_name),
646 val);
647 }
648 }
649 }
650 }
651 }
652 }
653
654 if (mode == OUTPUT_FMT_RVDS)
655 printf(" END\n");
656
657 return 0;
658 bail:
659 log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n");
660 return 1;
661 }
662
663 #endif 586 #endif
664 #endif /* defined(__GNUC__) && __GNUC__ */ 587 #endif /* defined(__GNUC__) && __GNUC__ */
665 588
666 589
667 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) 590 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
668 /* See "Microsoft Portable Executable and Common Object File Format Specificati on" 591 /* See "Microsoft Portable Executable and Common Object File Format Specificati on"
669 for reference. 592 for reference.
670 */ 593 */
671 #define get_le32(x) ((*(x)) | (*(x+1)) << 8 |(*(x+2)) << 16 | (*(x+3)) << 24 ) 594 #define get_le32(x) ((*(x)) | (*(x+1)) << 8 |(*(x+2)) << 16 | (*(x+3)) << 24 )
672 #define get_le16(x) ((*(x)) | (*(x+1)) << 8) 595 #define get_le16(x) ((*(x)) | (*(x+1)) << 8)
673 596
674 int parse_coff(uint8_t *buf, size_t sz) 597 int parse_coff(uint8_t *buf, size_t sz) {
675 { 598 unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr;
676 unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr; 599 unsigned int sectionrawdata_ptr;
677 unsigned int sectionrawdata_ptr; 600 unsigned int i;
678 unsigned int i; 601 uint8_t *ptr;
679 uint8_t *ptr; 602 uint32_t symoffset;
680 uint32_t symoffset; 603
681 604 char **sectionlist; // this array holds all section names in their correct or der.
682 char **sectionlist; //this array holds all section names in their correct o rder. 605 // it is used to check if the symbol is in .bss or .rdata section.
683 //it is used to check if the symbol is in .bss or .rdata section. 606
684 607 nsections = get_le16(buf + 2);
685 nsections = get_le16(buf + 2); 608 symtab_ptr = get_le32(buf + 8);
686 symtab_ptr = get_le32(buf + 8); 609 symtab_sz = get_le32(buf + 12);
687 symtab_sz = get_le32(buf + 12); 610 strtab_ptr = symtab_ptr + symtab_sz * 18;
688 strtab_ptr = symtab_ptr + symtab_sz * 18; 611
689 612 if (nsections > 96) {
690 if (nsections > 96) 613 log_msg("Too many sections\n");
691 { 614 return 1;
692 log_msg("Too many sections\n"); 615 }
693 return 1; 616
617 sectionlist = malloc(nsections * sizeof(sectionlist));
618
619 if (sectionlist == NULL) {
620 log_msg("Allocating first level of section list failed\n");
621 return 1;
622 }
623
624 // log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections);
625
626 /*
627 The size of optional header is always zero for an obj file. So, the section he ader
628 follows the file header immediately.
629 */
630
631 ptr = buf + 20; // section header
632
633 for (i = 0; i < nsections; i++) {
634 char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
635 strncpy(sectionname, ptr, 8);
636 // log_msg("COFF: Parsing section %s\n",sectionname);
637
638 sectionlist[i] = malloc(strlen(sectionname) + 1);
639
640 if (sectionlist[i] == NULL) {
641 log_msg("Allocating storage for %s failed\n", sectionname);
642 goto bail;
694 } 643 }
695 644 strcpy(sectionlist[i], sectionname);
696 sectionlist = malloc(nsections * sizeof(sectionlist)); 645
697 646 if (!strcmp(sectionname, ".rdata")) sectionrawdata_ptr = get_le32(ptr + 20);
698 if (sectionlist == NULL) 647
699 { 648 ptr += 40;
700 log_msg("Allocating first level of section list failed\n"); 649 }
701 return 1; 650
651 // log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
652 // log_msg("COFF: raw data pointer ofset for section .rdata is %u\n", sectionr awdata_ptr);
653
654 /* The compiler puts the data with non-zero offset in .rdata section, but put s the data with
655 zero offset in .bss section. So, if the data in in .bss section, set offse t=0.
656 Note from Wiki: In an object module compiled from C, the bss section conta ins
657 the local variables (but not functions) that were declared with the static keyword,
658 except for those with non-zero initial values. (In C, static variables are initialized
659 to zero by default.) It also contains the non-local (both extern and stati c) variables
660 that are also initialized to zero (either explicitly or by default).
661 */
662 // move to symbol table
663 /* COFF symbol table:
664 offset field
665 0 Name(*)
666 8 Value
667 12 SectionNumber
668 14 Type
669 16 StorageClass
670 17 NumberOfAuxSymbols
671 */
672 ptr = buf + symtab_ptr;
673
674 for (i = 0; i < symtab_sz; i++) {
675 int16_t section = get_le16(ptr + 12); // section number
676
677 if (section > 0 && ptr[16] == 2) {
678 // if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) {
679
680 if (get_le32(ptr)) {
681 char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
682 strncpy(name, ptr, 8);
683 // log_msg("COFF: Parsing symbol %s\n",name);
684 /* The 64bit Windows compiler doesn't prefix with an _.
685 * Check what's there, and bump if necessary
686 */
687 if (name[0] == '_')
688 printf("%-40s EQU ", name + 1);
689 else
690 printf("%-40s EQU ", name);
691 } else {
692 // log_msg("COFF: Parsing symbol %s\n",
693 // buf + strtab_ptr + get_le32(ptr+4));
694 if ((buf + strtab_ptr + get_le32(ptr + 4))[0] == '_')
695 printf("%-40s EQU ",
696 buf + strtab_ptr + get_le32(ptr + 4) + 1);
697 else
698 printf("%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4));
699 }
700
701 if (!(strcmp(sectionlist[section - 1], ".bss"))) {
702 symoffset = 0;
703 } else {
704 symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8));
705 }
706
707 // log_msg(" Section: %d\n",section);
708 // log_msg(" Class: %d\n",ptr[16]);
709 // log_msg(" Address: %u\n",get_le32(ptr+8));
710 // log_msg(" Offset: %u\n", symoffset);
711
712 printf("%5d\n", symoffset);
702 } 713 }
703 714
704 //log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections); 715 ptr += 18;
705 716 }
706 /* 717
707 The size of optional header is always zero for an obj file. So, the section header 718 printf(" END\n");
708 follows the file header immediately. 719
709 */ 720 for (i = 0; i < nsections; i++) {
710 721 free(sectionlist[i]);
711 ptr = buf + 20; //section header 722 }
712 723
713 for (i = 0; i < nsections; i++) 724 free(sectionlist);
714 { 725
715 char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 726 return 0;
716 strncpy(sectionname, ptr, 8);
717 //log_msg("COFF: Parsing section %s\n",sectionname);
718
719 sectionlist[i] = malloc(strlen(sectionname) + 1);
720
721 if (sectionlist[i] == NULL)
722 {
723 log_msg("Allocating storage for %s failed\n", sectionname);
724 goto bail;
725 }
726 strcpy(sectionlist[i], sectionname);
727
728 if (!strcmp(sectionname, ".rdata")) sectionrawdata_ptr = get_le32(ptr + 20);
729
730 ptr += 40;
731 }
732
733 //log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
734 //log_msg("COFF: raw data pointer ofset for section .rdata is %u\n", section rawdata_ptr);
735
736 /* The compiler puts the data with non-zero offset in .rdata section, but p uts the data with
737 zero offset in .bss section. So, if the data in in .bss section, set off set=0.
738 Note from Wiki: In an object module compiled from C, the bss section con tains
739 the local variables (but not functions) that were declared with the stat ic keyword,
740 except for those with non-zero initial values. (In C, static variables a re initialized
741 to zero by default.) It also contains the non-local (both extern and sta tic) variables
742 that are also initialized to zero (either explicitly or by default).
743 */
744 //move to symbol table
745 /* COFF symbol table:
746 offset field
747 0 Name(*)
748 8 Value
749 12 SectionNumber
750 14 Type
751 16 StorageClass
752 17 NumberOfAuxSymbols
753 */
754 ptr = buf + symtab_ptr;
755
756 for (i = 0; i < symtab_sz; i++)
757 {
758 int16_t section = get_le16(ptr + 12); //section number
759
760 if (section > 0 && ptr[16] == 2)
761 {
762 //if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) {
763
764 if (get_le32(ptr))
765 {
766 char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
767 strncpy(name, ptr, 8);
768 //log_msg("COFF: Parsing symbol %s\n",name);
769 /* The 64bit Windows compiler doesn't prefix with an _.
770 * Check what's there, and bump if necessary
771 */
772 if (name[0] == '_')
773 printf("%-40s EQU ", name + 1);
774 else
775 printf("%-40s EQU ", name);
776 }
777 else
778 {
779 //log_msg("COFF: Parsing symbol %s\n",
780 // buf + strtab_ptr + get_le32(ptr+4));
781 if ((buf + strtab_ptr + get_le32(ptr + 4))[0] == '_')
782 printf("%-40s EQU ",
783 buf + strtab_ptr + get_le32(ptr + 4) + 1);
784 else
785 printf("%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4));
786 }
787
788 if (!(strcmp(sectionlist[section-1], ".bss")))
789 {
790 symoffset = 0;
791 }
792 else
793 {
794 symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8 ));
795 }
796
797 //log_msg(" Section: %d\n",section);
798 //log_msg(" Class: %d\n",ptr[16]);
799 //log_msg(" Address: %u\n",get_le32(ptr+8));
800 //log_msg(" Offset: %u\n", symoffset);
801
802 printf("%5d\n", symoffset);
803 }
804
805 ptr += 18;
806 }
807
808 printf(" END\n");
809
810 for (i = 0; i < nsections; i++)
811 {
812 free(sectionlist[i]);
813 }
814
815 free(sectionlist);
816
817 return 0;
818 bail: 727 bail:
819 728
820 for (i = 0; i < nsections; i++) 729 for (i = 0; i < nsections; i++) {
821 { 730 free(sectionlist[i]);
822 free(sectionlist[i]); 731 }
823 } 732
824 733 free(sectionlist);
825 free(sectionlist); 734
826 735 return 1;
827 return 1;
828 } 736 }
829 #endif /* defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) */ 737 #endif /* defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) */
830 738
831 int main(int argc, char **argv) 739 int main(int argc, char **argv) {
832 { 740 output_fmt_t mode = OUTPUT_FMT_PLAIN;
833 output_fmt_t mode = OUTPUT_FMT_PLAIN; 741 const char *f;
834 const char *f; 742 uint8_t *file_buf;
835 uint8_t *file_buf; 743 int res;
836 int res; 744 FILE *fp;
837 FILE *fp; 745 long int file_size;
838 long int file_size; 746
839 747 if (argc < 2 || argc > 3) {
840 if (argc < 2 || argc > 3) 748 fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
841 { 749 fprintf(stderr, " <obj file>\tobject file to parse\n");
842 fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]); 750 fprintf(stderr, "Output Formats:\n");
843 fprintf(stderr, " <obj file>\tobject file to parse\n"); 751 fprintf(stderr, " gas - compatible with GNU assembler\n");
844 fprintf(stderr, "Output Formats:\n"); 752 fprintf(stderr, " rvds - compatible with armasm\n");
845 fprintf(stderr, " gas - compatible with GNU assembler\n"); 753 goto bail;
846 fprintf(stderr, " rvds - compatible with armasm\n"); 754 }
847 goto bail; 755
848 } 756 f = argv[2];
849 757
850 f = argv[2]; 758 if (!strcmp(argv[1], "rvds"))
851 759 mode = OUTPUT_FMT_RVDS;
852 if (!strcmp(argv[1], "rvds")) 760 else if (!strcmp(argv[1], "gas"))
853 mode = OUTPUT_FMT_RVDS; 761 mode = OUTPUT_FMT_GAS;
854 else if (!strcmp(argv[1], "gas")) 762 else
855 mode = OUTPUT_FMT_GAS; 763 f = argv[1];
856 else 764
857 f = argv[1]; 765 fp = fopen(f, "rb");
858 766
859 fp = fopen(f, "rb"); 767 if (!fp) {
860 768 perror("Unable to open file");
861 if (!fp) 769 goto bail;
862 { 770 }
863 perror("Unable to open file"); 771
864 goto bail; 772 if (fseek(fp, 0, SEEK_END)) {
865 } 773 perror("stat");
866 774 goto bail;
867 if (fseek(fp, 0, SEEK_END)) 775 }
868 { 776
869 perror("stat"); 777 file_size = ftell(fp);
870 goto bail; 778 file_buf = malloc(file_size);
871 } 779
872 780 if (!file_buf) {
873 file_size = ftell(fp); 781 perror("malloc");
874 file_buf = malloc(file_size); 782 goto bail;
875 783 }
876 if (!file_buf) 784
877 { 785 rewind(fp);
878 perror("malloc"); 786
879 goto bail; 787 if (fread(file_buf, sizeof(char), file_size, fp) != file_size) {
880 } 788 perror("read");
881 789 goto bail;
882 rewind(fp); 790 }
883 791
884 if (fread(file_buf, sizeof(char), file_size, fp) != file_size) 792 if (fclose(fp)) {
885 { 793 perror("close");
886 perror("read"); 794 goto bail;
887 goto bail; 795 }
888 }
889
890 if (fclose(fp))
891 {
892 perror("close");
893 goto bail;
894 }
895 796
896 #if defined(__GNUC__) && __GNUC__ 797 #if defined(__GNUC__) && __GNUC__
897 #if defined(__MACH__) 798 #if defined(__MACH__)
898 res = parse_macho(file_buf, file_size); 799 res = parse_macho(file_buf, file_size);
899 #elif defined(__ELF__) 800 #elif defined(__ELF__)
900 res = parse_elf(file_buf, file_size, mode); 801 res = parse_elf(file_buf, file_size, mode);
901 #endif 802 #endif
902 #endif 803 #endif
903 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) 804 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
904 res = parse_coff(file_buf, file_size); 805 res = parse_coff(file_buf, file_size);
905 #endif 806 #endif
906 807
907 free(file_buf); 808 free(file_buf);
908 809
909 if (!res) 810 if (!res)
910 return EXIT_SUCCESS; 811 return EXIT_SUCCESS;
911 812
912 bail: 813 bail:
913 return EXIT_FAILURE; 814 return EXIT_FAILURE;
914 } 815 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698