From: Richard Henderson <richard.henderson@linaro.org>
To: Yeqi Fu <fufuyqqqqqq@gmail.com>, alex.bennee@linaro.org
Cc: qemu-devel@nongnu.org, Paolo Bonzini <pbonzini@redhat.com>,
Thomas Huth <thuth@redhat.com>, Riku Voipio <riku.voipio@iki.fi>
Subject: Re: [RFC v5 02/10] build: Implement libnative library and the build machinery for libnative
Date: Fri, 25 Aug 2023 18:34:24 -0700 [thread overview]
Message-ID: <11a7fa7b-aa2b-65e1-b2b2-25b0eefee012@linaro.org> (raw)
In-Reply-To: <20230825102009.1754699-3-fufuyqqqqqq@gmail.com>
On 8/25/23 03:20, Yeqi Fu wrote:
> 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>
...
> diff --git a/common-user/native/libnative.S b/common-user/native/libnative.S
> new file mode 100644
> index 0000000000..3692eaa3cf
> --- /dev/null
> +++ b/common-user/native/libnative.S
> @@ -0,0 +1,69 @@
> +#if defined(i386) || defined(x86_64)
> +/*
> + * An unused instruction is utilized to mark a native call.
> + */
> +#define __SPECIAL_INSTR .byte 0x0f, 0xff;
> +#define __RET_INSTR ret;
> +#endif
> +
> +#if defined(arm) || defined(aarch64)
> +/*
> + * HLT is an invalid instruction for userspace programs,
> + * and is used to mark a native call.
> + */
> +#define __SPECIAL_INSTR hlt 0xffff;
> +#if defined(aarch64)
> +#define __RET_INSTR ret;
> +#else
> +#define __RET_INSTR bx lr;
> +#endif
> +#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 __SPECIAL_INSTR syscall 0xffff;
> +#define __RET_INSTR jr $ra;
> +#endif
> +
> +/* Symbols of native functions */
> +.section .data
> +sym_memset: .asciz "memset"
> +sym_memcpy: .asciz "memcpy"
> +sym_strncpy: .asciz "strncpy"
> +sym_memcmp: .asciz "memcmp"
> +sym_strncmp: .asciz "strncmp"
> +sym_strcpy: .asciz "strcpy"
> +sym_strcat: .asciz "strcat"
> +sym_strcmp: .asciz "strcmp"
> +
> +.macro define_function name
> +\name:
> +#if defined(x86_64) || defined(aarch64)
> + __SPECIAL_INSTR
> + .quad sym_\name
> + __RET_INSTR
> +#elif defined(mips64)
> +.align 4
> + __SPECIAL_INSTR
> + .quad sym_\name
> + __RET_INSTR
> +#elif defined(i386) || defined(mips) || defined(arm)
> + __SPECIAL_INSTR
> + .long sym_\name
> + __RET_INSTR
> +#endif
> +.endm
> +
> +define_function memcpy
> +define_function strncpy
> +define_function memset
> +define_function memcmp
> +define_function strncmp
> +define_function strcpy
> +define_function strcat
> +define_function strcmp
This cannot possibly work, since none of the symbols are marked .globl, and are therefore
not exported from your libnative.so.
Furthermore, you placed your strings in .data, but then failed to change back to .text, so
none of the instructions are in an executable load segment.
I conclude that your testing succeeded only because no library calls were replaced.
This is not sufficient testing.
In review of previous versions, I have mentioned that the x86 UD0 instruction has more
bytes than simply 0x0f 0xff -- at minimum 3 -- and moreover can be used in the assembler
to produce pc-relative values.
We can clean up the assembly as follows.
r~
-----
.macro special_instr sym
#if defined(__i386__)
ud0 \sym-1f, %eax; 1:
#elif defined(__x86_64__)
ud0 \sym(%rip), %eax
#elif defined(__arm__) || defined(__aarch64__)
hlt 0xffff
1: .word \sym - 1b
#elif defined(__mips__)
syscall 0xffff
1: .word \sym - 1b
#else
# error
#endif
.endm
.macro ret_instr
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
ret
#elif defined(__arm__)
bx lr
#elif defined(__mips__)
jr $ra
#else
# error
#endif
.endm
/* Symbols of native functions */
.macro define_function name
.text
\name:
special_instr 9f
ret_instr
.globl \name
.type \name, %function
.size \name, . - \name
.section .rodata
9: .asciz "\name"
.endm
define_function memcmp
define_function memcpy
define_function memset
define_function strcat
define_function strcmp
define_function strcpy
define_function strncmp
define_function strncpy
next prev parent reply other threads:[~2023-08-26 1:35 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-25 10:19 [RFC v5 00/10] Native Library Calls Yeqi Fu
2023-08-25 10:19 ` [RFC v5 01/10] build: Implement logic for sharing cross-building config files Yeqi Fu
2023-08-25 10:20 ` [RFC v5 02/10] build: Implement libnative library and the build machinery for libnative Yeqi Fu
2023-08-26 1:34 ` Richard Henderson [this message]
2023-08-25 10:20 ` [RFC v5 03/10] linux-user: Implement envlist_appendenv and add tests for envlist Yeqi Fu
2023-08-25 10:20 ` [RFC v5 04/10] linux-user: Implement native-bypass option support Yeqi Fu
2023-08-26 1:50 ` Richard Henderson
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=11a7fa7b-aa2b-65e1-b2b2-25b0eefee012@linaro.org \
--to=richard.henderson@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=fufuyqqqqqq@gmail.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).