Skip to content

Commit 4787bd0

Browse files
committed
Add stub for absolute B and B_COND.
issue: #44
1 parent 59e1d0b commit 4787bd0

14 files changed

+403
-51
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@
126126
"bar.h": "c",
127127
"__bit_reference": "cpp",
128128
"aarch64.h": "c",
129-
"charconv": "cpp"
129+
"charconv": "cpp",
130+
"__locale": "c"
130131
},
131132
"C_Cpp.errorSquiggles": "enabled",
132133

cTools/libs/arch/aarch64/CMakeLists.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,24 @@ add_vipon_library(
3333
TYPE ${VIPON_TOOLS_LIB_TYPE}
3434
HEADERS ${AARCH64_LIB_HEADERS}
3535
SOURCES ${AARCH64_LIB_SOURCES}
36-
LINK_LIBS string
36+
LINK_LIBS string aarch64_global_stack
37+
INSTALL ON
38+
)
39+
40+
set(AARCH64_GLOBAL_STACK_LIB_SOURCES
41+
aarch64_global_stack.c
42+
)
43+
44+
set(AARCH64_GLOBAL_STACK_LIB_HEADERS
45+
aarch64_global_stack.h
46+
)
47+
48+
add_vipon_library(
49+
NAME aarch64_global_stack
50+
TYPE ${VIPON_TOOLS_LIB_TYPE}
51+
HEADERS ${AARCH64_GLOBAL_STACK_LIB_SOURCES}
52+
SOURCES ${AARCH64_GLOBAL_STACK_LIB_HEADERS}
53+
LINK_LIBS vt_containers
3754
INSTALL ON
3855
)
3956

