Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cTools/libs/arch/aarch64/aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,3 +675,23 @@ uint8_t aarch64_put_cb( uint32_t *dst
return 4;
}

uint8_t aarch64_put_tb( uint32_t *dst
, uint64_t pc
, uint64_t target_addr
, uint8_t reg_num
, bool non_zero
, bool x64
, uint8_t bit_pos
)
{
int64_t imm14 = SIGN_EXTEND((int64_t)(target_addr - pc) >> 2, 13);

*dst = (x64 ? 0x10000000 : 0x0)
| (uint32_t)0x36000000
| (non_zero ? 0x01000000 : 0x0)
| (uint32_t)(bit_pos & 0x1f) << 19
| (uint32_t)(imm14 & 0x3FFF) << 5
| (uint32_t)(reg_num & 0x1F);

return 4;
}
10 changes: 10 additions & 0 deletions cTools/libs/arch/aarch64/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,5 +282,15 @@ uint8_t aarch64_put_cb( uint32_t *dst
, bool x64
);

EXPORT_FUNC
uint8_t aarch64_put_tb( uint32_t *dst
, uint64_t pc
, uint64_t target_addr
, uint8_t reg_num
, bool non_zero
, bool x64
, uint8_t bit_pos
);

#endif /* __AARCH64_H */

83 changes: 77 additions & 6 deletions cTools/libs/arch/aarch64/aarch64_code_move.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ aarch64_move_b_cond( uint32_t instr
uint64_t new_target_addr = new_pc + ((uint64_t)new_imm19 << 2);
if (target_addr == new_target_addr) {
STDERROR_LOG("BC\n");
// We can fit offset into 26 bits.
// We can fit offset into 19 bits.
r->type = RELOC_AARCH64_B_COND;
r->new_size = aarch64_put_b_cond( (uint32_t*)dst
, new_pc
Expand Down Expand Up @@ -399,7 +399,7 @@ aarch64_move_cb( uint32_t instr
uint64_t new_target_addr = new_pc + ((uint64_t)new_imm19 << 2);
if (target_addr == new_target_addr) {
STDERROR_LOG("CB\n");
// We can fit offset into 26 bits.
// We can fit offset into 19 bits.
r->type = RELOC_AARCH64_CB;
r->new_size = aarch64_put_cb( (uint32_t*)dst
, new_pc
Expand All @@ -415,6 +415,50 @@ aarch64_move_cb( uint32_t instr
return r->new_size;
}

static uint8_t
aarch64_move_tb( uint32_t instr
, uint8_t *dst
, uint64_t old_pc
, uint64_t new_pc
, vt_sorted_vector_t *rel
)
{
bt_reloc *r = GET_PRE_INIT_BT_RELOC(rel);
bool x64 = !!(instr & 0x80000000);
bool non_zero = !!(instr & 0x01000000);
uint8_t reg_num = instr & 0x1F;
int64_t imm14 = SIGN_EXTEND((instr >> 5) & 0x3FFF, 13);
uint8_t bit_pos = (x64 ? 0x20 : 0)
| ((instr & 0x00f80000) >> 19);

uint64_t target_addr = old_pc + ((uint64_t)imm14 << 2);
r->old_target = target_addr;
target_addr = get_instr_new_addr(target_addr, rel);
r->new_target = target_addr;

int64_t new_imm14 = ((target_addr - new_pc) >> 2) & 0x3FFF;
new_imm14 = SIGN_EXTEND(new_imm14, 13);

uint64_t new_target_addr = new_pc + ((uint64_t)new_imm14 << 2);
if (target_addr == new_target_addr) {
// We can fit offset into 14 bits.
r->type = RELOC_AARCH64_TB;
r->new_size = aarch64_put_tb( (uint32_t*)dst
, new_pc
, target_addr
, reg_num
, non_zero
, x64
, bit_pos
);
} else {
STDERROR_LOG("TB: cannot fit in the 11 bits\n");
}

return r->new_size;

}

CODE_MOVE_ERROR
aarch64_instr_move( const uint8_t *src
, uint8_t *dst
Expand Down Expand Up @@ -501,6 +545,15 @@ aarch64_instr_move( const uint8_t *src
STDERROR_LOG("CB: new instr: %"PRIx32"\n", *(uint32_t*)dst);
break;
}
case AARCH64_INSTR_OP_TBZ32:
case AARCH64_INSTR_OP_TBNZ32:
case AARCH64_INSTR_OP_TBZ64:
FALLTHROUGH;
case AARCH64_INSTR_OP_TBNZ64:
{
r->new_size = aarch64_move_tb(instr, dst, old_pc, new_pc, rel);
break;
}
case AARCH64_INSTR_OP_BCEQ:
case AARCH64_INSTR_OP_BCNE:
case AARCH64_INSTR_OP_BCCS:
Expand All @@ -517,10 +570,6 @@ aarch64_instr_move( const uint8_t *src
case AARCH64_INSTR_OP_BCLE:
case AARCH64_INSTR_OP_RETAASPPC:
case AARCH64_INSTR_OP_RETABSPPC:
case AARCH64_INSTR_OP_TBZ32:
case AARCH64_INSTR_OP_TBNZ32:
case AARCH64_INSTR_OP_TBZ64:
case AARCH64_INSTR_OP_TBNZ64:
case AARCH64_INSTR_OP_LDRF32:
case AARCH64_INSTR_OP_LDRF64:
case AARCH64_INSTR_OP_LDRF128:
Expand Down Expand Up @@ -767,6 +816,28 @@ resolve_relocations( vt_sorted_vector_t *rel
STDERROR_LOG("\tFinal CB: %"PRIx32"\n", *(uint32_t*)instr_p);
break;
}
case RELOC_AARCH64_TB:
{
STDERROR_LOG("Reloc CB:\n");
STDERROR_LOG("\told_target: 0x%"PRIx64", new_pc_old_target: 0x%"PRIx64"\n", r[i].old_target
, old_target->new_pc);
bool x64 = !!((*((uint32_t*)instr_p)) & 0x80000000);
bool non_zero = !!((*((uint32_t*)instr_p)) & 0x01000000);
uint8_t bit_pos = (x64 ? 0x20 : 0)
| (((*((uint32_t*)instr_p)) & 0x00f80000) >> 19);

STDERROR_LOG("\tPre Final CB: %"PRIx32"\n", *(uint32_t*)instr_p);
aarch64_put_tb( (uint32_t*)instr_p
, r[i].new_pc
, r[i].new_target
, reg_num
, non_zero
, x64
, bit_pos
);
STDERROR_LOG("\tFinal CB: %"PRIx32"\n", *(uint32_t*)instr_p);
break;
}
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions cTools/libs/arch/code_move.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef enum {
RELOC_AARCH64_B_COND,
RELOC_AARCH64_B_COND_ABS,
RELOC_AARCH64_CB,
RELOC_AARCH64_TB
} RELOC_TYPE;

static_assert(sizeof(RELOC_TYPE) == 4, "RELOC_TYPE must be 32 bit");
Expand Down
5 changes: 5 additions & 0 deletions cmake/toolchain/cflags/coverage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" ST
if (NOT WIN32)
append_cflags(COVERAGE_CFLAGS "-fprofile-instr-generate -fcoverage-mapping")
endif ()
if ("${CMAKE_XCODE_BUILD_SYSTEM}" STREQUAL "12")
# Problem detected with xcode 12, maybe some other versions also contain
# Xcode doesn't link coverage library without this parameter
string(APPEND _LINKER_FLAGS " --coverage")
endif ()
endif ()

append_cflags(COVERAGE_CFLAGS -fno-omit-frame-pointer)
Expand Down