amd64: stub uses new strategy
modified: stub/src/amd64-linux.elf-entry.S modified: stub/src/amd64-linux.elf-fold.S modified: p_lx_elf.cpp also .h, .bin.dump, .map
This commit is contained in:
@@ -1173,54 +1173,6 @@ void
|
||||
PackLinuxElf64amd::defineSymbols(Filter const *ft)
|
||||
{
|
||||
PackLinuxElf64::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_LOAD64) as an upper bound.
|
||||
unsigned len = 0; // XXX: 4GB
|
||||
upx_uint64_t lo_va_user = ~0ull; // infinity
|
||||
for (int j= e_phnum; --j>=0; ) {
|
||||
if (PT_LOAD64 == get_te32(&phdri[j].p_type)) {
|
||||
len += (unsigned)get_te64(&phdri[j].p_filesz);
|
||||
upx_uint64_t const va = get_te64(&phdri[j].p_vaddr);
|
||||
if (va < lo_va_user) {
|
||||
lo_va_user = va;
|
||||
}
|
||||
}
|
||||
}
|
||||
lsize = /*getLoaderSize()*/ 64 * 1024; // XXX: upper bound; avoid circularity
|
||||
upx_uint64_t lo_va_stub = get_te64(&elfout.phdr[0].p_vaddr);
|
||||
upx_uint64_t adrm;
|
||||
unsigned lenm;
|
||||
unsigned lenu;
|
||||
len += (7&-lsize) + lsize;
|
||||
const upx_uint64_t my_page_size = 4096u;
|
||||
const upx_uint64_t my_page_mask = 0u - 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 PackLinuxElf64::updateLoader
|
||||
set_te64( &elfout.ehdr.e_entry,
|
||||
get_te64(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);
|
||||
set_te64(&elfout.phdr[0].p_vaddr, lo_va_user);
|
||||
set_te64(&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 &Elf64_Ehdr
|
||||
|
||||
//linker->dumpSymbols(); // debug
|
||||
}
|
||||
|
||||
static const
|
||||
|
||||
Reference in New Issue
Block a user