1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdio.h>
20#include <sys/types.h>
21#include <fcntl.h>
22#include <sys/stat.h>
23#include <errno.h>
24#include <unistd.h>
25#include <sys/mman.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include "qemu.h"
30#include "disas.h"
31
32#include <mach-o/loader.h>
33#include <mach-o/fat.h>
34#include <mach-o/nlist.h>
35#include <mach-o/reloc.h>
36#include <mach-o/ppc/reloc.h>
37
38
39
40#ifdef DEBUG_MACHLOAD
41# define DPRINTF(...) do { qemu_log(__VA_ARGS__); printf(__VA_ARGS__); } while(0)
42#else
43# define DPRINTF(...) do { qemu_log(__VA_ARGS__); } while(0)
44#endif
45
46# define check_mach_header(x) (x.magic == MH_CIGAM)
47
48extern const char *interp_prefix;
49
50
51#define DONT_USE_DYLD_SHARED_MAP
52
53
54
55
56
57
58#ifdef OVERRIDE_DYLINKER
59# ifdef TARGET_I386
60# define DYLINKER_NAME "/Users/steg/qemu/tests/i386-darwin-env/usr/lib/dyld"
61# else
62# define DYLINKER_NAME "/usr/lib/dyld"
63# endif
64#endif
65
66
67struct nlist_extended
68{
69 union {
70 char *n_name;
71 long n_strx;
72 } n_un;
73 unsigned char n_type;
74 unsigned char n_sect;
75 short st_desc;
76 unsigned long st_value;
77 unsigned long st_size;
78};
79
80
81void *macho_text_sect = 0;
82int macho_offset = 0;
83
84int load_object(const char *filename, struct target_pt_regs * regs, void ** mh);
85void qerror(const char *format, ...);
86#ifdef TARGET_I386
87typedef struct mach_i386_thread_state {
88 unsigned int eax;
89 unsigned int ebx;
90 unsigned int ecx;
91 unsigned int edx;
92 unsigned int edi;
93 unsigned int esi;
94 unsigned int ebp;
95 unsigned int esp;
96 unsigned int ss;
97 unsigned int eflags;
98 unsigned int eip;
99 unsigned int cs;
100 unsigned int ds;
101 unsigned int es;
102 unsigned int fs;
103 unsigned int gs;
104} mach_i386_thread_state_t;
105
106void bswap_i386_thread_state(struct mach_i386_thread_state *ts)
107{
108 bswap32s((uint32_t*)&ts->eax);
109 bswap32s((uint32_t*)&ts->ebx);
110 bswap32s((uint32_t*)&ts->ecx);
111 bswap32s((uint32_t*)&ts->edx);
112 bswap32s((uint32_t*)&ts->edi);
113 bswap32s((uint32_t*)&ts->esi);
114 bswap32s((uint32_t*)&ts->ebp);
115 bswap32s((uint32_t*)&ts->esp);
116 bswap32s((uint32_t*)&ts->ss);
117 bswap32s((uint32_t*)&ts->eflags);
118 bswap32s((uint32_t*)&ts->eip);
119 bswap32s((uint32_t*)&ts->cs);
120 bswap32s((uint32_t*)&ts->ds);
121 bswap32s((uint32_t*)&ts->es);
122 bswap32s((uint32_t*)&ts->fs);
123 bswap32s((uint32_t*)&ts->gs);
124}
125#define target_thread_state mach_i386_thread_state
126#define TARGET_CPU_TYPE CPU_TYPE_I386
127#define TARGET_CPU_NAME "i386"
128#endif
129
130#ifdef TARGET_PPC
131struct mach_ppc_thread_state {
132 unsigned int srr0;
133 unsigned int srr1;
134 unsigned int r0;
135 unsigned int r1;
136 unsigned int r2;
137 unsigned int r3;
138 unsigned int r4;
139 unsigned int r5;
140 unsigned int r6;
141 unsigned int r7;
142 unsigned int r8;
143 unsigned int r9;
144 unsigned int r10;
145 unsigned int r11;
146 unsigned int r12;
147 unsigned int r13;
148 unsigned int r14;
149 unsigned int r15;
150 unsigned int r16;
151 unsigned int r17;
152 unsigned int r18;
153 unsigned int r19;
154 unsigned int r20;
155 unsigned int r21;
156 unsigned int r22;
157 unsigned int r23;
158 unsigned int r24;
159 unsigned int r25;
160 unsigned int r26;
161 unsigned int r27;
162 unsigned int r28;
163 unsigned int r29;
164 unsigned int r30;
165 unsigned int r31;
166
167 unsigned int cr;
168 unsigned int xer;
169 unsigned int lr;
170 unsigned int ctr;
171 unsigned int mq;
172
173 unsigned int vrsave;
174};
175
176void bswap_ppc_thread_state(struct mach_ppc_thread_state *ts)
177{
178 bswap32s((uint32_t*)&ts->srr0);
179 bswap32s((uint32_t*)&ts->srr1);
180 bswap32s((uint32_t*)&ts->r0);
181 bswap32s((uint32_t*)&ts->r1);
182 bswap32s((uint32_t*)&ts->r2);
183 bswap32s((uint32_t*)&ts->r3);
184 bswap32s((uint32_t*)&ts->r4);
185 bswap32s((uint32_t*)&ts->r5);
186 bswap32s((uint32_t*)&ts->r6);
187 bswap32s((uint32_t*)&ts->r7);
188 bswap32s((uint32_t*)&ts->r8);
189 bswap32s((uint32_t*)&ts->r9);
190 bswap32s((uint32_t*)&ts->r10);
191 bswap32s((uint32_t*)&ts->r11);
192 bswap32s((uint32_t*)&ts->r12);
193 bswap32s((uint32_t*)&ts->r13);
194 bswap32s((uint32_t*)&ts->r14);
195 bswap32s((uint32_t*)&ts->r15);
196 bswap32s((uint32_t*)&ts->r16);
197 bswap32s((uint32_t*)&ts->r17);
198 bswap32s((uint32_t*)&ts->r18);
199 bswap32s((uint32_t*)&ts->r19);
200 bswap32s((uint32_t*)&ts->r20);
201 bswap32s((uint32_t*)&ts->r21);
202 bswap32s((uint32_t*)&ts->r22);
203 bswap32s((uint32_t*)&ts->r23);
204 bswap32s((uint32_t*)&ts->r24);
205 bswap32s((uint32_t*)&ts->r25);
206 bswap32s((uint32_t*)&ts->r26);
207 bswap32s((uint32_t*)&ts->r27);
208 bswap32s((uint32_t*)&ts->r28);
209 bswap32s((uint32_t*)&ts->r29);
210 bswap32s((uint32_t*)&ts->r30);
211 bswap32s((uint32_t*)&ts->r31);
212
213 bswap32s((uint32_t*)&ts->cr);
214 bswap32s((uint32_t*)&ts->xer);
215 bswap32s((uint32_t*)&ts->lr);
216 bswap32s((uint32_t*)&ts->ctr);
217 bswap32s((uint32_t*)&ts->mq);
218
219 bswap32s((uint32_t*)&ts->vrsave);
220}
221
222#define target_thread_state mach_ppc_thread_state
223#define TARGET_CPU_TYPE CPU_TYPE_POWERPC
224#define TARGET_CPU_NAME "PowerPC"
225#endif
226
227struct target_thread_command {
228 unsigned long cmd;
229 unsigned long cmdsize;
230 unsigned long flavor;
231 unsigned long count;
232 struct target_thread_state state;
233};
234
235void bswap_tc(struct target_thread_command *tc)
236{
237 bswap32s((uint32_t*)(&tc->flavor));
238 bswap32s((uint32_t*)&tc->count);
239#if defined(TARGET_I386)
240 bswap_i386_thread_state(&tc->state);
241#elif defined(TARGET_PPC)
242 bswap_ppc_thread_state(&tc->state);
243#else
244# error unknown TARGET_CPU_TYPE
245#endif
246}
247
248void bswap_mh(struct mach_header *mh)
249{
250 bswap32s((uint32_t*)(&mh->magic));
251 bswap32s((uint32_t*)&mh->cputype);
252 bswap32s((uint32_t*)&mh->cpusubtype);
253 bswap32s((uint32_t*)&mh->filetype);
254 bswap32s((uint32_t*)&mh->ncmds);
255 bswap32s((uint32_t*)&mh->sizeofcmds);
256 bswap32s((uint32_t*)&mh->flags);
257}
258
259void bswap_lc(struct load_command *lc)
260{
261 bswap32s((uint32_t*)&lc->cmd);
262 bswap32s((uint32_t*)&lc->cmdsize);
263}
264
265
266void bswap_fh(struct fat_header *fh)
267{
268 bswap32s((uint32_t*)&fh->magic);
269 bswap32s((uint32_t*)&fh->nfat_arch);
270}
271
272void bswap_fa(struct fat_arch *fa)
273{
274 bswap32s((uint32_t*)&fa->cputype);
275 bswap32s((uint32_t*)&fa->cpusubtype);
276 bswap32s((uint32_t*)&fa->offset);
277 bswap32s((uint32_t*)&fa->size);
278 bswap32s((uint32_t*)&fa->align);
279}
280
281void bswap_segcmd(struct segment_command *sc)
282{
283 bswap32s((uint32_t*)&sc->vmaddr);
284 bswap32s((uint32_t*)&sc->vmsize);
285 bswap32s((uint32_t*)&sc->fileoff);
286 bswap32s((uint32_t*)&sc->filesize);
287 bswap32s((uint32_t*)&sc->maxprot);
288 bswap32s((uint32_t*)&sc->initprot);
289 bswap32s((uint32_t*)&sc->nsects);
290 bswap32s((uint32_t*)&sc->flags);
291}
292
293void bswap_symtabcmd(struct symtab_command *stc)
294{
295 bswap32s((uint32_t*)&stc->cmd);
296 bswap32s((uint32_t*)&stc->cmdsize);
297 bswap32s((uint32_t*)&stc->symoff);
298 bswap32s((uint32_t*)&stc->nsyms);
299 bswap32s((uint32_t*)&stc->stroff);
300 bswap32s((uint32_t*)&stc->strsize);
301}
302
303void bswap_sym(struct nlist *n)
304{
305 bswap32s((uint32_t*)&n->n_un.n_strx);
306 bswap16s((uint16_t*)&n->n_desc);
307 bswap32s((uint32_t*)&n->n_value);
308}
309
310int load_thread(struct mach_header *mh, struct target_thread_command *tc, struct target_pt_regs * regs, int fd, int mh_pos, int need_bswap)
311{
312 int entry;
313 if(need_bswap)
314 bswap_tc(tc);
315#if defined(TARGET_I386)
316 entry = tc->state.eip;
317 DPRINTF(" eax 0x%.8x\n ebx 0x%.8x\n ecx 0x%.8x\n edx 0x%.8x\n edi 0x%.8x\n esi 0x%.8x\n ebp 0x%.8x\n esp 0x%.8x\n ss 0x%.8x\n eflags 0x%.8x\n eip 0x%.8x\n cs 0x%.8x\n ds 0x%.8x\n es 0x%.8x\n fs 0x%.8x\n gs 0x%.8x\n",
318 tc->state.eax, tc->state.ebx, tc->state.ecx, tc->state.edx, tc->state.edi, tc->state.esi, tc->state.ebp,
319 tc->state.esp, tc->state.ss, tc->state.eflags, tc->state.eip, tc->state.cs, tc->state.ds, tc->state.es,
320 tc->state.fs, tc->state.gs );
321#define reg_copy(reg) regs->reg = tc->state.reg
322 if(regs)
323 {
324 reg_copy(eax);
325 reg_copy(ebx);
326 reg_copy(ecx);
327 reg_copy(edx);
328
329 reg_copy(edi);
330 reg_copy(esi);
331
332 reg_copy(ebp);
333 reg_copy(esp);
334
335 reg_copy(eflags);
336 reg_copy(eip);
337
338
339
340
341
342
343
344 }
345#undef reg_copy
346#elif defined(TARGET_PPC)
347 entry = tc->state.srr0;
348#endif
349 DPRINTF("load_thread: entry 0x%x\n", entry);
350 return entry;
351}
352
353int load_dylinker(struct mach_header *mh, struct dylinker_command *dc, int fd, int mh_pos, int need_bswap)
354{
355 int size;
356 char * dylinker_name;
357 size = dc->cmdsize - sizeof(struct dylinker_command);
358
359 if(need_bswap)
360 dylinker_name = (char*)(bswap_32(dc->name.offset)+(int)dc);
361 else
362 dylinker_name = (char*)((dc->name.offset)+(int)dc);
363
364#ifdef OVERRIDE_DYLINKER
365 dylinker_name = DYLINKER_NAME;
366#else
367 if(asprintf(&dylinker_name, "%s%s", interp_prefix, dylinker_name) == -1)
368 qerror("can't allocate the new dylinker name\n");
369#endif
370
371 DPRINTF("dylinker_name %s\n", dylinker_name);
372 return load_object(dylinker_name, NULL, NULL);
373}
374
375int load_segment(struct mach_header *mh, struct segment_command *sc, int fd, int mh_pos, int need_bswap, int fixed, int slide)
376{
377 unsigned long addr = sc->vmaddr;
378 unsigned long size = sc->filesize;
379 unsigned long error = 0;
380
381 if(need_bswap)
382 bswap_segcmd(sc);
383
384 if(sc->vmaddr == 0)
385 {
386 DPRINTF("load_segment: sc->vmaddr == 0 returning\n");
387 return -1;
388 }
389
390 if (strcmp(sc->segname, "__PAGEZERO") == 0)
391 {
392 DPRINTF("load_segment: __PAGEZERO returning\n");
393 return -1;
394 }
395
396
397
398 DPRINTF("load_segment: mmaping %s to 0x%x-(0x%x|0x%x) + 0x%x\n", sc->segname, sc->vmaddr, sc->filesize, sc->vmsize, slide);
399
400 if(sc->filesize > 0)
401 {
402 int opt = 0;
403
404 if(fixed)
405 opt |= MAP_FIXED;
406
407 DPRINTF("sc->vmaddr 0x%x slide 0x%x add 0x%x\n", slide, sc->vmaddr, sc->vmaddr+slide);
408
409 addr = target_mmap(sc->vmaddr+slide, sc->filesize, sc->initprot, opt, fd, mh_pos + sc->fileoff);
410
411 if(addr==-1)
412 qerror("load_segment: can't mmap at 0x%x\n", sc->vmaddr+slide);
413
414 error = addr-sc->vmaddr;
415 }
416 else
417 {
418 addr = sc->vmaddr+slide;
419 error = slide;
420 }
421
422 if(sc->vmsize > sc->filesize)
423 {
424 addr += sc->filesize;
425 size = sc->vmsize-sc->filesize;
426 addr = target_mmap(addr, size, sc->initprot, MAP_ANONYMOUS | MAP_FIXED, -1, 0);
427 if(addr==-1)
428 qerror("load_segment: can't mmap at 0x%x\n", sc->vmaddr+slide);
429 }
430
431 return error;
432}
433
434void *load_data(int fd, long offset, unsigned int size)
435{
436 char *data;
437
438 data = malloc(size);
439 if (!data)
440 return NULL;
441 lseek(fd, offset, SEEK_SET);
442 if (read(fd, data, size) != size) {
443 free(data);
444 return NULL;
445 }
446 return data;
447}
448
449
450int load_object(const char *filename, struct target_pt_regs * regs, void ** mh)
451{
452 int need_bswap = 0;
453 int entry_point = 0;
454 int dyld_entry_point = 0;
455 int slide, mmapfixed;
456 int fd;
457 struct load_command *lcmds, *lc;
458 int is_fat = 0;
459 unsigned int i, magic;
460 int mach_hdr_pos = 0;
461 struct mach_header mach_hdr;
462
463
464 struct symtab_command * symtabcmd = 0;
465 struct nlist_extended *symtab, *sym;
466 struct nlist *symtab_std, *syment;
467 char *strtab;
468
469 fd = open(filename, O_RDONLY);
470 if (fd < 0)
471 qerror("can't open file '%s'", filename);
472
473
474 if (read(fd, &magic, sizeof (magic)) != sizeof (magic))
475 qerror("unable to read Magic of '%s'", filename);
476
477
478 if(magic == MH_MAGIC)
479 {
480 is_fat = 0;
481 need_bswap = 0;
482 } else if (magic == MH_CIGAM)
483 {
484 is_fat = 0;
485 need_bswap = 1;
486 } else if (magic == FAT_MAGIC)
487 {
488 is_fat = 1;
489 need_bswap = 0;
490 } else if (magic == FAT_CIGAM)
491 {
492 is_fat = 1;
493 need_bswap = 1;
494 }
495 else
496 qerror("Not a Mach-O file.", filename);
497
498 DPRINTF("loading %s %s...\n", filename, is_fat ? "[FAT]": "[REGULAR]");
499 if(is_fat)
500 {
501 int found = 0;
502 struct fat_header fh;
503 struct fat_arch *fa;
504
505 lseek(fd, 0, SEEK_SET);
506
507
508 if (read(fd, &fh, sizeof (fh)) != sizeof (fh))
509 qerror("unable to read file header");
510
511 if(need_bswap)
512 bswap_fh(&fh);
513
514
515 fa = malloc(sizeof(struct fat_arch)*fh.nfat_arch);
516
517 if (read(fd, fa, sizeof(struct fat_arch)*fh.nfat_arch) != sizeof(struct fat_arch)*fh.nfat_arch)
518 qerror("unable to read file header");
519
520 for( i = 0; i < fh.nfat_arch; i++, fa++)
521 {
522 if(need_bswap)
523 bswap_fa(fa);
524 if(fa->cputype == TARGET_CPU_TYPE)
525 {
526 mach_hdr_pos = fa->offset;
527 lseek(fd, mach_hdr_pos, SEEK_SET);
528
529
530
531 if (read(fd, &mach_hdr, sizeof(struct mach_header)) != sizeof (struct mach_header))
532 qerror("unable to read file header");
533
534 if(mach_hdr.magic == MH_MAGIC)
535 need_bswap = 0;
536 else if (mach_hdr.magic == MH_CIGAM)
537 need_bswap = 1;
538 else
539 qerror("Invalid mach header in Fat Mach-O File");
540 found = 1;
541 break;
542 }
543 }
544 if(!found)
545 qerror("%s: No %s CPU found in FAT Header", filename, TARGET_CPU_NAME);
546 }
547 else
548 {
549 lseek(fd, 0, SEEK_SET);
550
551 if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))
552 qerror("%s: unable to read file header", filename);
553 }
554
555 if(need_bswap)
556 bswap_mh(&mach_hdr);
557
558 if ((mach_hdr.cputype) != TARGET_CPU_TYPE)
559 qerror("%s: Unsupported CPU 0x%x (only 0x%x(%s) supported)", filename, mach_hdr.cputype, TARGET_CPU_TYPE, TARGET_CPU_NAME);
560
561
562 switch(mach_hdr.filetype)
563 {
564 case MH_EXECUTE: break;
565 case MH_FVMLIB:
566 case MH_DYLIB:
567 case MH_DYLINKER: break;
568 default:
569 qerror("%s: Unsupported Mach type (0x%x)", filename, mach_hdr.filetype);
570 }
571
572
573 lcmds = malloc(mach_hdr.sizeofcmds);
574
575 if(read(fd, lcmds, mach_hdr.sizeofcmds) != mach_hdr.sizeofcmds)
576 qerror("%s: unable to read load_command", filename);
577 slide = 0;
578 mmapfixed = 0;
579 for(i=0, lc = lcmds; i < (mach_hdr.ncmds) ; i++)
580 {
581
582 if(need_bswap)
583 bswap_lc(lc);
584 switch(lc->cmd)
585 {
586 case LC_SEGMENT:
587
588 if(mach_hdr.filetype == MH_EXECUTE)
589 mmapfixed = 1;
590
591 slide = load_segment(&mach_hdr, (struct segment_command*)lc, fd, mach_hdr_pos, need_bswap, mmapfixed, slide);
592
593
594 if(slide != -1)
595 mmapfixed = 1;
596 else
597 slide = 0;
598
599 if(mach_hdr.filetype == MH_EXECUTE && slide != 0)
600 qerror("%s: Warning executable can't be mapped at the right address (offset: 0x%x)\n", filename, slide);
601
602 if(strcmp(((struct segment_command*)(lc))->segname, "__TEXT") == 0)
603 {
604
605 if(mach_hdr.filetype == MH_EXECUTE)
606 {
607
608 *mh = (void*)(((struct segment_command*)(lc))->vmaddr + slide);
609 }
610 else
611 {
612
613
614 macho_text_sect = (void*)(((struct segment_command*)(lc))->vmaddr + slide);
615 macho_offset = slide;
616 }
617 }
618 break;
619 case LC_LOAD_DYLINKER:
620 dyld_entry_point = load_dylinker( &mach_hdr, (struct dylinker_command*)lc, fd, mach_hdr_pos, need_bswap );
621 break;
622 case LC_LOAD_DYLIB:
623
624 break;
625 case LC_THREAD:
626 case LC_UNIXTHREAD:
627 {
628 struct target_pt_regs * _regs;
629 if(mach_hdr.filetype == MH_DYLINKER)
630 _regs = regs;
631 else
632 _regs = 0;
633 entry_point = load_thread( &mach_hdr, (struct target_thread_command*)lc, _regs, fd, mach_hdr_pos, need_bswap );
634 }
635 break;
636 case LC_SYMTAB:
637
638 symtabcmd = (struct symtab_command *)lc;
639 break;
640 case LC_ID_DYLINKER:
641 case LC_ID_DYLIB:
642 case LC_UUID:
643 case LC_DYSYMTAB:
644 case LC_TWOLEVEL_HINTS:
645 case LC_PREBIND_CKSUM:
646 case LC_SUB_LIBRARY:
647 break;
648 default: fprintf(stderr, "warning: unkown command 0x%x in '%s'\n", lc->cmd, filename);
649 }
650 lc = (struct load_command*)((int)(lc)+(lc->cmdsize));
651 }
652
653 if(symtabcmd)
654 {
655 if(need_bswap)
656 bswap_symtabcmd(symtabcmd);
657
658 symtab_std = load_data(fd, symtabcmd->symoff+mach_hdr_pos, symtabcmd->nsyms * sizeof(struct nlist));
659 strtab = load_data(fd, symtabcmd->stroff+mach_hdr_pos, symtabcmd->strsize);
660
661 symtab = malloc(sizeof(struct nlist_extended) * symtabcmd->nsyms);
662
663 if(need_bswap)
664 {
665 for(i = 0, syment = symtab_std; i < symtabcmd->nsyms; i++, syment++)
666 bswap_sym(syment);
667 }
668
669 for(i = 0, sym = symtab, syment = symtab_std; i < symtabcmd->nsyms; i++, sym++, syment++)
670 {
671 struct nlist *sym_follow, *sym_next = 0;
672 unsigned int j;
673 memset(sym, 0, sizeof(*sym));
674
675 sym->n_type = syment->n_type;
676 if ( syment->n_type & N_STAB )
677 continue;
678
679 memcpy(sym, syment, sizeof(*syment));
680
681
682 for(j = 0, sym_follow = symtab_std; j < symtabcmd->nsyms; j++, sym_follow++) {
683 if ( sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
684 continue;
685 if(!sym_next) {
686 sym_next = sym_follow;
687 continue;
688 }
689 if(!(sym_next->n_value > sym_follow->n_value))
690 continue;
691 sym_next = sym_follow;
692 }
693 if(sym_next)
694 sym->st_size = sym_next->n_value - sym->st_value;
695 else
696 sym->st_size = 10;
697
698 sym->st_value += slide;
699 }
700
701 free((void*)symtab_std);
702
703 {
704 DPRINTF("saving symtab of %s (%d symbol(s))\n", filename, symtabcmd->nsyms);
705 struct syminfo *s;
706 s = malloc(sizeof(*s));
707 s->disas_symtab = symtab;
708 s->disas_strtab = strtab;
709 s->disas_num_syms = symtabcmd->nsyms;
710 s->next = syminfos;
711 syminfos = s;
712 }
713 }
714 close(fd);
715 if(mach_hdr.filetype == MH_EXECUTE && dyld_entry_point)
716 return dyld_entry_point;
717 else
718 return entry_point+slide;
719}
720
721extern unsigned long stack_size;
722
723unsigned long setup_arg_pages(void * mh, char ** argv, char ** env)
724{
725 unsigned long stack_base, error, size;
726 int i;
727 int * stack;
728 int argc, envc;
729
730
731
732
733 size = stack_size;
734
735 error = target_mmap(0,
736 size + qemu_host_page_size,
737 PROT_READ | PROT_WRITE,
738 MAP_PRIVATE | MAP_ANONYMOUS,
739 -1, 0);
740 if (error == -1)
741 qerror("stk mmap");
742
743
744 target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
745
746 stack_base = error + size;
747 stack = (void*)stack_base;
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783 stack--;
784
785
786
787 *stack = 0;
788 stack--;
789
790
791 DPRINTF("pushing apple %s (0x%x)\n", (char*)argv[0], (int)argv[0]);
792 stl(stack, (int) argv[0]);
793
794 stack--;
795
796 stl(stack, 0);
797 stack--;
798
799
800 for(envc = 0; env[envc]; envc++);
801
802 for(i = envc-1; i >= 0; i--)
803 {
804 DPRINTF("pushing env %s (0x%x)\n", (char*)env[i], (int)env[i]);
805 stl(stack, (int)env[i]);
806 stack--;
807
808
809 page_set_flags((int)env[i], (int)(env[i]+strlen(env[i])), PROT_READ | PAGE_VALID);
810 }
811
812
813 if(interp_prefix[0])
814 {
815 char *dyld_root;
816 asprintf(&dyld_root, "DYLD_ROOT_PATH=%s", interp_prefix);
817 page_set_flags((int)dyld_root, (int)(dyld_root+strlen(interp_prefix)+1), PROT_READ | PAGE_VALID);
818
819 stl(stack, (int)dyld_root);
820 stack--;
821 }
822
823#ifdef DONT_USE_DYLD_SHARED_MAP
824 {
825 char *shared_map_mode;
826 asprintf(&shared_map_mode, "DYLD_SHARED_REGION=avoid");
827 page_set_flags((int)shared_map_mode, (int)(shared_map_mode+strlen(shared_map_mode)+1), PROT_READ | PAGE_VALID);
828
829 stl(stack, (int)shared_map_mode);
830 stack--;
831 }
832#endif
833
834#ifdef ACTIVATE_DYLD_TRACE
835 char * extra_env_static[] = {"DYLD_DEBUG_TRACE=yes",
836 "DYLD_PREBIND_DEBUG=3", "DYLD_UNKNOW_TRACE=yes",
837 "DYLD_PRINT_INITIALIZERS=yes",
838 "DYLD_PRINT_SEGMENTS=yes", "DYLD_PRINT_REBASINGS=yes", "DYLD_PRINT_BINDINGS=yes", "DYLD_PRINT_INITIALIZERS=yes", "DYLD_PRINT_WARNINGS=yes" };
839
840 char ** extra_env = malloc(sizeof(extra_env_static));
841 bcopy(extra_env_static, extra_env, sizeof(extra_env_static));
842 page_set_flags((int)extra_env, (int)((void*)extra_env+sizeof(extra_env_static)), PROT_READ | PAGE_VALID);
843
844 for(i = 0; i<9; i++)
845 {
846 DPRINTF("pushing (extra) env %s (0x%x)\n", (char*)extra_env[i], (int)extra_env[i]);
847 stl(stack, (int) extra_env[i]);
848 stack--;
849 }
850#endif
851
852 stl(stack, 0);
853 stack--;
854
855
856 for(argc = 0; argv[argc]; argc++);
857
858 for(i = argc-1; i >= 0; i--)
859 {
860 DPRINTF("pushing arg %s (0x%x)\n", (char*)argv[i], (int)argv[i]);
861 stl(stack, (int) argv[i]);
862 stack--;
863
864
865 page_set_flags((int)argv[i], (int)(argv[i]+strlen(argv[i])), PROT_READ | PAGE_VALID);
866 }
867
868 DPRINTF("pushing argc %d \n", argc);
869 stl(stack, argc);
870 stack--;
871
872 DPRINTF("pushing mh 0x%x \n", (int)mh);
873 stl(stack, (int) mh);
874
875
876 return (unsigned long)stack;
877}
878
879int mach_exec(const char * filename, char ** argv, char ** envp,
880 struct target_pt_regs * regs)
881{
882 int entrypoint, stack;
883 void * mh;
884
885 DPRINTF("mach_exec at 0x%x\n", (int)mach_exec);
886
887 entrypoint = load_object(filename, regs, &mh);
888 stack = setup_arg_pages(mh, argv, envp);
889#if defined(TARGET_I386)
890 regs->eip = entrypoint;
891 regs->esp = stack;
892#elif defined(TARGET_PPC)
893 regs->nip = entrypoint;
894 regs->gpr[1] = stack;
895#endif
896 DPRINTF("mach_exec returns eip set to 0x%x esp 0x%x mh 0x%x\n", entrypoint, stack, (int)mh);
897
898 if(!entrypoint)
899 qerror("%s: no entry point!\n", filename);
900
901 return 0;
902}
903