1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

Prepare for ability to compress PT_INTERP program.

Also save 16 bytes at cost of incompatible with glibc-2.1.1 (1999-12-29).
	fold_elf86.asm l_lx_elf.c

committer: jreiser <jreiser> 1032625240 +0000
This commit is contained in:
John Reiser 2002-09-21 16:20:40 +00:00
parent 448baac0f4
commit 8ad3d01d81
2 changed files with 44 additions and 33 deletions

View File

@ -106,50 +106,56 @@ L50:
mov ecx, [4+ eax] ; length of compressed ELF headers
add ecx, byte szb_info
pusha ; (AT_table, sz_cpr, f_expand, &tmp_ehdr, {sz_unc, &tmp}, {sz_cpr, &b1st_info} )
inc edi ; swap with above 'pusha' to inhibit auxv_up for PT_INTERP
EXTERN upx_main
call upx_main ; returns entry address
add esp, dword 8*4 + MAX_ELF_HDR + OVERHEAD ; remove 8 params, temp space
pop ebx ; &Elf32_Ehdr of this stub
push eax ; save entry address
mov esi, edi ; auxv table
L60: ; search for AT_PHDR
lodsd ; a_type
cmp al, byte AT_PHDR
lodsd ; a_un.a_ptr
jne L60
xchg eax, edi
dec edi ; auxv table
sub eax,eax ; 0, also AT_NULL
db 0x3c ; "cmpb al, byte ..." like "jmp 1+L60" but 1 byte shorter
L60:
scasd ; a_un
scasd ; a_val
jne L60 ; not AT_NULL
mov edx,[edi] ; &hatch
stosd ; clear a_un.a_ptr for AT_NULL
find_hatch:
push edi
EXTERN make_hatch
call make_hatch ; find hatch = make_hatch(phdr)
pop ecx ; junk the parameter
add edi, byte szElf32_Phdr ; prepare to try next Elf32_Phdr
test eax,eax
jz find_hatch
xchg eax,edx ; edx= &hatch
; _dl_start and company (ld-linux.so.2) assumes that it has virgin stack,
; and does not initialize all its stack local variables to zero.
; Ulrich Drepper (drepper@cyngus.com) has refused to fix the bugs.
; See GNU wwwgnats libc/1165 .
; _dl_start and company (ld-linux.so.2) once assumed that it had virgin stack,
; and did not initialize all its stack local variables to zero.
; See bug libc/1165 at http://bugs.gnu.org/cgi-bin/gnatsweb.pl
; Found 1999-06-16 glibc-2.1.1
; Fixed 1999-12-29 glibc-2.1.2
%define N_STKCLR (0x100 + MAX_ELF_HDR + OVERHEAD)/4
lea edi, [esp - 4*N_STKCLR]
pusha ; values will be zeroed
mov esi,esp ; save
mov esp,edi ; Linux does not grow stack below esp
mov ecx, N_STKCLR
xor eax,eax
rep stosd
mov esp,esi ; restore
%define N_STKCLR 8
; lea edi, [esp - 4*N_STKCLR]
; pusha ; values will be zeroed
; mov esi,esp ; save
; mov esp,edi ; Linux does not grow stack below esp
; mov ecx, N_STKCLR
; ; xor eax,eax ; eax already 0 from L60
; rep stosd
; mov esp,esi ; restore
; xor ecx, ecx ; ecx already 0 from "rep stosd"
xor ecx, ecx ; 0
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax ; 32 bytes of zeroes now on stack
push eax
pop ecx ; 0
mov al, __NR_munmap ; eax was 0 from L60
mov ch, PAGE_SIZE>>8 ; 0x1000
add ecx, [p_memsz + szElf32_Ehdr + ebx] ; length to unmap
mov bh, 0 ; from 0x401000 to 0x400000
mov eax, __NR_munmap ; do not dirty the stack with push byte + pop
jmp edx ; unmap ourselves via escape hatch, then goto entry
; called twice:

View File

@ -220,8 +220,9 @@ static void
__attribute__ ((regparm(3), stdcall))
auxv_up(Elf32_auxv_t *av, int const type, unsigned const value)
{
if (av && 0==(1&(int)av)) /* PT_INTERP usually inhibits, except for hatch */
for (;; ++av) {
if (av->a_type==type || av->a_type==AT_IGNORE) {
if (av->a_type==type || (av->a_type==AT_IGNORE && type!=AT_NULL)) {
av->a_type = type;
av->a_un.a_val = value;
return;
@ -275,7 +276,11 @@ do_xmap(int const fdi, Elf32_Ehdr const *const ehdr, struct Extent *const xi,
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
bzero(mlen+addr, frag); // fragment at hi end
if (xi) {
make_hatch(phdr);
void *const hatch = make_hatch(phdr);
if (0!=hatch) {
/* always update AT_NULL, especially for compressed PT_INTERP */
auxv_up((Elf32_auxv_t *)(~1 & (int)av), AT_NULL, hatch);
}
}
if (phdr->p_memsz != phdr->p_filesz) { // .bss
if (ET_DYN==ehdr->e_type) { // PT_INTERP whole pages of .bss?