49 static void file_load_macho(
struct machine *m,
struct memory *mem,
50 char *filename, uint64_t *entrypointp,
int arch,
int *byte_orderp,
51 int is_64bit,
int is_reversed)
57 unsigned char buf[65536];
58 char *symbols, *strings;
59 uint32_t cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
60 uint64_t vmaddr, vmsize, fileoff, filesize;
61 int cmd_type, cmd_len, i, flavor;
62 int32_t symoff, nsyms, stroff, strsize;
68 f = fopen(filename,
"r");
75 fatal(
"TODO: 64-bit Mach-O. Not supported yet.\n");
79 fatal(
"TODO: Reversed-endianness. Not supported yet.\n");
83 len = fread(buf, 1,
sizeof(buf), f);
85 fatal(
"Bad Mach-O file?\n");
89 unencode(cputype, &buf[4], uint32_t);
90 unencode(cpusubtype, &buf[8], uint32_t);
91 unencode(filetype, &buf[12], uint32_t);
93 unencode(sizeofcmds, &buf[20], uint32_t);
105 if (cputype != 0x12) {
106 fatal(
"Error: Unimplemented cputype 0x%x\n", cputype);
109 if (cpusubtype != 0) {
110 fatal(
"Error: Unimplemented cpusubtype 0x%x\n", cpusubtype);
115 fatal(
"Error: Unimplemented filetype 0x%x\n", filetype);
119 fatal(
"Error: File has 'undefined references'. Cannot" 120 " be executed.\n", flags);
126 fatal(
"Error: Unimplemented flags 0x%x\n", flags);
133 pos = is_64bit? 32 : 28;
137 unencode(cmd_type, &buf[pos], uint32_t);
138 unencode(cmd_len, &buf[pos+4], uint32_t);
141 debug(
"cmd %i, len=%i\n", cmd_type, cmd_len);
142 for (i=8; i<cmd_len; i++) {
143 unsigned char ch = buf[pos+i];
144 if (ch >=
' ' && ch < 127)
153 for (i=0; i<16; i++) {
154 if (buf[pos + 8 + i] == 0)
156 debug(
"%c", buf[pos + 8 + i]);
158 unencode(vmaddr, &buf[pos+8+16+0], uint32_t);
159 unencode(vmsize, &buf[pos+8+16+4], uint32_t);
160 unencode(fileoff, &buf[pos+8+16+8], uint32_t);
161 unencode(filesize, &buf[pos+8+16+12], uint32_t);
162 debug(
": vmaddr=0x%x size=0x%x fileoff=0x%x",
163 (
int)vmaddr, (
int)vmsize, (
int)fileoff);
170 fseek(f, fileoff, SEEK_SET);
173 while (filesize != 0) {
174 unsigned char buf2[32768];
175 ssize_t lenRead = filesize >
sizeof(buf2) ?
176 sizeof(buf2) : filesize;
177 lenRead = fread(buf2, 1, lenRead, f);
185 uint64_t vaddr1 = vmaddr &
187 uint64_t vaddr2 = (vmaddr +
189 if (vaddr2 < vaddr1) {
190 len2 = lenRead - vaddr2;
192 0], mem, vmaddr, &buf2[0],
197 vmaddr + len2, &buf2[len2], lenRead-len2,
200 fprintf(stderr,
"error reading\n");
212 unencode(symoff, &buf[pos+8], uint32_t);
213 unencode(nsyms, &buf[pos+12], uint32_t);
214 unencode(stroff, &buf[pos+16], uint32_t);
215 unencode(strsize, &buf[pos+20], uint32_t);
216 debug(
"symtable: %i symbols @ 0x%x (strings at " 217 "0x%x)\n", nsyms, symoff, stroff);
220 fseek(f, symoff, SEEK_SET);
221 if (fread(symbols, 1, 12 * nsyms, f) != (
size_t) 12*nsyms) {
222 fprintf(stderr,
"could not read symbols from %s\n", filename);
227 fseek(f, stroff, SEEK_SET);
228 if (fread(strings, 1, strsize, f) != (
size_t) strsize) {
229 fprintf(stderr,
"could not read symbol strings from %s\n", filename);
233 for (i=0; i<nsyms; i++) {
234 int n_strx, n_type, n_sect, n_desc;
236 unencode(n_strx, &symbols[i*12+0], int32_t);
237 unencode(n_type, &symbols[i*12+4], uint8_t);
238 unencode(n_sect, &symbols[i*12+5], uint8_t);
239 unencode(n_desc, &symbols[i*12+6], int16_t);
240 unencode(n_value, &symbols[i*12+8], uint32_t);
245 n_value, 0, strings + n_strx, 0, -1);
252 case 5:
debug(
"unix thread context: ");
256 unencode(flavor, &buf[pos+8], uint32_t);
258 fatal(
"unimplemented flavor %i\n", flavor);
263 fatal(
"non-PPC arch? TODO\n");
267 unencode(entry, &buf[pos+16], uint32_t);
269 debug(
"pc=0x%x\n", (
int)entry);
271 for (i=1; i<40; i++) {
273 unencode(x, &buf[pos+16+i*4], uint32_t);
275 fatal(
"Entry nr %i in the Mach-O" 276 " thread struct is non-zero" 277 " (0x%x). This is not supported" 278 " yet. TODO\n", i, x);
284 default:
fatal(
"WARNING! Unimplemented load command %i!\n",
289 }
while (pos < sizeofcmds && cmd_type != 0);
294 fatal(
"No entry point? Aborting.\n");
298 *entrypointp = entry;
305 n_executables_loaded ++;
void fatal(const char *fmt,...)
#define unencode(var, dataptr, typ)
void f(int s, int func, int only_name)
#define EMUL_LITTLE_ENDIAN
#define BITS_PER_MEMBLOCK
#define CHECK_ALLOCATION(ptr)
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
void add_symbol_name(struct symbol_context *, uint64_t addr, uint64_t len, const char *name, int type, int n_args)
struct symbol_context symbol_context