[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v6 7/9] target/arm: Add support for native library calls
From: |
Yeqi Fu |
Subject: |
[RFC v6 7/9] target/arm: Add support for native library calls |
Date: |
Wed, 13 Sep 2023 05:28:40 +0800 |
This commit introduces support for native library calls on the
arm target. When encountering special instructions reserved
for native calls, this commit extracts the function name and
generates the corresponding native call.
Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com>
---
configs/targets/aarch64-linux-user.mak | 1 +
configs/targets/arm-linux-user.mak | 1 +
target/arm/tcg/translate-a64.c | 32 ++++++++++++++++++++++++++
target/arm/tcg/translate.c | 29 +++++++++++++++++++++++
target/arm/tcg/translate.h | 5 ++++
5 files changed, 68 insertions(+)
diff --git a/configs/targets/aarch64-linux-user.mak
b/configs/targets/aarch64-linux-user.mak
index ba8bc5fe3f..5a8fd98cd9 100644
--- a/configs/targets/aarch64-linux-user.mak
+++ b/configs/targets/aarch64-linux-user.mak
@@ -4,3 +4,4 @@ TARGET_XML_FILES= gdb-xml/aarch64-core.xml
gdb-xml/aarch64-fpu.xml gdb-xml/aarch
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
+CONFIG_NATIVE_CALL=y
diff --git a/configs/targets/arm-linux-user.mak
b/configs/targets/arm-linux-user.mak
index 7f5d65794c..f934fb82da 100644
--- a/configs/targets/arm-linux-user.mak
+++ b/configs/targets/arm-linux-user.mak
@@ -5,3 +5,4 @@ TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml
gdb-xml/arm-vfp3.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
+CONFIG_NATIVE_CALL=y
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 3baab6aa60..00b69e9c24 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -25,6 +25,7 @@
#include "arm_ldst.h"
#include "semihosting/semihost.h"
#include "cpregs.h"
+#include "native/native.h"
static TCGv_i64 cpu_X[32];
static TCGv_i64 cpu_pc;
@@ -2400,6 +2401,10 @@ static bool trans_HLT(DisasContext *s, arg_i *a)
* it is required for halting debug disabled: it will UNDEF.
* Secondly, "HLT 0xf000" is the A64 semihosting syscall instruction.
*/
+ if (native_bypass_enabled() && (a->imm == 0xffff)) {
+ s->native_call_status = true;
+ return true;
+ }
if (semihosting_enabled(s->current_el == 0) && a->imm == 0xf000) {
gen_exception_internal_insn(s, EXCP_SEMIHOST);
} else {
@@ -13392,6 +13397,26 @@ void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs,
uint32_t rn_ofs,
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &op);
}
+static void gen_native_call(CPUState *cpu, DisasContext *s, CPUARMState *env)
+{
+#ifdef CONFIG_USER_ONLY
+ TCGv_i64 arg1 = tcg_temp_new_i64();
+ TCGv_i64 arg2 = tcg_temp_new_i64();
+ TCGv_i64 arg3 = tcg_temp_new_i64();
+ TCGv_i64 ret = tcg_temp_new_i64();
+ uint32_t func_tmp = translator_ldl_swap(env, &s->base, s->base.pc_next,
+ bswap_code(s->sctlr_b));
+ char *func_name = g2h(cpu, s->base.pc_next + func_tmp);
+ tcg_gen_mov_i64(arg1, cpu_reg(s, 0));
+ tcg_gen_mov_i64(arg2, cpu_reg(s, 1));
+ tcg_gen_mov_i64(arg3, cpu_reg(s, 2));
+ if (!gen_native_call_i64(func_name, ret, arg1, arg2, arg3)) {
+ unallocated_encoding(s);
+ }
+ tcg_gen_mov_i64(cpu_reg(s, 0), ret);
+#endif
+}
+
/* Crypto three-reg SHA512
* 31 21 20 16 15 14 13 12 11 10 9 5 4 0
* +-----------------------+------+---+---+-----+--------+------+------+
@@ -13950,6 +13975,13 @@ static void aarch64_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cpu)
uint64_t pc = s->base.pc_next;
uint32_t insn;
+ if (native_bypass_enabled() && s->native_call_status) {
+ gen_native_call(cpu, s, env);
+ s->base.pc_next = pc + 4;
+ s->native_call_status = false;
+ return;
+ }
+
/* Singlestep exceptions have the highest priority. */
if (s->ss_active && !s->pstate_ss) {
/* Singlestep state is Active-pending.
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 13c88ba1b9..7a5a0f9444 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -28,6 +28,7 @@
#include "semihosting/semihost.h"
#include "cpregs.h"
#include "exec/helper-proto.h"
+#include "native/native.h"
#define HELPER_H "helper.h"
#include "exec/helper-info.c.inc"
@@ -1125,6 +1126,23 @@ void gen_lookup_tb(DisasContext *s)
s->base.is_jmp = DISAS_EXIT;
}
+static void gen_native_call(CPUState *cpu, DisasContext *dc, CPUARMState *env)
+{
+#ifdef CONFIG_USER_ONLY
+ TCGv_i32 arg1 = load_reg(dc, 0);
+ TCGv_i32 arg2 = load_reg(dc, 1);
+ TCGv_i32 arg3 = load_reg(dc, 2);
+ TCGv_i32 ret = tcg_temp_new_i32();
+ uint32_t func_tmp =
+ arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
+ char *func_name = g2h(cpu, dc->base.pc_next + func_tmp);
+ if (!gen_native_call_i32(func_name, ret, arg1, arg2, arg3)) {
+ unallocated_encoding(dc);
+ }
+ store_reg(dc, 0, ret);
+#endif
+}
+
static inline void gen_hlt(DisasContext *s, int imm)
{
/* HLT. This has two purposes.
@@ -1139,6 +1157,10 @@ static inline void gen_hlt(DisasContext *s, int imm)
* semihosting, to provide some semblance of security
* (and for consistency with our 32-bit semihosting).
*/
+ if (native_bypass_enabled() && (imm == 0xffff)) {
+ s->native_call_status = true;
+ return;
+ }
if (semihosting_enabled(s->current_el == 0) &&
(imm == (s->thumb ? 0x3c : 0xf000))) {
gen_exception_internal_insn(s, EXCP_SEMIHOST);
@@ -9329,6 +9351,13 @@ static void arm_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cpu)
uint32_t pc = dc->base.pc_next;
unsigned int insn;
+ if (native_bypass_enabled() && dc->native_call_status) {
+ gen_native_call(cpu, dc, env);
+ dc->base.pc_next = pc + 4;
+ dc->native_call_status = false;
+ return;
+ }
+
/* Singlestep exceptions have the highest priority. */
if (arm_check_ss_active(dc)) {
dc->base.pc_next = pc + 4;
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index d1cacff0b2..3854a801e6 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -157,6 +157,11 @@ typedef struct DisasContext {
int c15_cpar;
/* TCG op of the current insn_start. */
TCGOp *insn_start;
+ /*
+ * Indicate whether the next instruction is a native function call (true)
+ * or not (false).
+ */
+ bool native_call_status;
} DisasContext;
typedef struct DisasCompare {
--
2.34.1
- [RFC v6 0/9] Native Library Calls, Yeqi Fu, 2023/09/12
- [RFC v6 1/9] build: Implement logic for sharing cross-building config files, Yeqi Fu, 2023/09/12
- [RFC v6 2/9] build: Implement libnative library and the build machinery for libnative, Yeqi Fu, 2023/09/12
- [RFC v6 3/9] linux-user: Implement native-bypass option support, Yeqi Fu, 2023/09/12
- [RFC v6 4/9] tcg: Add tcg opcodes and helpers for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 7/9] target/arm: Add support for native library calls,
Yeqi Fu <=
- [RFC v6 8/9] tests/tcg/multiarch: Add nativecall.c test, Yeqi Fu, 2023/09/12
- [RFC v6 5/9] target/i386: Add support for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 6/9] target/mips: Add support for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 9/9] docs/user: Add doc for native library calls, Yeqi Fu, 2023/09/12