Skip to content

Commit

Permalink
Add stub for absolute B and B_COND.
Browse files Browse the repository at this point in the history
issue: #44
  • Loading branch information
Vipon committed Feb 11, 2024
1 parent 59e1d0b commit 4787bd0
Show file tree
Hide file tree
Showing 14 changed files with 403 additions and 51 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@
"bar.h": "c",
"__bit_reference": "cpp",
"aarch64.h": "c",
"charconv": "cpp"
"charconv": "cpp",
"__locale": "c"
},
"C_Cpp.errorSquiggles": "enabled",

Expand Down
19 changes: 18 additions & 1 deletion cTools/libs/arch/aarch64/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,24 @@ add_vipon_library(
TYPE ${VIPON_TOOLS_LIB_TYPE}
HEADERS ${AARCH64_LIB_HEADERS}
SOURCES ${AARCH64_LIB_SOURCES}
LINK_LIBS string
LINK_LIBS string aarch64_global_stack
INSTALL ON
)

set(AARCH64_GLOBAL_STACK_LIB_SOURCES
aarch64_global_stack.c
)

set(AARCH64_GLOBAL_STACK_LIB_HEADERS
aarch64_global_stack.h
)

add_vipon_library(
NAME aarch64_global_stack
TYPE ${VIPON_TOOLS_LIB_TYPE}
HEADERS ${AARCH64_GLOBAL_STACK_LIB_SOURCES}
SOURCES ${AARCH64_GLOBAL_STACK_LIB_HEADERS}
LINK_LIBS vt_containers
INSTALL ON
)

Expand Down
98 changes: 78 additions & 20 deletions cTools/libs/arch/aarch64/aarch64.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***
* MIT License
*
* Copyright (c) 2023 Konychev Valera
* Copyright (c) 2023-2024 Konychev Valera
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -25,6 +25,7 @@
#include "bits.h"
#include "string.h"
#include "aarch64.h"
#include "aarch64_global_stack.h"

#include <inttypes.h>

Expand Down Expand Up @@ -357,34 +358,71 @@ uint8_t aarch64_put_b_x16_stub_abs( uint32_t *dst
return sizeof(b_x16_stub_abs);
}

static uint16_t key = 0;
uint8_t aarch64_put_b_stub_abs( uint32_t *dst
, uint64_t target_addr
, uint64_t x30_addr
)
{
uint8_t b_stub[] = {
UNUSED(target_addr);
STDERROR_PRINT("aarch64_put_b_stub_abs\n");
size_t instr_size = 0;
uint8_t b_stub_part0[] = {
0xfe, 0x77, 0xbf, 0xa9, // stp x30, x29, [sp, #-16]!
0x7d, 0x01, 0x00, 0x58, // ldr x29, 0x2c
0xbe, 0x03, 0x40, 0xf9, // ldr x30, [x29]
0x7e, 0x00, 0x00, 0xb5, // cbnz x30, 0xc
0xfe, 0x03, 0x40, 0xf9, // ldr x30, [sp, #16]
0xbe, 0x03, 0x00, 0xf9, // str x30, [x29]
0xfe, 0x77, 0xc1, 0xa8, // ldp x30, x29, [sp], #16
0xfe, 0x00, 0x00, 0x58, // ldr x30, 0x1c
0xc0, 0x03, 0x3f, 0xd6, // blr x30
0x7e, 0x00, 0x00, 0x58, // ldr x30, 0xc
0xde, 0x03, 0x40, 0xf9, // ldr x30, [x30]
0xc0, 0x03, 0x5f, 0xd6, // ret
0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, // .quad 0xdeadbeefdeadbeef
0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, // .quad 0xdeadbeefdeadbeef
0xe0, 0x07, 0xbf, 0xa9, // stp x0, x1, [sp, #-16]!
0xe0, 0x03, 0x1e, 0xaa, // mov x0, x30 // first argument for push_x30
0x01, 0x00, 0x80, 0xd2, // movz x1, key // second argument for push_x30
};

*(uint64_t*)(b_stub + 48) = x30_addr;
*(uint64_t*)(b_stub + 56) = target_addr;
uint32_t *instr = ((uint32_t*)b_stub_part0) + 3;
*instr |= (uint32_t)((key & 0xFFFF) << 5);
instr_size += sizeof(b_stub_part0);
memcpy(dst, b_stub_part0, sizeof(b_stub_part0));

memcpy(dst, b_stub, sizeof(b_stub));
instr_size += aarch64_put_adr_stub_abs(dst + (instr_size >> 2) //number of intr
, (uint64_t)push_x30
, 30
);

return sizeof(b_stub);
uint8_t b_stub_part1[] = {
0xc0, 0x03, 0x3f, 0xd6, // blr x30 // call push_x30
0xe0, 0x07, 0xc1, 0xa8, // ldp x0, x1, [sp], #16
0xfe, 0x77, 0xc1, 0xa8, // ldp x30, x29, [sp], #16
};
memcpy(dst + (instr_size >> 2), b_stub_part1, sizeof(b_stub_part1));
instr_size += sizeof(b_stub_part1);

instr_size += aarch64_put_adr_stub_abs( dst + (instr_size >> 2)
, target_addr
, 30
);

uint8_t b_stub_part2[] = {
0xc0, 0x03, 0x3f, 0xd6, // blr x30 // call target_addr
0xe0, 0x0f, 0x1f, 0xf8, // str x0, [sp, #-16]!
0x00, 0x00, 0x80, 0xd2, // movz x0, key
};
instr = ((uint32_t*)b_stub_part2) + 2;
*instr |= (uint32_t)((key & 0xFFFF) << 5);
memcpy(dst + (instr_size >> 2), b_stub_part2, sizeof(b_stub_part2));
instr_size += sizeof(b_stub_part2);

instr_size += aarch64_put_adr_stub_abs( dst + (instr_size >> 2)
, (uint64_t)pop_x30
, 30
);

uint8_t b_stub_part3[] = {
0xc0, 0x03, 0x3f, 0xd6, // blr x30 // call pop_x30
0xfe, 0x03, 0x00, 0xaa, // mov x30, x0
0xe0, 0x07, 0x41, 0xf8, // ldr x0, [sp], #16
0xc0, 0x03, 0x5f, 0xd6, // ret
};
memcpy(dst + (instr_size >> 2), b_stub_part3, sizeof(b_stub_part3));
instr_size += sizeof(b_stub_part3);

STDERROR_PRINT("instr_size: %zu\n", instr_size);
++key;
return instr_size;
}

uint8_t aarch64_put_bl( uint32_t *dst
Expand Down Expand Up @@ -585,6 +623,26 @@ uint8_t aarch64_put_b_cond( uint32_t *dst
return 4;
}

uint8_t aarch64_put_b_cond_stub_abs( uint32_t *dst
, uint64_t target_addr
, uint8_t cond
)
{
// b_cond CONDITION_TRUE
// b CONDITION_FALSE
// CONDITION_TRUE:
// b_stub_abs
// CONDITION_FALSE:
uint8_t b_cond_size = aarch64_put_b_cond(dst, 0 , 8, cond);
uint8_t b_abs_size = aarch64_put_b_stub_abs(
dst + 2, // two jumps before absolute stub
target_addr
);
uint8_t b_size = aarch64_put_b(dst + 1, 0, 4 + b_abs_size);

return (b_cond_size + b_abs_size + b_size);
}

uint8_t aarch64_put_bc_cond( uint32_t *dst
, uint64_t pc
, uint64_t target_addr
Expand Down
8 changes: 6 additions & 2 deletions cTools/libs/arch/aarch64/aarch64.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***
* MIT License
*
* Copyright (c) 2023 Konychev Valera
* Copyright (c) 2023-2024 Konychev Valera
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -188,7 +188,6 @@ uint8_t aarch64_put_b_x16_stub_abs( uint32_t *dst
EXPORT_FUNC
uint8_t aarch64_put_b_stub_abs( uint32_t *dst
, uint64_t target_addr
, uint64_t x30_addr
);

#define SIZE_BL_STUB_ABS 20
Expand Down Expand Up @@ -263,6 +262,11 @@ uint8_t aarch64_put_b_cond( uint32_t *dst
, uint8_t cond
);
EXPORT_FUNC
uint8_t aarch64_put_b_cond_stub_abs( uint32_t *dst
, uint64_t target_addr
, uint8_t cond
);
EXPORT_FUNC
uint8_t aarch64_put_bc_cond( uint32_t *dst
, uint64_t pc
, uint64_t target_addr
Expand Down
40 changes: 31 additions & 9 deletions cTools/libs/arch/aarch64/aarch64_code_move.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "comdef.h"
#include "aarch64.h"
#include "aarch64_code_move.h"
#include "vt_containers.h"

#include <inttypes.h>

Expand Down Expand Up @@ -65,6 +66,7 @@ pre_init_relocations( vt_sorted_vector_t *rel
};

if (vt_sorted_vector_insert(rel, &r)) {
STDERROR_PRINT("fail\n");
return -1;
}
}
Expand Down Expand Up @@ -208,12 +210,11 @@ aarch64_move_b( uint32_t instr
);
} else {
STDERROR_LOG("B_STUB\n");
static uint64_t x30_temp = 0;
STDERROR_LOG("target_addr: %"PRIx64"\n", target_addr);
// We cannot fit offset into 26 bits. Need to place b_stub.
r->type = RELOC_AARCH64_B_ABS;
r->new_size = aarch64_put_b_stub_abs( (uint32_t*)dst
, target_addr
, (uint64_t)(&x30_temp)
);
}

Expand Down Expand Up @@ -362,6 +363,11 @@ aarch64_move_b_cond( uint32_t instr
);
} else {
STDERROR_LOG("BC: cannot fit in the 19 bits\n");
r->type = RELOC_AARCH64_B_COND_ABS;
r->new_size = aarch64_put_b_cond_stub_abs( (uint32_t*)dst
, target_addr
, cond
);
}

return r->new_size;
Expand Down Expand Up @@ -530,7 +536,13 @@ aarch64_instr_move( const uint8_t *src
return (CODE_MOVE_ERROR)r->new_size;
}

static void
extern void
resolve_relocations( vt_sorted_vector_t *rel
, uint8_t *dst
, uint64_t old_pc
, uint64_t instr_num
);
void
resolve_relocations( vt_sorted_vector_t *rel
, uint8_t *dst
, uint64_t old_pc
Expand All @@ -544,8 +556,8 @@ resolve_relocations( vt_sorted_vector_t *rel
bt_reloc *r = (bt_reloc*) vt_sorted_vector_find_elem(rel, &start_reloc);
uint64_t i = 0;
uint8_t *instr_p = dst;
for (i = 0; i < instr_num; ++i, instr_p += r[i].new_size) {
STDERROR_LOG("\tinstr_p: %p | new_size %u\n", (void*)instr_p, r[i].new_size);
for (i = 0; i < instr_num; instr_p += r[i].new_size, ++i) {
STDERROR_PRINT("\tinstr_p: %p | new_size %u\n", (void*)instr_p, r[i].new_size);
if (r[i].type == RELOC_GP) {
// General instructions doesn't need to rebase
continue;
Expand Down Expand Up @@ -649,10 +661,9 @@ resolve_relocations( vt_sorted_vector_t *rel
*/
case RELOC_AARCH64_B_ABS:
{
uint64_t x30_addr = *(uint64_t*)(instr_p + 48);
//uint64_t x30_addr = *(uint64_t*)(instr_p + 48);
aarch64_put_b_stub_abs( (uint32_t*)instr_p
, r[i].new_target
, x30_addr
);
break;
}
Expand Down Expand Up @@ -723,7 +734,7 @@ resolve_relocations( vt_sorted_vector_t *rel
}
case RELOC_AARCH64_B_COND:
{
STDERROR_LOG("Reloc B_COND:\n");
STDERROR_PRINT("Reloc B_COND:\n");
STDERROR_LOG("\told_target: 0x%"PRIx64", new_pc_old_target: 0x%"PRIx64"\n", r[i].old_target
, old_target->new_pc);
uint8_t cond = (*((uint32_t*)instr_p)) & 0xF;
Expand All @@ -734,6 +745,16 @@ resolve_relocations( vt_sorted_vector_t *rel
);
break;
}
case RELOC_AARCH64_B_COND_ABS:
{
STDERROR_PRINT("Reloc B_COND_ABS:\n");
uint8_t cond = (*((uint32_t*)instr_p)) & 0xF;
aarch64_put_b_cond_stub_abs( (uint32_t*)instr_p
, r[i].new_target
, cond
);
break;
}
case RELOC_AARCH64_CB:
{
STDERROR_LOG("Reloc CB:\n");
Expand Down Expand Up @@ -797,7 +818,8 @@ aarch64_code_move( const uint8_t *src
, dst_size
, rel
);
//print_bytes(stderr, dst, new_instr_size);
//print_bytes(stderr, dst + new_code_size, new_instr_size);
//putchar('\n');

new_code_size += new_instr_size;
}
Expand Down
12 changes: 6 additions & 6 deletions cTools/libs/arch/aarch64/aarch64_code_move.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ CODE_MOVE_ERROR aarch64_code_move( const uint8_t *src
* will return maximum estimation.
* @param[in] src_size Size of source binary code in bytes.
*/
EXPORT_FUNC
CODE_MOVE_ERROR aarch64_estimate_space( const uint8_t *src
, uint64_t old_pc
, uint64_t new_pc
, uint64_t src_size
);
EXPORT_FUNC CODE_MOVE_ERROR
aarch64_estimate_space( const uint8_t *src
, uint64_t old_pc
, uint64_t new_pc
, uint64_t src_size
);

#endif /* __AARCH64_CODE_MOVE_H */

Loading

0 comments on commit 4787bd0

Please sign in to comment.