On Sun, 6 Feb 2022, Pali Rohár wrote:
Currently v*scanf functions are broken and crash when are called with more
than 30 arguments in va_list. This is because va_list v*scanf functions are
redirected to variadic *scanf functions and this redirect implemented in
scanf.S file has fixed limit for 30 arguments.
Number of arguments for msvcrt *scanf function can be determined from
format string by counting number of '%' characters which is the upper
limit. *scanf functions would not access more arguments than this number.
Every scanf parameter is pointer, it has fixed size and so upper stack size
limit can be exactly calculated.
Fix this scanf.S redirect implementation by dynamically allocating stack
for upper limit of pointer parameters.
---
I have tested this patch for i686 and x86_64. Both ARM (arm32 and aarch64)
changes are untested, so please test it if vsscanf() on these platforms
still works.
I wonder if we should try to keep the stack 16 byte aligned for i686 too -
GCC generally tries to keep such alignment on i686 too (even if it isn't
strictly required by the ABI). Then again, the only function we call
there is the msvcrt.dll function, which shouldn't assume anything else
than 4 byte alignment, so maybe it's fine.
I noticed that the arm version that I provided before did crash if
providing less than 2 '%' conversions. I simplified the arm and aarch64
versions a little and fixed that, see the attached patch that goes on top
of this. (I can squash it locally before pushing the patch too, sparing
you a re-send of the patch, if we decide we don't want to tweak anything
else.)
// Martin
From 74eaeb43a11365c2ac2ac175b420b9ec26a09596 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <mar...@martin.st>
Date: Tue, 8 Feb 2022 11:19:40 +0200
Subject: [PATCH] Further tweaks for scanf.S for arm
---
mingw-w64-crt/stdio/scanf.S | 33 +++++++--------------------------
1 file changed, 7 insertions(+), 26 deletions(-)
diff --git a/mingw-w64-crt/stdio/scanf.S b/mingw-w64-crt/stdio/scanf.S
index 323a8d5a8..41ff64598 100644
--- a/mingw-w64-crt/stdio/scanf.S
+++ b/mingw-w64-crt/stdio/scanf.S
@@ -172,14 +172,12 @@ __argtos:
push {r4-r8, lr}
ldr r12, [sp, #24]
- cmp r3, #0
- beq 2f
- subs r3, r3, #1
ldr r5, [r2], #4
- beq 2f
- subs r3, r3, #1
ldr r6, [r2], #4
- beq 2f
+
+ subs r3, r3, #2
+ mov r8, #0
+ ble 2f
/* Round the number of entries to an even number, to maintain
* 8 byte stack alignment. */
@@ -214,32 +212,15 @@ __argtos:
mov x11, x3
mov x12, x4
- cmp x11, #0
- b.eq 2f
-
- subs x11, x11, #1
ldr x2, [x10], #8
- b.eq 2f
-
- subs x11, x11, #1
ldr x3, [x10], #8
- b.eq 2f
-
- subs x11, x11, #1
ldr x4, [x10], #8
- b.eq 2f
-
- subs x11, x11, #1
ldr x5, [x10], #8
- b.eq 2f
-
- subs x11, x11, #1
ldr x6, [x10], #8
- b.eq 2f
-
- subs x11, x11, #1
ldr x7, [x10], #8
- b.eq 2f
+
+ subs x11, x11, #6
+ b.le 2f
/* Round the number of entries to an even number, to maintain
* 16 byte stack alignment. */
--
2.25.1
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public