Merge "[MIPS] Rewrite MIPS crtbegin* as C files."
diff --git a/libc/Android.mk b/libc/Android.mk
index 4206020..bfeb391 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -106,7 +106,6 @@
bionic/md5.c \
bionic/memmem.c \
bionic/memswap.c \
- bionic/mmap.c \
bionic/openat.c \
bionic/open.c \
bionic/pathconf.c \
@@ -200,6 +199,7 @@
bionic/__memcpy_chk.cpp \
bionic/__memmove_chk.cpp \
bionic/__memset_chk.cpp \
+ bionic/mmap.cpp \
bionic/pthread_attr.cpp \
bionic/pthread_detach.cpp \
bionic/pthread_equal.cpp \
diff --git a/libc/bionic/mmap.c b/libc/bionic/mmap.cpp
similarity index 69%
rename from libc/bionic/mmap.c
rename to libc/bionic/mmap.cpp
index 40a6538..864dea2 100644
--- a/libc/bionic/mmap.c
+++ b/libc/bionic/mmap.cpp
@@ -25,19 +25,30 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <unistd.h>
+
#include <errno.h>
#include <sys/mman.h>
+#include <unistd.h>
-extern void* __mmap2(void*, size_t, int, int, int, size_t);
+#include "private/ErrnoRestorer.h"
-#define MMAP2_SHIFT 12
-void* mmap(void *addr, size_t size, int prot, int flags, int fd, long offset)
-{
- if (offset & ((1UL << MMAP2_SHIFT)-1)) {
- errno = EINVAL;
- return MAP_FAILED;
- }
+// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
+extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
- return __mmap2(addr, size, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT);
+#define MMAP2_SHIFT 12 // 2**12 == 4096
+
+void* mmap(void* addr, size_t size, int prot, int flags, int fd, long offset) {
+ if (offset & ((1UL << MMAP2_SHIFT)-1)) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
+
+ if (result != MAP_FAILED && (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0) {
+ ErrnoRestorer errno_restorer;
+ madvise(result, size, MADV_MERGEABLE);
+ }
+
+ return result;
}
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index d38e20c..63695d3 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -62,7 +62,16 @@
thread->tls[i] = NULL;
}
+ // Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
+ thread->tls[TLS_SLOT_SELF] = thread->tls;
+ thread->tls[TLS_SLOT_THREAD_ID] = thread;
+ // GCC looks in the TLS for the stack guard on x86, so copy it there from our global.
+ thread->tls[TLS_SLOT_STACK_GUARD] = (void*) __stack_chk_guard;
+
+ __set_tls(thread->tls);
+
// Create and set an alternate signal stack.
+ // This must happen after __set_tls, in case a system call fails and tries to set errno.
stack_t ss;
ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
if (ss.ss_sp != MAP_FAILED) {
@@ -71,14 +80,6 @@
sigaltstack(&ss, NULL);
thread->alternate_signal_stack = ss.ss_sp;
}
-
- // Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
- thread->tls[TLS_SLOT_SELF] = thread->tls;
- thread->tls[TLS_SLOT_THREAD_ID] = thread;
- // GCC looks in the TLS for the stack guard on x86, so copy it there from our global.
- thread->tls[TLS_SLOT_STACK_GUARD] = (void*) __stack_chk_guard;
-
- __set_tls(thread->tls);
}
// This trampoline is called from the assembly _pthread_clone function.