linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/11] Add dynamic memory allocator support for nolibc
@ 2022-03-24  7:30 Ammar Faizi
  2022-03-24  7:30 ` [PATCH v1 01/11] tools/nolibc: x86-64: Update System V ABI document link Ammar Faizi
                   ` (10 more replies)
  0 siblings, 11 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

Hi,

This is a patchset to add dynamic memory allocator support for
nolibc after 2 RFCs, please review the changes carefully.

There are 3 *new* patches after RFC v2:
  Address report from Alviro:
   - Replace `asm` with `__asm__`.
  Address suggestions from David:
   - x86-64: Use appropriate register constraints if exist (Suggested by David).
   - i386: Use appropriate register constraints if exist.

@@ Changelog:
---
   Link RFC v2: https://lore.kernel.org/lkml/20220322102115.186179-1-ammarfaizi2@gnuweeb.org/
   RFC v2 -> v1:
     - Rebase, sync with Paul's tree.
     - Add new 3 patches [PATCH 03/11], [PATCH 04/11], [PATCH 05/11].

     [PATCH 02/11]
     - Append Reviewed-by tag from Nick.
     - s/Removing/remove/

     [PATCH 06/11]
     - 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).

     [PATCH 09/11]
     - 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 RFC v1: https://lore.kernel.org/lkml/20220320093750.159991-1-ammarfaizi2@gnuweeb.org/
   RFC v1 -> RFC v2:
    - Add 2 new patches [PATCH 5/8] and [PATCH 7/8].

    [PATCH 2/8]
    - Remove all `.global _start` for all build (GCC and Clang) instead of
      removing all `.weak _start` for clang build (Comment from Willy).

    [PATCH 3/8]
    - Fix %ebp saving method. Don't use redzone, i386 doesn't have a redzone
      (comment from David and Alviro).

    [PATCH 6/8]
    - Move container_of() and offsetof() macro to types.h with a
      separate patch (comment from Willy).

    [PATCH 8/8]
    - 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.

Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---
Ammar Faizi (11):
  tools/nolibc: x86-64: Update System V ABI document link
  tools/nolibc: Remove .global _start from the entry point code
  tools/nolibc: Replace `asm` with `__asm__`
  tools/nolibc: x86-64: Use appropriate register constraints if exist
  tools/nolibc: i386: Use appropriate register constraints if exist
  tools/nolibc: i386: Implement syscall with 6 arguments
  tools/nolibc/sys: Implement `mmap()` and `munmap()`
  tools/nolibc/types: Implement `offsetof()` and `container_of()` macro
  tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()`
  tools/nolibc/string: Implement `strnlen()`
  tools/include/string: Implement `strdup()` and `strndup()`

 tools/include/nolibc/arch-aarch64.h |  73 +++++-----
 tools/include/nolibc/arch-arm.h     |  59 ++++----
 tools/include/nolibc/arch-i386.h    | 188 ++++++++++++-------------
 tools/include/nolibc/arch-mips.h    |  63 +++++----
 tools/include/nolibc/arch-riscv.h   |  75 +++++-----
 tools/include/nolibc/arch-x86_64.h  | 207 +++++++++++++---------------
 tools/include/nolibc/stdlib.h       |  81 +++++++++++
 tools/include/nolibc/string.h       |  41 ++++++
 tools/include/nolibc/sys.h          |  62 +++++++++
 tools/include/nolibc/types.h        |  11 ++
 10 files changed, 515 insertions(+), 345 deletions(-)


base-commit: b3f38ba2d1ccaa4c4b2096a310e7b170ef559d4d
-- 
Ammar Faizi


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [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 <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link RFC v2: https://lore.kernel.org/lkml/20220322102115.186179-2-ammarfaizi2@gnuweeb.org/
   RFC v2 -> v1:
    * No changes *

   Link RFC v1: https://lore.kernel.org/lkml/20220320093750.159991-2-ammarfaizi2@gnuweeb.org
   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: llvm@lists.linux.dev
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link RFC v2: https://lore.kernel.org/llvm/20220322102115.186179-3-ammarfaizi2@gnuweeb.org
   RFC v2 -> v1:
    - Append Reviewed-by tag from Nick.
    - s/Removing/remove/

   Link RFC v1: https://lore.kernel.org/llvm/20220320093750.159991-3-ammarfaizi2@gnuweeb.org
   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 <alviro.iskandar@gnuweeb.org>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---

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

* [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/3d2cfdeecddc45dc8e4beada305b5948@AcuMS.aculab.com
Suggested-by: David Laight <David.Laight@ACULAB.COM>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---
 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

* [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/3d2cfdeecddc45dc8e4beada305b5948@AcuMS.aculab.com
Suggested-by: David Laight <David.Laight@ACULAB.COM>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---
 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: x86@kernel.org
Cc: llvm@lists.linux.dev
Link: https://lore.kernel.org/lkml/2e335ac54db44f1d8496583d97f9dab0@AcuMS.aculab.com
Suggested-by: David Laight <David.Laight@ACULAB.COM>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link RFC v2: https://lore.kernel.org/lkml/20220322102115.186179-4-ammarfaizi2@gnuweeb.org
   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/20220320093750.159991-4-ammarfaizi2@gnuweeb.org
   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 <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link RFC v2: https://lore.kernel.org/lkml/20220322102115.186179-5-ammarfaizi2@gnuweeb.org/
   RFC v2 -> v1:
    * No changes *

   Link RFC v1: https://lore.kernel.org/lkml/20220320093750.159991-5-ammarfaizi2@gnuweeb.org/
   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 <ammarfaizi2@gnuweeb.org>
---
@@ Changelog:

   Link RFC v2: https://lore.kernel.org/lkml/20220322102115.186179-6-ammarfaizi2@gnuweeb.org/
   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 <David.Laight@ACULAB.COM>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link v2: https://lore.kernel.org/lkml/20220322102115.186179-7-ammarfaizi2@gnuweeb.org/
   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/20220320093750.159991-6-ammarfaizi2@gnuweeb.org
   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 <alviro.iskandar@gnuweeb.org>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link v2: https://lore.kernel.org/lkml/20220322102115.186179-8-ammarfaizi2@gnuweeb.org/
   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 <ammarfaizi2@gnuweeb.org>
---

@@ Changelog:

   Link RFC v2: https://lore.kernel.org/lkml/20220322102115.186179-9-ammarfaizi2@gnuweeb.org/
   RFC v2 -> v1:
    * No changes *

   Link RFC v1: https://lore.kernel.org/lkml/20220320093750.159991-7-ammarfaizi2@gnuweeb.org/
   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

* 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 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 <w@1wt.eu> 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 <w@1wt.eu> 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 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

* 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 <w@1wt.eu> 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

end of thread, other threads:[~2022-03-24 15:42 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [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
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
2022-03-24  9:00       ` Ammar Faizi
2022-03-24 15:42       ` Willy Tarreau
2022-03-24  7:30 ` [PATCH v1 05/11] tools/nolibc: i386: " Ammar Faizi
2022-03-24  7:30 ` [PATCH v1 06/11] tools/nolibc: i386: Implement syscall with 6 arguments Ammar Faizi
2022-03-24  7:30 ` [PATCH v1 07/11] tools/nolibc/sys: Implement `mmap()` and `munmap()` Ammar Faizi
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 ` [PATCH v1 09/11] tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()` 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

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).