mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
upx_itoa() in assembler to enforce no relocation
Makefile l_lx_exec.c upx_itoa.asm committer: jreiser <jreiser> 1037070863 +0000
This commit is contained in:
parent
f3b64cfe78
commit
de6e8c8020
|
@ -322,11 +322,14 @@ fold_elf86.h: l_lx_elf.o fold_elf86.o l_lx_elf86.lds
|
||||||
l_lx_exec.o: l_lx_exec.c
|
l_lx_exec.o: l_lx_exec.c
|
||||||
$(CC_LINUX_I386) -c $<
|
$(CC_LINUX_I386) -c $<
|
||||||
|
|
||||||
|
upx_itoa.o: upx_itoa.asm
|
||||||
|
$(NASM) -f elf -o $@ $<
|
||||||
|
|
||||||
fold_exec86.o: fold_exec86.asm
|
fold_exec86.o: fold_exec86.asm
|
||||||
$(NASM) -f elf -o $@ $<
|
$(NASM) -f elf -o $@ $<
|
||||||
|
|
||||||
fold_exec86.h: l_lx_exec.o fold_exec86.o l_lx_exec86.lds
|
fold_exec86.h: l_lx_exec.o upx_itoa.o fold_exec86.o l_lx_exec86.lds
|
||||||
ld -T $(srcdir)/l_lx_exec86.lds -Map $T.map -o $T.bin $T.o l_lx_exec.o
|
ld -T $(srcdir)/l_lx_exec86.lds -Map $T.map -o $T.bin $T.o l_lx_exec.o upx_itoa.o
|
||||||
objcopy -S -R .comment -R .note $T.bin
|
objcopy -S -R .comment -R .note $T.bin
|
||||||
$(STRIPELF) $T.bin
|
$(STRIPELF) $T.bin
|
||||||
$(BRANDELF) $T.bin
|
$(BRANDELF) $T.bin
|
||||||
|
|
|
@ -73,33 +73,35 @@ static __inline__ int xwrite(int fd, const void *buf, int count)
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// FIXME: all code in this source file must be relocatible, so
|
extern char *
|
||||||
// we have to use `volatile' here.
|
__attribute__ ((regparm(2), stdcall)) // be ruthless
|
||||||
// FIXME: rewrite upx_itoa() in assembly
|
upx_itoa(unsigned long v, char *buf);
|
||||||
static char *upx_itoa(char *buf, unsigned long v)
|
// Some versions of gcc optimize the division and/or remainder using
|
||||||
{
|
// a multiplication by (2**32)/10, and use a relocatable 32-bit address
|
||||||
// const unsigned TEN = 10;
|
// to reference the constant. We require no relocations because we move
|
||||||
volatile unsigned TEN = 10;
|
// the code at runtime. See upx_itoa.asm for replacement [also smaller.]
|
||||||
char *p = buf;
|
//static char *upx_itoa(unsigned long v, char *buf)
|
||||||
{
|
//{
|
||||||
unsigned long k = v;
|
// volatile unsigned TEN = 10; // an ugly way to achieve no relocation
|
||||||
do {
|
// char *p = buf;
|
||||||
p++;
|
// {
|
||||||
k /= TEN;
|
// unsigned long k = v;
|
||||||
} while (k > 0);
|
// do {
|
||||||
}
|
// p++;
|
||||||
buf = p;
|
// k /= TEN;
|
||||||
*p = 0;
|
// } while (k > 0);
|
||||||
{
|
// }
|
||||||
unsigned long k = v;
|
// buf = p;
|
||||||
do {
|
// *p = 0;
|
||||||
*--p = '0' + k % TEN;
|
// {
|
||||||
k /= TEN;
|
// unsigned long k = v;
|
||||||
} while (k > 0);
|
// do {
|
||||||
}
|
// *--p = '0' + k % TEN;
|
||||||
return buf;
|
// k /= TEN;
|
||||||
}
|
// } while (k > 0);
|
||||||
|
// }
|
||||||
|
// return buf;
|
||||||
|
//}
|
||||||
|
|
||||||
static uint32_t ascii5(char *p, uint32_t v, unsigned n)
|
static uint32_t ascii5(char *p, uint32_t v, unsigned n)
|
||||||
{
|
{
|
||||||
|
@ -159,9 +161,9 @@ go_self(char const *tmpname, char *argv[], char *envp[])
|
||||||
SET4(procself_buf + 0, '/', 'p', 'r', 'o');
|
SET4(procself_buf + 0, '/', 'p', 'r', 'o');
|
||||||
SET4(procself_buf + 4, 'c', '/', 0 , 0 );
|
SET4(procself_buf + 4, 'c', '/', 0 , 0 );
|
||||||
{
|
{
|
||||||
char *const procself = upx_itoa(procself_buf + 6, getpid());
|
char *const procself = upx_itoa(getpid(), procself_buf + 6);
|
||||||
SET4(procself, '/', 'f', 'd', '/');
|
SET4(procself, '/', 'f', 'd', '/');
|
||||||
upx_itoa(procself + 4, fdi);
|
upx_itoa(fdi, procself + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for working /proc/self/fd/X by accessing the
|
// Check for working /proc/self/fd/X by accessing the
|
||||||
|
|
54
src/stub/upx_itoa.asm
Normal file
54
src/stub/upx_itoa.asm
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
; l_lx_itoa.asm -- decimal print; smaller than gcc, and no relocations
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 2002 John F. Reiser
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; John F. Reiser
|
||||||
|
; <jreiser@users.sourceforge.net>
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
BITS 32
|
||||||
|
SECTION .text
|
||||||
|
GLOBAL upx_itoa
|
||||||
|
|
||||||
|
upx_itoa: ; char *upx_itoa(eax= unsigned v, edx= char *buf) /* 0<=(int)v */
|
||||||
|
push edi ; save register
|
||||||
|
mov edi,edx ; output ptr
|
||||||
|
push byte 10
|
||||||
|
cld
|
||||||
|
pop ecx ; radix
|
||||||
|
call recur
|
||||||
|
mov [edi],ah ; NUL terminate
|
||||||
|
xchg eax,edi ; eax= continuation point
|
||||||
|
pop edi ; restore register
|
||||||
|
ret
|
||||||
|
recur:
|
||||||
|
cdq ; zero extend eax into edx [use "sub edx,edx" if eax < 0 ]
|
||||||
|
div ecx ; eax=quo, edx=rem; flags are undefined
|
||||||
|
push edx
|
||||||
|
test eax,eax
|
||||||
|
je quo0
|
||||||
|
call recur
|
||||||
|
quo0:
|
||||||
|
pop eax ; remainder
|
||||||
|
add al, byte '0'
|
||||||
|
stosb
|
||||||
|
ret
|
Loading…
Reference in New Issue
Block a user