aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Paulsson <paulsson@linux.vnet.ibm.com>2021-11-10 20:27:42 +0100
committerJonas Paulsson <paulsson@linux.vnet.ibm.com>2021-11-17 14:42:08 -0500
commit4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6 (patch)
tree2f1975e62ac942df87700ced67f4a37dc068a757
parent5f99f771ec7134898d67ed0d2234562df756e332 (diff)
downloadllvm-4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6.zip
llvm-4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6.tar.gz
llvm-4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6.tar.bz2
[SystemZ] [Sanitizer] Bugfixes in internal_clone().
The __flags variable needs to be of type 'long' in order to get sign extended properly. internal_clone() uses an svc (Supervisor Call) directly (as opposed to internal_syscall), and therefore needs to take care to set errno and return -1 as needed. Review: Ulrich Weigand
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
index bb2f5b5..74db831 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
@@ -57,8 +57,10 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr) {
- if (!fn || !child_stack)
- return -EINVAL;
+ if (!fn || !child_stack) {
+ errno = EINVAL;
+ return -1;
+ }
CHECK_EQ(0, (uptr)child_stack % 16);
// Minimum frame size.
#ifdef __s390x__
@@ -71,9 +73,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
// And pass parameters.
((unsigned long *)child_stack)[1] = (uptr)fn;
((unsigned long *)child_stack)[2] = (uptr)arg;
- register long res __asm__("r2");
+ register uptr res __asm__("r2");
register void *__cstack __asm__("r2") = child_stack;
- register int __flags __asm__("r3") = flags;
+ register long __flags __asm__("r3") = flags;
register int * __ptidptr __asm__("r4") = parent_tidptr;
register int * __ctidptr __asm__("r5") = child_tidptr;
register void * __newtls __asm__("r6") = newtls;
@@ -113,6 +115,10 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
"r"(__ctidptr),
"r"(__newtls)
: "memory", "cc");
+ if (res >= (uptr)-4095) {
+ errno = -res;
+ return -1;
+ }
return res;
}