[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] Native Library Calls
|
From: |
Alex Bennée |
|
Subject: |
Re: [RFC] Native Library Calls |
|
Date: |
Wed, 31 May 2023 09:02:12 +0100 |
|
User-agent: |
mu4e 1.11.6; emacs 29.0.91 |
Yeqi Fu <fufuyqqqqqq@gmail.com> writes:
> This patch introduces a set of feature instructions for native calls
> and provides helpers to translate these instructions to corresponding
> native functions. A shared library is also implemented, where native
> functions are rewritten as feature instructions. At runtime, user
> programs load the shared library, and feature instructions are
> executed when native functions are called. This patch is applicable
> to user programs with architectures x86, x86_64, arm, aarch64, mips,
> and mips64. To build, compile libnative.c into a shared library for
> the user program's architecture and run the
> '../configure --enable-user-native-call && make' command.
>
> Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com>
> ---
> include/exec/user/native-func.h | 8 +++
> libnative.c | 76 ++++++++++++++++++++++++++++
<snip>
> --- /dev/null
> +++ b/libnative.c
> @@ -0,0 +1,76 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#define NATIVE_MEMCPY 0x1001
> +#define NATIVE_MEMCMP 0x1002
> +#define NATIVE_MEMSET 0x1003
> +#define NATIVE_STRCPY 0x1004
> +#define NATIVE_STRCMP 0x1005
> +#define NATIVE_STRCAT 0x1006
> +
> +void *memcpy(void *dest, const void *src, size_t n);
> +int memcmp(const void *s1, const void *s2, size_t n);
> +void *memset(void *s, int c, size_t n);
> +char *strcpy(char *dest, const char *src);
> +int strcmp(const char *s1, const char *s2);
> +char *strcat(char *dest, const char *src);
> +
> +#define STR_MACRO(str) #str
> +#define STR(num) STR_MACRO(num)
> +
> +#if defined(TARGET_X86_64) || defined(TARGET_I386)
> +
> +/* unused opcode */
> +#define __PREFIX_INSTR \
> + ".byte 0x0f,0xff;"
> +
> +#define NATIVE_CALL_EXPR(func) \
> + __PREFIX_INSTR \
> + ".word " STR(func) ";" : : :
> +#endif
> +
> +#if defined(TARGET_ARM) || defined(TARGET_AARCH64)
> +
> +/* unused syscall number */
> +#define __PREFIX_INSTR \
> + "svc 0xff;"
> +
> +#define NATIVE_CALL_EXPR(func) \
> + __PREFIX_INSTR \
> + ".word " STR(func) ";" : : :
> +
> +#endif
> +
> +#if defined(TARGET_MIPS) || defined(TARGET_MIPS64)
> +
> +/* unused bytes in syscall instructions */
> +#define NATIVE_CALL_EXPR(func) \
> + ".long " STR((0x1 << 24) + (func << 8) + 0xC) ";" : : :
> +
> +#endif
> +
> +void *memcpy(void *dest, const void *src, size_t n)
> +{
> + __asm__ volatile(NATIVE_CALL_EXPR(NATIVE_MEMCPY));
> +}
> +
> +int memcmp(const void *s1, const void *s2, size_t n)
> +{
> + __asm__ volatile(NATIVE_CALL_EXPR(NATIVE_MEMCMP));
> +}
> +void *memset(void *s, int c, size_t n)
> +{
> + __asm__ volatile(NATIVE_CALL_EXPR(NATIVE_MEMSET));
> +}
> +char *strcpy(char *dest, const char *src)
> +{
> + __asm__ volatile(NATIVE_CALL_EXPR(NATIVE_STRCPY));
> +}
> +int strcmp(const char *s1, const char *s2)
> +{
> + __asm__ volatile(NATIVE_CALL_EXPR(NATIVE_STRCMP));
> +}
> +char *strcat(char *dest, const char *src)
> +{
> + __asm__ volatile(NATIVE_CALL_EXPR(NATIVE_STRCAT));
> +}
I've just realised we don't actually plumb libnative into the build. We
do have cross compilers available so we should use them when we have
them. See tests/tcg/$ARCH-linux-user/config-target.mak.
We also use these to build some of the firmware when needed.
--
Alex Bennée
Virtualisation Tech Lead @ Linaro