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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user