diff --git a/.vscode/settings.json b/.vscode/settings.json index 9cf087d..211bbb3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -126,7 +126,8 @@ "bar.h": "c", "__bit_reference": "cpp", "aarch64.h": "c", - "charconv": "cpp" + "charconv": "cpp", + "__locale": "c" }, "C_Cpp.errorSquiggles": "enabled", diff --git a/cTools/libs/arch/aarch64/CMakeLists.txt b/cTools/libs/arch/aarch64/CMakeLists.txt index 4eee2ab..190d8ec 100644 --- a/cTools/libs/arch/aarch64/CMakeLists.txt +++ b/cTools/libs/arch/aarch64/CMakeLists.txt @@ -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 ) diff --git a/cTools/libs/arch/aarch64/aarch64.c b/cTools/libs/arch/aarch64/aarch64.c index 0d50825..0216676 100644 --- a/cTools/libs/arch/aarch64/aarch64.c +++ b/cTools/libs/arch/aarch64/aarch64.c @@ -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 @@ -25,6 +25,7 @@ #include "bits.h" #include "string.h" #include "aarch64.h" +#include "aarch64_global_stack.h" #include @@ -357,34 +358,70 @@ 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"); + uint8_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); + + ++key; + return instr_size; } uint8_t aarch64_put_bl( uint32_t *dst @@ -585,6 +622,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 diff --git a/cTools/libs/arch/aarch64/aarch64.h b/cTools/libs/arch/aarch64/aarch64.h index 19e92f4..0644f64 100644 --- a/cTools/libs/arch/aarch64/aarch64.h +++ b/cTools/libs/arch/aarch64/aarch64.h @@ -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 @@ -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 @@ -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 diff --git a/cTools/libs/arch/aarch64/aarch64_code_move.c b/cTools/libs/arch/aarch64/aarch64_code_move.c index 57a51e5..56627a6 100644 --- a/cTools/libs/arch/aarch64/aarch64_code_move.c +++ b/cTools/libs/arch/aarch64/aarch64_code_move.c @@ -28,6 +28,7 @@ #include "comdef.h" #include "aarch64.h" #include "aarch64_code_move.h" +#include "vt_containers.h" #include @@ -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; } } @@ -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) ); } @@ -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; @@ -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 @@ -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; @@ -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; } @@ -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; @@ -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"); @@ -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; } diff --git a/cTools/libs/arch/aarch64/aarch64_code_move.h b/cTools/libs/arch/aarch64/aarch64_code_move.h index 10fbfc1..9f547b1 100644 --- a/cTools/libs/arch/aarch64/aarch64_code_move.h +++ b/cTools/libs/arch/aarch64/aarch64_code_move.h @@ -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 */ diff --git a/cTools/libs/arch/aarch64/aarch64_global_stack.c b/cTools/libs/arch/aarch64/aarch64_global_stack.c new file mode 100644 index 0000000..9b343eb --- /dev/null +++ b/cTools/libs/arch/aarch64/aarch64_global_stack.c @@ -0,0 +1,168 @@ +/*** + * MIT License + * + * Copyright (c) 2024 Konychev Valerii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "vt_containers.h" +#include "aarch64_global_stack.h" +#include + +typedef struct { + uint64_t addr; + uint64_t key; +} ret_addr; + +static vt_stack_t global_stack = { + .v.capacity = 0, + .v.data = NULL, + .v.elem_size = sizeof(ret_addr), + .v.end = 0, +}; +static __attribute__ ((destructor(101))) +void desctructor_global_stack(void) +{ + vt_stack_fini(&global_stack); +} + +extern void _push_x30(uint64_t x30, uint16_t key); +void +_push_x30(uint64_t x30, uint16_t key) +{ + STDERROR_PRINT("push_x30 start: x30 0x%"PRIx64 ", key %"PRIu16"\n", x30, key); + ret_addr ret = { + .addr = x30, + .key = key, + }; + vt_stack_push(&global_stack, &ret); + STDERROR_PRINT("push_x30 end\n"); +} + +#if AARCH64_DEFINED == 1 +asm( +".globl _push_x30\n" +"_push_x30:\n" + "stp x0, x1, [sp, #-16]!\n" + "stp x2, x3, [sp, #-16]!\n" + "stp x4, x5, [sp, #-16]!\n" + "stp x6, x7, [sp, #-16]!\n" + "stp x8, x9, [sp, #-16]!\n" + "stp x10, x11, [sp, #-16]!\n" + "stp x12, x13, [sp, #-16]!\n" + "stp x14, x15, [sp, #-16]!\n" + "stp x16, x17, [sp, #-16]!\n" + "stp x18, x19, [sp, #-16]!\n" + "stp x20, x21, [sp, #-16]!\n" + "stp x22, x23, [sp, #-16]!\n" + "stp x24, x25, [sp, #-16]!\n" + "stp x26, x27, [sp, #-16]!\n" + "stp x28, x29, [sp, #-16]!\n" + "str x30, [sp, #-16]!\n" + "bl __push_x30\n" + "ldr x30, [sp], #16\n" + "ldp x28, x29, [sp], #16\n" + "ldp x26, x27, [sp], #16\n" + "ldp x24, x25, [sp], #16\n" + "ldp x22, x23, [sp], #16\n" + "ldp x20, x21, [sp], #16\n" + "ldp x18, x19, [sp], #16\n" + "ldp x16, x17, [sp], #16\n" + "ldp x14, x15, [sp], #16\n" + "ldp x12, x13, [sp], #16\n" + "ldp x10, x11, [sp], #16\n" + "ldp x8, x9, [sp], #16\n" + "ldp x6, x7, [sp], #16\n" + "ldp x4, x5, [sp], #16\n" + "ldp x2, x3, [sp], #16\n" + "ldp x0, x1, [sp], #16\n" + "ret\n" +); +#else // AARCH64_DEFINED +void +push_x30(uint64_t x30, uint16_t key) +{ + UNUSED(x30); + UNUSED(key); +} +#endif // AARCH64_DEFINED + +extern uint64_t _pop_x30(uint16_t key); +uint64_t +_pop_x30(uint16_t key) +{ + STDERROR_PRINT("pop_x30: key %"PRIu16"\n", key); + + ret_addr *ret; + do { + ret = (ret_addr*) vt_stack_pop(&global_stack); + STDERROR_PRINT("pop_x30: addr: 0x%"PRIx64", key %"PRIu64"\n", ret->addr, ret->key); + } while (ret->key != key); + + return ret->addr; +} + +#if AARCH64_DEFINED == 1 +asm( +".globl _pop_x30\n" +"_pop_x30:\n" + "str x1, [sp, #-16]!\n" + "stp x2, x3, [sp, #-16]!\n" + "stp x4, x5, [sp, #-16]!\n" + "stp x6, x7, [sp, #-16]!\n" + "stp x8, x9, [sp, #-16]!\n" + "stp x10, x11, [sp, #-16]!\n" + "stp x12, x13, [sp, #-16]!\n" + "stp x14, x15, [sp, #-16]!\n" + "stp x16, x17, [sp, #-16]!\n" + "stp x18, x19, [sp, #-16]!\n" + "stp x20, x21, [sp, #-16]!\n" + "stp x22, x23, [sp, #-16]!\n" + "stp x24, x25, [sp, #-16]!\n" + "stp x26, x27, [sp, #-16]!\n" + "stp x28, x29, [sp, #-16]!\n" + "str x30, [sp, #-16]!\n" + "bl __pop_x30\n" + "ldr x30, [sp], #16\n" + "ldp x28, x29, [sp], #16\n" + "ldp x26, x27, [sp], #16\n" + "ldp x24, x25, [sp], #16\n" + "ldp x22, x23, [sp], #16\n" + "ldp x20, x21, [sp], #16\n" + "ldp x18, x19, [sp], #16\n" + "ldp x16, x17, [sp], #16\n" + "ldp x14, x15, [sp], #16\n" + "ldp x12, x13, [sp], #16\n" + "ldp x10, x11, [sp], #16\n" + "ldp x8, x9, [sp], #16\n" + "ldp x6, x7, [sp], #16\n" + "ldp x4, x5, [sp], #16\n" + "ldp x2, x3, [sp], #16\n" + "ldr x1, [sp], #16\n" + "ret\n" +); +#else // AARCH64_DEFINED +void +pop_x30(uint16_t key) +{ + UNUSED(key); +} +#endif // AARCH64_DEFINED + diff --git a/cTools/libs/arch/aarch64/aarch64_global_stack.h b/cTools/libs/arch/aarch64/aarch64_global_stack.h new file mode 100644 index 0000000..3825e4f --- /dev/null +++ b/cTools/libs/arch/aarch64/aarch64_global_stack.h @@ -0,0 +1,38 @@ +/*** + * MIT License + * + * Copyright (c) 2023 Konychev Valerii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __AARCH64_GLOBAL_STACK_H +#define __AARCH64_GLOBAL_STACK_H + +#include "os.h" +#include + +EXPORT_FUNC void +push_x30(uint64_t x30, uint16_t key); + +EXPORT_FUNC void +pop_x30(uint16_t key); + +#endif /* __AARCH64_GLOBAL_STACK_H */ + diff --git a/cTools/libs/arch/aarch64/test/aarch64_code_move.c b/cTools/libs/arch/aarch64/test/aarch64_code_move.c index 2b920c0..0a9fbe9 100644 --- a/cTools/libs/arch/aarch64/test/aarch64_code_move.c +++ b/cTools/libs/arch/aarch64/test/aarch64_code_move.c @@ -27,6 +27,7 @@ #include "comdef.h" #include "binParse.h" #include "aarch64_code_move.h" +#include "aarch64_global_stack.h" #include #include @@ -86,12 +87,25 @@ void call_func5(uint32_t *n) } } +static volatile +uint32_t temp6 = 0; +extern +void call_func6(uint32_t *n); +void call_func6(uint32_t *n) +{ + ++temp6; + if (temp6 == 3) { + return; + } + + call_func6(n); +} + extern void test_move_and_exec(void *func, const char *fn, void *arg);// __attribute__((section("__TEXT,__my_sect"))); void test_move_and_exec(void *func, const char *fn, void *arg) { - STDERROR_PRINT("arg %p\n", arg); BinSymPtr sym = binParser.getSymByName(binParser.bin, fn); uint64_t func_size = binParser.getSSymSize(binParser.bin, sym); uint64_t buff_size = (uint64_t)aarch64_estimate_space( (const uint8_t*)func @@ -100,6 +114,7 @@ void test_move_and_exec(void *func, const char *fn, void *arg) , func_size ); + buff_size += 1024; uint8_t *buff = Calloc(buff_size, 1); if (buff == NULL) return; @@ -129,9 +144,6 @@ void test_move_and_exec(void *func, const char *fn, void *arg) } Free(buff); vt_sorted_vector_fini(&sv); - - //asm("msr NZCV, x1\n"); - //asm("mrs x0, NZCV"); } #endif /* AARCH64_DEFINED == 1 */ @@ -139,19 +151,18 @@ void test_move_and_exec(void *func, const char *fn, void *arg) int main(int argc, const char *argv[]) { UNUSED(argc); - UNUSED(argv); - //VERBOSE = 1; initBinParser(argv[0]); #if AARCH64_DEFINED == 1 test_move_and_exec(call_func0, SYM_PREFIX"call_func0", NULL); test_move_and_exec(call_func1, SYM_PREFIX"call_func1", NULL); - uint32_t arg32 = 2; + uint32_t arg32 = 3; test_move_and_exec(call_func2, SYM_PREFIX"call_func2", &arg32); test_move_and_exec(call_func3, SYM_PREFIX"call_func3", &arg32); test_move_and_exec(call_func4, SYM_PREFIX"call_func4", &arg32); test_move_and_exec(call_func5, SYM_PREFIX"call_func5", &arg32); + test_move_and_exec(call_func6, SYM_PREFIX"call_func6", &arg32); #endif /* AARCH64_DEFINED == 1 */ finiBinParser(); diff --git a/cTools/libs/arch/code_move.h b/cTools/libs/arch/code_move.h index f33c71d..0145f71 100644 --- a/cTools/libs/arch/code_move.h +++ b/cTools/libs/arch/code_move.h @@ -62,6 +62,7 @@ typedef enum { RELOC_AARCH64_LDR_ABS48, RELOC_AARCH64_LDR_ABS, RELOC_AARCH64_B_COND, + RELOC_AARCH64_B_COND_ABS, RELOC_AARCH64_CB, } RELOC_TYPE; diff --git a/cTools/libs/containers/tests/vt_vector_test.c b/cTools/libs/containers/tests/vt_vector_test.c index a251732..7382007 100644 --- a/cTools/libs/containers/tests/vt_vector_test.c +++ b/cTools/libs/containers/tests/vt_vector_test.c @@ -115,13 +115,32 @@ vt_vector_for_each_test(void) --i; for (; i >= 0 ; --i) { - EXPECT_INT_EQ(*(int*) vt_vector_pop_back(&v), i + 2); + int res = *(int*) vt_vector_pop_back(&v); + EXPECT_INT_EQ(i + 2, res); } vt_vector_fini(&v); return 0; } +static vt_vector_t global_vector = { + .capacity = 0, + .data = NULL, + .elem_size = sizeof(int), + .end = 0, +}; +static void +vt_vector_null_global_test(void) +{ + int i = 0; + vt_vector_push_back(&global_vector, &i); + i = 100; + vt_vector_push_back(&global_vector, &i); + int res = *(int*) vt_vector_pop_back(&global_vector); + EXPECT_INT_EQ(i, res); + vt_vector_fini(&global_vector); +} + int main(void) { @@ -129,6 +148,7 @@ main(void) EXPECT_FUNC_EQ(vt_vector_push_back_test(), 0); EXPECT_FUNC_EQ(vt_vector_pop_back_test(), 0); EXPECT_FUNC_EQ(vt_vector_for_each_test(), 0); + vt_vector_null_global_test(); return 0; } diff --git a/cTools/libs/containers/vt_sorted_vector.c b/cTools/libs/containers/vt_sorted_vector.c index 8058fc6..ebc844e 100644 --- a/cTools/libs/containers/vt_sorted_vector.c +++ b/cTools/libs/containers/vt_sorted_vector.c @@ -35,7 +35,7 @@ vt_sorted_vector_find_elem(const vt_sorted_vector_t *sv, const void* elem) const vt_vector_t *v = (const vt_vector_t*)sv; int (*cmp)(const void *, const void *) = sv->cmp; - return bsearch(elem, v->data, v->end + 1, v->elem_size, cmp); + return bsearch(elem, v->data, v->end, v->elem_size, cmp); } int @@ -43,7 +43,11 @@ vt_sorted_vector_insert(vt_sorted_vector_t *sv, const void* elem) { vt_vector_t *v = (vt_vector_t*)sv; if (v->capacity == v->end) { - if (vt_vector_resize(v, v->capacity * 2) == -1) { + size_t new_cap = v->capacity * 2; + if (new_cap == 0) { + new_cap = 1; + } + if (vt_vector_resize(v, new_cap) == -1) { LOG_ERROR("Cannot expand Vector"); return -1; } diff --git a/cTools/libs/containers/vt_stack.h b/cTools/libs/containers/vt_stack.h index 6d7b023..0f5d965 100644 --- a/cTools/libs/containers/vt_stack.h +++ b/cTools/libs/containers/vt_stack.h @@ -55,6 +55,7 @@ vt_stack_init(vt_stack_t *s, size_t capacity, size_t elem_size) static inline void vt_stack_fini(vt_stack_t *s) { + STDERROR_PRINT("vt_stack_fini\n"); vt_vector_fini((vt_vector_t*)s); } diff --git a/cTools/libs/containers/vt_vector.c b/cTools/libs/containers/vt_vector.c index ab86241..7688ef0 100644 --- a/cTools/libs/containers/vt_vector.c +++ b/cTools/libs/containers/vt_vector.c @@ -72,6 +72,7 @@ int vt_vector_resize(vt_vector_t *v, size_t capacity) { v->capacity = capacity; + STDERROR_PRINT("capacity: %zu, elem_size: %zu\n", capacity, v->elem_size); void *data = Malloc(capacity * v->elem_size); if (data == NULL) { LOG_ERROR("Cannot allocate memory"); @@ -83,7 +84,9 @@ vt_vector_resize(vt_vector_t *v, size_t capacity) } size_t num = v->end; - directCopyBytes(v->data, data, num * v->elem_size); + if (v->end) { + directCopyBytes(v->data, data, num * v->elem_size); + } Free(v->data); v->data = data; @@ -94,7 +97,11 @@ vt_vector_resize(vt_vector_t *v, size_t capacity) static int vt_vector_expand(vt_vector_t *v) { - return vt_vector_resize(v, v->capacity *= 2); + size_t new_cap = v->capacity *= 2; + if (new_cap == 0) { + new_cap = 1; + } + return vt_vector_resize(v, new_cap); } int