[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251027102457.11280-1-w@1wt.eu>
Date: Mon, 27 Oct 2025 11:24:57 +0100
From: Willy Tarreau <w@....eu>
To: Thomas Weissschuh <linux@...ssschuh.net>
Cc: linux-kernel@...r.kernel.org, Willy Tarreau <w@....eu>,
Ammar Faizi <ammarfaizi2@...weeb.org>
Subject: [PATCH] tools/nolibc: x86: fix section mismatch caused by asm "mem*" functions
I recently got occasional build failures at -Os or -Oz that would always
involve waitpid(), where the assembler would complain about this:
init.s: Error: .size expression for waitpid.constprop.0 does not evaluate to a constant
And without -fno-asynchronous-unwind-tables it could also spit such
errors:
init.s:836: Error: CFI instruction used without previous .cfi_startproc
init.s:838: Error: .cfi_endproc without corresponding .cfi_startproc
init.s: Error: open CFI at the end of file; missing .cfi_endproc directive
A trimmed down reproducer is as simple as this:
int main(int argc, char **argv)
{
int ret, status;
if (argc == 0)
ret = waitpid(-1, &status, 0);
else
ret = waitpid(-1, &status, 0);
return status;
}
It produces the following asm code on x86_64:
.text
.section .text.nolibc_memmove_memcpy
.weak memmove
.weak memcpy
memmove:
memcpy:
movq %rdx, %rcx
(...)
retq
.section .text.nolibc_memset
.weak memset
memset:
xchgl %eax, %esi
movq %rdx, %rcx
pushq %rdi
rep stosb
popq %rax
retq
.type waitpid.constprop.0.isra.0, @function
waitpid.constprop.0.isra.0:
subq $8, %rsp
(...)
jmp *.L5(,%rax,8)
.section .rodata
.align 8
.align 4
.L5:
.quad .L10
(...)
.quad .L4
.text
.L10:
(...)
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE273:
.size waitpid.constprop.0.isra.0, .-waitpid.constprop.0.isra.0
It's a bit dense, but here's the explanation: the compiler has emitted a
".text" statement because it knows it's working in the .text section.
Then, our hand-written asm code for the mem* functions forced the section
to .text.something without the compiler knowing about it, so it thinks
the code is still being emitted for .text. As such, without any .section
statement, the waitpid.constprop.0.isra.0 label is in fact placed in the
previously created section, here .text.nolibc_memset.
The waitpid() function involves a switch/case statement that can be
turned to a jump table, which is what the compiler does with the .rodata
section, and after that it restores .text, which is no longer the
previous .text.nolibc_memset section. Then the CFI statements cross a
section, so does the .size calculation, which explains the error.
While a first approach consisting in placing an explicit ".text" at the
end of these functions was verified to work, it's still unreliable as
it depends on what the compiler remembers having emitted previously. A
better approach is to replace the ".section" with ".pushsection", and
place a ".popsection" at the end, so that these code blocks are agnostic
to where they're placed relative to other blocks.
Fixes: 553845eebd60 ("tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()`")
Fixes: 12108aa8c1a1 ("tools/nolibc: x86-64: Use `rep stosb` for `memset()`")
Cc: Ammar Faizi <ammarfaizi2@...weeb.org>
Signed-off-by: Willy Tarreau <w@....eu>
---
tools/include/nolibc/arch-x86.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h
index d3efc0c3b8ad..c8b0c3e624a5 100644
--- a/tools/include/nolibc/arch-x86.h
+++ b/tools/include/nolibc/arch-x86.h
@@ -351,7 +351,7 @@ void *memcpy(void *dst, const void *src, size_t len);
void *memset(void *dst, int c, size_t len);
__asm__ (
-".section .text.nolibc_memmove_memcpy\n"
+".pushsection .text.nolibc_memmove_memcpy\n"
".weak memmove\n"
".weak memcpy\n"
"memmove:\n"
@@ -371,8 +371,9 @@ __asm__ (
"rep movsb\n\t"
"cld\n\t"
"retq\n"
+".popsection\n"
-".section .text.nolibc_memset\n"
+".pushsection .text.nolibc_memset\n"
".weak memset\n"
"memset:\n"
"xchgl %eax, %esi\n\t"
@@ -381,6 +382,7 @@ __asm__ (
"rep stosb\n\t"
"popq %rax\n\t"
"retq\n"
+".popsection\n"
);
#endif /* !defined(__x86_64__) */
--
2.35.3
Powered by blists - more mailing lists