54 static void file_load_ecoff(
struct machine *m,
struct memory *mem,
55 char *filename, uint64_t *entrypointp,
56 int arch, uint64_t *gpp,
int *byte_orderp)
59 int f_magic, f_nscns, f_nsyms;
61 off_t f_symptr, a_tsize, a_dsize, a_bsize;
62 uint64_t a_entry, a_tstart, a_dstart, a_bstart, a_gp, end_addr=0;
63 const char *format_name;
66 int len, secn, total_len, chunk_size;
68 int program_byte_order = -1;
69 unsigned char buf[8192];
71 f = fopen(filename,
"r");
77 len = fread(&exechdr, 1,
sizeof(exechdr),
f);
78 if (len !=
sizeof(exechdr)) {
79 fprintf(stderr,
" not a complete ecoff image\n");
94 format_name =
"MIPS1 BE";
99 format_name =
"MIPS1 BE-LE";
104 format_name =
"MIPS1 LE";
109 format_name =
"MIPS2 BE";
113 format_name =
"MIPS2 LE";
118 format_name =
"MIPS3 BE";
122 format_name =
"MIPS3 LE";
126 fprintf(stderr,
"%s: unimplemented ECOFF format, magic = "
127 "0x%04x\n", filename, (
int)f_magic);
135 debug(
"ECOFF, %s, %i sections, %i symbols @ 0x%lx\n",
136 format_name, f_nscns, f_nsyms, (
long)f_symptr);
142 debug(
"magic 0x%04x, tsize 0x%x, dsize 0x%x, bsize 0x%x\n",
143 a_magic, (
int)a_tsize, (
int)a_dsize, (
int)a_bsize);
148 debug(
"text @ 0x%08x, data @ 0x%08x, bss @ 0x%08x\n",
149 (
int)a_tstart, (
int)a_dstart, (
int)a_bstart);
152 unencode(a_gp, &exechdr.
a.gp_value, uint32_t);
153 debug(
"entrypoint 0x%08x, gp = 0x%08x\n",
154 (
int)a_entry, (
int)a_gp);
164 if (f_nscns == 0 && a_magic == 0x108) {
165 uint64_t where = a_tstart;
167 fseek(
f, 0x50, SEEK_SET);
170 len = fread(buf, 1, chunk_size,
f);
178 debug(
"MACH/pmax hack (!), read 0x%x bytes\n", total_len);
182 for (secn=0; secn<f_nscns; secn++) {
190 len = fread(&scnhdr, 1,
sizeof(scnhdr),
f);
191 if (len !=
sizeof(scnhdr)) {
192 fprintf(stderr,
"%s: incomplete section "
193 "header %i\n", filename, secn);
199 for (i=0; i<
sizeof(scnhdr.
s_name); i++)
216 debug(
"0x%x @ 0x%08x, offset 0x%lx, flags 0x%x)\n",
226 fprintf(stderr,
"%s: relocatable code/data in "
227 "section nr %i: not yet implemented\n",
242 if ((
s_vaddr & 0xf) == 0) chunk_size = 0x10;
243 if ((
s_vaddr & 0xff) == 0) chunk_size = 0x100;
244 if ((
s_vaddr & 0xfff) == 0) chunk_size = 0x1000;
245 while (total_len <
s_size) {
247 if (total_len + len >
s_size)
249 len = fread(buf, 1, chunk_size,
f);
251 debug(
"!!! total_len = %i, "
252 "chunk_size = %i, len = %i\n",
253 total_len, chunk_size, len);
264 fseek(
f, oldpos, SEEK_SET);
268 if (f_symptr != 0 && f_nsyms != 0) {
274 int nsymbols, sym_nr;
276 fseek(
f, f_symptr, SEEK_SET);
278 len = fread(&symhdr, 1,
sizeof(symhdr),
f);
279 if (len !=
sizeof(symhdr)) {
280 fprintf(stderr,
"%s: not a complete "
281 "ecoff image: symhdr broken\n", filename);
285 unencode(sym_magic, &symhdr.magic, uint16_t);
286 unencode(crfd, &symhdr.crfd, uint32_t);
287 unencode(cbRfdOffset, &symhdr.cbRfdOffset, uint32_t);
288 unencode(issMax, &symhdr.issMax, uint32_t);
289 unencode(cbSsOffset, &symhdr.cbSsOffset, uint32_t);
290 unencode(issExtMax, &symhdr.issExtMax, uint32_t);
291 unencode(cbSsExtOffset, &symhdr.cbSsExtOffset, uint32_t);
292 unencode(iextMax, &symhdr.iextMax, uint32_t);
293 unencode(cbExtOffset, &symhdr.cbExtOffset, uint32_t);
296 unsigned char *ms_sym_buf;
298 int n_real_symbols = 0;
300 debug(
"bad symbol magic, assuming Microsoft format: ");
309 malloc(
sizeof(
struct ms_sym) * f_nsyms));
310 fseek(
f, f_symptr, SEEK_SET);
311 len = fread(ms_sym_buf, 1,
312 sizeof(
struct ms_sym) * f_nsyms,
f);
313 sym = (
struct ms_sym *) ms_sym_buf;
314 for (sym_nr=0; sym_nr<f_nsyms; sym_nr++) {
316 uint32_t v,
t, altname;
321 + (sym->
value[2] << 16)
322 + ((uint64_t)sym->
value[3] << 24);
323 altname = sym->
name[4] + (sym->
name[5] << 8)
324 + (sym->
name[6] << 16)
325 + ((uint64_t)sym->
name[3] << 24);
330 if (
t == 0x20 && sym->
name[0]) {
336 }
else if (
t == 0x20 && !sym->
name[0]) {
338 ofs = f_symptr + altname +
339 sizeof(
struct ms_sym) * f_nsyms;
340 fseek(
f, ofs, SEEK_SET);
342 fprintf(stderr,
"error reading symbol from %s\n", filename);
370 debug(
"%i symbols\n", n_real_symbols);
373 goto skip_normal_coff_symbols;
376 debug(
"symbol header: magic = 0x%x\n", sym_magic);
378 debug(
"%i symbols @ 0x%08x (strings @ 0x%08x)\n",
379 iextMax, cbExtOffset, cbSsExtOffset);
382 memset(symbol_data, 0, issExtMax + 2);
383 fseek(
f, cbSsExtOffset, SEEK_SET);
384 if (fread(symbol_data, 1, issExtMax + 1,
f) != (
size_t) issExtMax+1) {
385 fprintf(stderr,
"error reading symbol data from %s\n", filename);
393 memset(extsyms, 0, iextMax *
sizeof(
struct ecoff_extsym));
394 fseek(
f, cbExtOffset, SEEK_SET);
395 if (fread(extsyms, 1, iextMax *
sizeof(
struct ecoff_extsym),
f) !=
397 fprintf(stderr,
"error reading extsyms from %s\n", filename);
402 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
403 uint64_t
value, strindex;
405 unencode(strindex, &extsyms[sym_nr].es_strindex,
413 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
419 extsyms[sym_nr].es_value, 0,
420 symbol_data + extsyms[sym_nr].es_strindex, 0, -1);
426 skip_normal_coff_symbols:
432 *entrypointp = a_entry;
436 if (program_byte_order != -1)
437 encoding = program_byte_order;
444 n_executables_loaded ++;