Merge "Move malloc dispatch table to __libc_globals."
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 8f25a89..794f50f 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -30,6 +30,7 @@
 #include <sys/mman.h>
 #include <unistd.h>
 
+#include "private/bionic_macros.h"
 #include "private/ErrnoRestorer.h"
 
 // mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
@@ -45,6 +46,13 @@
     return MAP_FAILED;
   }
 
+  // prevent allocations large enough for `end - start` to overflow
+  size_t rounded = BIONIC_ALIGN(size, PAGE_SIZE);
+  if (rounded < size || size > PTRDIFF_MAX) {
+    errno = ENOMEM;
+    return MAP_FAILED;
+  }
+
   bool is_private_anonymous = (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0;
   void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
 
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index f22464e..c464f46 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/linker/Android.mk b/linker/Android.mk
index 585a738..8be53a1 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -2,7 +2,9 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+LOCAL_CLANG := true
+
+LOCAL_SRC_FILES := \
     debugger.cpp \
     dlfcn.cpp \
     linker.cpp \
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 841b957..406cdee 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1318,6 +1318,10 @@
     int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
     if (fd != -1) {
       *file_offset = 0;
+      if (!realpath_fd(fd, realpath)) {
+        PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
+        *realpath = name;
+      }
     }
     return fd;
   }
@@ -3104,6 +3108,7 @@
   if (has_text_relocations) {
     // Fail if app is targeting sdk version > 22
     if (get_application_target_sdk_version() > 22) {
+      PRINT("%s: has text relocations", get_realpath());
       DL_ERR("%s: has text relocations", get_realpath());
       return false;
     }
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 00cbdc6..ed972ba 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -830,10 +830,11 @@
 }
 
 #if defined(__LP64__)
-#define BIONIC_PATH_TO_LIBC "/system/lib64/libc.so"
+#define PATH_TO_SYSTEM_LIB "/system/lib64/"
 #else
-#define BIONIC_PATH_TO_LIBC "/system/lib/libc.so"
+#define PATH_TO_SYSTEM_LIB "/system/lib/"
 #endif
+#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
 
 TEST(dlfcn, dladdr_libc) {
 #if defined(__BIONIC__)
@@ -843,7 +844,7 @@
 
   // /system/lib is symlink when this test is executed on host.
   char libc_realpath[PATH_MAX];
-  ASSERT_TRUE(realpath(BIONIC_PATH_TO_LIBC, libc_realpath) == libc_realpath);
+  ASSERT_TRUE(realpath(PATH_TO_LIBC, libc_realpath) == libc_realpath);
 
   ASSERT_STREQ(libc_realpath, info.dli_fname);
   // TODO: add check for dfi_fbase
@@ -1063,7 +1064,7 @@
   return 0;
 }
 
-TEST(dlfcn, dt_runpath) {
+TEST(dlfcn, dt_runpath_smoke) {
   void* handle = dlopen("libtest_dt_runpath_d.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
 
@@ -1076,3 +1077,17 @@
 
   dlclose(handle);
 }
+
+TEST(dlfcn, dt_runpath_absolute_path) {
+  void* handle = dlopen(PATH_TO_SYSTEM_LIB "libtest_dt_runpath_d.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  typedef void *(* dlopen_b_fn)();
+  dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
+  ASSERT_TRUE(fn != nullptr) << dlerror();
+
+  void *p = fn();
+  ASSERT_TRUE(p != nullptr);
+
+  dlclose(handle);
+}