Revamp powerpc{,64le,64}.
Fix 64-bit stack frame (8*8 bytes for spilling a0-a7). Avoid using r2 (t0). Prepare for -pie executables. Prepare for unified strategy in stubs. modified: p_lx_elf.cpp modified: stub/src/amd64-linux.elf-main.c modified: stub/src/arch/powerpc/32/bxx.S modified: stub/src/arch/powerpc/32/lzma_d.S modified: stub/src/arch/powerpc/32/nrv2b_d.S modified: stub/src/arch/powerpc/32/nrv2d_d.S modified: stub/src/arch/powerpc/32/nrv2e_d.S modified: stub/src/arch/powerpc/32/ppc_regs.h new file: stub/src/arch/powerpc/64/Makefile new file: stub/src/arch/powerpc/64/Makefile.extra new file: stub/src/arch/powerpc/64/lzma_d.S new file: stub/src/arch/powerpc/64/lzma_d_cf.S new file: stub/src/arch/powerpc/64/lzma_d_cs.S modified: stub/src/arch/powerpc/64le/bxx.S copied: stub/src/arch/powerpc/64le/lzma_d.S -> stub/src/arch/powerpc/64le/lzma_d-common.S modified: stub/src/arch/powerpc/64le/lzma_d.S modified: stub/src/arch/powerpc/64le/lzma_d_cs.S modified: stub/src/arch/powerpc/64le/nrv2b_d.S modified: stub/src/arch/powerpc/64le/nrv2d_d.S modified: stub/src/arch/powerpc/64le/nrv2e_d.S modified: stub/src/arch/powerpc/64le/ppc_regs.h modified: stub/src/i386-darwin.macho-entry.S modified: stub/src/powerpc-darwin.dylib-entry.S modified: stub/src/powerpc-darwin.macho-entry.S modified: stub/src/powerpc-darwin.macho-fold.S modified: stub/src/powerpc-linux.elf-entry.S modified: stub/src/powerpc-linux.elf-fold.S modified: stub/src/powerpc-linux.elf-main.c modified: stub/src/powerpc64-darwin.dylib-entry.S modified: stub/src/powerpc64-darwin.macho-entry.S modified: stub/src/powerpc64-darwin.macho-fold.S modified: stub/src/powerpc64-darwin.macho-main.c modified: stub/src/powerpc64-linux.elf-main.c modified: stub/src/powerpc64-savegpr0.S modified: stub/src/powerpc64le-darwin.dylib-entry.S modified: stub/src/powerpc64le-darwin.macho-entry.S modified: stub/src/powerpc64le-darwin.macho-fold.S modified: stub/src/powerpc64le-linux.elf-entry.S modified: stub/src/powerpc64le-linux.elf-fold.S modified: stub/i386-darwin.macho-entry.h modified: stub/powerpc-darwin.dylib-entry.h modified: stub/powerpc-darwin.macho-entry.h modified: stub/powerpc-darwin.macho-fold.h modified: stub/powerpc-linux.elf-entry.h modified: stub/powerpc-linux.elf-fold.h modified: stub/powerpc-linux.kernel.vmlinux.h modified: stub/powerpc64-linux.elf-entry.h modified: stub/powerpc64-linux.elf-fold.h modified: stub/powerpc64le-darwin.dylib-entry.h modified: stub/powerpc64le-darwin.macho-entry.h modified: stub/powerpc64le-darwin.macho-fold.h modified: stub/powerpc64le-linux.elf-entry.h modified: stub/powerpc64le-linux.elf-fold.h modified: stub/powerpc64le-linux.kernel.vmlinux.h modified: stub/tmp/i386-darwin.macho-entry.bin.dump modified: stub/tmp/powerpc-darwin.dylib-entry.bin.dump modified: stub/tmp/powerpc-darwin.macho-entry.bin.dump modified: stub/tmp/powerpc-linux.elf-entry.bin.dump modified: stub/tmp/powerpc-linux.elf-fold.map modified: stub/tmp/powerpc64le-darwin.dylib-entry.bin.dump modified: stub/tmp/powerpc64le-darwin.macho-entry.bin.dump modified: stub/tmp/powerpc64le-linux.elf-entry.bin.dump modified: stub/tmp/powerpc64le-linux.elf-fold.map modified: stub/tmp/powerpc64le-linux.kernel.vmlinux.bin.dump
This commit is contained in:
+69
-6
@@ -516,7 +516,7 @@ PackLinuxElf::addStubEntrySections(Filter const *)
|
||||
if (hasLoaderSection("ELFMAINXu")) {
|
||||
// brk() trouble if static
|
||||
all_pages |= (Elf32_Ehdr::EM_ARM==e_machine && 0x8000==load_va);
|
||||
addLoader(/*(all_pages ? "LUNMP000" : "LUNMP001"),*/ "ELFMAINXu", NULL);
|
||||
addLoader("ELFMAINXu", NULL);
|
||||
}
|
||||
//addLoader(getDecompressorSections(), NULL);
|
||||
addLoader(
|
||||
@@ -533,7 +533,7 @@ PackLinuxElf::addStubEntrySections(Filter const *)
|
||||
}
|
||||
addLoader("+40,ELFMAINZ", NULL);
|
||||
if (hasLoaderSection("ELFMAINZu")) {
|
||||
addLoader(/*(all_pages ? "LUNMP000" : "LUNMP001"),*/ "ELFMAINZu", NULL);
|
||||
addLoader("ELFMAINZu", NULL);
|
||||
}
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
}
|
||||
@@ -547,6 +547,54 @@ void PackLinuxElf::defineSymbols(Filter const *)
|
||||
void PackLinuxElf32::defineSymbols(Filter const *ft)
|
||||
{
|
||||
PackLinuxElf::defineSymbols(ft);
|
||||
|
||||
// We want to know if compressed data, plus stub, plus a couple pages,
|
||||
// will fit below the uncompressed program in memory. But we don't
|
||||
// know the final total compressed size yet, so use the uncompressed
|
||||
// size (total over all PT_LOAD32) as an upper bound.
|
||||
unsigned len = 0; // XXX: 4GB
|
||||
upx_uint32_t lo_va_user = ~0u; // infinity
|
||||
for (int j= e_phnum; --j>=0; ) {
|
||||
if (PT_LOAD32 == get_te32(&phdri[j].p_type)) {
|
||||
len += (unsigned)get_te32(&phdri[j].p_filesz);
|
||||
upx_uint32_t const va = get_te32(&phdri[j].p_vaddr);
|
||||
if (va < lo_va_user) {
|
||||
lo_va_user = va;
|
||||
}
|
||||
}
|
||||
}
|
||||
lsize = /*getLoaderSize()*/ 64 * 1024; // XXX: upper bound; avoid circularity
|
||||
upx_uint32_t lo_va_stub = get_te32(&elfout.phdr[0].p_vaddr);
|
||||
upx_uint32_t adrm;
|
||||
unsigned lenm;
|
||||
unsigned lenu;
|
||||
len += (7&-lsize) + lsize;
|
||||
upx_uint32_t my_page_size = 4096u;
|
||||
upx_uint32_t my_page_mask = -my_page_size;
|
||||
is_big = (lo_va_user < (lo_va_stub + len + 2 * my_page_size));
|
||||
if (is_pie || (is_big /*&& ehdri.ET_EXEC==get_te16(&ehdri.e_type)*/)) {
|
||||
// .e_entry is set later by PackLinuxElf32::updateLoader
|
||||
set_te32( &elfout.ehdr.e_entry,
|
||||
get_te32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);
|
||||
set_te32(&elfout.phdr[0].p_vaddr, lo_va_user);
|
||||
set_te32(&elfout.phdr[0].p_paddr, lo_va_user);
|
||||
lo_va_stub = lo_va_user;
|
||||
adrm = getbrk(phdri, e_phnum) - lo_va_user;
|
||||
lenm = my_page_size + len;
|
||||
lenu = my_page_size + len;
|
||||
}
|
||||
else {
|
||||
adrm = len;
|
||||
lenm = my_page_size;
|
||||
lenu = my_page_size + len;
|
||||
}
|
||||
adrm = my_page_mask & (~my_page_mask + adrm); // round up to page boundary
|
||||
|
||||
linker->defineSymbol("LENU", lenu); // len for unmap
|
||||
linker->defineSymbol("LENM", lenm); // len for map
|
||||
linker->defineSymbol("ADRM", adrm); // offset from &Elf32_Ehdr
|
||||
|
||||
//linker->dumpSymbols(); // debug
|
||||
}
|
||||
|
||||
void PackLinuxElf64::defineSymbols(Filter const *ft)
|
||||
@@ -765,8 +813,9 @@ void PackLinuxElf32mipseb::updateLoader(OutputFile *fo)
|
||||
|
||||
void PackLinuxElf32::updateLoader(OutputFile * /*fo*/)
|
||||
{
|
||||
set_te32(&elfout.ehdr.e_entry, sz_pack2 +
|
||||
get_te32(&elfout.phdr[0].p_vaddr));
|
||||
unsigned start = linker->getSymbolOffset("_start");
|
||||
unsigned vbase = get_te32(&elfout.phdr[0].p_vaddr);
|
||||
set_te32(&elfout.ehdr.e_entry, start + sz_pack2 + vbase);
|
||||
}
|
||||
|
||||
void PackLinuxElf64::updateLoader(OutputFile * /*fo*/)
|
||||
@@ -959,8 +1008,7 @@ void PackLinuxElf32x86::addStubEntrySections(Filter const *ft)
|
||||
if (Elf32_Ehdr::ET_DYN==get_te16(&ehdri.e_type)) {
|
||||
addLoader("LEXECDYN", NULL);
|
||||
}
|
||||
addLoader(/*((opt->o_unix.unmap_all_pages|is_big) ? "LUNMP000" : "LUNMP001"),*/
|
||||
"LEXEC025", NULL);
|
||||
addLoader("LEXEC025", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
}
|
||||
|
||||
@@ -1080,6 +1128,21 @@ PackLinuxElf64::buildLinuxLoader(
|
||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
||||
throwInternalError("loader compression failed");
|
||||
}
|
||||
#if 1 //{ debugging only
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
ucl_uint tmp_len = h.sz_unc; // LZMA uses this as EOF
|
||||
unsigned char *tmp = New(unsigned char, tmp_len);
|
||||
memset(tmp, 0, tmp_len);
|
||||
int r = upx_decompress(sizeof(h) + cprLoader, h.sz_cpr, tmp, &tmp_len, h.b_method, NULL);
|
||||
if (r == UPX_E_OUT_OF_MEMORY)
|
||||
throwOutOfMemoryException();
|
||||
printf("\n%d %d: %d %d %d\n", h.b_method, r, h.sz_cpr, h.sz_unc, tmp_len);
|
||||
for (unsigned j=0; j < h.sz_unc; ++j) if (tmp[j]!=uncLoader[j]) {
|
||||
printf("%d: %x %x\n", j, tmp[j], uncLoader[j]);
|
||||
}
|
||||
delete[] tmp;
|
||||
}
|
||||
#endif //}
|
||||
unsigned const sz_cpr = h.sz_cpr;
|
||||
set_te32(&h.sz_cpr, h.sz_cpr);
|
||||
set_te32(&h.sz_unc, h.sz_unc);
|
||||
|
||||
Reference in New Issue
Block a user