From: "Alex Bennée" <alex.bennee@linaro.org>
To: Yeqi Fu <fufuyqqqqqq@gmail.com>
Cc: richard.henderson@linaro.org, qemu-devel@nongnu.org,
Paolo Bonzini <pbonzini@redhat.com>,
Thomas Huth <thuth@redhat.com>, Riku Voipio <riku.voipio@iki.fi>
Subject: Re: [RFC v4 02/11] build: Implement libnative library and the build machinery for libnative
Date: Wed, 09 Aug 2023 16:18:47 +0100 [thread overview]
Message-ID: <87wmy444vk.fsf@linaro.org> (raw)
In-Reply-To: <20230808141739.3110740-3-fufuyqqqqqq@gmail.com>
Yeqi Fu <fufuyqqqqqq@gmail.com> writes:
> This commit implements a shared library, where native functions are
> rewritten as special instructions. At runtime, user programs load
> the shared library, and special instructions are executed when
> native functions are called.
>
> Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com>
> ---
> Makefile | 2 +
> common-user/native/Makefile.include | 9 ++++
> common-user/native/Makefile.target | 22 ++++++++++
> common-user/native/libnative.c | 67 +++++++++++++++++++++++++++++
> configure | 39 +++++++++++++++++
> include/native/libnative.h | 8 ++++
> 6 files changed, 147 insertions(+)
> create mode 100644 common-user/native/Makefile.include
> create mode 100644 common-user/native/Makefile.target
> create mode 100644 common-user/native/libnative.c
> create mode 100644 include/native/libnative.h
>
> diff --git a/Makefile b/Makefile
> index 5d48dfac18..6f6147b40f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -182,6 +182,8 @@ SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet)
>
> include $(SRC_PATH)/tests/Makefile.include
>
> +include $(SRC_PATH)/common-user/native/Makefile.include
> +
> all: recurse-all
>
> ROMS_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(ROMS)))
> diff --git a/common-user/native/Makefile.include b/common-user/native/Makefile.include
> new file mode 100644
> index 0000000000..40d20bcd4c
> --- /dev/null
> +++ b/common-user/native/Makefile.include
> @@ -0,0 +1,9 @@
> +.PHONY: build-native
> +build-native: $(NATIVE_TARGETS:%=build-native-library-%)
> +$(NATIVE_TARGETS:%=build-native-library-%): build-native-library-%:
> + $(call quiet-command, \
> + $(MAKE) -C common-user/native/$* $(SUBDIR_MAKEFLAGS), \
> + "BUILD","$* native library")
> +# endif
> +
> +all: build-native
> diff --git a/common-user/native/Makefile.target b/common-user/native/Makefile.target
> new file mode 100644
> index 0000000000..0c1241b368
> --- /dev/null
> +++ b/common-user/native/Makefile.target
> @@ -0,0 +1,22 @@
> +# -*- Mode: makefile -*-
> +#
> +# Library for native calls
> +#
> +
> +all:
> +-include ../../config-host.mak
This is sensitive to the out of tree build structure the user chooses. For
example:
➜ pwd
/home/alex/lsrc/qemu.git/builds/user/common-user/native/aarch64-linux-user
🕙16:20:08 alex@zen:common-user/native/aarch64-linux-user on review/native-lib-calls-v4 [$!?]
➜ make libnative.so
make: *** No rule to make target '/common-user/native/libnative.c', needed by 'libnative.so'. Stop.
🕙16:20:13 alex@zen:common-user/native/aarch64-linux-user on review/native-lib-calls-v4 [$!?] [🔴 USAGE]
✗
I think this can be solved the same way as we do for tests/tcg by
symlinking the config-host.mak into place and referring to it directly
or adjusting the include to ../../../config-host.mak because the top of
the build tree has a symlinked copy as well.
> +-include config-target.mak
> +
> +CFLAGS+=-O1 -fPIC -shared -fno-stack-protector -I$(SRC_PATH)/include -D$(TARGET_NAME)
> +LDFLAGS+=
> +
> +SRC = $(SRC_PATH)/common-user/native/libnative.c
> +LIBNATIVE = libnative.so
> +
> +all: $(LIBNATIVE)
> +
> +$(LIBNATIVE): $(SRC)
> + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(EXTRA_NATIVE_CALL_FLAGS) $< -o $@ $(LDFLAGS)
> +
> +clean:
> + rm -f $(LIBNATIVE)
> diff --git a/common-user/native/libnative.c b/common-user/native/libnative.c
> new file mode 100644
> index 0000000000..662ae6fbfe
> --- /dev/null
> +++ b/common-user/native/libnative.c
> @@ -0,0 +1,67 @@
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#include "native/libnative.h"
> +
> +#define WRAP_NATIVE() \
> + do { \
> + __asm__ volatile(__CALL_EXPR : : : "memory"); \
> + } while (0)
> +
> +#if defined(i386) || defined(x86_64)
> +/*
> + * An unused instruction is utilized to mark a native call.
> + */
> +#define __CALL_EXPR ".byte 0x0f, 0xff;"
> +#endif
> +
> +#if defined(arm) || defined(aarch64)
> +/*
> + * HLT is an invalid instruction for userspace and usefully has 16
> + * bits of spare immeadiate data which we can stuff data in.
> + */
> +#define __CALL_EXPR "hlt 0xffff;"
> +#endif
> +
> +#if defined(mips) || defined(mips64)
> +/*
> + * The syscall instruction contains 20 unused bits, which are typically
> + * set to 0. These bits can be used to store non-zero data,
> + * distinguishing them from a regular syscall instruction.
> + */
> +#define __CALL_EXPR "syscall 0xffff;"
> +#endif
> +
> +void *memcpy(void *dest, const void *src, size_t n)
> +{
> + WRAP_NATIVE();
> +}
> +int memcmp(const void *s1, const void *s2, size_t n)
> +{
> + WRAP_NATIVE();
> +}
> +void *memset(void *s, int c, size_t n)
> +{
> + WRAP_NATIVE();
> +}
> +char *strncpy(char *dest, const char *src, size_t n)
> +{
> + WRAP_NATIVE();
> +}
> +int strncmp(const char *s1, const char *s2, size_t n)
> +{
> + WRAP_NATIVE();
> +}
> +char *strcpy(char *dest, const char *src)
> +{
> + WRAP_NATIVE();
> +}
> +char *strcat(char *dest, const char *src)
> +{
> + WRAP_NATIVE();
> +}
> +int strcmp(const char *s1, const char *s2)
> +{
> + WRAP_NATIVE();
> +}
> diff --git a/configure b/configure
> index a076583141..e02fc2c5c0 100755
> --- a/configure
> +++ b/configure
> @@ -1822,6 +1822,45 @@ if test "$tcg" = "enabled"; then
> fi
> )
>
> +# common-user/native configuration
> +(mkdir -p common-user/native
> +
> +native_targets=
> +for target in $target_list; do
> + case $target in
> + *-softmmu)
> + continue
> + ;;
> + esac
> +
> + # native call is only supported on these architectures
> + arch=${target%%-*}
> + config_target_mak=common-user/native/$target/config-target.mak
> + case $arch in
> + i386|x86_64|arm|aarch64|mips|mips64)
> + if test -f cross-build/$target/config-target.mak; then
> + mkdir -p "common-user/native/$target"
> + ln -srf cross-build/$target/config-target.mak "$config_target_mak"
> + if test $arch = arm; then
> + echo "EXTRA_NATIVE_CALL_FLAGS=-marm" >> "$config_target_mak"
> + fi
> + if test $arch = $cpu || \
> + { test $arch = i386 && test $cpu = x86_64; } || \
> + { test $arch = arm && test $cpu = aarch64; } || \
> + { test $arch = mips && test $cpu = mips64; }; then
> + echo "LD_PREFIX=/" >> "$config_target_mak"
> + fi
> + echo "LIBNATIVE=$PWD/common-user/native/$target/libnative.so" >> "$config_target_mak"
> + ln -sf $source_path/common-user/native/Makefile.target common-user/native/$target/Makefile
> + native_targets="$native_targets $target"
> + fi
> + ;;
> + esac
> +done
> +
> +echo "NATIVE_TARGETS=$native_targets" >> config-host.mak
> +)
> +
> if test "$skip_meson" = no; then
> cross="config-meson.cross.new"
> meson_quote() {
> diff --git a/include/native/libnative.h b/include/native/libnative.h
> new file mode 100644
> index 0000000000..ec990d8e5f
> --- /dev/null
> +++ b/include/native/libnative.h
> @@ -0,0 +1,8 @@
> +void *memset(void *s, int c, size_t n);
> +void *memcpy(void *dest, const void *src, size_t n);
> +char *strncpy(char *dest, const char *src, size_t n);
> +int memcmp(const void *s1, const void *s2, size_t n);
> +int strncmp(const char *s1, const char *s2, size_t n);
> +char *strcpy(char *dest, const char *src);
> +char *strcat(char *dest, const char *src);
> +int strcmp(const char *s1, const char *s2);
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2023-08-09 15:23 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-08 14:17 [RFC v4 00/11] Native Library Calls Yeqi Fu
2023-08-08 14:17 ` [RFC v4 01/11] build: Implement logic for sharing cross-building config files Yeqi Fu
2023-08-09 12:24 ` Manos Pitsidianakis
2023-08-09 14:42 ` Alex Bennée
2023-08-09 15:23 ` Alex Bennée
2023-08-10 8:41 ` Alex Bennée
2023-08-08 14:17 ` [RFC v4 02/11] build: Implement libnative library and the build machinery for libnative Yeqi Fu
2023-08-09 15:18 ` Alex Bennée [this message]
2023-08-09 16:10 ` Richard Henderson
2023-08-08 14:17 ` [RFC v4 03/11] linux-user: Implement envlist_appendenv and add tests for envlist Yeqi Fu
2023-08-09 15:27 ` Alex Bennée
2023-08-09 15:44 ` Richard Henderson
2023-08-09 16:06 ` Richard Henderson
2023-08-08 14:17 ` [RFC v4 04/11] linux-user: Implement native-bypass option support Yeqi Fu
2023-08-09 15:42 ` Richard Henderson
2023-08-09 15:47 ` Alex Bennée
2023-08-08 14:17 ` [RFC v4 05/11] linux-user/elfload: Add support for parsing symbols of native libraries Yeqi Fu
2023-08-09 16:14 ` Richard Henderson
2023-08-09 17:04 ` Alex Bennée
2023-08-08 14:17 ` [RFC v4 06/11] tcg: Add tcg opcodes and helpers for native library calls Yeqi Fu
2023-08-09 16:41 ` Alex Bennée
2023-08-08 14:17 ` [RFC v4 07/11] target/i386: Add support " Yeqi Fu
2023-08-09 16:44 ` Richard Henderson
2023-08-08 14:17 ` [RFC v4 08/11] target/mips: " Yeqi Fu
2023-08-08 14:17 ` [RFC v4 09/11] target/arm: " Yeqi Fu
2023-08-08 14:17 ` [RFC v4 10/11] tests/tcg/multiarch: Add nativecall.c test Yeqi Fu
2023-08-09 8:42 ` Alex Bennée
2023-08-09 17:01 ` Alex Bennée
2023-08-09 17:12 ` Alex Bennée
2023-08-08 14:17 ` [RFC v4 11/11] docs/user: Add doc for native library calls Yeqi Fu
2023-08-09 12:51 ` Manos Pitsidianakis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wmy444vk.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=fufuyqqqqqq@gmail.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=riku.voipio@iki.fi \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.