work on PackLinuxElf32arm; add nrv2b_d8.S
This commit is contained in:
parent
436532bed7
commit
52e8326d54
@ -903,6 +903,34 @@ void ElfLinkerArmLE::relocate1(Relocation *rel, upx_byte *location,
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
void ElfLinkerArmBE::relocate1(Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
set_be24(1+ location, get_be24(1+ location) + value / 4);
|
||||
}
|
||||
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||
{
|
||||
set_be32(location, get_be32(location) + value);
|
||||
}
|
||||
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
value += ((get_be16(location) & 0x7ff) << 12);
|
||||
value += (get_be16(location + 2) & 0x7ff) << 1;
|
||||
|
||||
set_be16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||
set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||
|
||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||
//set_be32(location, get_be32(location) + value / 4);
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
|
||||
@ -294,6 +294,15 @@ protected:
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
|
||||
class ElfLinkerArmBE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
|
||||
protected:
|
||||
virtual void relocate1(Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
@ -169,7 +169,7 @@ void PackLinuxElf::pack3(OutputFile *fo, Filter &ft)
|
||||
len += (3& -len);
|
||||
set_native32(&disp, len); // FIXME? -(sz_elf_hdrs+sizeof(l_info)+sizeof(p_info))
|
||||
fo->write(&disp, sizeof(disp));
|
||||
sz_pack2 = 4+ len;
|
||||
sz_pack2 = sizeof(disp) + len;
|
||||
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
@ -239,6 +239,18 @@ PackLinuxElf::getCompressionMethods(int method, int level) const
|
||||
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||
}
|
||||
|
||||
int const *
|
||||
PackLinuxElf32armLe::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||
}
|
||||
|
||||
int const *
|
||||
PackLinuxElf32armBe::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||
}
|
||||
|
||||
int const *
|
||||
PackLinuxElf32ppc::getFilters() const
|
||||
{
|
||||
@ -265,6 +277,23 @@ void PackLinuxElf64::patchLoader()
|
||||
{
|
||||
}
|
||||
|
||||
void PackLinuxElf32::ARM_updateLoader(OutputFile *fo)
|
||||
{
|
||||
set_native32(&elfout.ehdr.e_entry, fo->getBytesWritten() +
|
||||
linker->getSymbolOffset("_start") +
|
||||
get_native32(&elfout.phdr[0].p_vaddr));
|
||||
}
|
||||
|
||||
void PackLinuxElf32armLe::updateLoader(OutputFile *fo)
|
||||
{
|
||||
ARM_updateLoader(fo);
|
||||
}
|
||||
|
||||
void PackLinuxElf32armBe::updateLoader(OutputFile *fo)
|
||||
{
|
||||
ARM_updateLoader(fo);
|
||||
}
|
||||
|
||||
void PackLinuxElf32::updateLoader(OutputFile *fo)
|
||||
{
|
||||
set_native32(&elfout.ehdr.e_entry, fo->getBytesWritten() +
|
||||
@ -1536,7 +1565,7 @@ void PackLinuxElf32::ARM_addLinkerSymbols(Filter const * /*ft*/)
|
||||
len += lsize;
|
||||
bool const is_big = true;
|
||||
if (is_big) {
|
||||
set_native32( &elfout.ehdr.e_entry,
|
||||
set_native32( &elfout.ehdr.e_entry, linker->getSymbolOffset("_start") +
|
||||
get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);
|
||||
set_native32(&elfout.phdr[0].p_vaddr, lo_va_user);
|
||||
set_native32(&elfout.phdr[0].p_paddr, lo_va_user);
|
||||
@ -1557,14 +1586,12 @@ void PackLinuxElf32::ARM_addLinkerSymbols(Filter const * /*ft*/)
|
||||
adrm = PAGE_MASK & (~PAGE_MASK + adrm); // round up to page boundary
|
||||
adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary
|
||||
|
||||
linker->defineSymbol("ADRX", adrx); // compressed input for eXpansion
|
||||
linker->defineSymbol("LENX", len0 - hlen);
|
||||
linker->defineSymbol("CPR0", linker->getSymbolOffset("cpr0") -
|
||||
linker->getSymbolOffset("_start"));
|
||||
linker->defineSymbol("LENF", linker->getSymbolOffset("end_decompress") -
|
||||
linker->getSymbolOffset("_start"));
|
||||
|
||||
linker->defineSymbol("CNTC", cntc); // count for copy
|
||||
linker->defineSymbol("ADRC", adrc); // addr for copy
|
||||
|
||||
linker->defineSymbol("LENM", lenm); // len for map
|
||||
linker->defineSymbol("ADRM", adrm); // addr for map
|
||||
linker->defineSymbol("ADRM", adrm); // addr for map
|
||||
#undef PAGE_SIZE
|
||||
#undef PAGE_MASK
|
||||
}
|
||||
@ -1962,6 +1989,11 @@ PackLinuxElf32armLe::~PackLinuxElf32armLe()
|
||||
{
|
||||
}
|
||||
|
||||
Linker* PackLinuxElf32armLe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerArmLE();
|
||||
}
|
||||
|
||||
PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f)
|
||||
{
|
||||
e_machine = Elf32_Ehdr::EM_ARM;
|
||||
@ -1974,6 +2006,11 @@ PackLinuxElf32armBe::~PackLinuxElf32armBe()
|
||||
{
|
||||
}
|
||||
|
||||
Linker* PackLinuxElf32armBe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerArmBE();
|
||||
}
|
||||
|
||||
unsigned
|
||||
PackLinuxElf32::elf_get_offset_from_address(unsigned const addr) const
|
||||
{
|
||||
|
||||
@ -92,6 +92,7 @@ protected:
|
||||
// but the class hierarchy splits after this class.
|
||||
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
|
||||
virtual void ARM_addLinkerSymbols(Filter const *ft);
|
||||
virtual void ARM_updateLoader(OutputFile *);
|
||||
virtual void ARM_pack1(OutputFile *, bool isBE);
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
@ -398,8 +399,11 @@ public:
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual void addLinkerSymbols(Filter const *);
|
||||
};
|
||||
|
||||
@ -414,8 +418,11 @@ public:
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual void addLinkerSymbols(Filter const *);
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -46,7 +46,6 @@
|
||||
ldrb ip,meth; cmp ip,#M_LZMA; bne not_lzma
|
||||
|
||||
PUSH {fp,lr}
|
||||
mov fp,sp
|
||||
|
||||
#define a0 r0
|
||||
#define a1 r1
|
||||
@ -71,8 +70,8 @@
|
||||
mov fp,fp,LSR #3 // lit_context_bits + lit_pos_bits
|
||||
mov ip,ip,LSL fp // 2*LZMA_LIT_SIZE << (lit_context_bits + lit_pos_bits)
|
||||
mov fp,sp
|
||||
add ip,ip,# ((4*4 + 2*LZMA_BASE_SIZE)>>8)<<8
|
||||
add ip,ip,#0xff & (4*4 + 2*LZMA_BASE_SIZE)
|
||||
add ip,ip,# ((State + 2*LZMA_BASE_SIZE)>>8)<<8
|
||||
add ip,ip,#0xff & (State + 2*LZMA_BASE_SIZE)
|
||||
sub sp,sp,ip
|
||||
|
||||
ldr ip,[ldst]
|
||||
@ -101,6 +100,10 @@
|
||||
strb ip,[sp,#0 + State]
|
||||
|
||||
add a0,sp,#State
|
||||
bl 1f // the call
|
||||
mov sp,fp
|
||||
POP {fp,pc}
|
||||
1:
|
||||
|
||||
section LZMA_DEC10
|
||||
#include "lzma_d_cs.S"
|
||||
@ -109,8 +112,6 @@
|
||||
#include "lzma_d_cf.S"
|
||||
|
||||
section LZMA_DEC30
|
||||
mov sp,fp
|
||||
POP {fp,pc}
|
||||
|
||||
not_lzma:
|
||||
|
||||
|
||||
121
src/stub/src/arch/arm/v4a/nrv2b_d8.S
Normal file
121
src/stub/src/arch/arm/v4a/nrv2b_d8.S
Normal file
@ -0,0 +1,121 @@
|
||||
/* nrv2b_d8.S -- ARM decompressor for NRV2B
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#define src r0
|
||||
#define len r1
|
||||
#define dst r2
|
||||
#define tmp r3
|
||||
#define bits r4
|
||||
#define off r5
|
||||
|
||||
/* macros reduce "noise" when comparing this ARM code to corresponding THUMB code */
|
||||
#define PUSH stmdb sp!,
|
||||
#define POP ldmia sp!,
|
||||
#define ADD2( dst,src) add dst,dst,src
|
||||
#define ADD2S(dst,src) adds dst,dst,src
|
||||
#define ADC2( dst,src) adc dst,dst,src
|
||||
#define ADC2S(dst,src) adcs dst,dst,src
|
||||
#define SUB2( dst,src) sub dst,dst,src
|
||||
#define SUB2S(dst,src) subs dst,dst,src
|
||||
#define LDRB3(reg,psrc,incr) ldrb reg,psrc,incr
|
||||
#define STRB3(reg,pdst,incr) strb reg,pdst,incr
|
||||
|
||||
#undef GETBIT
|
||||
#define GETBIT ADD2S(bits,bits); bleq get8_n2b
|
||||
|
||||
#define getnextb(reg) GETBIT; ADC2S(reg,reg) /* Set Condition Codes on result */
|
||||
#define jnextb0 GETBIT; bcc
|
||||
#define jnextb1 GETBIT; bcs
|
||||
|
||||
ucl_nrv2b_decompress_8: .globl ucl_nrv2b_decompress_8 // ARM mode
|
||||
.type ucl_nrv2b_decompress_8, %function
|
||||
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst) */
|
||||
add r1,len,src // r1= eof_src;
|
||||
PUSH {r1,r2,r3, r4,r5, lr}
|
||||
mvn off,#~-1 // off= -1 initial condition
|
||||
mov bits,#1<<31 // refill next time
|
||||
b top_n2b
|
||||
|
||||
eof_n2b:
|
||||
POP {r1,r3,r4} // r1= eof_src; r3= orig_dst; r4= plen_dst
|
||||
SUB2(src,r1) // 0 if actual src length equals expected length
|
||||
SUB2(dst,r3) // actual dst length
|
||||
str dst,[r4]
|
||||
POP {r4,r5, pc} // return
|
||||
|
||||
get8_n2b: // In: Carry set [from adding 0x80000000 (1<<31) to itself]
|
||||
LDRB3(bits,[src],#1) // zero-extend next byte
|
||||
adc bits,bits,bits // double and insert CarryIn as low bit
|
||||
movs bits,bits,lsl #24 // move to top byte, and set CarryOut from old bit 8
|
||||
mov pc,lr
|
||||
|
||||
lit_n2b:
|
||||
LDRB3(tmp,[src],#1)
|
||||
STRB3(tmp,[dst],#1)
|
||||
top_n2b:
|
||||
jnextb1 lit_n2b
|
||||
|
||||
mov len,#1 // the msb
|
||||
getoff_n2b: // ss11 len= [2..)
|
||||
getnextb(len)
|
||||
jnextb0 getoff_n2b
|
||||
|
||||
sub tmp,len,#3 // set Carry
|
||||
mov len,#0 // Carry unaffected
|
||||
blo offprev_n2b // ss11 returned 2
|
||||
LDRB3(off,[src],#1) // low 8 bits
|
||||
orr off,off,tmp,lsl #8
|
||||
mvns off,off; beq eof_n2b // off= ~off
|
||||
offprev_n2b: // In: 0==len
|
||||
getnextb(len); getnextb(len); bne plus1_n2b // two bits; 1,2,3 ==> 2,3,4
|
||||
|
||||
mov len,#1 // the msb
|
||||
getlen_n2b: // ss11 len= [2..)
|
||||
getnextb(len)
|
||||
jnextb0 getlen_n2b
|
||||
ADD2(len,#2) // [2..) ==> [4..);
|
||||
plus1_n2b:
|
||||
ADD2(len,#1) // 1,2,3 ==> 2,3,4; [4..) ==> [5..)
|
||||
/* 'cmn': add the inputs, set condition codes, discard the sum */
|
||||
cmn off,#0xd<<8 // within M2_MAX_OFFSET
|
||||
addcc len,len,#1 // too far away, so minimum match length is 3
|
||||
ldrb tmp,[dst] // force cacheline allocate
|
||||
copy_n2b:
|
||||
ldrb tmp,[dst,off]
|
||||
STRB3(tmp,[dst],#1)
|
||||
SUB2S(len,#1); bne copy_n2b
|
||||
b top_n2b
|
||||
|
||||
.size ucl_nrv2b_decompress_8, .-ucl_nrv2b_decompress_8
|
||||
/*
|
||||
vi:ts=8:et:nowrap
|
||||
*/
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
*/
|
||||
#define section .section
|
||||
|
||||
#define bkpt .long 0xe1200070
|
||||
sz_Elf32_Ehdr = 13*4
|
||||
sz_Elf32_Phdr = 8*4
|
||||
|
||||
@ -49,16 +50,26 @@ MAP_ANONYMOUS= 0x20
|
||||
PAGE_SHIFT= 12
|
||||
PAGE_SIZE = -(~0<<PAGE_SHIFT)
|
||||
|
||||
//.long sz_pack2 // placed there by ::pack3()
|
||||
section ELFMAINX
|
||||
start_params:
|
||||
.long ADRM // dst for map
|
||||
.long LENF // end_decompress - _start
|
||||
.long CPR0 // cpr0 - _start
|
||||
_start: .globl _start
|
||||
/* Get some pages: enough
|
||||
to duplicate the entire compressed PT_LOAD, plus 1 page, located just after
|
||||
the brk() of the _un_compressed program. The address and length are pre-
|
||||
calculated by PackLinuxElf32arm::pack3(), and patched in at compress time.
|
||||
the brk() of the _un_compressed program. The address is pre-calculated
|
||||
calculated by PackLinuxElf32arm::addLinkerSymbols().
|
||||
*/
|
||||
adr r12,start_params
|
||||
ldmia r12!,{r0,r1, r8,r10} // ADRM,LENM, ADRC,CNTC
|
||||
stmdb sp!,{r0,r1,r2} // ADRU,LENU,space for sz_unc
|
||||
adr r12,start_params -4
|
||||
ldmia r12!,{r1,r2, r10,r11} // r1= sz_pack2; r2= ADRM; r10= LENF; r11= CPR0;
|
||||
add r10,r10,r12 // end_decompress
|
||||
add r11,r11,r12 // cpr0
|
||||
mov r0,r2
|
||||
sub r8,r12,r1 // 4*4+ (char *)&our_Elf32_Ehdr
|
||||
add r1,r1,# PAGE_SIZE
|
||||
stmdb sp!,{r0,r1,r2} // ADRU,LENU,space for sz_unc
|
||||
mov r2,#PROT_READ | PROT_WRITE | PROT_EXEC
|
||||
mov r3,#MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
|
||||
mvn r4,#0 // -1; cater to *BSD for fd when MAP_ANON
|
||||
@ -66,14 +77,15 @@ _start: .globl _start
|
||||
cmn r0,#4096
|
||||
bcs msg_SELinux
|
||||
mov r9,r0 // destination for copy
|
||||
bic r8,r8,#0xff // round down to page boundary
|
||||
copy:
|
||||
ldmia r8!,{r0,r1,r2,r3,r4,r5,r6,r7}; subs r10,r10,#1
|
||||
stmia r9!,{r0,r1,r2,r3,r4,r5,r6,r7}; bne copy
|
||||
ldmia r8!,{r0,r1,r2,r3,r4,r5,r6,r7}; cmp r8,r10
|
||||
stmia r9!,{r0,r1,r2,r3,r4,r5,r6,r7}; blo copy
|
||||
|
||||
mov lr,r9 // dst for unfolded code
|
||||
sub r11,r9,r8 // relocation amount
|
||||
ldmia r12!,{r1,r4,r9,r10} // len_f,cpr0,LENX,ADRX
|
||||
add r5,r12,r11 // relocated f_decompress
|
||||
add r12,r12,# f_decompress - _start
|
||||
add r5,r11,r12 // relocated f_decompress
|
||||
|
||||
/* linux/include/asm-arm/unistd.h */
|
||||
#define __NR_SYSCALL_BASE 0x900000
|
||||
@ -81,7 +93,7 @@ copy:
|
||||
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
||||
|
||||
mov r0,r5
|
||||
add r1,r1,r0 // relocated end_decompress
|
||||
mov r1,r10 // relocated end_decompress
|
||||
mov r2,#0
|
||||
swi __ARM_NR_cacheflush // relocated decompressor
|
||||
|
||||
@ -92,27 +104,23 @@ copy:
|
||||
ldrb r4,[r4,# b_method ]
|
||||
mov pc,r5 // decompress folded code; go there (lr)
|
||||
|
||||
start_params:
|
||||
.long ADRM // dst for map
|
||||
.long LENM // len for map
|
||||
|
||||
.long ADRC // src for copy
|
||||
.long CNTC // cnt for copy: number of 32-byte blocks
|
||||
|
||||
.long len_f // length of decompressor code
|
||||
.long cpr0
|
||||
|
||||
.long LENX // total size of compressed data
|
||||
.long ADRX // &b_info of 1st compressed block (after moving)
|
||||
f_decompress:
|
||||
#define LINUX_ARM_CACHEFLUSH 1
|
||||
|
||||
section NRV_HEAD
|
||||
// empty
|
||||
section NRV_TAIL
|
||||
// empty
|
||||
|
||||
section NRV2E
|
||||
#include "arch/arm/v4a/nrv2e_d8.S"
|
||||
|
||||
section NRV2D
|
||||
#include "arch/arm/v4a/nrv2d_d8.S"
|
||||
|
||||
section NRV2B
|
||||
#include "arch/arm/v4a/nrv2b_d8.S"
|
||||
|
||||
#include "arch/arm/v4a/lzma_d.S"
|
||||
|
||||
section ELFMAINY
|
||||
|
||||
Loading…
Reference in New Issue
Block a user