diff --git a/src/stub/src/amd64-linux.elf-main.c b/src/stub/src/amd64-linux.elf-main.c index 05cdc34c..3a496d14 100644 --- a/src/stub/src/amd64-linux.elf-main.c +++ b/src/stub/src/amd64-linux.elf-main.c @@ -144,6 +144,8 @@ unpackExtent( f_unfilter *f_unf ) { + DPRINTF("unpackExtent xi=(%%p %%p) xo=(%%p %%p) f_exp=%%p f_unf=%%p\\n", + xi->size, xi->buf, xo->size, xo->buf, f_exp, f_unf); while (xo->size) { struct b_info h; // Note: if h.sz_unc == h.sz_cpr then the block was not @@ -235,6 +237,7 @@ make_hatch_ppc64( static void upx_bzero(char *p, size_t len) { + DPRINTF("bzero %%x %%x\\n", p, len); if (len) do { *p++= 0; } while (--len); @@ -279,6 +282,9 @@ auxv_up(Elf64_auxv_t *av, unsigned const type, uint64_t const value) static Elf64_Addr // returns relocation constant xfind_pages(unsigned mflags, Elf64_Phdr const *phdr, int phnum, char **const p_brk +#if defined(__powerpc64__) + , size_t const PAGE_MASK +#endif ) { size_t lo= ~0, hi= 0, szlo= 0; @@ -312,14 +318,21 @@ do_xmap( f_expand *const f_exp, f_unfilter *const f_unf, Elf64_Addr *p_reloc +#if defined(__powerpc64__) + , size_t const PAGE_MASK +#endif ) { Elf64_Phdr const *phdr = (Elf64_Phdr const *)(void const *)(ehdr->e_phoff + (char const *)ehdr); char *v_brk; Elf64_Addr const reloc = xfind_pages( - ((ET_DYN!=ehdr->e_type) ? MAP_FIXED : 0), phdr, ehdr->e_phnum, &v_brk); - DPRINTF("do_xmap reloc=%%p", reloc); + ((ET_DYN!=ehdr->e_type) ? MAP_FIXED : 0), phdr, ehdr->e_phnum, &v_brk +#if defined(__powerpc64__) + , PAGE_MASK +#endif + ); + DPRINTF("do_xmap reloc=%%p\\n", reloc); int j; for (j=0; j < ehdr->e_phnum; ++phdr, ++j) if (xi && PT_PHDR==phdr->p_type) { @@ -410,11 +423,12 @@ upx_main( // returns entry address Elf64_Ehdr *const ehdr, // temp char[sz_ehdr] for decompressing Elf64_auxv_t *const av, f_expand *const f_exp, - f_unfilter *const f_unf, + f_unfilter *const f_unf #if defined(__x86_64) //{ - Elf64_Addr reloc // In: &Elf64_Ehdr for stub + , Elf64_Addr reloc // In: &Elf64_Ehdr for stub #elif defined(__powerpc64__) //}{ - Elf64_Addr *p_reloc // In: &Elf64_Ehdr for stub; Out: 'slide' for PT_INTERP + , Elf64_Addr *p_reloc // In: &Elf64_Ehdr for stub; Out: 'slide' for PT_INTERP + , size_t const PAGE_MASK #endif //} ) { @@ -447,7 +461,11 @@ upx_main( // returns entry address } // De-compress Ehdr again into actual position, then de-compress the rest. - Elf64_Addr entry = do_xmap(ehdr, &xi1, 0, av, f_exp, f_unf, p_reloc); + Elf64_Addr entry = do_xmap(ehdr, &xi1, 0, av, f_exp, f_unf, p_reloc +#if defined(__powerpc64__) + , PAGE_MASK +#endif + ); DPRINTF("upx_main2 entry=%%p *p_reloc=%%p\\n", entry, *p_reloc); auxv_up(av, AT_ENTRY , entry); @@ -466,7 +484,11 @@ ERR_LAB } // We expect PT_INTERP to be ET_DYN at 0. // Thus do_xmap will set *p_reloc = slide. - entry = do_xmap(ehdr, 0, fdi, 0, 0, 0, p_reloc); + entry = do_xmap(ehdr, 0, fdi, 0, 0, 0, p_reloc +#if defined(__powerpc64__) + , PAGE_MASK +#endif + ); auxv_up(av, AT_BASE, *p_reloc); // musl close(fdi); } diff --git a/src/stub/src/include/linux.h b/src/stub/src/include/linux.h index 671bdc4d..dc37a8d8 100644 --- a/src/stub/src/include/linux.h +++ b/src/stub/src/include/linux.h @@ -90,16 +90,21 @@ struct timespec { // misc constants -#if defined(__mips__) || defined(__powerpc64__) +#if defined(__powerpc64__) //{ +// __powerpc64__ hardware uses 64KiB in 64-bit mode, 4KiB in 32-bit mode. +// EXCEPT qemu-ppc64 uses 4KiB in 64-bit mode, too. +// So PAGE_SIZE is not constant in 64-bit mode of __powerpc64__. + // empty: not constant, must use run-time value from AT_PAGESZ +#elif defined(__mips__) //}{ #define PAGE_MASK (~0ul<<16) // discards the offset, keeps the page #define PAGE_SIZE ( 1ul<<16) -#elif defined(__amd64__) +#elif defined(__amd64__) //}{ #define PAGE_MASK (~0ul<<12) // discards the offset, keeps the page #define PAGE_SIZE ( 1ul<<12) -#elif defined(__i386__) || defined(__powerpc__) || defined(__arm__) || defined(__AARCH64EL__) +#elif defined(__i386__) || defined(__powerpc__) || defined(__arm__) || defined(__AARCH64EL__) //}{ #define PAGE_MASK (~0ul<<12) // discards the offset, keeps the page #define PAGE_SIZE ( 1ul<<12) -#endif +#endif //} #define SEEK_SET 0 #define SEEK_CUR 1 diff --git a/src/stub/src/powerpc64le-linux.elf-fold.S b/src/stub/src/powerpc64le-linux.elf-fold.S index 2484943c..26c5736f 100644 --- a/src/stub/src/powerpc64le-linux.elf-fold.S +++ b/src/stub/src/powerpc64le-linux.elf-fold.S @@ -175,13 +175,15 @@ r_reloc= 32 - 1 # used slot in register save area mr a3,r_auxv // &Elf64_auxv_t mr a4,r_exp // &decompress: f_expand mr a5,r_unf // &f_unf + mr a7,r_PMASK // page_mask #if BIG_ENDIAN //{ setup indirection for entry to f_exp and f_unf std a4,3*NBPW(sp); la a4,3*NBPW(sp) // use tmp.xlc std a5,4*NBPW(sp); la a5,4*NBPW(sp) // use tmp.ld #endif //} call upx_main // Out: a0= entry // entry= upx_main(b_info *a0, total_size a1, Elf_Ehdr *a2, Elf64_auxv_t *a3, -// f_exp a4, f_unf a5, p_reloc a6) +// f_exp a4, f_unf a5, p_reloc a6, page_mask a7) + teq r0,r0 #if BIG_ENDIAN //{ ld r0,SZ_FRAME+OVERHEAD +SZ_FRAME+r_reloc*NBPW(sp) // reloc for ET_DYN ld r2,NBPW(r3); add r2,r2,r0 // toc