cTools/libs/arch/aarch64/aarch64.c

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/***
22
* MIT License
33
*
4-
* Copyright (c) 2023 Konychev Valera
4+
* Copyright (c) 2023-2024 Konychev Valera
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,7 @@
2525
#include "bits.h"
2626
#include "string.h"
2727
#include "aarch64.h"
28+
#include "aarch64_global_stack.h"
2829

2930
#include <inttypes.h>
3031

@@ -357,34 +358,71 @@ uint8_t aarch64_put_b_x16_stub_abs( uint32_t *dst
357358
return sizeof(b_x16_stub_abs);
358359
}
359360

361+
static uint16_t key = 0;
360362
uint8_t aarch64_put_b_stub_abs( uint32_t *dst
361363
, uint64_t target_addr
362-
, uint64_t x30_addr
363364
)
364365
{
365-
uint8_t b_stub[] = {
366+
UNUSED(target_addr);
367+
STDERROR_PRINT("aarch64_put_b_stub_abs\n");
368+
size_t instr_size = 0;
369+
uint8_t b_stub_part0[] = {
366370
0xfe, 0x77, 0xbf, 0xa9, // stp x30, x29, [sp, #-16]!
367-
0x7d, 0x01, 0x00, 0x58, // ldr x29, 0x2c
368-
0xbe, 0x03, 0x40, 0xf9, // ldr x30, [x29]
369-
0x7e, 0x00, 0x00, 0xb5, // cbnz x30, 0xc
370-
0xfe, 0x03, 0x40, 0xf9, // ldr x30, [sp, #16]
371-
0xbe, 0x03, 0x00, 0xf9, // str x30, [x29]
372-
0xfe, 0x77, 0xc1, 0xa8, // ldp x30, x29, [sp], #16
373-
0xfe, 0x00, 0x00, 0x58, // ldr x30, 0x1c
374-
0xc0, 0x03, 0x3f, 0xd6, // blr x30
375-
0x7e, 0x00, 0x00, 0x58, // ldr x30, 0xc
376-
0xde, 0x03, 0x40, 0xf9, // ldr x30, [x30]
377-
0xc0, 0x03, 0x5f, 0xd6, // ret
378-
0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, // .quad 0xdeadbeefdeadbeef
379-
0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, // .quad 0xdeadbeefdeadbeef
371+
0xe0, 0x07, 0xbf, 0xa9, // stp x0, x1, [sp, #-16]!
372+
0xe0, 0x03, 0x1e, 0xaa, // mov x0, x30 // first argument for push_x30
373+
0x01, 0x00, 0x80, 0xd2, // movz x1, key // second argument for push_x30
380374
};
381375

382-
*(uint64_t*)(b_stub + 48) = x30_addr;
383-
*(uint64_t*)(b_stub + 56) = target_addr;
376+
uint32_t *instr = ((uint32_t*)b_stub_part0) + 3;
377+
*instr |= (uint32_t)((key & 0xFFFF) << 5);
378+
instr_size += sizeof(b_stub_part0);
379+
memcpy(dst, b_stub_part0, sizeof(b_stub_part0));
384380

385-
memcpy(dst, b_stub, sizeof(b_stub));
381+
instr_size += aarch64_put_adr_stub_abs(dst + (instr_size >> 2) //number of intr
382+
, (uint64_t)push_x30
383+
, 30
384+
);
386385

387-
return sizeof(b_stub);
386+
uint8_t b_stub_part1[] = {
387+
0xc0, 0x03, 0x3f, 0xd6, // blr x30 // call push_x30
388+
0xe0, 0x07, 0xc1, 0xa8, // ldp x0, x1, [sp], #16
389+
0xfe, 0x77, 0xc1, 0xa8, // ldp x30, x29, [sp], #16
390+
};
391+
memcpy(dst + (instr_size >> 2), b_stub_part1, sizeof(b_stub_part1));
392+
instr_size += sizeof(b_stub_part1);
393+
394+
instr_size += aarch64_put_adr_stub_abs( dst + (instr_size >> 2)
395+
, target_addr
396+
, 30
397+
);
398+
399+
uint8_t b_stub_part2[] = {
400+
0xc0, 0x03, 0x3f, 0xd6, // blr x30 // call target_addr
401+
0xe0, 0x0f, 0x1f, 0xf8, // str x0, [sp, #-16]!
402+
0x00, 0x00, 0x80, 0xd2, // movz x0, key
403+
};
404+
instr = ((uint32_t*)b_stub_part2) + 2;
405+
*instr |= (uint32_t)((key & 0xFFFF) << 5);
406+
memcpy(dst + (instr_size >> 2), b_stub_part2, sizeof(b_stub_part2));
407+
instr_size += sizeof(b_stub_part2);
408+
409+
instr_size += aarch64_put_adr_stub_abs( dst + (instr_size >> 2)
410+
, (uint64_t)pop_x30
411+
, 30
412+
);
413+
414+
uint8_t b_stub_part3[] = {
415+
0xc0, 0x03, 0x3f, 0xd6, // blr x30 // call pop_x30
416+
0xfe, 0x03, 0x00, 0xaa, // mov x30, x0
417+
0xe0, 0x07, 0x41, 0xf8, // ldr x0, [sp], #16
418+
0xc0, 0x03, 0x5f, 0xd6, // ret
419+
};
420+
memcpy(dst + (instr_size >> 2), b_stub_part3, sizeof(b_stub_part3));
421+
instr_size += sizeof(b_stub_part3);
422+
423+
STDERROR_PRINT("instr_size: %zu\n", instr_size);
424+
++key;
425+
return instr_size;
388426
}
389427

390428
uint8_t aarch64_put_bl( uint32_t *dst
@@ -585,6 +623,26 @@ uint8_t aarch64_put_b_cond( uint32_t *dst
585623
return 4;
586624
}
587625

626+
uint8_t aarch64_put_b_cond_stub_abs( uint32_t *dst
627+
, uint64_t target_addr
628+
, uint8_t cond
629+
)
630+
{
631+
// b_cond CONDITION_TRUE
632+
// b CONDITION_FALSE
633+
// CONDITION_TRUE:
634+
// b_stub_abs
635+
// CONDITION_FALSE:
636+
uint8_t b_cond_size = aarch64_put_b_cond(dst, 0 , 8, cond);
637+
uint8_t b_abs_size = aarch64_put_b_stub_abs(
638+
dst + 2, // two jumps before absolute stub
639+
target_addr
640+
);
641+
uint8_t b_size = aarch64_put_b(dst + 1, 0, 4 + b_abs_size);
642+
643+
return (b_cond_size + b_abs_size + b_size);
644+
}
645+
588646
uint8_t aarch64_put_bc_cond( uint32_t *dst
589647
, uint64_t pc
590648
, uint64_t target_addr

cTools/libs/arch/aarch64/aarch64.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/***
22
* MIT License
33
*
4-
* Copyright (c) 2023 Konychev Valera
4+
* Copyright (c) 2023-2024 Konychev Valera
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -188,7 +188,6 @@ uint8_t aarch64_put_b_x16_stub_abs( uint32_t *dst
188188
EXPORT_FUNC
189189
uint8_t aarch64_put_b_stub_abs( uint32_t *dst
190190
, uint64_t target_addr
191-
, uint64_t x30_addr
192191
);
193192

194193
#define SIZE_BL_STUB_ABS 20
@@ -263,6 +262,11 @@ uint8_t aarch64_put_b_cond( uint32_t *dst
263262
, uint8_t cond
264263
);
265264
EXPORT_FUNC
265+
uint8_t aarch64_put_b_cond_stub_abs( uint32_t *dst
266+
, uint64_t target_addr
267+
, uint8_t cond
268+
);
269+
EXPORT_FUNC
266270
uint8_t aarch64_put_bc_cond( uint32_t *dst
267271
, uint64_t pc
268272
, uint64_t target_addr

cTools/libs/arch/aarch64/aarch64_code_move.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "comdef.h"
2929
#include "aarch64.h"
3030
#include "aarch64_code_move.h"
31+
#include "vt_containers.h"
3132

3233
#include <inttypes.h>
3334

@@ -65,6 +66,7 @@ pre_init_relocations( vt_sorted_vector_t *rel
6566
};
6667

6768
if (vt_sorted_vector_insert(rel, &r)) {
69+
STDERROR_PRINT("fail\n");
6870
return -1;
6971
}
7072
}
@@ -208,12 +210,11 @@ aarch64_move_b( uint32_t instr
208210
);
209211
} else {
210212
STDERROR_LOG("B_STUB\n");
211-
static uint64_t x30_temp = 0;
213+
STDERROR_LOG("target_addr: %"PRIx64"\n", target_addr);
212214
// We cannot fit offset into 26 bits. Need to place b_stub.
213215
r->type = RELOC_AARCH64_B_ABS;
214216
r->new_size = aarch64_put_b_stub_abs( (uint32_t*)dst
215217
, target_addr
216-
, (uint64_t)(&x30_temp)
217218
);
218219
}
219220

@@ -362,6 +363,11 @@ aarch64_move_b_cond( uint32_t instr
362363
);
363364
} else {
364365
STDERROR_LOG("BC: cannot fit in the 19 bits\n");
366+
r->type = RELOC_AARCH64_B_COND_ABS;
367+
r->new_size = aarch64_put_b_cond_stub_abs( (uint32_t*)dst
368+
, target_addr
369+
, cond
370+
);
365371
}
366372

367373
return r->new_size;
@@ -530,7 +536,13 @@ aarch64_instr_move( const uint8_t *src
530536
return (CODE_MOVE_ERROR)r->new_size;
531537
}
532538

533-
static void
539+
extern void
540+
resolve_relocations( vt_sorted_vector_t *rel
541+
, uint8_t *dst
542+
, uint64_t old_pc
543+
, uint64_t instr_num
544+
);
545+
void
534546
resolve_relocations( vt_sorted_vector_t *rel
535547
, uint8_t *dst
536548
, uint64_t old_pc
@@ -544,8 +556,8 @@ resolve_relocations( vt_sorted_vector_t *rel
544556
bt_reloc *r = (bt_reloc*) vt_sorted_vector_find_elem(rel, &start_reloc);
545557
uint64_t i = 0;
546558
uint8_t *instr_p = dst;
547-
for (i = 0; i < instr_num; ++i, instr_p += r[i].new_size) {
548-
STDERROR_LOG("\tinstr_p: %p | new_size %u\n", (void*)instr_p, r[i].new_size);
559+
for (i = 0; i < instr_num; instr_p += r[i].new_size, ++i) {
560+
STDERROR_PRINT("\tinstr_p: %p | new_size %u\n", (void*)instr_p, r[i].new_size);
549561
if (r[i].type == RELOC_GP) {
550562
// General instructions doesn't need to rebase
551563
continue;
@@ -649,10 +661,9 @@ resolve_relocations( vt_sorted_vector_t *rel
649661
*/
650662
case RELOC_AARCH64_B_ABS:
651663
{
652-
uint64_t x30_addr = *(uint64_t*)(instr_p + 48);
664+
//uint64_t x30_addr = *(uint64_t*)(instr_p + 48);
653665
aarch64_put_b_stub_abs( (uint32_t*)instr_p
654666
, r[i].new_target
655-
, x30_addr
656667
);
657668
break;
658669
}
@@ -723,7 +734,7 @@ resolve_relocations( vt_sorted_vector_t *rel
723734
}
724735
case RELOC_AARCH64_B_COND:
725736
{
726-
STDERROR_LOG("Reloc B_COND:\n");
737+
STDERROR_PRINT("Reloc B_COND:\n");
727738
STDERROR_LOG("\told_target: 0x%"PRIx64", new_pc_old_target: 0x%"PRIx64"\n", r[i].old_target
728739
, old_target->new_pc);
729740
uint8_t cond = (*((uint32_t*)instr_p)) & 0xF;
@@ -734,6 +745,16 @@ resolve_relocations( vt_sorted_vector_t *rel
734745
);
735746
break;
736747
}
748+
case RELOC_AARCH64_B_COND_ABS:
749+
{
750+
STDERROR_PRINT("Reloc B_COND_ABS:\n");
751+
uint8_t cond = (*((uint32_t*)instr_p)) & 0xF;
752+
aarch64_put_b_cond_stub_abs( (uint32_t*)instr_p
753+
, r[i].new_target
754+
, cond
755+
);
756+
break;
757+
}
737758
case RELOC_AARCH64_CB:
738759
{
739760
STDERROR_LOG("Reloc CB:\n");
@@ -797,7 +818,8 @@ aarch64_code_move( const uint8_t *src
797818
, dst_size
798819
, rel
799820
);
800-
//print_bytes(stderr, dst, new_instr_size);
821+
//print_bytes(stderr, dst + new_code_size, new_instr_size);
822+
//putchar('\n');
801823

802824
new_code_size += new_instr_size;
803825
}

cTools/libs/arch/aarch64/aarch64_code_move.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ CODE_MOVE_ERROR aarch64_code_move( const uint8_t *src
8585
* will return maximum estimation.
8686
* @param[in] src_size Size of source binary code in bytes.
8787
*/
88-
EXPORT_FUNC
89-
CODE_MOVE_ERROR aarch64_estimate_space( const uint8_t *src
90-
, uint64_t old_pc
91-
, uint64_t new_pc
92-
, uint64_t src_size
93-
);
88+
EXPORT_FUNC CODE_MOVE_ERROR
89+
aarch64_estimate_space( const uint8_t *src
90+
, uint64_t old_pc
91+
, uint64_t new_pc
92+
, uint64_t src_size
93+
);
9494

9595
#endif /* __AARCH64_CODE_MOVE_H */
9696

0 commit comments

Comments
 (0)