Commit 853d6f7a835ff33cf53f2922e4039d4cfad8ac17
1 parent
93ac68bc
sparc support - hack to fix case where real_host_page_size < TARGET_PAGE_SIZE (t…
…ypically sparc target case) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@389 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
42 additions
and
7 deletions
linux-user/elfload.c
@@ -83,6 +83,27 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i | @@ -83,6 +83,27 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i | ||
83 | 83 | ||
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | +#ifdef TARGET_SPARC | ||
87 | + | ||
88 | +#define ELF_START_MMAP 0x80000000 | ||
89 | + | ||
90 | +#define elf_check_arch(x) ( (x) == EM_SPARC ) | ||
91 | + | ||
92 | +#define ELF_CLASS ELFCLASS32 | ||
93 | +#define ELF_DATA ELFDATA2MSB | ||
94 | +#define ELF_ARCH EM_SPARC | ||
95 | + | ||
96 | +/*XXX*/ | ||
97 | +#define ELF_PLAT_INIT(_r) | ||
98 | + | ||
99 | +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) | ||
100 | +{ | ||
101 | + regs->u_regs[0] = infop->entry; | ||
102 | + regs->u_regs[1] = infop->start_stack; | ||
103 | +} | ||
104 | + | ||
105 | +#endif | ||
106 | + | ||
86 | #include "elf.h" | 107 | #include "elf.h" |
87 | 108 | ||
88 | /* | 109 | /* |
@@ -456,18 +477,32 @@ static void set_brk(unsigned long start, unsigned long end) | @@ -456,18 +477,32 @@ static void set_brk(unsigned long start, unsigned long end) | ||
456 | } | 477 | } |
457 | 478 | ||
458 | 479 | ||
459 | -/* We need to explicitly zero any fractional pages | ||
460 | - after the data section (i.e. bss). This would | ||
461 | - contain the junk from the file that should not | ||
462 | - be in memory */ | ||
463 | - | ||
464 | - | 480 | +/* We need to explicitly zero any fractional pages after the data |
481 | + section (i.e. bss). This would contain the junk from the file that | ||
482 | + should not be in memory. */ | ||
465 | static void padzero(unsigned long elf_bss) | 483 | static void padzero(unsigned long elf_bss) |
466 | { | 484 | { |
467 | unsigned long nbyte; | 485 | unsigned long nbyte; |
468 | char * fpnt; | 486 | char * fpnt; |
469 | 487 | ||
470 | - nbyte = elf_bss & (host_page_size-1); /* was TARGET_PAGE_SIZE - JRP */ | 488 | + /* XXX: this is really a hack : if the real host page size is |
489 | + smaller than the target page size, some pages after the end | ||
490 | + of the file may not be mapped. A better fix would be to | ||
491 | + patch target_mmap(), but it is more complicated as the file | ||
492 | + size must be known */ | ||
493 | + if (real_host_page_size < host_page_size) { | ||
494 | + unsigned long end_addr, end_addr1; | ||
495 | + end_addr1 = (elf_bss + real_host_page_size - 1) & | ||
496 | + ~(real_host_page_size - 1); | ||
497 | + end_addr = HOST_PAGE_ALIGN(elf_bss); | ||
498 | + if (end_addr1 < end_addr) { | ||
499 | + mmap((void *)end_addr1, end_addr - end_addr1, | ||
500 | + PROT_READ|PROT_WRITE|PROT_EXEC, | ||
501 | + MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | ||
502 | + } | ||
503 | + } | ||
504 | + | ||
505 | + nbyte = elf_bss & (host_page_size-1); | ||
471 | if (nbyte) { | 506 | if (nbyte) { |
472 | nbyte = host_page_size - nbyte; | 507 | nbyte = host_page_size - nbyte; |
473 | fpnt = (char *) elf_bss; | 508 | fpnt = (char *) elf_bss; |