file_elf.cc Source File

Back to the index.

file_elf.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2014 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: ELF file support
29  */
30 
31 /* Note: Included from file.c. */
32 
33 
34 #include "thirdparty/exec_elf.h"
35 
36 /* ELF machine types as strings: (same as exec_elf.h) */
37 #define N_ELF_MACHINE_TYPES 89
38 static const char *elf_machine_type[N_ELF_MACHINE_TYPES] = {
39  "NONE", "M32", "SPARC", "386", /* 0..3 */
40  "68K", "88K", "486", "860", /* 4..7 */
41  "MIPS", "S370", "MIPS_RS3_LE", "RS6000", /* 8..11 */
42  "unknown12", "unknown13", "unknown14", "PARISC", /* 12..15 */
43  "NCUBE", "VPP500", "SPARC32PLUS", "960", /* 16..19 */
44  "PPC", "PPC64", "unknown22", "unknown23", /* 20..23 */
45  "unknown24", "unknown25", "unknown26", "unknown27", /* 24..27 */
46  "unknown28", "unknown29", "unknown30", "unknown31", /* 28..31 */
47  "unknown32", "unknown33", "unknown34", "unknown35", /* 32..35 */
48  "V800", "FR20", "RH32", "RCE", /* 36..39 */
49  "ARM", "ALPHA", "SH", "SPARCV9", /* 40..43 */
50  "TRICORE", "ARC", "H8_300", "H8_300H", /* 44..47 */
51  "H8S", "H8_500", "IA_64", "MIPS_X", /* 48..51 */
52  "COLDFIRE", "68HC12", "unknown54", "unknown55", /* 52..55 */
53  "unknown56", "unknown57", "unknown58", "unknown59", /* 56..59 */
54  "unknown60", "unknown61", "AMD64", "unknown63", /* 60..63 */
55  "unknown64", "unknown65", "unknown66", "unknown67", /* 64..67 */
56  "unknown68", "unknown69", "unknown70", "unknown71", /* 68..71 */
57  "unknown72", "unknown73", "unknown74", "unknown75", /* 72..75 */
58  "unknown76", "unknown77", "unknown78", "unknown79", /* 76..79 */
59  "unknown80", "unknown81", "unknown82", "AVR", /* 80..83 */
60  "unknown84", "unknown85", "unknown86", "unknown87", /* 84..87 */
61  "M32R" /* 88 */
62 };
63 
64 
65 /*
66  * file_load_elf():
67  *
68  * Loads an ELF image into the emulated memory. The entry point (read from
69  * the ELF header) and the initial value of the gp register (read from the
70  * ELF symbol table) are stored in the specified CPU's registers.
71  *
72  * This is pretty heavy stuff, but is needed because of the heaviness of
73  * ELF files. :-/ Hopefully it will be able to recognize most valid ELFs.
74  */
75 static void file_load_elf(struct machine *m, struct memory *mem,
76  char *filename, uint64_t *entrypointp, int arch, uint64_t *gpp,
77  int *byte_order, uint64_t *tocp)
78 {
79  Elf32_Ehdr hdr32;
80  Elf64_Ehdr hdr64;
81  FILE *f;
82  uint64_t eentry;
83  int len, i, ok;
84  int elf64, encoding, eflags;
85  int etype, emachine;
86  int ephnum, ephentsize, eshnum, eshentsize;
87  off_t ephoff, eshoff;
88  Elf32_Phdr phdr32;
89  Elf64_Phdr phdr64;
90  Elf32_Shdr shdr32;
91  Elf64_Shdr shdr64;
92  Elf32_Sym sym32;
93  Elf64_Sym sym64;
94  int ofs;
95  int chunk_len = 1024, align_len;
96  char *symbol_strings = NULL;
97  size_t symbol_length = 0;
98  const char *s;
99  int n_symbols = 0;
100  Elf32_Sym *symbols_sym32 = NULL;
101  Elf64_Sym *symbols_sym64 = NULL;
102 
103  f = fopen(filename, "r");
104  if (f == NULL) {
105  perror(filename);
106  exit(1);
107  }
108 
109  len = fread(&hdr32, 1, sizeof(Elf32_Ehdr), f);
110  if (len < (signed int)sizeof(Elf32_Ehdr)) {
111  fprintf(stderr, "%s: not an ELF file image\n", filename);
112  exit(1);
113  }
114 
115  if (memcmp(&hdr32.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) {
116  fprintf(stderr, "%s: not an ELF file image\n", filename);
117  exit(1);
118  }
119 
120  switch (hdr32.e_ident[EI_CLASS]) {
121  case ELFCLASS32:
122  elf64 = 0;
123  break;
124  case ELFCLASS64:
125  elf64 = 1;
126  fseek(f, 0, SEEK_SET);
127  len = fread(&hdr64, 1, sizeof(Elf64_Ehdr), f);
128  if (len < (signed int)sizeof(Elf64_Ehdr)) {
129  fprintf(stderr, "%s: not an ELF64 file image\n",
130  filename);
131  exit(1);
132  }
133  break;
134  default:
135  fprintf(stderr, "%s: unknown ELF class '%i'\n",
136  filename, hdr32.e_ident[EI_CLASS]);
137  exit(1);
138  }
139 
140  encoding = hdr32.e_ident[EI_DATA];
141  if (encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) {
142  fprintf(stderr, "%s: unknown data encoding '%i'\n",
143  filename, hdr32.e_ident[EI_DATA]);
144  exit(1);
145  }
146 
147  if (elf64) {
148  unencode(etype, &hdr64.e_type, Elf64_Quarter);
149  unencode(eflags, &hdr64.e_flags, Elf64_Half);
150  unencode(emachine, &hdr64.e_machine, Elf64_Quarter);
151  unencode(eentry, &hdr64.e_entry, Elf64_Addr);
152  unencode(ephnum, &hdr64.e_phnum, Elf64_Quarter);
153  unencode(ephentsize, &hdr64.e_phentsize, Elf64_Quarter);
154  unencode(ephoff, &hdr64.e_phoff, Elf64_Off);
155  unencode(eshnum, &hdr64.e_shnum, Elf64_Quarter);
156  unencode(eshentsize, &hdr64.e_shentsize, Elf64_Quarter);
157  unencode(eshoff, &hdr64.e_shoff, Elf64_Off);
158  if (ephentsize != sizeof(Elf64_Phdr)) {
159  fprintf(stderr, "%s: incorrect phentsize? %i, should "
160  "be %i\nPerhaps this is a dynamically linked "
161  "binary (which isn't supported yet).\n", filename,
162  (int)ephentsize, (int)sizeof(Elf64_Phdr));
163  exit(1);
164  }
165  if (eshentsize != sizeof(Elf64_Shdr)) {
166  fprintf(stderr, "%s: incorrect shentsize? %i, should "
167  "be %i\nPerhaps this is a dynamically linked "
168  "binary (which isn't supported yet).\n", filename,
169  (int)eshentsize, (int)sizeof(Elf64_Shdr));
170  exit(1);
171  }
172  } else {
173  unencode(etype, &hdr32.e_type, Elf32_Half);
174  unencode(eflags, &hdr32.e_flags, Elf32_Word);
175  unencode(emachine, &hdr32.e_machine, Elf32_Half);
176  unencode(eentry, &hdr32.e_entry, Elf32_Addr);
177  unencode(ephnum, &hdr32.e_phnum, Elf32_Half);
178  unencode(ephentsize, &hdr32.e_phentsize, Elf32_Half);
179  unencode(ephoff, &hdr32.e_phoff, Elf32_Off);
180  unencode(eshnum, &hdr32.e_shnum, Elf32_Half);
181  unencode(eshentsize, &hdr32.e_shentsize, Elf32_Half);
182  unencode(eshoff, &hdr32.e_shoff, Elf32_Off);
183  if (ephentsize != sizeof(Elf32_Phdr)) {
184  fprintf(stderr, "%s: incorrect phentsize? %i, should "
185  "be %i\nPerhaps this is a dynamically linked "
186  "binary (which isn't supported yet).\n", filename,
187  (int)ephentsize, (int)sizeof(Elf32_Phdr));
188  exit(1);
189  }
190  if (eshentsize != sizeof(Elf32_Shdr)) {
191  fprintf(stderr, "%s: incorrect shentsize? %i, should "
192  "be %i\nPerhaps this is a dynamically linked "
193  "binary (which isn't supported yet).\n", filename,
194  (int)eshentsize, (int)sizeof(Elf32_Shdr));
195  exit(1);
196  }
197  }
198 
199  if ( etype != ET_EXEC ) {
200  fprintf(stderr, "%s is not an ELF Executable file, type = %i\n",
201  filename, etype);
202  exit(1);
203  }
204 
205  ok = 0;
206  switch (arch) {
207  case ARCH_M88K:
208  switch (emachine) {
209  case EM_88K:
210  ok = 1;
211  }
212  break;
213  case ARCH_ALPHA:
214  switch (emachine) {
215  case EM_ALPHA:
216  case -28634:
217  ok = 1;
218  }
219  break;
220  case ARCH_ARM:
221  switch (emachine) {
222  case EM_ARM:
223  ok = 1;
224  }
225  break;
226  /* case ARCH_AVR:
227  switch (emachine) {
228  case EM_AVR:
229  ok = 1;
230  }
231  break;
232  case ARCH_AVR32:
233  switch (emachine) {
234  case 6317:
235  ok = 1;
236  }
237  break;
238  case ARCH_HPPA:
239  switch (emachine) {
240  case EM_PARISC:
241  ok = 1;
242  }
243  break;
244  case ARCH_I960:
245  switch (emachine) {
246  case EM_960:
247  ok = 1;
248  }
249  break;
250  case ARCH_IA64:
251  switch (emachine) {
252  case EM_IA_64:
253  ok = 1;
254  }
255  break;
256  case ARCH_M68K:
257  switch (emachine) {
258  case EM_68K:
259  ok = 1;
260  }
261  break;
262  case ARCH_M32R:
263  switch (emachine) {
264  case EM_M32R:
265  ok = 1;
266  }
267  break;*/
268  case ARCH_MIPS:
269  switch (emachine) {
270  case EM_MIPS:
271  case EM_MIPS_RS3_LE:
272  ok = 1;
273  }
274  break;
275  case ARCH_PPC:
276  switch (emachine) {
277  case EM_PPC:
278  case EM_PPC64:
279  ok = 1;
280  }
281  break;
282  case ARCH_SH:
283  switch (emachine) {
284  case EM_SH:
285  ok = 1;
286  }
287  break;
288  /*case ARCH_SPARC:
289  switch (emachine) {
290  case EM_SPARC:
291  case EM_SPARCV9:
292  ok = 1;
293  }
294  break;
295  case ARCH_X86:
296  switch (emachine) {
297  case EM_386:
298  case EM_486:
299  *tocp = 1;
300  ok = 1;
301  break;
302  case EM_AMD64:
303  *tocp = 2;
304  ok = 1;
305  break;
306  }
307  break; */
308  default:
309  fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");
310  }
311  if (!ok) {
312  fprintf(stderr, "%s: this is a ", filename);
313  if (emachine >= 0 && emachine < N_ELF_MACHINE_TYPES)
314  fprintf(stderr, "%s", elf_machine_type[emachine]);
315  else
316  fprintf(stderr, "machine type '%i'", emachine);
317  fprintf(stderr, " ELF binary!\n");
318  exit(1);
319  }
320 
321  s = "entry point";
322  if (elf64 && arch == ARCH_PPC)
323  s = "function descriptor at";
324 
325  debug("ELF%i %s, %s 0x", elf64? 64 : 32,
326  encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);
327 
328  if (elf64)
329  debug("%016" PRIx64"\n", (uint64_t) eentry);
330  else
331  debug("%08" PRIx32"\n", (uint32_t) eentry);
332 
333  /*
334  * SH64: 32-bit instruction encoding?
335  */
336  if (arch == ARCH_SH && (eentry & 1)) {
337  fatal("SH64: 32-bit instruction encoding: TODO\n");
338  /* m->cpus[0]->cd.sh.compact = 0; */
339  m->cpus[0]->cd.sh.cpu_type.bits = 64;
340  exit(1);
341  }
342 
343  /* Read the program headers: */
344 
345  for (i=0; i<ephnum; i++) {
346  int p_type;
347  uint64_t p_offset;
348  uint64_t p_vaddr;
349  uint64_t p_paddr;
350  uint64_t p_filesz;
351  uint64_t p_memsz;
352  int p_flags;
353  int p_align;
354  int allRead;
355 
356  fseek(f, ephoff + i * ephentsize, SEEK_SET);
357 
358  if (elf64) {
359  allRead = fread(&phdr64, 1, sizeof(Elf64_Phdr), f) == sizeof(Elf64_Phdr);
360  unencode(p_type, &phdr64.p_type, Elf64_Half);
361  unencode(p_flags, &phdr64.p_flags, Elf64_Half);
362  unencode(p_offset, &phdr64.p_offset, Elf64_Off);
363  unencode(p_vaddr, &phdr64.p_vaddr, Elf64_Addr);
364  unencode(p_paddr, &phdr64.p_paddr, Elf64_Addr);
365  unencode(p_filesz, &phdr64.p_filesz, Elf64_Xword);
366  unencode(p_memsz, &phdr64.p_memsz, Elf64_Xword);
367  unencode(p_align, &phdr64.p_align, Elf64_Xword);
368  } else {
369  allRead = fread(&phdr32, 1, sizeof(Elf32_Phdr), f) == sizeof(Elf32_Phdr);
370  unencode(p_type, &phdr32.p_type, Elf32_Word);
371  unencode(p_offset, &phdr32.p_offset, Elf32_Off);
372  unencode(p_vaddr, &phdr32.p_vaddr, Elf32_Addr);
373  unencode(p_paddr, &phdr32.p_paddr, Elf32_Addr);
374  unencode(p_filesz, &phdr32.p_filesz, Elf32_Word);
375  unencode(p_memsz, &phdr32.p_memsz, Elf32_Word);
376  unencode(p_flags, &phdr32.p_flags, Elf32_Word);
377  unencode(p_align, &phdr32.p_align, Elf32_Word);
378  }
379 
380  if (!allRead) {
381  fprintf(stderr, "Could not read Phdr from %s. Aborting.\n", filename);
382  exit(1);
383  }
384 
385  /*
386  * Hack for loading PPC kernels that are linked to high
387  * addresses. (This requires enabling of instruction and
388  * data virtual address translation.)
389  */
390  if (arch == ARCH_PPC) {
391  if ( (elf64 && (p_vaddr >> 60) != 0) ||
392  (!elf64 && (p_vaddr >> 28) != 0) )
393  m->cpus[m->bootstrap_cpu]->
394  cd.ppc.msr |= PPC_MSR_IR | PPC_MSR_DR;
395  }
396 
397  if (p_memsz != 0 && (p_type == PT_LOAD ||
398  (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
399  debug("chunk %i (", i);
400  if (p_type == PT_LOAD)
401  debug("load");
402  else
403  debug("0x%08" PRIx32, (uint32_t) p_type);
404 
405  debug(") @ 0x%" PRIx64", vaddr 0x", (uint64_t) p_offset);
406 
407  if (elf64)
408  debug("%016" PRIx64, (uint64_t) p_vaddr);
409  else
410  debug("%08" PRIx32, (uint32_t) p_vaddr);
411 
412  debug(" len=0x%" PRIx64"\n", (uint64_t) p_memsz);
413 
414  if (p_vaddr != p_paddr) {
415  if (elf64)
416  debug("NOTE: vaddr (0x%" PRIx64") and "
417  "paddr (0x%" PRIx64") differ; using "
418  "vaddr\n", (uint64_t) p_vaddr,
419  (uint64_t) p_paddr);
420  else
421  debug("NOTE: vaddr (0x%08" PRIx32") and "
422  "paddr (0x%08" PRIx32") differ; usin"
423  "g vaddr\n", (uint32_t) p_vaddr,
424  (uint32_t)p_paddr);
425  }
426 
427  if (p_memsz < p_filesz) {
428  fprintf(stderr, "%s: memsz < filesz. TODO: how"
429  " to handle this? memsz=%016" PRIx64
430  " filesz=%016" PRIx64"\n", filename,
431  (uint64_t) p_memsz, (uint64_t) p_filesz);
432  exit(1);
433  }
434 
435  fseek(f, p_offset, SEEK_SET);
436  align_len = 1;
437  if ((p_vaddr & 0xf)==0) align_len = 0x10;
438  if ((p_vaddr & 0x3f)==0) align_len = 0x40;
439  if ((p_vaddr & 0xff)==0) align_len = 0x100;
440  if ((p_vaddr & 0xfff)==0) align_len = 0x1000;
441  if ((p_vaddr & 0x3fff)==0) align_len = 0x4000;
442  if ((p_vaddr & 0xffff)==0) align_len = 0x10000;
443  ofs = 0; len = chunk_len = align_len;
444  while (ofs < (int64_t)p_filesz && len==chunk_len) {
445  unsigned char *ch;
446 
447  CHECK_ALLOCATION(ch = (unsigned char *) malloc(chunk_len));
448 
449  /* Switch to larger size, if possible: */
450  if (align_len < 0x10000 &&
451  ((p_vaddr + ofs) & 0xffff)==0) {
452  align_len = 0x10000;
453  len = chunk_len = align_len;
454  free(ch);
455  CHECK_ALLOCATION(ch=(unsigned char *)malloc(chunk_len));
456  } else if (align_len < 0x1000 &&
457  ((p_vaddr + ofs) & 0xfff)==0) {
458  align_len = 0x1000;
459  len = chunk_len = align_len;
460  free(ch);
461  CHECK_ALLOCATION(ch=(unsigned char *)malloc(chunk_len));
462  }
463 
464  len = fread(&ch[0], 1, chunk_len, f);
465  if (ofs + len > (int64_t)p_filesz)
466  len = p_filesz - ofs;
467 
468  int j = 0;
469  while (j < len) {
470  size_t len_to_copy;
471  len_to_copy = (j + align_len) <= len?
472  align_len : len - j;
473  m->cpus[0]->memory_rw(m->cpus[0], mem,
474  p_vaddr + ofs, &ch[j], len_to_copy,
476  ofs += align_len;
477  j += align_len;
478  }
479 
480  free(ch);
481  }
482  }
483  }
484 
485  /*
486  * Read the section headers to find the address of the _gp
487  * symbol (for MIPS):
488  */
489 
490  for (i=0; i<eshnum; i++) {
491  int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;
492  uint64_t sh_addr, sh_size, sh_addralign;
493  off_t sh_offset;
494  int n_entries; /* for reading the symbol / string tables */
495 
496  /* debug("section header %i at %016" PRIx64"\n", i,
497  (uint64_t) eshoff+i*eshentsize); */
498 
499  fseek(f, eshoff + i * eshentsize, SEEK_SET);
500 
501  if (elf64) {
502  len = fread(&shdr64, 1, sizeof(Elf64_Shdr), f);
503  if (len != sizeof(Elf64_Shdr)) {
504  fprintf(stderr, "couldn't read header\n");
505  exit(1);
506  }
507  unencode(sh_name, &shdr64.sh_name, Elf64_Half);
508  unencode(sh_type, &shdr64.sh_type, Elf64_Half);
509  unencode(sh_flags, &shdr64.sh_flags, Elf64_Xword);
510  unencode(sh_addr, &shdr64.sh_addr, Elf64_Addr);
511  unencode(sh_offset, &shdr64.sh_offset, Elf64_Off);
512  unencode(sh_size, &shdr64.sh_size, Elf64_Xword);
513  unencode(sh_link, &shdr64.sh_link, Elf64_Half);
514  unencode(sh_info, &shdr64.sh_info, Elf64_Half);
515  unencode(sh_addralign, &shdr64.sh_addralign,
516  Elf64_Xword);
517  unencode(sh_entsize, &shdr64.sh_entsize, Elf64_Xword);
518  } else {
519  len = fread(&shdr32, 1, sizeof(Elf32_Shdr), f);
520  if (len != sizeof(Elf32_Shdr)) {
521  fprintf(stderr, "couldn't read header\n");
522  exit(1);
523  }
524  unencode(sh_name, &shdr32.sh_name, Elf32_Word);
525  unencode(sh_type, &shdr32.sh_type, Elf32_Word);
526  unencode(sh_flags, &shdr32.sh_flags, Elf32_Word);
527  unencode(sh_addr, &shdr32.sh_addr, Elf32_Addr);
528  unencode(sh_offset, &shdr32.sh_offset, Elf32_Off);
529  unencode(sh_size, &shdr32.sh_size, Elf32_Word);
530  unencode(sh_link, &shdr32.sh_link, Elf32_Word);
531  unencode(sh_info, &shdr32.sh_info, Elf32_Word);
532  unencode(sh_addralign, &shdr32.sh_addralign,Elf32_Word);
533  unencode(sh_entsize, &shdr32.sh_entsize, Elf32_Word);
534  }
535 
536  /* debug("sh_name=%04lx, sh_type=%08lx, sh_flags=%08lx"
537  " sh_size=%06lx sh_entsize=%03lx\n",
538  (long)sh_name, (long)sh_type, (long)sh_flags,
539  (long)sh_size, (long)sh_entsize); */
540 
541  /* Perhaps it is bad to reuse sh_entsize like this? TODO */
542  if (elf64)
543  sh_entsize = sizeof(Elf64_Sym);
544  else
545  sh_entsize = sizeof(Elf32_Sym);
546 
547  if (sh_type == SHT_SYMTAB) {
548  size_t len2;
549  n_entries = sh_size / sh_entsize;
550 
551  fseek(f, sh_offset, SEEK_SET);
552 
553  if (elf64) {
554  if (symbols_sym64 != NULL)
555  free(symbols_sym64);
556 
557  CHECK_ALLOCATION(symbols_sym64 = (Elf64_Sym *)
558  malloc(sh_size));
559 
560  len2 = fread(symbols_sym64, 1, sh_entsize *
561  n_entries, f);
562  } else {
563  if (symbols_sym32 != NULL)
564  free(symbols_sym32);
565 
566  CHECK_ALLOCATION(symbols_sym32 = (Elf32_Sym *)
567  malloc(sh_size));
568 
569  len2 = fread(symbols_sym32, 1,
570  sh_entsize * n_entries, f);
571  }
572 
573  if (len2 != sh_size) {
574  fprintf(stderr, "could not read symbols from "
575  "%s\n", filename);
576  exit(1);
577  }
578 
579  debug("%i symbol entries at 0x%" PRIx64"\n",
580  (int) n_entries, (uint64_t) sh_offset);
581 
582  n_symbols = n_entries;
583  }
584 
585  /*
586  * TODO: This is incorrect, there may be several strtab
587  * sections.
588  *
589  * For now, the simple/stupid guess that the largest string
590  * table is the one to use seems to be good enough.
591  */
592 
593  if (sh_type == SHT_STRTAB && sh_size > symbol_length) {
594  if (symbol_strings != NULL)
595  free(symbol_strings);
596 
597  CHECK_ALLOCATION(symbol_strings = (char *) malloc(sh_size + 1));
598 
599  fseek(f, sh_offset, SEEK_SET);
600  size_t len2 = fread(symbol_strings, 1, sh_size, f);
601  if (len2 != sh_size) {
602  fprintf(stderr, "could not read symbols from "
603  "%s\n", filename);
604  exit(1);
605  }
606 
607  debug("%i bytes of symbol strings at 0x%" PRIx64"\n",
608  (int) sh_size, (uint64_t) sh_offset);
609 
610  symbol_strings[sh_size] = '\0';
611  symbol_length = sh_size;
612  }
613  }
614 
615  fclose(f);
616 
617  /* Decode symbols: */
618  if (symbol_strings != NULL) {
619  for (i=0; i<n_symbols; i++) {
620  uint64_t st_name, addr, size;
621  int st_info;
622 
623  if (elf64) {
624  sym64 = symbols_sym64[i];
625  unencode(st_name, &sym64.st_name, Elf64_Half);
626  unencode(st_info, &sym64.st_info, Elf_Byte);
627  unencode(addr, &sym64.st_value, Elf64_Addr);
628  unencode(size, &sym64.st_size, Elf64_Xword);
629  } else {
630  sym32 = symbols_sym32[i];
631  unencode(st_name, &sym32.st_name, Elf32_Word);
632  unencode(st_info, &sym32.st_info, Elf_Byte);
633  unencode(addr, &sym32.st_value, Elf32_Word);
634  unencode(size, &sym32.st_size, Elf32_Word);
635  }
636 
637  /* debug("symbol info=0x%02x addr=0x%016" PRIx64
638  " (%i) '%s'\n", st_info, (uint64_t) addr,
639  st_name, symbol_strings + st_name); */
640 
641  if (size == 0)
642  size ++;
643 
644  if (addr != 0) /* && ((st_info >> 4) & 0xf)
645  >= STB_GLOBAL) */ {
646  /* debug("symbol info=0x%02x addr=0x%016" PRIx64
647  " '%s'\n", st_info, (uint64_t) addr,
648  symbol_strings + st_name); */
650  addr, size, symbol_strings + st_name,
651  0, -1);
652  }
653 
654  if (strcmp(symbol_strings + st_name, "_gp") == 0) {
655  debug("found _gp address: 0x");
656  if (elf64)
657  debug("%016" PRIx64"\n", (uint64_t)addr);
658  else
659  debug("%08" PRIx32"\n", (uint32_t)addr);
660  *gpp = addr;
661  }
662  }
663  }
664 
665  *entrypointp = eentry;
666 
667  if (encoding == ELFDATA2LSB)
668  *byte_order = EMUL_LITTLE_ENDIAN;
669  else
670  *byte_order = EMUL_BIG_ENDIAN;
671 
672  if (elf64 && arch == ARCH_PPC) {
673  /*
674  * Special case for 64-bit PPC ELFs:
675  *
676  * The ELF starting symbol points to a ".opd" section
677  * which contains a function descriptor:
678  *
679  * uint64_t start;
680  * uint64_t toc_base;
681  * uint64_t something_else; (?)
682  */
683  int res;
684  unsigned char b[sizeof(uint64_t)];
685  uint64_t toc_base;
686 
687  debug("PPC64: ");
688 
689  res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry, b,
690  sizeof(b), MEM_READ, NO_EXCEPTIONS);
691  if (!res)
692  debug(" [WARNING: could not read memory?] ");
693 
694  /* PPC are always big-endian: */
695  *entrypointp = ((uint64_t)b[0] << 56) +
696  ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
697  ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
698  ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
699  (uint64_t)b[7];
700 
701  res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry + 8,
702  b, sizeof(b), MEM_READ, NO_EXCEPTIONS);
703  if (!res)
704  fatal(" [WARNING: could not read memory?] ");
705 
706  toc_base = ((uint64_t)b[0] << 56) +
707  ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
708  ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
709  ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
710  (uint64_t)b[7];
711 
712  debug("entrypoint 0x%016" PRIx64", toc_base 0x%016" PRIx64"\n",
713  (uint64_t) *entrypointp, (uint64_t) toc_base);
714  if (tocp != NULL)
715  *tocp = toc_base;
716  }
717 
718  n_executables_loaded ++;
719 }
720 
Elf32_Sym::st_value
Elf32_Word st_value
Definition: exec_elf.h:422
Elf64_Shdr::sh_name
Elf64_Half sh_name
Definition: exec_elf.h:375
EM_MIPS
#define EM_MIPS
Definition: exec_elf.h:210
Elf32_Shdr::sh_type
Elf32_Word sh_type
Definition: exec_elf.h:363
ELFCLASS32
#define ELFCLASS32
Definition: exec_elf.h:149
Elf64_Sym::st_value
Elf64_Addr st_value
Definition: exec_elf.h:434
machine::bootstrap_cpu
int bootstrap_cpu
Definition: machine.h:136
SELFMAG
#define SELFMAG
Definition: exec_elf.h:145
ARCH_PPC
#define ARCH_PPC
Definition: machine.h:204
f
void f(int s, int func, int only_name)
Definition: generate_arm_r.c:45
Elf32_Shdr::sh_size
Elf32_Word sh_size
Definition: exec_elf.h:367
Elf64_Ehdr::e_shoff
Elf64_Off e_shoff
Definition: exec_elf.h:117
PT_LOAD
#define PT_LOAD
Definition: exec_elf.h:337
Elf32_Phdr::p_align
Elf32_Word p_align
Definition: exec_elf.h:321
Elf64_Phdr::p_filesz
Elf64_Xword p_filesz
Definition: exec_elf.h:330
Elf64_Ehdr::e_phnum
Elf64_Quarter e_phnum
Definition: exec_elf.h:121
EM_ALPHA
#define EM_ALPHA
Definition: exec_elf.h:229
machine::symbol_context
struct symbol_context symbol_context
Definition: machine.h:144
Elf64_Half
uint32_t Elf64_Half
Definition: exec_elf.h:83
Elf64_Phdr::p_type
Elf64_Half p_type
Definition: exec_elf.h:325
memory
Definition: memory.h:75
Elf64_Ehdr::e_phentsize
Elf64_Quarter e_phentsize
Definition: exec_elf.h:120
debug
#define debug
Definition: dev_adb.cc:57
Elf64_Ehdr::e_type
Elf64_Quarter e_type
Definition: exec_elf.h:112
Elf32_Ehdr::e_phoff
Elf32_Off e_phoff
Definition: exec_elf.h:99
Elf64_Shdr::sh_offset
Elf64_Off sh_offset
Definition: exec_elf.h:379
machine::cpus
struct cpu ** cpus
Definition: machine.h:140
Elf32_Shdr::sh_addr
Elf32_Addr sh_addr
Definition: exec_elf.h:365
Elf32_Phdr::p_memsz
Elf32_Word p_memsz
Definition: exec_elf.h:319
Elf32_Off
uint32_t Elf32_Off
Definition: exec_elf.h:52
Elf32_Shdr::sh_entsize
Elf32_Word sh_entsize
Definition: exec_elf.h:371
Elf64_Sym::st_name
Elf64_Half st_name
Definition: exec_elf.h:430
Elf32_Sym::st_info
Elf_Byte st_info
Definition: exec_elf.h:424
EI_CLASS
#define EI_CLASS
Definition: exec_elf.h:132
Elf64_Shdr::sh_info
Elf64_Half sh_info
Definition: exec_elf.h:382
Elf32_Shdr::sh_offset
Elf32_Off sh_offset
Definition: exec_elf.h:366
Elf64_Ehdr::e_phoff
Elf64_Off e_phoff
Definition: exec_elf.h:116
unencode
#define unencode(var, dataptr, typ)
Definition: file.cc:69
ELFCLASS64
#define ELFCLASS64
Definition: exec_elf.h:150
Elf64_Ehdr::e_machine
Elf64_Quarter e_machine
Definition: exec_elf.h:113
MEM_READ
#define MEM_READ
Definition: memory.h:116
Elf32_Ehdr::e_shentsize
Elf32_Half e_shentsize
Definition: exec_elf.h:105
Elf64_Ehdr::e_shentsize
Elf64_Quarter e_shentsize
Definition: exec_elf.h:122
EI_DATA
#define EI_DATA
Definition: exec_elf.h:133
EMUL_BIG_ENDIAN
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
Elf64_Off
uint64_t Elf64_Off
Definition: exec_elf.h:63
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
ET_EXEC
#define ET_EXEC
Definition: exec_elf.h:190
Elf32_Phdr::p_type
Elf32_Word p_type
Definition: exec_elf.h:314
ppc_cpu::msr
uint64_t msr
Definition: cpu_ppc.h:130
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
ARCH_M88K
#define ARCH_M88K
Definition: machine.h:208
exec_elf.h
Elf64_Phdr::p_vaddr
Elf64_Addr p_vaddr
Definition: exec_elf.h:328
Elf64_Phdr
Definition: exec_elf.h:324
Elf32_Ehdr::e_shoff
Elf32_Off e_shoff
Definition: exec_elf.h:100
Elf32_Phdr::p_offset
Elf32_Off p_offset
Definition: exec_elf.h:315
Elf32_Ehdr::e_flags
Elf32_Word e_flags
Definition: exec_elf.h:101
Elf32_Phdr::p_vaddr
Elf32_Addr p_vaddr
Definition: exec_elf.h:316
Elf32_Phdr::p_paddr
Elf32_Addr p_paddr
Definition: exec_elf.h:317
Elf64_Shdr::sh_addr
Elf64_Addr sh_addr
Definition: exec_elf.h:378
EI_MAG0
#define EI_MAG0
Definition: exec_elf.h:128
Elf32_Half
uint16_t Elf32_Half
Definition: exec_elf.h:58
ARCH_MIPS
#define ARCH_MIPS
Definition: machine.h:203
Elf32_Shdr::sh_flags
Elf32_Word sh_flags
Definition: exec_elf.h:364
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
Elf64_Sym::st_size
Elf64_Xword st_size
Definition: exec_elf.h:435
Elf64_Shdr::sh_type
Elf64_Half sh_type
Definition: exec_elf.h:376
EM_ARM
#define EM_ARM
Definition: exec_elf.h:228
PF_MASKPROC
#define PF_MASKPROC
Definition: exec_elf.h:351
Elf64_Phdr::p_paddr
Elf64_Addr p_paddr
Definition: exec_elf.h:329
cpu::cd
union cpu::@1 cd
Elf32_Phdr::p_filesz
Elf32_Word p_filesz
Definition: exec_elf.h:318
machine
Definition: machine.h:97
Elf64_Ehdr
Definition: exec_elf.h:110
Elf64_Shdr
Definition: exec_elf.h:374
ARCH_SH
#define ARCH_SH
Definition: machine.h:207
cpu::sh
struct sh_cpu sh
Definition: cpu.h:448
Elf32_Addr
uint32_t Elf32_Addr
Definition: exec_elf.h:50
Elf32_Ehdr::e_entry
Elf32_Addr e_entry
Definition: exec_elf.h:98
EM_88K
#define EM_88K
Definition: exec_elf.h:206
Elf32_Sym::st_name
Elf32_Word st_name
Definition: exec_elf.h:421
Elf64_Shdr::sh_link
Elf64_Half sh_link
Definition: exec_elf.h:381
Elf32_Phdr
Definition: exec_elf.h:313
Elf64_Sym::st_info
Elf_Byte st_info
Definition: exec_elf.h:431
Elf32_Word
uint32_t Elf32_Word
Definition: exec_elf.h:56
Elf64_Shdr::sh_flags
Elf64_Xword sh_flags
Definition: exec_elf.h:377
Elf32_Ehdr::e_machine
Elf32_Half e_machine
Definition: exec_elf.h:96
Elf32_Phdr::p_flags
Elf32_Word p_flags
Definition: exec_elf.h:320
Elf64_Phdr::p_align
Elf64_Xword p_align
Definition: exec_elf.h:332
Elf64_Ehdr::e_shnum
Elf64_Quarter e_shnum
Definition: exec_elf.h:123
cpu::ppc
struct ppc_cpu ppc
Definition: cpu.h:447
EM_PPC64
#define EM_PPC64
Definition: exec_elf.h:221
Elf_Byte
uint8_t Elf_Byte
Definition: exec_elf.h:48
EMUL_LITTLE_ENDIAN
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
Elf32_Shdr::sh_name
Elf32_Word sh_name
Definition: exec_elf.h:362
Elf64_Phdr::p_offset
Elf64_Off p_offset
Definition: exec_elf.h:327
Elf64_Shdr::sh_entsize
Elf64_Xword sh_entsize
Definition: exec_elf.h:384
sh_cpu::cpu_type
struct sh_cpu_type_def cpu_type
Definition: cpu_sh.h:97
SHT_SYMTAB
#define SHT_SYMTAB
Definition: exec_elf.h:390
ELFMAG
#define ELFMAG
Definition: exec_elf.h:144
PT_MIPS_REGINFO
#define PT_MIPS_REGINFO
Definition: exec_elf.h:356
Elf32_Ehdr
Definition: exec_elf.h:93
Elf32_Shdr
Definition: exec_elf.h:361
Elf64_Ehdr::e_flags
Elf64_Half e_flags
Definition: exec_elf.h:118
Elf64_Ehdr::e_entry
Elf64_Addr e_entry
Definition: exec_elf.h:115
NO_EXCEPTIONS
#define NO_EXCEPTIONS
Definition: memory.h:125
Elf64_Phdr::p_flags
Elf64_Half p_flags
Definition: exec_elf.h:326
EM_MIPS_RS3_LE
#define EM_MIPS_RS3_LE
Definition: exec_elf.h:212
Elf32_Ehdr::e_shnum
Elf32_Half e_shnum
Definition: exec_elf.h:106
Elf32_Ehdr::e_ident
unsigned char e_ident[ELF_NIDENT]
Definition: exec_elf.h:94
PPC_MSR_IR
#define PPC_MSR_IR
Definition: cpu_ppc.h:168
sh_cpu_type_def::bits
int bits
Definition: cpu_sh.h:55
N_ELF_MACHINE_TYPES
#define N_ELF_MACHINE_TYPES
Definition: file_elf.cc:37
ARCH_ARM
#define ARCH_ARM
Definition: machine.h:206
Elf64_Addr
uint64_t Elf64_Addr
Definition: exec_elf.h:61
ARCH_ALPHA
#define ARCH_ALPHA
Definition: machine.h:205
add_symbol_name
void add_symbol_name(struct symbol_context *, uint64_t addr, uint64_t len, const char *name, int type, int n_args)
Definition: symbol.cc:199
Elf32_Shdr::sh_addralign
Elf32_Word sh_addralign
Definition: exec_elf.h:370
SHT_STRTAB
#define SHT_STRTAB
Definition: exec_elf.h:391
ELFDATA2LSB
#define ELFDATA2LSB
Definition: exec_elf.h:155
ELFDATA2MSB
#define ELFDATA2MSB
Definition: exec_elf.h:156
Elf32_Ehdr::e_phentsize
Elf32_Half e_phentsize
Definition: exec_elf.h:103
Elf32_Sym::st_size
Elf32_Word st_size
Definition: exec_elf.h:423
Elf64_Xword
uint64_t Elf64_Xword
Definition: exec_elf.h:81
Elf32_Ehdr::e_type
Elf32_Half e_type
Definition: exec_elf.h:95
PPC_MSR_DR
#define PPC_MSR_DR
Definition: cpu_ppc.h:169
Elf64_Sym
Definition: exec_elf.h:429
EM_PPC
#define EM_PPC
Definition: exec_elf.h:220
Elf32_Shdr::sh_link
Elf32_Word sh_link
Definition: exec_elf.h:368
Elf64_Shdr::sh_size
Elf64_Xword sh_size
Definition: exec_elf.h:380
Elf32_Shdr::sh_info
Elf32_Word sh_info
Definition: exec_elf.h:369
Elf64_Shdr::sh_addralign
Elf64_Xword sh_addralign
Definition: exec_elf.h:383
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:368
Elf32_Sym
Definition: exec_elf.h:420
Elf64_Quarter
uint16_t Elf64_Quarter
Definition: exec_elf.h:85
EM_SH
#define EM_SH
Definition: exec_elf.h:230
Elf64_Phdr::p_memsz
Elf64_Xword p_memsz
Definition: exec_elf.h:331
Elf32_Ehdr::e_phnum
Elf32_Half e_phnum
Definition: exec_elf.h:104
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18