file_aout.cc Source File

Back to the index.

file_aout.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2009 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: a.out executable file support
29  */
30 
31 /* Note: Included from file.c. */
32 
33 
34 #include "thirdparty/exec_aout.h"
35 
36 
37 #define AOUT_FLAG_DECOSF1 1
38 #define AOUT_FLAG_FROM_BEGINNING 2
39 #define AOUT_FLAG_VADDR_ZERO_HACK 4
40 #define AOUT_FLAG_NO_SIZES 8
41 
42 struct aout_symbol {
43  uint32_t strindex;
44  uint32_t type;
45  uint32_t addr;
46 };
47 
48 
49 /*
50  * file_load_aout():
51  *
52  * Loads an a.out binary image into the emulated memory. The entry point
53  * (read from the a.out header) is stored in the specified CPU's registers.
54  *
55  * TODO: This has to be rewritten / corrected to support multiple a.out
56  * formats, where text/data are aligned differently.
57  */
58 static void file_load_aout(struct machine *m, struct memory *mem,
59  char *filename, int flags,
60  uint64_t *entrypointp, int arch, int *byte_orderp)
61 {
62  struct exec aout_header;
63  FILE *f;
64  int len;
65  int encoding = ELFDATA2LSB;
66  uint32_t entry, datasize, textsize;
67  int32_t symbsize = 0;
68  uint32_t vaddr, total_len;
69  unsigned char buf[65536];
70  unsigned char *syms;
71 
72  if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
73  encoding = ELFDATA2MSB;
74 
75  f = fopen(filename, "r");
76  if (f == NULL) {
77  perror(filename);
78  exit(1);
79  }
80 
81  if (flags & AOUT_FLAG_DECOSF1) {
82  if (fread(&buf, 1, 32, f) != 32) {
83  perror(filename);
84  exit(1);
85  }
86  vaddr = buf[16] + (buf[17] << 8) +
87  (buf[18] << 16) + ((uint64_t)buf[19] << 24);
88  entry = buf[20] + (buf[21] << 8) +
89  (buf[22] << 16) + ((uint64_t)buf[23] << 24);
90  debug("OSF1 a.out, load address 0x%08lx, "
91  "entry point 0x%08x\n", (long)vaddr, (long)entry);
92  symbsize = 0;
93  fseek(f, 0, SEEK_END);
94  /* This is of course wrong, but should work anyway: */
95  textsize = ftello(f) - 512;
96  datasize = 0;
97  fseek(f, 512, SEEK_SET);
98  } else if (flags & AOUT_FLAG_NO_SIZES) {
99  fseek(f, 0, SEEK_END);
100  textsize = ftello(f) - 32;
101  datasize = 0;
102  vaddr = entry = 0;
103  fseek(f, 32, SEEK_SET);
104  } else {
105  len = fread(&aout_header, 1, sizeof(aout_header), f);
106  if (len != sizeof(aout_header)) {
107  fprintf(stderr, "%s: not a complete a.out image\n",
108  filename);
109  exit(1);
110  }
111 
112  unencode(entry, &aout_header.a_entry, uint32_t);
113  debug("a.out, entry point 0x%08lx\n", (long)entry);
114  vaddr = entry;
115 
116  if (flags & AOUT_FLAG_VADDR_ZERO_HACK)
117  vaddr = 0;
118 
119  unencode(textsize, &aout_header.a_text, uint32_t);
120  unencode(datasize, &aout_header.a_data, uint32_t);
121  debug("text + data = %i + %i bytes\n", textsize, datasize);
122 
123  unencode(symbsize, &aout_header.a_syms, uint32_t);
124  }
125 
126  if (flags & AOUT_FLAG_FROM_BEGINNING) {
127  fseek(f, 0, SEEK_SET);
128  vaddr &= ~0xfff;
129  }
130 
131  /* Load text and data: */
132  total_len = textsize + datasize;
133  while (total_len != 0) {
134  len = total_len > sizeof(buf) ? sizeof(buf) : total_len;
135  len = fread(buf, 1, len, f);
136 
137  /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
138  (int)len, (int)vaddr, buf[0], buf[1], buf[2]); */
139 
140  if (len > 0) {
141  int len2 = 0;
142  uint64_t vaddr1 = vaddr &
143  ((1 << BITS_PER_MEMBLOCK) - 1);
144  uint64_t vaddr2 = (vaddr +
145  len) & ((1 << BITS_PER_MEMBLOCK) - 1);
146  if (vaddr2 < vaddr1) {
147  len2 = len - vaddr2;
148  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
149  &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
150  }
151  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
152  &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
153  } else {
154  if (flags & AOUT_FLAG_DECOSF1)
155  break;
156  else {
157  fprintf(stderr, "could not read from %s,"
158  " wanted to read %i bytes\n", filename,
159  (int) total_len);
160  exit(1);
161  }
162  }
163 
164  vaddr += len;
165  total_len -= len;
166  }
167 
168  if (symbsize != 0) {
169  struct aout_symbol *aout_symbol_ptr;
170  int i, n_symbols;
171  uint32_t type, addr, str_index;
172  uint32_t strings_len;
173  char *string_symbols;
174  off_t oldpos;
175 
176  debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftello(f));
177  CHECK_ALLOCATION(syms = (unsigned char *) malloc(symbsize));
178  len = fread(syms, 1, symbsize, f);
179  if (len != symbsize) {
180  fprintf(stderr, "error reading symbols from %s\n",
181  filename);
182  exit(1);
183  }
184 
185  oldpos = ftello(f);
186  fseek(f, 0, SEEK_END);
187  strings_len = ftello(f) - oldpos;
188  fseek(f, oldpos, SEEK_SET);
189  debug("strings: %i bytes @ 0x%x\n", strings_len,(int)ftello(f));
190  CHECK_ALLOCATION(string_symbols = (char *) malloc(strings_len));
191  if (fread(string_symbols, 1, strings_len, f) != strings_len) {
192  fprintf(stderr, "Could not read symbols from %s?\n", filename);
193  perror("fread");
194  exit(1);
195  }
196 
197  aout_symbol_ptr = (struct aout_symbol *) syms;
198  n_symbols = symbsize / sizeof(struct aout_symbol);
199  i = 0;
200  while (i < n_symbols) {
201  unencode(str_index, &aout_symbol_ptr[i].strindex,
202  uint32_t);
203  unencode(type, &aout_symbol_ptr[i].type, uint32_t);
204  unencode(addr, &aout_symbol_ptr[i].addr, uint32_t);
205 
206  /* debug("symbol type 0x%04x @ 0x%08x: %s\n",
207  type, addr, string_symbols + str_index); */
208 
209  if (type != 0 && addr != 0)
211  addr, 0, string_symbols + str_index, 0, -1);
212  i++;
213  }
214 
215  free(string_symbols);
216  free(syms);
217  }
218 
219  fclose(f);
220 
221  *entrypointp = (int32_t)entry;
222 
223  if (encoding == ELFDATA2LSB)
224  *byte_orderp = EMUL_LITTLE_ENDIAN;
225  else
226  *byte_orderp = EMUL_BIG_ENDIAN;
227 
228  n_executables_loaded ++;
229 }
230 
#define AOUT_FLAG_NO_SIZES
Definition: file_aout.cc:40
#define AOUT_FLAG_DECOSF1
Definition: file_aout.cc:37
#define unencode(var, dataptr, typ)
Definition: file.cc:68
uint32_t a_syms
Definition: exec_aout.h:53
uint32_t a_data
Definition: exec_aout.h:51
void f(int s, int func, int only_name)
uint32_t a_entry
Definition: exec_aout.h:54
uint32_t strindex
Definition: file_aout.cc:43
struct cpu ** cpus
Definition: machine.h:140
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
#define ELFDATA2LSB
Definition: exec_elf.h:154
#define ELFDATA2MSB
Definition: exec_elf.h:155
#define BITS_PER_MEMBLOCK
Definition: memory.h:92
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
#define AOUT_FLAG_VADDR_ZERO_HACK
Definition: file_aout.cc:39
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:365
#define MEM_WRITE
Definition: memory.h:117
#define AOUT_FLAG_FROM_BEGINNING
Definition: file_aout.cc:38
Definition: exec_aout.h:48
#define debug
Definition: dev_adb.cc:57
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
#define NO_EXCEPTIONS
Definition: memory.h:125
struct symbol_context symbol_context
Definition: machine.h:144
uint8_t byte_order
Definition: cpu.h:347
Definition: memory.h:75
uint32_t type
Definition: file_aout.cc:44
uint32_t addr
Definition: file_aout.cc:45
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
uint32_t a_text
Definition: exec_aout.h:50

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13