From b688d202901dcde10e2f42a33732ebb658c82842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20V=C3=A1rady?= Date: Mon, 3 Jan 2022 02:20:30 +0100 Subject: [PATCH] exe-elf: word-align trampoline code Thumb is a halfword-aligned instruction set encoding, but our trampoline code uses a PC-relative jump, which needs to be positioned on a word aligned address. --- src/exe-elf-arm-fixup.h | 18 +++++++++++++++++- src/exe-elf.c | 5 +---- src/exe-elf.h | 4 ++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/exe-elf-arm-fixup.h b/src/exe-elf-arm-fixup.h index cb63d05..da0384f 100644 --- a/src/exe-elf-arm-fixup.h +++ b/src/exe-elf-arm-fixup.h @@ -29,10 +29,16 @@ #include #include +#include "common.h" +#include "exe-elf.h" + extern void *bxfi_trampoline_thumb; extern void *bxfi_trampoline_thumb_addr; extern void *bxfi_trampoline_thumb_end; +extern void *bxfi_trampoline_thumb_nop; +extern void *bxfi_trampoline_thumb_nop_end; + static inline int bxfi_exe_is_arm_thumb_func(void *func_addr) { return (uintptr_t) func_addr & 0x1U; @@ -44,6 +50,11 @@ static inline void bxfi_exe_fix_func_addr_if_in_arm_thumb_mode(void **addr) *addr = (void *) (uintptr_t) ((uintptr_t) *addr & ~0x1ULL); } +static inline int bxfi_exe_is_arm_func_word_aligned(void *func_addr) +{ + return ((uintptr_t) func_addr & 0x3U) == 0; +} + static inline void bxfi_exe_trampoline_fixup(void **func_to_patch, void **trampoline, void **trampoline_end, void **trampoline_addr) { @@ -58,7 +69,12 @@ static inline void bxfi_exe_trampoline_fixup(void **func_to_patch, void **trampo static inline size_t bxfi_exe_inject_prelude(void *func_to_patch) { - return 0; + if (bxfi_exe_is_arm_func_word_aligned(func_to_patch)) + return 0; + + size_t nop_len = BXFI_TRAMPOLINE_SIZE(&bxfi_trampoline_thumb_nop, &bxfi_trampoline_thumb_nop_end); + memcpy(nonstd (void *) func_to_patch, &bxfi_trampoline_thumb_nop, nop_len); + return nop_len; } #endif /* !EXE_ELF_ARM_FIXUP_H_ */ diff --git a/src/exe-elf.c b/src/exe-elf.c index b5a2e17..30a6857 100644 --- a/src/exe-elf.c +++ b/src/exe-elf.c @@ -29,6 +29,7 @@ #include "config.h" #include "exe.h" +#include "exe-elf.h" #include "addr.h" #include "common.h" @@ -158,10 +159,6 @@ extern void *bxfi_trampoline; extern void *bxfi_trampoline_addr; extern void *bxfi_trampoline_end; -#define BXFI_TRAMPOLINE_SIZE(Start, End) \ - ((uintptr_t) End \ - - (uintptr_t) Start) - int bxfi_exe_patch_main(bxfi_exe_fn *new_main) { void *addr = nonstd (void *) &main; diff --git a/src/exe-elf.h b/src/exe-elf.h index 8434463..543757d 100644 --- a/src/exe-elf.h +++ b/src/exe-elf.h @@ -33,6 +33,10 @@ # define ElfW__(e, t) e ## t #endif +#define BXFI_TRAMPOLINE_SIZE(Start, End) \ + ((uintptr_t) End \ + - (uintptr_t) Start) + typedef struct link_map *bxfi_exe_lib; typedef struct r_debug *bxfi_exe_ctx; typedef void (bxfi_exe_fn)(void);