64-bit Power PC linux uses 64KiB page size, but qemu-ppc64{,le} uses 4KiB.

modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/include/linux.h
	modified:   stub/src/powerpc64le-linux.elf-fold.S
This commit is contained in:
John Reiser
2017-09-24 20:24:46 -07:00
parent 6470c748db
commit 63aea4a7dc
3 changed files with 41 additions and 12 deletions
+29 -7
View File
@@ -144,6 +144,8 @@ unpackExtent(
f_unfilter *f_unf 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) { while (xo->size) {
struct b_info h; struct b_info h;
// Note: if h.sz_unc == h.sz_cpr then the block was not // Note: if h.sz_unc == h.sz_cpr then the block was not
@@ -235,6 +237,7 @@ make_hatch_ppc64(
static void static void
upx_bzero(char *p, size_t len) upx_bzero(char *p, size_t len)
{ {
DPRINTF("bzero %%x %%x\\n", p, len);
if (len) do { if (len) do {
*p++= 0; *p++= 0;
} while (--len); } 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 static Elf64_Addr // returns relocation constant
xfind_pages(unsigned mflags, Elf64_Phdr const *phdr, int phnum, xfind_pages(unsigned mflags, Elf64_Phdr const *phdr, int phnum,
char **const p_brk char **const p_brk
#if defined(__powerpc64__)
, size_t const PAGE_MASK
#endif
) )
{ {
size_t lo= ~0, hi= 0, szlo= 0; size_t lo= ~0, hi= 0, szlo= 0;
@@ -312,14 +318,21 @@ do_xmap(
f_expand *const f_exp, f_expand *const f_exp,
f_unfilter *const f_unf, f_unfilter *const f_unf,
Elf64_Addr *p_reloc 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 + Elf64_Phdr const *phdr = (Elf64_Phdr const *)(void const *)(ehdr->e_phoff +
(char const *)ehdr); (char const *)ehdr);
char *v_brk; char *v_brk;
Elf64_Addr const reloc = xfind_pages( Elf64_Addr const reloc = xfind_pages(
((ET_DYN!=ehdr->e_type) ? MAP_FIXED : 0), phdr, ehdr->e_phnum, &v_brk); ((ET_DYN!=ehdr->e_type) ? MAP_FIXED : 0), phdr, ehdr->e_phnum, &v_brk
DPRINTF("do_xmap reloc=%%p", reloc); #if defined(__powerpc64__)
, PAGE_MASK
#endif
);
DPRINTF("do_xmap reloc=%%p\\n", reloc);
int j; int j;
for (j=0; j < ehdr->e_phnum; ++phdr, ++j) for (j=0; j < ehdr->e_phnum; ++phdr, ++j)
if (xi && PT_PHDR==phdr->p_type) { 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_Ehdr *const ehdr, // temp char[sz_ehdr] for decompressing
Elf64_auxv_t *const av, Elf64_auxv_t *const av,
f_expand *const f_exp, f_expand *const f_exp,
f_unfilter *const f_unf, f_unfilter *const f_unf
#if defined(__x86_64) //{ #if defined(__x86_64) //{
Elf64_Addr reloc // In: &Elf64_Ehdr for stub , Elf64_Addr reloc // In: &Elf64_Ehdr for stub
#elif defined(__powerpc64__) //}{ #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 //} #endif //}
) )
{ {
@@ -447,7 +461,11 @@ upx_main( // returns entry address
} }
// De-compress Ehdr again into actual position, then de-compress the rest. // 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); DPRINTF("upx_main2 entry=%%p *p_reloc=%%p\\n", entry, *p_reloc);
auxv_up(av, AT_ENTRY , entry); auxv_up(av, AT_ENTRY , entry);
@@ -466,7 +484,11 @@ ERR_LAB
} }
// We expect PT_INTERP to be ET_DYN at 0. // We expect PT_INTERP to be ET_DYN at 0.
// Thus do_xmap will set *p_reloc = slide. // 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 auxv_up(av, AT_BASE, *p_reloc); // musl
close(fdi); close(fdi);
} }
+9 -4
View File
@@ -90,16 +90,21 @@ struct timespec {
// misc constants // 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_MASK (~0ul<<16) // discards the offset, keeps the page
#define PAGE_SIZE ( 1ul<<16) #define PAGE_SIZE ( 1ul<<16)
#elif defined(__amd64__) #elif defined(__amd64__) //}{
#define PAGE_MASK (~0ul<<12) // discards the offset, keeps the page #define PAGE_MASK (~0ul<<12) // discards the offset, keeps the page
#define PAGE_SIZE ( 1ul<<12) #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_MASK (~0ul<<12) // discards the offset, keeps the page
#define PAGE_SIZE ( 1ul<<12) #define PAGE_SIZE ( 1ul<<12)
#endif #endif //}
#define SEEK_SET 0 #define SEEK_SET 0
#define SEEK_CUR 1 #define SEEK_CUR 1
+3 -1
View File
@@ -175,13 +175,15 @@ r_reloc= 32 - 1 # used slot in register save area
mr a3,r_auxv // &Elf64_auxv_t mr a3,r_auxv // &Elf64_auxv_t
mr a4,r_exp // &decompress: f_expand mr a4,r_exp // &decompress: f_expand
mr a5,r_unf // &f_unf 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 #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 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 std a5,4*NBPW(sp); la a5,4*NBPW(sp) // use tmp.ld
#endif //} #endif //}
call upx_main // Out: a0= entry call upx_main // Out: a0= entry
// entry= upx_main(b_info *a0, total_size a1, Elf_Ehdr *a2, Elf64_auxv_t *a3, // 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 //{ #if BIG_ENDIAN //{
ld r0,SZ_FRAME+OVERHEAD +SZ_FRAME+r_reloc*NBPW(sp) // reloc for ET_DYN ld r0,SZ_FRAME+OVERHEAD +SZ_FRAME+r_reloc*NBPW(sp) // reloc for ET_DYN
ld r2,NBPW(r3); add r2,r2,r0 // toc ld r2,NBPW(r3); add r2,r2,r0 // toc