1
0
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:
John Reiser 2002-11-12 03:14:23 +00:00
parent f3b64cfe78
commit de6e8c8020
3 changed files with 90 additions and 31 deletions

View File

@ -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
$(CC_LINUX_I386) -c $<
upx_itoa.o: upx_itoa.asm
$(NASM) -f elf -o $@ $<
fold_exec86.o: fold_exec86.asm
$(NASM) -f elf -o $@ $<
fold_exec86.h: l_lx_exec.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
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 upx_itoa.o
objcopy -S -R .comment -R .note $T.bin
$(STRIPELF) $T.bin
$(BRANDELF) $T.bin

View File

@ -73,33 +73,35 @@ static __inline__ int xwrite(int fd, const void *buf, int count)
// util
**************************************************************************/
// FIXME: all code in this source file must be relocatible, so
// we have to use `volatile' here.
// FIXME: rewrite upx_itoa() in assembly
static char *upx_itoa(char *buf, unsigned long v)
{
// const unsigned TEN = 10;
volatile unsigned TEN = 10;
char *p = buf;
{
unsigned long k = v;
do {
p++;
k /= TEN;
} while (k > 0);
}
buf = p;
*p = 0;
{
unsigned long k = v;
do {
*--p = '0' + k % TEN;
k /= TEN;
} while (k > 0);
}
return buf;
}
extern char *
__attribute__ ((regparm(2), stdcall)) // be ruthless
upx_itoa(unsigned long v, char *buf);
// Some versions of gcc optimize the division and/or remainder using
// a multiplication by (2**32)/10, and use a relocatable 32-bit address
// to reference the constant. We require no relocations because we move
// the code at runtime. See upx_itoa.asm for replacement [also smaller.]
//static char *upx_itoa(unsigned long v, char *buf)
//{
// volatile unsigned TEN = 10; // an ugly way to achieve no relocation
// char *p = buf;
// {
// unsigned long k = v;
// do {
// p++;
// k /= TEN;
// } while (k > 0);
// }
// buf = p;
// *p = 0;
// {
// unsigned long k = v;
// do {
// *--p = '0' + k % TEN;
// k /= TEN;
// } while (k > 0);
// }
// return buf;
//}
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 + 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', '/');
upx_itoa(procself + 4, fdi);
upx_itoa(fdi, procself + 4);
}
// Check for working /proc/self/fd/X by accessing the

54
src/stub/upx_itoa.asm Normal file
View 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