Skip to contentSkip to conversation

linux-user/flatload: fix initial stack pointer alignment

PATCH Superseded Max Filippov 2 participants 4 messages Oct 24, 2018

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 linux-user/flatload: fix initial stack pointer alignment

Stack pointer alignment code incorrectly adds stack_size to sp instead of subtracting it. It also does not take flat_argvp_envp_on_stack() into account when calculating stack_size. This results in initial stack pointer misalignment with certain set of command line arguments and environment variables and correct alignment for the same binary with a different set of arguments. This misalignment causes failures in the following tests in the testsuite of gcc built for xtensa uclinux:

gcc.dg/torture/vshuf-v64qi.c
gcc.dg/torture/vshuf-v8sf.c
gcc.dg/torture/vshuf-v8si.c

---
 linux-user/flatload.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
linux-user/flatload.c +5 -3
index 2eefe55e5000..1893966b5b30 100644
@@ -771,10 +771,12 @@ int load_flt_binary(struct linux_binprm *bprm, struct image_info *info)
     /* Enforce final stack alignment of 16 bytes.  This is sufficient
        for all current targets, and excess alignment is harmless.  */
     stack_len = bprm->envc + bprm->argc + 2;
-    stack_len += 3;	/* argc, arvg, argp */
+    stack_len += flat_argvp_envp_on_stack() ? 2 : 0; /* arvg, argp */
+    stack_len += 1; /* argc */
     stack_len *= sizeof(abi_ulong);
-    if ((sp + stack_len) & 15)
-        sp -= 16 - ((sp + stack_len) & 15);
+    if ((sp - stack_len) & 15) {
+        sp -= ((sp - stack_len) & 15);
+    }
     sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p,
                              flat_argvp_envp_on_stack());
 
Signature · 1 line
2.11.0
#1 lore raw
Quoted 23 lines · Max Filippov

Stack pointer alignment code incorrectly adds stack_size to sp instead of subtracting it. It also does not take flat_argvp_envp_on_stack() into account when calculating stack_size. This results in initial stack pointer misalignment with certain set of command line arguments and environment variables and correct alignment for the same binary with a different set of arguments. This misalignment causes failures in the following tests in the testsuite of gcc built for xtensa uclinux:

gcc.dg/torture/vshuf-v64qi.c
gcc.dg/torture/vshuf-v8sf.c
gcc.dg/torture/vshuf-v8si.c

---
 linux-user/flatload.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
linux-user/flatload.c +0 -0
index 2eefe55e5000..1893966b5b30 100644
@@ -771,10 +771,12 @@ int load_flt_binary(struct linux_binprm *bprm, struct image_info *info)
     /* Enforce final stack alignment of 16 bytes.  This is sufficient

linux-user/flatload.c int load_flt_binary(struct linux_binprm *bprm, struct image_info *info) · line 778

Quoted 10 lines
linux-user/flatload.c +5 -3
        for all current targets, and excess alignment is harmless.  */
     stack_len = bprm->envc + bprm->argc + 2;
-    stack_len += 3;	/* argc, arvg, argp */
+    stack_len += flat_argvp_envp_on_stack() ? 2 : 0; /* arvg, argp */
+    stack_len += 1; /* argc */>      stack_len *= sizeof(abi_ulong);
-    if ((sp + stack_len) & 15)
-        sp -= 16 - ((sp + stack_len) & 15);
+    if ((sp - stack_len) & 15) {
+        sp -= ((sp - stack_len) & 15);
+    }

If I understand correctly the purpose, I think it could be clearer like:

    sp = (sp - stack_len) & ~15;

Thanks,
Laurent

#2 lore raw
Quoted 5 lines · Laurent Vivier
Quoted 4 lines
linux-user/flatload.c +0 -0
index 2eefe55e5000..1893966b5b30 100644
Quoted 8 lines

linux-user/flatload.c int load_flt_binary(struct linux_binprm *bprm, struct image_info *info) · line 779

Quoted 4 lines
linux-user/flatload.c +3 -1
-        sp -= 16 - ((sp + stack_len) & 15);
+    if ((sp - stack_len) & 15) {
+        sp -= ((sp - stack_len) & 15);
+    }

If I understand correctly the purpose, I think it could be clearer like:

    sp = (sp - stack_len) & ~15;

Yes, you're right. I'll send v2.

Signature · 2 lines
Thanks.
-- Max
#3 lore raw
Quoted 12 lines · Max Filippov
Quoted 10 lines · Laurent Vivier
Quoted 9 lines
linux-user/flatload.c +3 -1
index 2eefe55e5000..1893966b5b30 100644
 
-        sp -= 16 - ((sp + stack_len) & 15);
+    if ((sp - stack_len) & 15) {
+        sp -= ((sp - stack_len) & 15);
+    }
Quoted 5 lines
Quoted 3 lines

If I understand correctly the purpose, I think it could be clearer like:

    sp = (sp - stack_len) & ~15;

Yes, you're right. I'll send v2.

Well, not exactly. The sp is not moved down stack_len + alignment bytes, only the alignment bytes. I'll send v2 anyway.

Signature · 2 lines
Thanks.
-- Max