tools/nolibc: prevent gcc from making memset() loop over itself
[ Upstream commit 1bfbe1f3e96720daf185f03d101f072d69753f88 ]
When building on ARM in thumb mode with gcc-11.3 at -O2 or -O3,
nolibc-test segfaults during the select() tests. It turns out that at
this level, gcc recognizes an opportunity for using memset() to zero
the fd_set, but it miscompiles it because it also recognizes a memset
pattern as well, and decides to call memset() from the memset() code:
000122bc <memset>:
122bc: b510 push {r4, lr}
122be: 0004 movs r4, r0
122c0: 2a00 cmp r2, #0
122c2: d003 beq.n 122cc <memset+0x10>
122c4: 23ff movs r3, #255 ; 0xff
122c6: 4019 ands r1, r3
122c8: f7ff fff8 bl 122bc <memset>
122cc: 0020 movs r0, r4
122ce: bd10 pop {r4, pc}
Simply placing an empty asm() statement inside the loop suffices to
avoid this.
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
f3b7893078
commit
141fe35cb1
1 changed files with 4 additions and 1 deletions
|
|
@ -88,8 +88,11 @@ void *memset(void *dst, int b, size_t len)
|
|||
{
|
||||
char *p = dst;
|
||||
|
||||
while (len--)
|
||||
while (len--) {
|
||||
/* prevent gcc from recognizing memset() here */
|
||||
asm volatile("");
|
||||
*(p++) = b;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue