* [PATCH v1 01/11] tools/nolibc: x86-64: Update System V ABI document link
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 02/11] tools/nolibc: Remove .global _start from the entry point code Ammar Faizi
` (9 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi
The old link no longer works, update it.
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link RFC v2: https://lore.kernel.org/lkml/[email protected]/
RFC v2 -> v1:
* No changes *
Link RFC v1: https://lore.kernel.org/lkml/[email protected]
RFC v1 -> RFC v2:
* No changes *
---
tools/include/nolibc/arch-x86_64.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index fe517c16cd4d..a7b70ea51b68 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -61,7 +61,7 @@ struct sys_stat_struct {
* - see also x86-64 ABI section A.2 AMD64 Linux Kernel Conventions, A.2.1
* Calling Conventions.
*
- * Link x86-64 ABI: https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/x86-64-psABI
+ * Link x86-64 ABI: https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/home
*
*/
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 02/11] tools/nolibc: Remove .global _start from the entry point code
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 01/11] tools/nolibc: x86-64: Update System V ABI document link Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 03/11] tools/nolibc: Replace `asm` with `__asm__` Ammar Faizi
` (8 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi,
llvm, Nick Desaulniers
Building with clang yields the following error:
```
<inline asm>:3:1: error: _start changed binding to STB_GLOBAL
.global _start
^
1 error generated.
```
Make sure only specify one between `.global _start` and `.weak _start`.
Remove `.global _start`.
Cc: [email protected]
Reviewed-by: Nick Desaulniers <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link RFC v2: https://lore.kernel.org/llvm/[email protected]
RFC v2 -> v1:
- Append Reviewed-by tag from Nick.
- s/Removing/remove/
Link RFC v1: https://lore.kernel.org/llvm/[email protected]
RFC v1 -> RFC v2:
- Remove all `.global _start` for all build (GCC and Clang) instead of
removing all `.weak _start` for clang build (Comment from Willy).
---
tools/include/nolibc/arch-aarch64.h | 1 -
tools/include/nolibc/arch-arm.h | 1 -
tools/include/nolibc/arch-i386.h | 1 -
tools/include/nolibc/arch-mips.h | 1 -
tools/include/nolibc/arch-riscv.h | 1 -
tools/include/nolibc/arch-x86_64.h | 1 -
6 files changed, 6 deletions(-)
diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h
index 87d9e434820c..2dbd80d633cb 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/arch-aarch64.h
@@ -184,7 +184,6 @@ struct sys_stat_struct {
/* startup code */
asm(".section .text\n"
".weak _start\n"
- ".global _start\n"
"_start:\n"
"ldr x0, [sp]\n" // argc (x0) was in the stack
"add x1, sp, 8\n" // argv (x1) = sp
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 001a3c8c9ad5..1191395b5acd 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -177,7 +177,6 @@ struct sys_stat_struct {
/* startup code */
asm(".section .text\n"
".weak _start\n"
- ".global _start\n"
"_start:\n"
#if defined(__THUMBEB__) || defined(__THUMBEL__)
/* We enter here in 32-bit mode but if some previous functions were in
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index d7e4d53325a3..125a691fc631 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -176,7 +176,6 @@ struct sys_stat_struct {
*/
asm(".section .text\n"
".weak _start\n"
- ".global _start\n"
"_start:\n"
"pop %eax\n" // argc (first arg, %eax)
"mov %esp, %ebx\n" // argv[] (second arg, %ebx)
diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index c9a6aac87c6d..1a124790c99f 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -192,7 +192,6 @@ struct sys_stat_struct {
asm(".section .text\n"
".weak __start\n"
".set nomips16\n"
- ".global __start\n"
".set noreorder\n"
".option pic0\n"
".ent __start\n"
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index bc10b7b5706d..511d67fc534e 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -185,7 +185,6 @@ struct sys_stat_struct {
/* startup code */
asm(".section .text\n"
".weak _start\n"
- ".global _start\n"
"_start:\n"
".option push\n"
".option norelax\n"
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index a7b70ea51b68..84c174181425 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -199,7 +199,6 @@ struct sys_stat_struct {
*/
asm(".section .text\n"
".weak _start\n"
- ".global _start\n"
"_start:\n"
"pop %rdi\n" // argc (first arg, %rdi)
"mov %rsp, %rsi\n" // argv[] (second arg, %rsi)
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 03/11] tools/nolibc: Replace `asm` with `__asm__`
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 01/11] tools/nolibc: x86-64: Update System V ABI document link Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 02/11] tools/nolibc: Remove .global _start from the entry point code Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:41 ` Willy Tarreau
2022-03-24 7:30 ` [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist Ammar Faizi
` (7 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi
Replace `asm` with `__asm__` to support compilation with -std flag.
Using `asm` with -std flag makes GCC think `asm()` is a function call
instead of an inline assembly.
GCC doc says:
For the C language, the `asm` keyword is a GNU extension. When
writing C code that can be compiled with `-ansi` and the `-std`
options that select C dialects without GNU extensions, use
`__asm__` instead of `asm`.
Link: https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html
Reported-by: Alviro Iskandar Setiawan <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
In private conversation with Alviro, we found that using -std flag hits
the following errors:
```
In file included from arch.h:21,
from nolibc.h:97,
from test.c:2:
arch-i386.h:177:5: error: expected declaration specifiers or ‘...’ before string constant
177 | asm(".section .text\n"
| ^~~~~~~~~~~~~~~~~~
sys.h: In function ‘sys_brk’:
arch-i386.h:83:28: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘asm’
83 | register long _num asm("eax") = (num); \
| ^~~
sys.h:57:24: note: in expansion of macro ‘my_syscall1’
57 | return (void *)my_syscall1(__NR_brk, addr);
| ^~~~~~~~~~~
arch-i386.h:83:28: warning: implicit declaration of function ‘asm’ [-Wimplicit-function-declaration]
83 | register long _num asm("eax") = (num); \
| ^~~
sys.h:57:24: note: in expansion of macro ‘my_syscall1’
57 | return (void *)my_syscall1(__NR_brk, addr);
| ^~~~~~~~~~~
arch-i386.h:83:39: error: lvalue required as left operand of assignment
83 | register long _num asm("eax") = (num); \
| ^
sys.h:57:24: note: in expansion of macro ‘my_syscall1’
57 | return (void *)my_syscall1(__NR_brk, addr);
| ^~~~~~~~~~~
arch-i386.h:84:29: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘asm’
84 | register long _arg1 asm("ebx") = (long)(arg1); \
```
It is because inline ASM is a GNU extension. So GCC thinks asm() is a
function call. To make it always available for any kind of compilation,
use `__asm__` instead of `asm`.
---
tools/include/nolibc/arch-aarch64.h | 72 ++++++++++++++--------------
tools/include/nolibc/arch-arm.h | 58 +++++++++++-----------
tools/include/nolibc/arch-i386.h | 56 +++++++++++-----------
tools/include/nolibc/arch-mips.h | 62 ++++++++++++------------
tools/include/nolibc/arch-riscv.h | 74 ++++++++++++++---------------
tools/include/nolibc/arch-x86_64.h | 72 ++++++++++++++--------------
6 files changed, 197 insertions(+), 197 deletions(-)
diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h
index 2dbd80d633cb..d7f4fcf46d51 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/arch-aarch64.h
@@ -64,10 +64,10 @@ struct sys_stat_struct {
#define my_syscall0(num) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0"); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_num) \
@@ -78,10 +78,10 @@ struct sys_stat_struct {
#define my_syscall1(num, arg1) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0") = (long)(arg1); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0") = (long)(arg1); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), \
@@ -93,11 +93,11 @@ struct sys_stat_struct {
#define my_syscall2(num, arg1, arg2) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0") = (long)(arg1); \
- register long _arg2 asm("x1") = (long)(arg2); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0") = (long)(arg1); \
+ register long _arg2 __asm__("x1") = (long)(arg2); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), "r"(_arg2), \
@@ -109,12 +109,12 @@ struct sys_stat_struct {
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0") = (long)(arg1); \
- register long _arg2 asm("x1") = (long)(arg2); \
- register long _arg3 asm("x2") = (long)(arg3); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0") = (long)(arg1); \
+ register long _arg2 __asm__("x1") = (long)(arg2); \
+ register long _arg3 __asm__("x2") = (long)(arg3); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), \
@@ -126,13 +126,13 @@ struct sys_stat_struct {
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0") = (long)(arg1); \
- register long _arg2 asm("x1") = (long)(arg2); \
- register long _arg3 asm("x2") = (long)(arg3); \
- register long _arg4 asm("x3") = (long)(arg4); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0") = (long)(arg1); \
+ register long _arg2 __asm__("x1") = (long)(arg2); \
+ register long _arg3 __asm__("x2") = (long)(arg3); \
+ register long _arg4 __asm__("x3") = (long)(arg4); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
@@ -144,14 +144,14 @@ struct sys_stat_struct {
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0") = (long)(arg1); \
- register long _arg2 asm("x1") = (long)(arg2); \
- register long _arg3 asm("x2") = (long)(arg3); \
- register long _arg4 asm("x3") = (long)(arg4); \
- register long _arg5 asm("x4") = (long)(arg5); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0") = (long)(arg1); \
+ register long _arg2 __asm__("x1") = (long)(arg2); \
+ register long _arg3 __asm__("x2") = (long)(arg3); \
+ register long _arg4 __asm__("x3") = (long)(arg4); \
+ register long _arg5 __asm__("x4") = (long)(arg5); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r" (_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
@@ -163,15 +163,15 @@ struct sys_stat_struct {
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
- register long _num asm("x8") = (num); \
- register long _arg1 asm("x0") = (long)(arg1); \
- register long _arg2 asm("x1") = (long)(arg2); \
- register long _arg3 asm("x2") = (long)(arg3); \
- register long _arg4 asm("x3") = (long)(arg4); \
- register long _arg5 asm("x4") = (long)(arg5); \
- register long _arg6 asm("x5") = (long)(arg6); \
+ register long _num __asm__("x8") = (num); \
+ register long _arg1 __asm__("x0") = (long)(arg1); \
+ register long _arg2 __asm__("x1") = (long)(arg2); \
+ register long _arg3 __asm__("x2") = (long)(arg3); \
+ register long _arg4 __asm__("x3") = (long)(arg4); \
+ register long _arg5 __asm__("x4") = (long)(arg5); \
+ register long _arg6 __asm__("x5") = (long)(arg6); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r" (_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 1191395b5acd..0e88cbe42588 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -77,10 +77,10 @@ struct sys_stat_struct {
#define my_syscall0(num) \
({ \
- register long _num asm("r7") = (num); \
- register long _arg1 asm("r0"); \
+ register long _num __asm__("r7") = (num); \
+ register long _arg1 __asm__("r0"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_num) \
@@ -91,10 +91,10 @@ struct sys_stat_struct {
#define my_syscall1(num, arg1) \
({ \
- register long _num asm("r7") = (num); \
- register long _arg1 asm("r0") = (long)(arg1); \
+ register long _num __asm__("r7") = (num); \
+ register long _arg1 __asm__("r0") = (long)(arg1); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), \
@@ -106,11 +106,11 @@ struct sys_stat_struct {
#define my_syscall2(num, arg1, arg2) \
({ \
- register long _num asm("r7") = (num); \
- register long _arg1 asm("r0") = (long)(arg1); \
- register long _arg2 asm("r1") = (long)(arg2); \
+ register long _num __asm__("r7") = (num); \
+ register long _arg1 __asm__("r0") = (long)(arg1); \
+ register long _arg2 __asm__("r1") = (long)(arg2); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), "r"(_arg2), \
@@ -122,12 +122,12 @@ struct sys_stat_struct {
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
- register long _num asm("r7") = (num); \
- register long _arg1 asm("r0") = (long)(arg1); \
- register long _arg2 asm("r1") = (long)(arg2); \
- register long _arg3 asm("r2") = (long)(arg3); \
+ register long _num __asm__("r7") = (num); \
+ register long _arg1 __asm__("r0") = (long)(arg1); \
+ register long _arg2 __asm__("r1") = (long)(arg2); \
+ register long _arg3 __asm__("r2") = (long)(arg3); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), \
@@ -139,13 +139,13 @@ struct sys_stat_struct {
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
- register long _num asm("r7") = (num); \
- register long _arg1 asm("r0") = (long)(arg1); \
- register long _arg2 asm("r1") = (long)(arg2); \
- register long _arg3 asm("r2") = (long)(arg3); \
- register long _arg4 asm("r3") = (long)(arg4); \
+ register long _num __asm__("r7") = (num); \
+ register long _arg1 __asm__("r0") = (long)(arg1); \
+ register long _arg2 __asm__("r1") = (long)(arg2); \
+ register long _arg3 __asm__("r2") = (long)(arg3); \
+ register long _arg4 __asm__("r3") = (long)(arg4); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r"(_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
@@ -157,14 +157,14 @@ struct sys_stat_struct {
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- register long _num asm("r7") = (num); \
- register long _arg1 asm("r0") = (long)(arg1); \
- register long _arg2 asm("r1") = (long)(arg2); \
- register long _arg3 asm("r2") = (long)(arg3); \
- register long _arg4 asm("r3") = (long)(arg4); \
- register long _arg5 asm("r4") = (long)(arg5); \
+ register long _num __asm__("r7") = (num); \
+ register long _arg1 __asm__("r0") = (long)(arg1); \
+ register long _arg2 __asm__("r1") = (long)(arg2); \
+ register long _arg3 __asm__("r2") = (long)(arg3); \
+ register long _arg4 __asm__("r3") = (long)(arg4); \
+ register long _arg5 __asm__("r4") = (long)(arg5); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"svc #0\n" \
: "=r" (_arg1) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
@@ -175,7 +175,7 @@ struct sys_stat_struct {
})
/* startup code */
-asm(".section .text\n"
+__asm__(".section .text\n"
".weak _start\n"
"_start:\n"
#if defined(__THUMBEB__) || defined(__THUMBEL__)
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index 125a691fc631..ff2e6bb453cf 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -66,9 +66,9 @@ struct sys_stat_struct {
#define my_syscall0(num) \
({ \
long _ret; \
- register long _num asm("eax") = (num); \
+ register long _num __asm__("eax") = (num); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"int $0x80\n" \
: "=a" (_ret) \
: "0"(_num) \
@@ -80,10 +80,10 @@ struct sys_stat_struct {
#define my_syscall1(num, arg1) \
({ \
long _ret; \
- register long _num asm("eax") = (num); \
- register long _arg1 asm("ebx") = (long)(arg1); \
+ register long _num __asm__("eax") = (num); \
+ register long _arg1 __asm__("ebx") = (long)(arg1); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"int $0x80\n" \
: "=a" (_ret) \
: "r"(_arg1), \
@@ -96,11 +96,11 @@ struct sys_stat_struct {
#define my_syscall2(num, arg1, arg2) \
({ \
long _ret; \
- register long _num asm("eax") = (num); \
- register long _arg1 asm("ebx") = (long)(arg1); \
- register long _arg2 asm("ecx") = (long)(arg2); \
+ register long _num __asm__("eax") = (num); \
+ register long _arg1 __asm__("ebx") = (long)(arg1); \
+ register long _arg2 __asm__("ecx") = (long)(arg2); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"int $0x80\n" \
: "=a" (_ret) \
: "r"(_arg1), "r"(_arg2), \
@@ -113,12 +113,12 @@ struct sys_stat_struct {
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
long _ret; \
- register long _num asm("eax") = (num); \
- register long _arg1 asm("ebx") = (long)(arg1); \
- register long _arg2 asm("ecx") = (long)(arg2); \
- register long _arg3 asm("edx") = (long)(arg3); \
+ register long _num __asm__("eax") = (num); \
+ register long _arg1 __asm__("ebx") = (long)(arg1); \
+ register long _arg2 __asm__("ecx") = (long)(arg2); \
+ register long _arg3 __asm__("edx") = (long)(arg3); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"int $0x80\n" \
: "=a" (_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), \
@@ -131,13 +131,13 @@ struct sys_stat_struct {
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
long _ret; \
- register long _num asm("eax") = (num); \
- register long _arg1 asm("ebx") = (long)(arg1); \
- register long _arg2 asm("ecx") = (long)(arg2); \
- register long _arg3 asm("edx") = (long)(arg3); \
- register long _arg4 asm("esi") = (long)(arg4); \
+ register long _num __asm__("eax") = (num); \
+ register long _arg1 __asm__("ebx") = (long)(arg1); \
+ register long _arg2 __asm__("ecx") = (long)(arg2); \
+ register long _arg3 __asm__("edx") = (long)(arg3); \
+ register long _arg4 __asm__("esi") = (long)(arg4); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"int $0x80\n" \
: "=a" (_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
@@ -150,14 +150,14 @@ struct sys_stat_struct {
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
long _ret; \
- register long _num asm("eax") = (num); \
- register long _arg1 asm("ebx") = (long)(arg1); \
- register long _arg2 asm("ecx") = (long)(arg2); \
- register long _arg3 asm("edx") = (long)(arg3); \
- register long _arg4 asm("esi") = (long)(arg4); \
- register long _arg5 asm("edi") = (long)(arg5); \
+ register long _num __asm__("eax") = (num); \
+ register long _arg1 __asm__("ebx") = (long)(arg1); \
+ register long _arg2 __asm__("ecx") = (long)(arg2); \
+ register long _arg3 __asm__("edx") = (long)(arg3); \
+ register long _arg4 __asm__("esi") = (long)(arg4); \
+ register long _arg5 __asm__("edi") = (long)(arg5); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"int $0x80\n" \
: "=a" (_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
@@ -174,7 +174,7 @@ struct sys_stat_struct {
* 2) The deepest stack frame should be set to zero
*
*/
-asm(".section .text\n"
+__asm__(".section .text\n"
".weak _start\n"
"_start:\n"
"pop %eax\n" // argc (first arg, %eax)
diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index 1a124790c99f..b43da77fde0e 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -69,10 +69,10 @@ struct sys_stat_struct {
#define my_syscall0(num) \
({ \
- register long _num asm("v0") = (num); \
- register long _arg4 asm("a3"); \
+ register long _num __asm__("v0") = (num); \
+ register long _arg4 __asm__("a3"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"addiu $sp, $sp, -32\n" \
"syscall\n" \
"addiu $sp, $sp, 32\n" \
@@ -86,11 +86,11 @@ struct sys_stat_struct {
#define my_syscall1(num, arg1) \
({ \
- register long _num asm("v0") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg4 asm("a3"); \
+ register long _num __asm__("v0") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg4 __asm__("a3"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"addiu $sp, $sp, -32\n" \
"syscall\n" \
"addiu $sp, $sp, 32\n" \
@@ -105,12 +105,12 @@ struct sys_stat_struct {
#define my_syscall2(num, arg1, arg2) \
({ \
- register long _num asm("v0") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg4 asm("a3"); \
+ register long _num __asm__("v0") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg4 __asm__("a3"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"addiu $sp, $sp, -32\n" \
"syscall\n" \
"addiu $sp, $sp, 32\n" \
@@ -125,13 +125,13 @@ struct sys_stat_struct {
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
- register long _num asm("v0") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
- register long _arg4 asm("a3"); \
+ register long _num __asm__("v0") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
+ register long _arg4 __asm__("a3"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"addiu $sp, $sp, -32\n" \
"syscall\n" \
"addiu $sp, $sp, 32\n" \
@@ -146,13 +146,13 @@ struct sys_stat_struct {
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
- register long _num asm("v0") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
- register long _arg4 asm("a3") = (long)(arg4); \
+ register long _num __asm__("v0") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
+ register long _arg4 __asm__("a3") = (long)(arg4); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"addiu $sp, $sp, -32\n" \
"syscall\n" \
"addiu $sp, $sp, 32\n" \
@@ -167,14 +167,14 @@ struct sys_stat_struct {
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- register long _num asm("v0") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
- register long _arg4 asm("a3") = (long)(arg4); \
+ register long _num __asm__("v0") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
+ register long _arg4 __asm__("a3") = (long)(arg4); \
register long _arg5 = (long)(arg5); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"addiu $sp, $sp, -32\n" \
"sw %7, 16($sp)\n" \
"syscall\n " \
@@ -189,7 +189,7 @@ struct sys_stat_struct {
})
/* startup code, note that it's called __start on MIPS */
-asm(".section .text\n"
+__asm__(".section .text\n"
".weak __start\n"
".set nomips16\n"
".set noreorder\n"
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index 511d67fc534e..100bc71da344 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -66,10 +66,10 @@ struct sys_stat_struct {
#define my_syscall0(num) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0"); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0"); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n\t" \
: "=r"(_arg1) \
: "r"(_num) \
@@ -80,10 +80,10 @@ struct sys_stat_struct {
#define my_syscall1(num, arg1) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_num) \
@@ -94,11 +94,11 @@ struct sys_stat_struct {
#define my_syscall2(num, arg1, arg2) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), \
@@ -110,12 +110,12 @@ struct sys_stat_struct {
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n\t" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), \
@@ -127,13 +127,13 @@ struct sys_stat_struct {
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
- register long _arg4 asm("a3") = (long)(arg4); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
+ register long _arg4 __asm__("a3") = (long)(arg4); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), "r"(_arg4), \
@@ -145,14 +145,14 @@ struct sys_stat_struct {
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
- register long _arg4 asm("a3") = (long)(arg4); \
- register long _arg5 asm("a4") = (long)(arg5); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
+ register long _arg4 __asm__("a3") = (long)(arg4); \
+ register long _arg5 __asm__("a4") = (long)(arg5); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
@@ -164,15 +164,15 @@ struct sys_stat_struct {
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
- register long _num asm("a7") = (num); \
- register long _arg1 asm("a0") = (long)(arg1); \
- register long _arg2 asm("a1") = (long)(arg2); \
- register long _arg3 asm("a2") = (long)(arg3); \
- register long _arg4 asm("a3") = (long)(arg4); \
- register long _arg5 asm("a4") = (long)(arg5); \
- register long _arg6 asm("a5") = (long)(arg6); \
+ register long _num __asm__("a7") = (num); \
+ register long _arg1 __asm__("a0") = (long)(arg1); \
+ register long _arg2 __asm__("a1") = (long)(arg2); \
+ register long _arg3 __asm__("a2") = (long)(arg3); \
+ register long _arg4 __asm__("a3") = (long)(arg4); \
+ register long _arg5 __asm__("a4") = (long)(arg5); \
+ register long _arg6 __asm__("a5") = (long)(arg6); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
@@ -183,7 +183,7 @@ struct sys_stat_struct {
})
/* startup code */
-asm(".section .text\n"
+__asm__(".section .text\n"
".weak _start\n"
"_start:\n"
".option push\n"
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index 84c174181425..afc50f84a036 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -68,9 +68,9 @@ struct sys_stat_struct {
#define my_syscall0(num) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
+ register long _num __asm__("rax") = (num); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "0"(_num) \
@@ -82,10 +82,10 @@ struct sys_stat_struct {
#define my_syscall1(num, arg1) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
- register long _arg1 asm("rdi") = (long)(arg1); \
+ register long _num __asm__("rax") = (num); \
+ register long _arg1 __asm__("rdi") = (long)(arg1); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "r"(_arg1), \
@@ -98,11 +98,11 @@ struct sys_stat_struct {
#define my_syscall2(num, arg1, arg2) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
- register long _arg1 asm("rdi") = (long)(arg1); \
- register long _arg2 asm("rsi") = (long)(arg2); \
+ register long _num __asm__("rax") = (num); \
+ register long _arg1 __asm__("rdi") = (long)(arg1); \
+ register long _arg2 __asm__("rsi") = (long)(arg2); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "r"(_arg1), "r"(_arg2), \
@@ -115,12 +115,12 @@ struct sys_stat_struct {
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
- register long _arg1 asm("rdi") = (long)(arg1); \
- register long _arg2 asm("rsi") = (long)(arg2); \
- register long _arg3 asm("rdx") = (long)(arg3); \
+ register long _num __asm__("rax") = (num); \
+ register long _arg1 __asm__("rdi") = (long)(arg1); \
+ register long _arg2 __asm__("rsi") = (long)(arg2); \
+ register long _arg3 __asm__("rdx") = (long)(arg3); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), \
@@ -133,13 +133,13 @@ struct sys_stat_struct {
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
- register long _arg1 asm("rdi") = (long)(arg1); \
- register long _arg2 asm("rsi") = (long)(arg2); \
- register long _arg3 asm("rdx") = (long)(arg3); \
- register long _arg4 asm("r10") = (long)(arg4); \
+ register long _num __asm__("rax") = (num); \
+ register long _arg1 __asm__("rdi") = (long)(arg1); \
+ register long _arg2 __asm__("rsi") = (long)(arg2); \
+ register long _arg3 __asm__("rdx") = (long)(arg3); \
+ register long _arg4 __asm__("r10") = (long)(arg4); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
@@ -152,14 +152,14 @@ struct sys_stat_struct {
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
- register long _arg1 asm("rdi") = (long)(arg1); \
- register long _arg2 asm("rsi") = (long)(arg2); \
- register long _arg3 asm("rdx") = (long)(arg3); \
- register long _arg4 asm("r10") = (long)(arg4); \
- register long _arg5 asm("r8") = (long)(arg5); \
+ register long _num __asm__("rax") = (num); \
+ register long _arg1 __asm__("rdi") = (long)(arg1); \
+ register long _arg2 __asm__("rsi") = (long)(arg2); \
+ register long _arg3 __asm__("rdx") = (long)(arg3); \
+ register long _arg4 __asm__("r10") = (long)(arg4); \
+ register long _arg5 __asm__("r8") = (long)(arg5); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
@@ -172,15 +172,15 @@ struct sys_stat_struct {
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
long _ret; \
- register long _num asm("rax") = (num); \
- register long _arg1 asm("rdi") = (long)(arg1); \
- register long _arg2 asm("rsi") = (long)(arg2); \
- register long _arg3 asm("rdx") = (long)(arg3); \
- register long _arg4 asm("r10") = (long)(arg4); \
- register long _arg5 asm("r8") = (long)(arg5); \
- register long _arg6 asm("r9") = (long)(arg6); \
+ register long _num __asm__("rax") = (num); \
+ register long _arg1 __asm__("rdi") = (long)(arg1); \
+ register long _arg2 __asm__("rsi") = (long)(arg2); \
+ register long _arg3 __asm__("rdx") = (long)(arg3); \
+ register long _arg4 __asm__("r10") = (long)(arg4); \
+ register long _arg5 __asm__("r8") = (long)(arg5); \
+ register long _arg6 __asm__("r9") = (long)(arg6); \
\
- asm volatile ( \
+ __asm__ volatile ( \
"syscall\n" \
: "=a"(_ret) \
: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
@@ -197,7 +197,7 @@ struct sys_stat_struct {
* 2) The deepest stack frame should be zero (the %rbp).
*
*/
-asm(".section .text\n"
+__asm__(".section .text\n"
".weak _start\n"
"_start:\n"
"pop %rdi\n" // argc (first arg, %rdi)
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v1 03/11] tools/nolibc: Replace `asm` with `__asm__`
2022-03-24 7:30 ` [PATCH v1 03/11] tools/nolibc: Replace `asm` with `__asm__` Ammar Faizi
@ 2022-03-24 7:41 ` Willy Tarreau
2022-03-24 9:03 ` Ammar Faizi
0 siblings, 1 reply; 18+ messages in thread
From: Willy Tarreau @ 2022-03-24 7:41 UTC (permalink / raw)
To: Ammar Faizi
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List
On Thu, Mar 24, 2022 at 02:30:31PM +0700, Ammar Faizi wrote:
> Replace `asm` with `__asm__` to support compilation with -std flag.
> Using `asm` with -std flag makes GCC think `asm()` is a function call
> instead of an inline assembly.
OK fair enough, and if we have to do it, better do it early anyway.
Thanks,
Willy
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 03/11] tools/nolibc: Replace `asm` with `__asm__`
2022-03-24 7:41 ` Willy Tarreau
@ 2022-03-24 9:03 ` Ammar Faizi
0 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 9:03 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List
On 3/24/22 2:41 PM, Willy Tarreau wrote:
> On Thu, Mar 24, 2022 at 02:30:31PM +0700, Ammar Faizi wrote:
>> Replace `asm` with `__asm__` to support compilation with -std flag.
>> Using `asm` with -std flag makes GCC think `asm()` is a function call
>> instead of an inline assembly.
>
> OK fair enough, and if we have to do it, better do it early anyway.
I will make this one as the second patch after patch that fixes the
System V ABI document link (in the next version). So this will be
[PATCH 02/N].
Please holler if it should be the first patch.
--
Ammar Faizi
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (2 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 03/11] tools/nolibc: Replace `asm` with `__asm__` Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:57 ` Willy Tarreau
2022-03-24 7:30 ` [PATCH v1 05/11] tools/nolibc: i386: " Ammar Faizi
` (6 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi,
David Laight
Use appropriate register constraints if exist. Don't use register
variables for all inputs.
Register variables with "r" constraint should be used when we need to
pass data through a specific register to extended inline assembly that
doesn't have a specific register constraint associated with it (anything
outside %rax, %rbx, %rcx, %rdx, %rsi, %rdi).
It also simplifies the macro definition.
Link: https://lore.kernel.org/lkml/[email protected]
Suggested-by: David Laight <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
tools/include/nolibc/arch-x86_64.h | 202 +++++++++++++----------------
1 file changed, 91 insertions(+), 111 deletions(-)
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index afc50f84a036..3067f553c03c 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -65,129 +65,109 @@ struct sys_stat_struct {
*
*/
-#define my_syscall0(num) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall0(num) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall1(num, arg1) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- register long _arg1 __asm__("rdi") = (long)(arg1); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "r"(_arg1), \
- "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall1(num, arg1) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : "D"(arg1) /* %rdi */ \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall2(num, arg1, arg2) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- register long _arg1 __asm__("rdi") = (long)(arg1); \
- register long _arg2 __asm__("rsi") = (long)(arg2); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "r"(_arg1), "r"(_arg2), \
- "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall2(num, arg1, arg2) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : "D"(arg1), /* %rdi */ \
+ "S"(arg2) /* %rsi */ \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall3(num, arg1, arg2, arg3) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- register long _arg1 __asm__("rdi") = (long)(arg1); \
- register long _arg2 __asm__("rsi") = (long)(arg2); \
- register long _arg3 __asm__("rdx") = (long)(arg3); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), \
- "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall3(num, arg1, arg2, arg3) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : "D"(arg1), /* %rdi */ \
+ "S"(arg2), /* %rsi */ \
+ "d"(arg3) /* %rdx */ \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall4(num, arg1, arg2, arg3, arg4) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- register long _arg1 __asm__("rdi") = (long)(arg1); \
- register long _arg2 __asm__("rsi") = (long)(arg2); \
- register long _arg3 __asm__("rdx") = (long)(arg3); \
- register long _arg4 __asm__("r10") = (long)(arg4); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
- "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall4(num, arg1, arg2, arg3, arg4) \
+({ \
+ long _ret = (num); \
+ register long _arg4 __asm__("r10") = (long)(arg4); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : "D"(arg1), /* %rdi */ \
+ "S"(arg2), /* %rsi */ \
+ "d"(arg3), /* %rdx */ \
+ "r"(_arg4) /* %r10 */ \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- register long _arg1 __asm__("rdi") = (long)(arg1); \
- register long _arg2 __asm__("rsi") = (long)(arg2); \
- register long _arg3 __asm__("rdx") = (long)(arg3); \
- register long _arg4 __asm__("r10") = (long)(arg4); \
- register long _arg5 __asm__("r8") = (long)(arg5); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
- "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ long _ret = (num); \
+ register long _arg4 __asm__("r10") = (long)(arg4); \
+ register long _arg5 __asm__("r8") = (long)(arg5); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : "D"(arg1), /* %rdi */ \
+ "S"(arg2), /* %rsi */ \
+ "d"(arg3), /* %rdx */ \
+ "r"(_arg4), /* %r10 */ \
+ "r"(_arg5) /* %r8 */ \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
-({ \
- long _ret; \
- register long _num __asm__("rax") = (num); \
- register long _arg1 __asm__("rdi") = (long)(arg1); \
- register long _arg2 __asm__("rsi") = (long)(arg2); \
- register long _arg3 __asm__("rdx") = (long)(arg3); \
- register long _arg4 __asm__("r10") = (long)(arg4); \
- register long _arg5 __asm__("r8") = (long)(arg5); \
- register long _arg6 __asm__("r9") = (long)(arg6); \
- \
- __asm__ volatile ( \
- "syscall\n" \
- : "=a"(_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
- "r"(_arg6), "0"(_num) \
- : "rcx", "r11", "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ long _ret = (num); \
+ register long _arg4 __asm__("r10") = (long)(arg4); \
+ register long _arg5 __asm__("r8") = (long)(arg5); \
+ register long _arg6 __asm__("r9") = (long)(arg6); \
+ __asm__ volatile ( \
+ "syscall\n" \
+ : "+a"(_ret) /* %rax */ \
+ : "D"(arg1), /* %rdi */ \
+ "S"(arg2), /* %rsi */ \
+ "d"(arg3), /* %rdx */ \
+ "r"(_arg4), /* %r10 */ \
+ "r"(_arg5), /* %r8 */ \
+ "r"(_arg6) /* %r9 */ \
+ : "rcx", "r11", "memory", "cc" \
+ ); \
+ _ret; \
})
/* startup code */
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist
2022-03-24 7:30 ` [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist Ammar Faizi
@ 2022-03-24 7:57 ` Willy Tarreau
2022-03-24 8:33 ` Alviro Iskandar Setiawan
0 siblings, 1 reply; 18+ messages in thread
From: Willy Tarreau @ 2022-03-24 7:57 UTC (permalink / raw)
To: Ammar Faizi
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, David Laight
On Thu, Mar 24, 2022 at 02:30:32PM +0700, Ammar Faizi wrote:
> Use appropriate register constraints if exist. Don't use register
> variables for all inputs.
>
> Register variables with "r" constraint should be used when we need to
> pass data through a specific register to extended inline assembly that
> doesn't have a specific register constraint associated with it (anything
> outside %rax, %rbx, %rcx, %rdx, %rsi, %rdi).
>
> It also simplifies the macro definition.
I'm a bit bothered by this one because I went the exact opposite route
in the early design precisely because I found that the current one was
simpler. E.g, I personally find this one:
> -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
> -({ \
> - long _ret; \
> - register long _num __asm__("rax") = (num); \
> - register long _arg1 __asm__("rdi") = (long)(arg1); \
> - register long _arg2 __asm__("rsi") = (long)(arg2); \
> - register long _arg3 __asm__("rdx") = (long)(arg3); \
> - register long _arg4 __asm__("r10") = (long)(arg4); \
> - register long _arg5 __asm__("r8") = (long)(arg5); \
> - register long _arg6 __asm__("r9") = (long)(arg6); \
> - \
> - __asm__ volatile ( \
> - "syscall\n" \
> - : "=a"(_ret) \
> - : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
> - "r"(_arg6), "0"(_num) \
> - : "rcx", "r11", "memory", "cc" \
> - ); \
> - _ret; \
Easier to grasp than this one:
> +#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
> +({ \
> + long _ret = (num); \
> + register long _arg4 __asm__("r10") = (long)(arg4); \
> + register long _arg5 __asm__("r8") = (long)(arg5); \
> + register long _arg6 __asm__("r9") = (long)(arg6); \
> + __asm__ volatile ( \
> + "syscall\n" \
> + : "+a"(_ret) /* %rax */ \
> + : "D"(arg1), /* %rdi */ \
> + "S"(arg2), /* %rsi */ \
> + "d"(arg3), /* %rdx */ \
> + "r"(_arg4), /* %r10 */ \
> + "r"(_arg5), /* %r8 */ \
> + "r"(_arg6) /* %r9 */ \
> + : "rcx", "r11", "memory", "cc" \
> + ); \
> + _ret; \
> })
where only half of the registers are described at one place and the
other half is described in comments at another place. But admittedly
it's a matter of taste. However the same approach was adopted for all
other archs (arm, aarch64, mips, riscv) and I tend to find it easier
to compare the ABI between architectures when all registers are
described at once than when two of them (i386 and x86_64) make an
exception.
I'd say that if there is any technical benefit in doing this (occasional
code improvement or better support for older or exotic compilers), I'd say
"ok go for it", but if it's only a matter of taste, I'm not convinced at
all and am rather seeing this as a regression. Now if there's rough
consensus around this approach I'll abide, but then I'd request that other
archs are adapted as well so that we don't keep a different approach only
for these two ones.
Thanks,
Willy
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist
2022-03-24 7:57 ` Willy Tarreau
@ 2022-03-24 8:33 ` Alviro Iskandar Setiawan
2022-03-24 9:00 ` Ammar Faizi
2022-03-24 15:42 ` Willy Tarreau
0 siblings, 2 replies; 18+ messages in thread
From: Alviro Iskandar Setiawan @ 2022-03-24 8:33 UTC (permalink / raw)
To: Willy Tarreau
Cc: Ammar Faizi, Paul E. McKenney, Nugraha, Linux Kernel Mailing List,
GNU/Weeb Mailing List, David Laight
On Thu, Mar 24, 2022 at 2:57 PM Willy Tarreau <[email protected]> wrote:
> On Thu, Mar 24, 2022 at 02:30:32PM +0700, Ammar Faizi wrote:
> > Use appropriate register constraints if exist. Don't use register
> > variables for all inputs.
> >
> > Register variables with "r" constraint should be used when we need to
> > pass data through a specific register to extended inline assembly that
> > doesn't have a specific register constraint associated with it (anything
> > outside %rax, %rbx, %rcx, %rdx, %rsi, %rdi).
> >
> > It also simplifies the macro definition.
>
> I'm a bit bothered by this one because I went the exact opposite route
> in the early design precisely because I found that the current one was
> simpler. [...]
[...]
> I'd say that if there is any technical benefit in doing this (occasional
> code improvement or better support for older or exotic compilers), I'd say
> "ok go for it", but if it's only a matter of taste, I'm not convinced at
> all and am rather seeing this as a regression. Now if there's rough
> consensus around this approach I'll abide, but then I'd request that other
> archs are adapted as well so that we don't keep a different approach only
> for these two ones.
I don't see any technical benefit for x86-64, so I don't think there
is a need in doing this. Though I personally prefer to use register
constraints if they exist instead of register variables for everything
(oh yeah, matter of taste since I don't have any technical argument to
say it's better respecting the resulting codegen). The only real issue
is for the syscall6() implementation on i386 as we've been bitten by a
real compiler issue. In short, I am neutral on this change.
Regards~~
-- Viro
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist
2022-03-24 8:33 ` Alviro Iskandar Setiawan
@ 2022-03-24 9:00 ` Ammar Faizi
2022-03-24 15:42 ` Willy Tarreau
1 sibling, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 9:00 UTC (permalink / raw)
To: Alviro Iskandar Setiawan, Willy Tarreau
Cc: Paul E. McKenney, Nugraha, Linux Kernel Mailing List,
GNU/Weeb Mailing List, David Laight
On 3/24/22 3:33 PM, Alviro Iskandar Setiawan wrote:
> On Thu, Mar 24, 2022 at 2:57 PM Willy Tarreau <[email protected]> wrote:
>> On Thu, Mar 24, 2022 at 02:30:32PM +0700, Ammar Faizi wrote:
>>> Use appropriate register constraints if exist. Don't use register
>>> variables for all inputs.
>>>
>>> Register variables with "r" constraint should be used when we need to
>>> pass data through a specific register to extended inline assembly that
>>> doesn't have a specific register constraint associated with it (anything
>>> outside %rax, %rbx, %rcx, %rdx, %rsi, %rdi).
>>>
>>> It also simplifies the macro definition.
>>
>> I'm a bit bothered by this one because I went the exact opposite route
>> in the early design precisely because I found that the current one was
>> simpler. [...]
> [...]
>> I'd say that if there is any technical benefit in doing this (occasional
>> code improvement or better support for older or exotic compilers), I'd say
>> "ok go for it", but if it's only a matter of taste, I'm not convinced at
>> all and am rather seeing this as a regression. Now if there's rough
>> consensus around this approach I'll abide, but then I'd request that other
>> archs are adapted as well so that we don't keep a different approach only
>> for these two ones.
>
> I don't see any technical benefit for x86-64, so I don't think there
> is a need in doing this. Though I personally prefer to use register
> constraints if they exist instead of register variables for everything
> (oh yeah, matter of taste since I don't have any technical argument to
> say it's better respecting the resulting codegen). The only real issue
> is for the syscall6() implementation on i386 as we've been bitten by a
> real compiler issue. In short, I am neutral on this change.
OK then, I will drop this patch in the next version. I agree that it
doesn't really show any technical benefit and there is no danger in
doing the current implementation.
And yes, the syscall6() for i386 is somewhat problematic and we've a
confirmed bug that lives in many versions of GCC and it's not even fixed
in the current trunk. It's proven that using register constraints can
be a valid workaround to deal with this bug.
2022-03-23 13:50:18 UTC, Jakub Jelinek wrote:
> Anyway, with the "b" etc. constraints (which is a good idea to use on
> x86 when it has single register constraints for those but can't be used
> on other arches which do not have such constraints) you just trigger
> slightly different path in the RA, [...]
See the discussion here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105032#c7
^^^ That is only for syscall6() on i386.
As such, I will drop this patch and another one that does this on i386.
Thanks!
--
Ammar Faizi
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist
2022-03-24 8:33 ` Alviro Iskandar Setiawan
2022-03-24 9:00 ` Ammar Faizi
@ 2022-03-24 15:42 ` Willy Tarreau
1 sibling, 0 replies; 18+ messages in thread
From: Willy Tarreau @ 2022-03-24 15:42 UTC (permalink / raw)
To: Alviro Iskandar Setiawan
Cc: Ammar Faizi, Paul E. McKenney, Nugraha, Linux Kernel Mailing List,
GNU/Weeb Mailing List, David Laight
On Thu, Mar 24, 2022 at 03:33:57PM +0700, Alviro Iskandar Setiawan wrote:
> On Thu, Mar 24, 2022 at 2:57 PM Willy Tarreau <[email protected]> wrote:
> > On Thu, Mar 24, 2022 at 02:30:32PM +0700, Ammar Faizi wrote:
> > > Use appropriate register constraints if exist. Don't use register
> > > variables for all inputs.
> > >
> > > Register variables with "r" constraint should be used when we need to
> > > pass data through a specific register to extended inline assembly that
> > > doesn't have a specific register constraint associated with it (anything
> > > outside %rax, %rbx, %rcx, %rdx, %rsi, %rdi).
> > >
> > > It also simplifies the macro definition.
> >
> > I'm a bit bothered by this one because I went the exact opposite route
> > in the early design precisely because I found that the current one was
> > simpler. [...]
> [...]
> > I'd say that if there is any technical benefit in doing this (occasional
> > code improvement or better support for older or exotic compilers), I'd say
> > "ok go for it", but if it's only a matter of taste, I'm not convinced at
> > all and am rather seeing this as a regression. Now if there's rough
> > consensus around this approach I'll abide, but then I'd request that other
> > archs are adapted as well so that we don't keep a different approach only
> > for these two ones.
>
> I don't see any technical benefit for x86-64, so I don't think there
> is a need in doing this. Though I personally prefer to use register
> constraints if they exist instead of register variables for everything
> (oh yeah, matter of taste since I don't have any technical argument to
> say it's better respecting the resulting codegen). The only real issue
> is for the syscall6() implementation on i386 as we've been bitten by a
> real compiler issue. In short, I am neutral on this change.
Just to be clear, I usually only use register constraints as well but I
changed this for the syscalls since they were not sufficient, and found
that the mix of the two was really not great to deal with.
Thanks,
Willy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v1 05/11] tools/nolibc: i386: Use appropriate register constraints if exist
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (3 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 04/11] tools/nolibc: x86-64: Use appropriate register constraints if exist Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 06/11] tools/nolibc: i386: Implement syscall with 6 arguments Ammar Faizi
` (5 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi,
David Laight
Use appropriate register constraints if exist. Don't use register
variables for all inputs.
Register variables with "r" constraint should be used when we need to
pass data through a specific register to extended inline assembly that
doesn't have a specific register constraint associated with it (anything
outside %eax, %ebx, %ecx, %edx, %esi, %edi).
It also simplifies the macro definition.
Link: https://lore.kernel.org/lkml/[email protected]
Suggested-by: David Laight <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
tools/include/nolibc/arch-i386.h | 162 +++++++++++++------------------
1 file changed, 70 insertions(+), 92 deletions(-)
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index ff2e6bb453cf..6eb96ee8c4f7 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -63,108 +63,86 @@ struct sys_stat_struct {
*/
#define __ARCH_WANT_SYS_OLD_SELECT
-#define my_syscall0(num) \
-({ \
- long _ret; \
- register long _num __asm__("eax") = (num); \
- \
- __asm__ volatile ( \
- "int $0x80\n" \
- : "=a" (_ret) \
- : "0"(_num) \
- : "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall0(num) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "int $0x80\n" \
+ : "+a"(_ret) /* %eax */ \
+ : \
+ : "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall1(num, arg1) \
-({ \
- long _ret; \
- register long _num __asm__("eax") = (num); \
- register long _arg1 __asm__("ebx") = (long)(arg1); \
- \
- __asm__ volatile ( \
- "int $0x80\n" \
- : "=a" (_ret) \
- : "r"(_arg1), \
- "0"(_num) \
- : "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall1(num, arg1) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "int $0x80\n" \
+ : "+a"(_ret) /* %eax */ \
+ : "b"(arg1) /* %ebx */ \
+ : "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall2(num, arg1, arg2) \
-({ \
- long _ret; \
- register long _num __asm__("eax") = (num); \
- register long _arg1 __asm__("ebx") = (long)(arg1); \
- register long _arg2 __asm__("ecx") = (long)(arg2); \
- \
- __asm__ volatile ( \
- "int $0x80\n" \
- : "=a" (_ret) \
- : "r"(_arg1), "r"(_arg2), \
- "0"(_num) \
- : "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall2(num, arg1, arg2) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "int $0x80\n" \
+ : "+a"(_ret) /* %eax */ \
+ : "b"(arg1), /* %ebx */ \
+ "c"(arg2) /* %ecx */ \
+ : "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall3(num, arg1, arg2, arg3) \
-({ \
- long _ret; \
- register long _num __asm__("eax") = (num); \
- register long _arg1 __asm__("ebx") = (long)(arg1); \
- register long _arg2 __asm__("ecx") = (long)(arg2); \
- register long _arg3 __asm__("edx") = (long)(arg3); \
- \
- __asm__ volatile ( \
- "int $0x80\n" \
- : "=a" (_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), \
- "0"(_num) \
- : "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall3(num, arg1, arg2, arg3) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "int $0x80\n" \
+ : "+a"(_ret) /* %eax */ \
+ : "b"(arg1), /* %ebx */ \
+ "c"(arg2), /* %ecx */ \
+ "d"(arg3) /* %edx */ \
+ : "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall4(num, arg1, arg2, arg3, arg4) \
-({ \
- long _ret; \
- register long _num __asm__("eax") = (num); \
- register long _arg1 __asm__("ebx") = (long)(arg1); \
- register long _arg2 __asm__("ecx") = (long)(arg2); \
- register long _arg3 __asm__("edx") = (long)(arg3); \
- register long _arg4 __asm__("esi") = (long)(arg4); \
- \
- __asm__ volatile ( \
- "int $0x80\n" \
- : "=a" (_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
- "0"(_num) \
- : "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall4(num, arg1, arg2, arg3, arg4) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "int $0x80\n" \
+ : "+a"(_ret) /* %eax */ \
+ : "b"(arg1), /* %ebx */ \
+ "c"(arg2), /* %ecx */ \
+ "d"(arg3), /* %edx */ \
+ "S"(arg4) /* %esi */ \
+ : "memory", "cc" \
+ ); \
+ _ret; \
})
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
-({ \
- long _ret; \
- register long _num __asm__("eax") = (num); \
- register long _arg1 __asm__("ebx") = (long)(arg1); \
- register long _arg2 __asm__("ecx") = (long)(arg2); \
- register long _arg3 __asm__("edx") = (long)(arg3); \
- register long _arg4 __asm__("esi") = (long)(arg4); \
- register long _arg5 __asm__("edi") = (long)(arg5); \
- \
- __asm__ volatile ( \
- "int $0x80\n" \
- : "=a" (_ret) \
- : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
- "0"(_num) \
- : "memory", "cc" \
- ); \
- _ret; \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ long _ret = (num); \
+ __asm__ volatile ( \
+ "int $0x80\n" \
+ : "+a"(_ret) /* %eax */ \
+ : "b"(arg1), /* %ebx */ \
+ "c"(arg2), /* %ecx */ \
+ "d"(arg3), /* %edx */ \
+ "S"(arg4), /* %esi */ \
+ "D"(arg5) /* %edi */ \
+ : "memory", "cc" \
+ ); \
+ _ret; \
})
/* startup code */
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 06/11] tools/nolibc: i386: Implement syscall with 6 arguments
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (4 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 05/11] tools/nolibc: i386: " Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 07/11] tools/nolibc/sys: Implement `mmap()` and `munmap()` Ammar Faizi
` (4 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi,
x86, llvm, David Laight
On i386, the 6th argument of syscall goes in %ebp. However, both Clang
and GCC cannot use %ebp in the clobber list and in the "r" constraint
without using -fomit-frame-pointer. To make it always available for
any kind of compilation, the below workaround is implemented.
1) Push the 6-th argument.
2) Push %ebp.
3) Load the 6-th argument from 4(%esp) to %ebp.
4) Do the syscall (int $0x80).
5) Pop %ebp (restore the old value of %ebp).
6) Add %esp by 4 (undo the stack pointer).
Cc: [email protected]
Cc: [email protected]
Link: https://lore.kernel.org/lkml/[email protected]
Suggested-by: David Laight <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link RFC v2: https://lore.kernel.org/lkml/[email protected]
RFC v2 -> v1:
- Use the same pattern for syscall6, regardless using GCC or Clang
(comment from David).
- Use appropriate constraints for syscall6 instead of always using
register variables (comment from David).
Link RFC v1: https://lore.kernel.org/llvm/[email protected]
RFC v1 -> RFC v2:
- Fix %ebp saving method. Don't use redzone, i386 doesn't have a redzone
(comment from David and Alviro).
---
tools/include/nolibc/arch-i386.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index 6eb96ee8c4f7..cdffd99664ae 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -145,6 +145,29 @@ struct sys_stat_struct {
_ret; \
})
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ long _eax = (long)(num); \
+ long _arg6 = (long)(arg6); /* Always in memory */ \
+ __asm__ volatile ( \
+ "pushl %[_arg6]\n\t" \
+ "pushl %%ebp\n\t" \
+ "movl 4(%%esp),%%ebp\n\t" \
+ "int $0x80\n\t" \
+ "popl %%ebp\n\t" \
+ "addl $4,%%esp\n\t" \
+ : "+a"(_eax) /* %eax */ \
+ : "b"(arg1), /* %ebx */ \
+ "c"(arg2), /* %ecx */ \
+ "d"(arg3), /* %edx */ \
+ "S"(arg4), /* %esi */ \
+ "D"(arg5), /* %edi */ \
+ [_arg6]"m"(_arg6) /* memory */ \
+ : "memory", "cc" \
+ ); \
+ _eax; \
+})
+
/* startup code */
/*
* i386 System V ABI mandates:
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 07/11] tools/nolibc/sys: Implement `mmap()` and `munmap()`
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (5 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 06/11] tools/nolibc: i386: Implement syscall with 6 arguments Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 08/11] tools/nolibc/types: Implement `offsetof()` and `container_of()` macro Ammar Faizi
` (3 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi
Implement mmap() and munmap(). Currently, they are only available for
architecures that have my_syscall6 macro. For architectures that don't
have, this function will return -1 with errno set to ENOSYS (Function
not implemented).
This has been tested on x86 and i386.
Notes for i386:
1) The common mmap() syscall implementation uses __NR_mmap2 instead
of __NR_mmap.
2) The offset must be shifted-right by 12-bit.
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link RFC v2: https://lore.kernel.org/lkml/[email protected]/
RFC v2 -> v1:
* No changes *
Link RFC v1: https://lore.kernel.org/lkml/[email protected]/
RFC v1 -> RFC v2:
* No changes *
---
tools/include/nolibc/sys.h | 62 ++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 4d4308d5d111..08491070387b 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -14,6 +14,7 @@
#include <asm/unistd.h>
#include <asm/signal.h> // for SIGCHLD
#include <asm/ioctls.h>
+#include <asm/mman.h>
#include <linux/fs.h>
#include <linux/loop.h>
#include <linux/time.h>
@@ -675,6 +676,67 @@ int mknod(const char *path, mode_t mode, dev_t dev)
return ret;
}
+#ifndef MAP_SHARED
+#define MAP_SHARED 0x01 /* Share changes */
+#define MAP_PRIVATE 0x02 /* Changes are private */
+#define MAP_SHARED_VALIDATE 0x03 /* share + validate extension flags */
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static __attribute__((unused))
+void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset)
+{
+#ifndef my_syscall6
+ /* Function not implemented. */
+ return -ENOSYS;
+#else
+
+ int n;
+
+#if defined(__i386__)
+ n = __NR_mmap2;
+ offset >>= 12;
+#else
+ n = __NR_mmap;
+#endif
+
+ return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
+#endif
+}
+
+static __attribute__((unused))
+void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
+
+ if ((unsigned long)ret >= -4095UL) {
+ SET_ERRNO(-(long)ret);
+ ret = MAP_FAILED;
+ }
+ return ret;
+}
+
+static __attribute__((unused))
+int sys_munmap(void *addr, size_t length)
+{
+ return my_syscall2(__NR_munmap, addr, length);
+}
+
+static __attribute__((unused))
+int munmap(void *addr, size_t length)
+{
+ int ret = sys_munmap(addr, length);
+
+ if (ret < 0) {
+ SET_ERRNO(-ret);
+ ret = -1;
+ }
+ return ret;
+}
/*
* int mount(const char *source, const char *target,
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 08/11] tools/nolibc/types: Implement `offsetof()` and `container_of()` macro
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (6 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 07/11] tools/nolibc/sys: Implement `mmap()` and `munmap()` Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 09/11] tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()` Ammar Faizi
` (2 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi
Implement `offsetof()` and `container_of()` macro. The first use case
of these macros is for `malloc()`, `realloc()` and `free()`.
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link RFC v2: https://lore.kernel.org/lkml/[email protected]/
RFC v2 -> v1:
* No changes *
---
tools/include/nolibc/types.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index 357e60ad38a8..959997034e55 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -191,4 +191,15 @@ struct stat {
#define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff))
#define minor(dev) ((unsigned int)(((dev) & 0xff))
+#ifndef offsetof
+#define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD)
+#endif
+
+#ifndef container_of
+#define container_of(PTR, TYPE, FIELD) ({ \
+ __typeof__(((TYPE *)0)->FIELD) *__FIELD_PTR = (PTR); \
+ (TYPE *)((char *) __FIELD_PTR - offsetof(TYPE, FIELD)); \
+})
+#endif
+
#endif /* _NOLIBC_TYPES_H */
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 09/11] tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()`
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (7 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 08/11] tools/nolibc/types: Implement `offsetof()` and `container_of()` macro Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 10/11] tools/nolibc/string: Implement `strnlen()` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 11/11] tools/include/string: Implement `strdup()` and `strndup()` Ammar Faizi
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi,
David Laight
Implement basic dynamic allocator functions. These functions are
currently only available on architectures that have nolibc mmap()
syscall implemented. These are not a super-fast memory allocator,
but at least they can satisfy basic needs for having heap without
libc.
Cc: David Laight <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link v2: https://lore.kernel.org/lkml/[email protected]/
RFC v2 -> v1:
- Round up the malloc() allocation to 4096 (comment from David).
- Don't realloc() if we still have enough memory to contain the
requested new size (comment from David).
- Fix conflict with getenv() fix (after rebase).
Link v1: https://lore.kernel.org/lkml/[email protected]
RFC v1 -> RFC v2:
- Move container_of() and offsetof() macro to types.h with a
separate patch (comment from Willy).
---
tools/include/nolibc/stdlib.h | 81 +++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
index 8a07e263f0d0..8fd32eaf8037 100644
--- a/tools/include/nolibc/stdlib.h
+++ b/tools/include/nolibc/stdlib.h
@@ -11,7 +11,12 @@
#include "arch.h"
#include "types.h"
#include "sys.h"
+#include "string.h"
+struct nolibc_heap {
+ size_t len;
+ char user_p[] __attribute__((__aligned__));
+};
/* Buffer used to store int-to-ASCII conversions. Will only be implemented if
* any of the related functions is implemented. The area is large enough to
@@ -60,6 +65,18 @@ int atoi(const char *s)
return atol(s);
}
+static __attribute__((unused))
+void free(void *ptr)
+{
+ struct nolibc_heap *heap;
+
+ if (!ptr)
+ return;
+
+ heap = container_of(ptr, struct nolibc_heap, user_p);
+ munmap(heap, heap->len);
+}
+
/* getenv() tries to find the environment variable named <name> in the
* environment array pointed to by global variable "environ" which must be
* declared as a char **, and must be terminated by a NULL (it is recommended
@@ -91,6 +108,70 @@ char *getenv(const char *name)
return _getenv(name, environ);
}
+static __attribute__((unused))
+void *malloc(size_t len)
+{
+ struct nolibc_heap *heap;
+
+ /* Always allocate memory with size multiple of 4096. */
+ len = sizeof(*heap) + len;
+ len = (len + 4095UL) & -4096UL;
+ heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE,
+ -1, 0);
+ if (__builtin_expect(heap == MAP_FAILED, 0))
+ return NULL;
+
+ heap->len = len;
+ return heap->user_p;
+}
+
+static __attribute__((unused))
+void *calloc(size_t size, size_t nmemb)
+{
+ void *orig;
+ size_t res = 0;
+
+ if (__builtin_expect(__builtin_mul_overflow(nmemb, size, &res), 0)) {
+ SET_ERRNO(ENOMEM);
+ return NULL;
+ }
+
+ /*
+ * No need to zero the heap, the MAP_ANONYMOUS in malloc()
+ * already does it.
+ */
+ return malloc(res);
+}
+
+static __attribute__((unused))
+void *realloc(void *old_ptr, size_t new_size)
+{
+ struct nolibc_heap *heap;
+ size_t user_p_len;
+ void *ret;
+
+ if (!old_ptr)
+ return malloc(new_size);
+
+ heap = container_of(old_ptr, struct nolibc_heap, user_p);
+ user_p_len = heap->len - sizeof(*heap);
+ /*
+ * Don't realloc() if @user_p_len >= @new_size, this block of
+ * memory is still enough to handle the @new_size. Just return
+ * the same pointer.
+ */
+ if (user_p_len >= new_size)
+ return old_ptr;
+
+ ret = malloc(new_size);
+ if (__builtin_expect(!ret, 0))
+ return NULL;
+
+ memcpy(ret, heap->user_p, heap->len);
+ munmap(heap, heap->len);
+ return ret;
+}
+
/* Converts the unsigned long integer <in> to its hex representation into
* buffer <buffer>, which must be long enough to store the number and the
* trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 10/11] tools/nolibc/string: Implement `strnlen()`
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (8 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 09/11] tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()` Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
2022-03-24 7:30 ` [PATCH v1 11/11] tools/include/string: Implement `strdup()` and `strndup()` Ammar Faizi
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi
size_t strnlen(const char *str, size_t maxlen);
The strnlen() function returns the number of bytes in the string
pointed to by sstr, excluding the terminating null byte ('\0'), but at
most maxlen. In doing this, strnlen() looks only at the first maxlen
characters in the string pointed to by str and never beyond str[maxlen-1].
The first use case of this function is for determining the memory
allocation size in the strndup() function.
Link: https://lore.kernel.org/lkml/CAOG64qMpEMh+EkOfjNdAoueC+uQyT2Uv3689_sOr37-JxdJf4g@mail.gmail.com
Suggested-by: Alviro Iskandar Setiawan <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link v2: https://lore.kernel.org/lkml/[email protected]/
RFC v2 -> v1:
* No changes *
---
tools/include/nolibc/string.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index 75a453870498..f43d52a44d09 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -147,6 +147,15 @@ size_t nolibc_strlen(const char *str)
#define strlen(str) nolibc_strlen((str))
#endif
+static __attribute__((unused))
+size_t strnlen(const char *str, size_t maxlen)
+{
+ size_t len;
+
+ for (len = 0; (len < maxlen) && str[len]; len++);
+ return len;
+}
+
static __attribute__((unused))
size_t strlcat(char *dst, const char *src, size_t size)
{
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 11/11] tools/include/string: Implement `strdup()` and `strndup()`
2022-03-24 7:30 [PATCH v1 00/11] Add dynamic memory allocator support for nolibc Ammar Faizi
` (9 preceding siblings ...)
2022-03-24 7:30 ` [PATCH v1 10/11] tools/nolibc/string: Implement `strnlen()` Ammar Faizi
@ 2022-03-24 7:30 ` Ammar Faizi
10 siblings, 0 replies; 18+ messages in thread
From: Ammar Faizi @ 2022-03-24 7:30 UTC (permalink / raw)
To: Willy Tarreau
Cc: Paul E. McKenney, Alviro Iskandar Setiawan, Nugraha,
Linux Kernel Mailing List, GNU/Weeb Mailing List, Ammar Faizi
These functions are currently only available on architectures that have
my_syscall6() macro implemented. Since these functions use malloc(),
malloc() uses mmap(), mmap() depends on my_syscall6() macro.
On architectures that don't support my_syscall6(), these function will
always return NULL with errno set to ENOSYS.
Signed-off-by: Ammar Faizi <[email protected]>
---
@@ Changelog:
Link RFC v2: https://lore.kernel.org/lkml/[email protected]/
RFC v2 -> v1:
* No changes *
Link RFC v1: https://lore.kernel.org/lkml/[email protected]/
RFC v1 -> RFC v2:
- Update strdup and strndup implementation, use strlen and strnlen to get
the string length first (comment from Willy and Alviro).
- Fix the subject line prefix, it was "tools/include/string: ", it should be
"tools/nolibc/string: ".
- Update the commit message.
---
tools/include/nolibc/string.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index f43d52a44d09..bef35bee9c44 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -9,6 +9,8 @@
#include "std.h"
+static void *malloc(size_t len);
+
/*
* As much as possible, please keep functions alphabetically sorted.
*/
@@ -156,6 +158,36 @@ size_t strnlen(const char *str, size_t maxlen)
return len;
}
+static __attribute__((unused))
+char *strdup(const char *str)
+{
+ size_t len;
+ char *ret;
+
+ len = strlen(str);
+ ret = malloc(len + 1);
+ if (__builtin_expect(ret != NULL, 1))
+ memcpy(ret, str, len + 1);
+
+ return ret;
+}
+
+static __attribute__((unused))
+char *strndup(const char *str, size_t maxlen)
+{
+ size_t len;
+ char *ret;
+
+ len = strnlen(str, maxlen);
+ ret = malloc(len + 1);
+ if (__builtin_expect(ret != NULL, 1)) {
+ memcpy(ret, str, len);
+ ret[len] = '\0';
+ }
+
+ return ret;
+}
+
static __attribute__((unused))
size_t strlcat(char *dst, const char *src, size_t size)
{
--
Ammar Faizi
^ permalink raw reply related [flat|nested] 18+ messages in thread