diff options
author | Colin Cross <ccross@android.com> | 2014-02-14 18:56:23 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2014-02-18 12:11:38 -0800 |
commit | 3d19a8319b9c27af8aa5cfbf495da0fe7fa62d3e (patch) | |
tree | a51591477e2f6f97ae56ae027d01ca1ff8c302ef /libc/bionic/__set_errno.cpp | |
parent | d4bc9ef83b36916d5e63c4c3e4a092381473ea52 (diff) | |
download | android_bionic-3d19a8319b9c27af8aa5cfbf495da0fe7fa62d3e.tar.gz android_bionic-3d19a8319b9c27af8aa5cfbf495da0fe7fa62d3e.tar.bz2 android_bionic-3d19a8319b9c27af8aa5cfbf495da0fe7fa62d3e.zip |
bionic: fix __set_errno for arm64 syscalls that return a 64-bit value
bionic/libc/arch-arm64/syscalls/read.S ends with:
b.hi __set_errno
ret
END(read)
If __set_errno returns int, it will set w0 to 0xFFFFFFFF, which means
x0 is 0x00000000FFFFFFFF. When interpreted as a ssize_t that is
INT_MAX, not -1.
Change __set_errno to return long, which will cause x0 to be set instead
of w0.
Change-Id: I9f9ea0f2995928d2ea240eb2ff7758ecdf0ff412
Diffstat (limited to 'libc/bionic/__set_errno.cpp')
-rw-r--r-- | libc/bionic/__set_errno.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/libc/bionic/__set_errno.cpp b/libc/bionic/__set_errno.cpp index af6a68eb1..236aeacee 100644 --- a/libc/bionic/__set_errno.cpp +++ b/libc/bionic/__set_errno.cpp @@ -31,8 +31,19 @@ // This function is called from our assembler syscall stubs. // C/C++ code should just assign 'errno' instead. -// TODO: this should be __LIBC_HIDDEN__ but was exposed in <errno.h> in the NDK. -extern "C" int __set_errno(int n) { +// The return type is 'long' because we use the same routine in calls +// that return an int as in ones that return a ssize_t. On a 32-bit +// system these are the same size, but on a 64-bit system they're not. +// 'long' gives us 32-bit on 32-bit systems, 64-bit on 64-bit systems. + +#if __LP64__ +extern "C" __LIBC_HIDDEN__ long __set_errno(int); +#else +// __set_errno was mistakenly exposed in <errno.h> in the 32-bit NDK. +extern "C" long __set_errno(int); +#endif + +long __set_errno(int n) { errno = n; return -1; } |