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; |