mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08:00
arm64 tracing in stub
modified: ../../linker.cpp modified: ../../p_lx_elf.cpp modified: arm64-linux.elf-entry.S
This commit is contained in:
parent
61798d33f0
commit
90714cf624
|
@ -592,35 +592,6 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
|
||||||
super::relocate1(rel, location, value, type);
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinkerARM64::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value,
|
|
||||||
const char *type) {
|
|
||||||
if (strncmp(type, "R_AARCH64_", 10))
|
|
||||||
return super::relocate1(rel, location, value, type);
|
|
||||||
type += 10;
|
|
||||||
|
|
||||||
if (!strncmp(type, "PREL", 4)) {
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
type += 4;
|
|
||||||
|
|
||||||
if (!strcmp(type, "16"))
|
|
||||||
set_le16(location, get_le16(location) + value);
|
|
||||||
else if (!strncmp(type, "32", 2)) // for "32" and "32S"
|
|
||||||
set_le32(location, get_le32(location) + value);
|
|
||||||
else if (!strcmp(type, "64"))
|
|
||||||
set_le64(location, get_le64(location) + value);
|
|
||||||
} else if (!strcmp(type, "ABS32")) {
|
|
||||||
set_le32(location, get_le32(location) + value);
|
|
||||||
} else if (!strcmp(type, "ABS64")) {
|
|
||||||
set_le64(location, get_le64(location) + value);
|
|
||||||
} else if (!strcmp(type, "CONDBR19")) {
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
upx_uint32_t const m19 = ~(~0u << 19);
|
|
||||||
upx_uint32_t w = get_le32(location);
|
|
||||||
set_le32(location, (w & ~(m19 << 5)) | ((((w >> 5) + (value >> 2)) & m19) << 5));
|
|
||||||
} else
|
|
||||||
super::relocate1(rel, location, value, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value,
|
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value,
|
||||||
const char *type) {
|
const char *type) {
|
||||||
if (strcmp(type, "R_ARM_PC24") == 0) {
|
if (strcmp(type, "R_ARM_PC24") == 0) {
|
||||||
|
@ -670,12 +641,36 @@ void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location, upx_ui
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinkerArm64LE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value,
|
void ElfLinkerArm64LE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value,
|
||||||
const char *type) {
|
const char *type)
|
||||||
if (strcmp(type, "R_AARCH64_CALL26") == 0) {
|
{
|
||||||
|
if (strncmp(type, "R_AARCH64_", 10))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 10;
|
||||||
|
|
||||||
|
if (!strncmp(type, "PREL", 4)) {
|
||||||
value -= rel->section->offset + rel->offset;
|
value -= rel->section->offset + rel->offset;
|
||||||
set_le24(location, get_le24(location) + value / 4); // FIXME set_le26
|
type += 4;
|
||||||
} else if (strcmp(type, "R_AARCH64_ABS32") == 0) {
|
|
||||||
|
if (!strcmp(type, "16"))
|
||||||
|
set_le16(location, get_le16(location) + value);
|
||||||
|
else if (!strncmp(type, "32", 2)) // for "32" and "32S"
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else if (!strcmp(type, "64"))
|
||||||
|
set_le64(location, get_le64(location) + value);
|
||||||
|
} else if (!strcmp(type, "ABS32")) {
|
||||||
set_le32(location, get_le32(location) + value);
|
set_le32(location, get_le32(location) + value);
|
||||||
|
} else if (!strcmp(type, "ABS64")) {
|
||||||
|
set_le64(location, get_le64(location) + value);
|
||||||
|
} else if (!strcmp(type, "CONDBR19")) {
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
upx_uint32_t const m19 = ~(~0u << 19);
|
||||||
|
upx_uint32_t w = get_le32(location);
|
||||||
|
set_le32(location, (w & ~(m19 << 5)) | ((((w >> 5) + (value >> 2)) & m19) << 5));
|
||||||
|
} else if (!strcmp(type, "CALL26")) {
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
upx_uint32_t const m26 = ~(~0u << 26);
|
||||||
|
upx_uint32_t w = get_le32(location);
|
||||||
|
set_le32(location, (w & ~m26) | (m26 & (value >> 2)));
|
||||||
} else
|
} else
|
||||||
super::relocate1(rel, location, value, type);
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,7 +647,7 @@ Linker* PackLinuxElf64amd::newLinker() const
|
||||||
|
|
||||||
Linker* PackLinuxElf64arm::newLinker() const
|
Linker* PackLinuxElf64arm::newLinker() const
|
||||||
{
|
{
|
||||||
return new ElfLinkerARM64;
|
return new ElfLinkerArm64LE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int const *
|
int const *
|
||||||
|
|
|
@ -60,6 +60,12 @@ __ARM_NR_cacheflush = 255 // FIXME
|
||||||
#ifndef DEBUG /*{*/
|
#ifndef DEBUG /*{*/
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
|
#if DEBUG //{
|
||||||
|
#define TRACE(arg) stp lr,x0,[sp,#-2*8]!; mov x0,arg; bl trace; ldr lr,[sp],#2*8
|
||||||
|
#else //}{
|
||||||
|
#define TRACE(arg) /*empty*/
|
||||||
|
#endif //}
|
||||||
|
|
||||||
|
|
||||||
//.long sz_pack2 // placed there by ::pack3()
|
//.long sz_pack2 // placed there by ::pack3()
|
||||||
section ELFMAINX
|
section ELFMAINX
|
||||||
|
@ -78,13 +84,8 @@ _start: .globl _start
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if DEBUG /*{*/
|
#if DEBUG /*{*/
|
||||||
#define TRACE_REGS r0-r12,r14,r15
|
brk #0
|
||||||
// sp (r13) is not included because the write-back might cause UNDEFINED behavior
|
TRACE(#0)
|
||||||
// if the write-back register is not first or last. The actual value of sp
|
|
||||||
// usually does not matter. Just remember that lr (r14) and pc (r15) are stored
|
|
||||||
// one word closer to the stack pointer because r13 has been omitted.
|
|
||||||
|
|
||||||
stmdb sp!,{TRACE_REGS}; mov r0,#1; bl trace
|
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
|
|
||||||
adr x12,start_params -4 // &sz_pack2
|
adr x12,start_params -4 // &sz_pack2
|
||||||
|
@ -111,7 +112,7 @@ D_sz_unc=2*8 // stack displacement to sz_unc
|
||||||
mov w4,#-1 // fd= -1; cater to *BSD for fd when MAP_ANON
|
mov w4,#-1 // fd= -1; cater to *BSD for fd when MAP_ANON
|
||||||
do_sys __NR_mmap64
|
do_sys __NR_mmap64
|
||||||
#if DEBUG /*{*/
|
#if DEBUG /*{*/
|
||||||
stmdb sp!,{TRACE_REGS}; mov r0,#2; bl trace
|
TRACE(#2)
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
cmn x0,#4096
|
cmn x0,#4096
|
||||||
bcs msg_SELinux
|
bcs msg_SELinux
|
||||||
|
@ -155,52 +156,98 @@ D_stm1=0*8
|
||||||
str w3,[sp,#D_stm1 + D_sz_unc] // sz_unc; lzma needs for EOF
|
str w3,[sp,#D_stm1 + D_sz_unc] // sz_unc; lzma needs for EOF
|
||||||
add x3, sp,#D_stm1 + D_sz_unc // &sz_unc
|
add x3, sp,#D_stm1 + D_sz_unc // &sz_unc
|
||||||
#if DEBUG /*{*/
|
#if DEBUG /*{*/
|
||||||
stmdb sp!,{TRACE_REGS}; mov r0,#3; bl trace
|
TRACE(#3)
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
br x15 // decompress folded code, return to *lr
|
br x15 // decompress folded code, return to *lr
|
||||||
|
|
||||||
#if DEBUG /*{*/
|
#if DEBUG /*{*/
|
||||||
TRACE_BUFLEN=512
|
TRACE_BUFLEN=1024
|
||||||
trace:
|
trace: // DEFICIENCY: modifies condition code
|
||||||
str lr,[sp,#(-1+ 15)*4] @ return pc; [remember: sp is not stored]
|
stp x0, x1,[sp,#-32*8]!
|
||||||
mov r4,sp @ &saved_r0
|
stp x2, x3,[sp,# 2*8]
|
||||||
|
stp x4, x5,[sp,# 4*8]
|
||||||
|
stp x6, x7,[sp,# 6*8]
|
||||||
|
stp x8, x9,[sp,# 8*8]
|
||||||
|
stp x10,x11,[sp,#10*8]
|
||||||
|
stp x12,x13,[sp,#12*8]
|
||||||
|
stp x14,x15,[sp,#14*8]
|
||||||
|
stp x16,x17,[sp,#16*8]
|
||||||
|
stp x18,x19,[sp,#18*8]
|
||||||
|
stp x20,x21,[sp,#20*8]
|
||||||
|
stp x22,x23,[sp,#22*8]
|
||||||
|
stp x24,x25,[sp,#24*8]
|
||||||
|
stp x26,x27,[sp,#26*8]
|
||||||
|
stp x28,x29,[sp,#28*8]
|
||||||
|
add x1,lr,#4 // u_pc
|
||||||
|
add x2,sp, #32*8 + 2*8 // u_sp
|
||||||
|
stp x1, x2,[sp,#30*8]
|
||||||
|
|
||||||
|
ldr x1,[sp,#(1+ 32)*8] // x1= u_x0
|
||||||
|
str x1,[sp] // u_x0
|
||||||
|
|
||||||
|
mov x4,sp // &u_x0
|
||||||
sub sp,sp,#TRACE_BUFLEN
|
sub sp,sp,#TRACE_BUFLEN
|
||||||
mov r2,sp @ output string
|
mov x2,sp // output string
|
||||||
|
|
||||||
mov r1,#'\n'; bl trace_hex @ In: r0 as label
|
mov w1,#'\n'; bl trace_hex // In: r0 as label
|
||||||
mov r1,#'>'; strb r1,[r2],#1
|
mov w1,#'>'; strb w1,[x2],#1
|
||||||
|
|
||||||
mov r5,#3 @ rows to print
|
mov w5,#10 // nrows to print
|
||||||
L600: @ each row
|
L600: // each row
|
||||||
sub r0,r4,#TRACE_BUFLEN
|
add x1,sp,#TRACE_BUFLEN
|
||||||
sub r0,r0,sp
|
sub x0,x4,x1
|
||||||
mov r0,r0,lsr #2; mov r1,#'\n'; bl trace_hex @ which block of 8
|
lsr x0,x0,#3; mov w1,#'\n'; bl trace_hex2 // which block of 4
|
||||||
|
|
||||||
mov r6,#8 @ words per row
|
mov w6,#4 // 64-bit words per row
|
||||||
L610: @ each word
|
L610: // each word
|
||||||
ldr r0,[r4],#4; mov r1,#' '; bl trace_hex @ next word
|
ldr x0,[x4],#8; mov w1,#(' '<<8)|' '; bl trace_hex // next word
|
||||||
subs r6,r6,#1; bgt L610
|
sub w6,w6,#1; cbnz w6,L610
|
||||||
|
|
||||||
subs r5,r5,#1; bgt L600
|
sub w5,w5,#1; cbnz w5,L600
|
||||||
|
|
||||||
mov r0,#'\n'; strb r0,[r2],#1
|
mov w0,#'\n'; strb w0,[x2],#1
|
||||||
sub r2,r2,sp @ count
|
mov x1,sp // buf
|
||||||
mov r1,sp @ buf
|
sub x2,x2,x1 // count
|
||||||
mov r0,#2 @ FD_STDERR
|
mov w0,#2 // FD_STDERR
|
||||||
do_sys __NR_write
|
do_sys __NR_write
|
||||||
add sp,sp,#TRACE_BUFLEN
|
add sp,sp,#TRACE_BUFLEN
|
||||||
ldmia sp!,{TRACE_REGS}
|
|
||||||
|
|
||||||
trace_hex: // In: r0=val, r1=punctuation before, r2=ptr; Uses: r3, ip
|
ldp x16,x17,[sp,#16*8]
|
||||||
strb r1,[r2],#1 @ punctuation
|
ldp x18,x19,[sp,#18*8]
|
||||||
mov r3,#4*(8 -1) @ shift count
|
ldp x20,x21,[sp,#20*8]
|
||||||
adr ip,hex
|
ldp x22,x23,[sp,#22*8]
|
||||||
|
ldp x24,x25,[sp,#24*8]
|
||||||
|
ldp x26,x27,[sp,#26*8]
|
||||||
|
ldp x28,x29,[sp,#28*8]
|
||||||
|
ldp x30, x0,[sp,#30*8]
|
||||||
|
sub lr, lr,#4 // our lr
|
||||||
|
|
||||||
|
ldp x14,x15,[sp,#14*8]
|
||||||
|
ldp x12,x13,[sp,#12*8]
|
||||||
|
ldp x10,x11,[sp,#10*8]
|
||||||
|
ldp x8, x9,[sp,# 8*8]
|
||||||
|
ldp x6, x7,[sp,# 6*8]
|
||||||
|
ldp x4, x5,[sp,# 4*8]
|
||||||
|
ldp x2, x3,[sp,# 2*8]
|
||||||
|
ldp x0, x1,[sp],#32*8
|
||||||
|
ret
|
||||||
|
|
||||||
|
trace_hex2:
|
||||||
|
mov w3,#2; b trace_hexwid
|
||||||
|
trace_hex: // In: x0=val, w1=punctuation before, x2=ptr; Uses: w3, x7
|
||||||
|
mov w3,#16 // ndigits
|
||||||
|
trace_hexwid:
|
||||||
|
strb w1,[x2],#1; lsr w1,w1,#8; cbnz w1,trace_hexwid // punctuation
|
||||||
|
adr x7,hex
|
||||||
|
sub w3,w3,#1
|
||||||
L620:
|
L620:
|
||||||
mov r1,r0,lsr r3
|
cmp w3,#-1+ 8; mov w1,#'_'; strb w1,[x2]; cinc x2,x2,eq
|
||||||
and r1,r1,#0xf
|
lsl w1,w3,#2 // 4 bits per hex digit
|
||||||
ldrb r1,[ip, r1]
|
lsr x1,x0,x1 // right justify next digit
|
||||||
strb r1,[r2],#1
|
and x1,x1,#0xf
|
||||||
subs r3,r3,#4; bge L620
|
ldrb w1,[x7, x1]
|
||||||
|
strb w1,[x2],#1
|
||||||
|
subs w3,w3,#1; bge L620
|
||||||
ret
|
ret
|
||||||
hex:
|
hex:
|
||||||
.ascii "0123456789abcdef"
|
.ascii "0123456789abcdef"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user