Merge "Add support for non-zero vaddr in maps."
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index 6ef81bb..d72a160 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -39,7 +39,6 @@
     arch-arm/bionic/__bionic_clone.S \
     arch-arm/bionic/_exit_with_stack_teardown.S \
     arch-arm/bionic/libgcc_compat.c \
-    arch-arm/bionic/libgcc_protect_unwind.c \
     arch-arm/bionic/__restore.S \
     arch-arm/bionic/setjmp.S \
     arch-arm/bionic/syscall.S \
diff --git a/libc/arch-arm/bionic/libgcc_protect_unwind.c b/libc/arch-arm/bionic/libgcc_protect_unwind.c
deleted file mode 100644
index 6d758fc..0000000
--- a/libc/arch-arm/bionic/libgcc_protect_unwind.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO: This file should go away once unwinder migration to libc++.so is complete.
-
-extern char _Unwind_Backtrace __attribute((visibility("protected")));
-extern char __gnu_Unwind_Find_exidx __attribute((visibility("protected")));
-extern char __gnu_Unwind_Restore_VFP_D __attribute((visibility("protected")));
-extern char __gnu_Unwind_Restore_VFP __attribute((visibility("protected")));
-extern char __gnu_Unwind_Restore_VFP_D_16_to_31 __attribute((visibility("protected")));
-extern char __gnu_Unwind_Restore_WMMXD __attribute((visibility("protected")));
-extern char __gnu_Unwind_Restore_WMMXC __attribute((visibility("protected")));
-extern char _Unwind_GetCFA __attribute((visibility("protected")));
-extern char __gnu_Unwind_RaiseException __attribute((visibility("protected")));
-extern char __gnu_Unwind_ForcedUnwind __attribute((visibility("protected")));
-extern char __gnu_Unwind_Resume __attribute((visibility("protected")));
-extern char __gnu_Unwind_Resume_or_Rethrow __attribute((visibility("protected")));
-extern char _Unwind_Complete __attribute((visibility("protected")));
-extern char _Unwind_DeleteException __attribute((visibility("protected")));
-extern char _Unwind_VRS_Get __attribute((visibility("protected")));
-extern char _Unwind_VRS_Set __attribute((visibility("protected")));
-extern char __gnu_Unwind_Backtrace __attribute((visibility("protected")));
-extern char _Unwind_VRS_Pop __attribute((visibility("protected")));
-extern char __gnu_Unwind_Save_VFP_D __attribute((visibility("protected")));
-extern char __gnu_Unwind_Save_VFP __attribute((visibility("protected")));
-extern char __gnu_Unwind_Save_VFP_D_16_to_31 __attribute((visibility("protected")));
-extern char __gnu_Unwind_Save_WMMXD __attribute((visibility("protected")));
-extern char __gnu_Unwind_Save_WMMXC __attribute((visibility("protected")));
-extern char ___Unwind_RaiseException __attribute((visibility("protected")));
-extern char _Unwind_RaiseException __attribute((visibility("protected")));
-extern char ___Unwind_Resume __attribute((visibility("protected")));
-extern char _Unwind_Resume __attribute((visibility("protected")));
-extern char ___Unwind_Resume_or_Rethrow __attribute((visibility("protected")));
-extern char _Unwind_Resume_or_Rethrow __attribute((visibility("protected")));
-extern char ___Unwind_ForcedUnwind __attribute((visibility("protected")));
-extern char _Unwind_ForcedUnwind __attribute((visibility("protected")));
-extern char ___Unwind_Backtrace __attribute((visibility("protected")));
-extern char _Unwind_GetRegionStart __attribute((visibility("protected")));
-extern char _Unwind_GetLanguageSpecificData __attribute((visibility("protected")));
-extern char _Unwind_GetDataRelBase __attribute((visibility("protected")));
-extern char _Unwind_GetTextRelBase __attribute((visibility("protected")));
-
-void* __bionic_libgcc_unwind_symbols[] = {
-    &_Unwind_Backtrace,
-    &__gnu_Unwind_Find_exidx,
-    &__gnu_Unwind_Restore_VFP_D,
-    &__gnu_Unwind_Restore_VFP,
-    &__gnu_Unwind_Restore_VFP_D_16_to_31,
-    &__gnu_Unwind_Restore_WMMXD,
-    &__gnu_Unwind_Restore_WMMXC,
-    &_Unwind_GetCFA,
-    &__gnu_Unwind_RaiseException,
-    &__gnu_Unwind_ForcedUnwind,
-    &__gnu_Unwind_Resume,
-    &__gnu_Unwind_Resume_or_Rethrow,
-    &_Unwind_Complete,
-    &_Unwind_DeleteException,
-    &_Unwind_VRS_Get,
-    &_Unwind_VRS_Set,
-    &__gnu_Unwind_Backtrace,
-    &_Unwind_VRS_Pop,
-    &__gnu_Unwind_Save_VFP_D,
-    &__gnu_Unwind_Save_VFP,
-    &__gnu_Unwind_Save_VFP_D_16_to_31,
-    &__gnu_Unwind_Save_WMMXD,
-    &__gnu_Unwind_Save_WMMXC,
-    &___Unwind_RaiseException,
-    &_Unwind_RaiseException,
-    &___Unwind_Resume,
-    &_Unwind_Resume,
-    &___Unwind_Resume_or_Rethrow,
-    &_Unwind_Resume_or_Rethrow,
-    &___Unwind_ForcedUnwind,
-    &_Unwind_ForcedUnwind,
-    &___Unwind_Backtrace,
-    &_Unwind_GetRegionStart,
-    &_Unwind_GetLanguageSpecificData,
-    &_Unwind_GetDataRelBase,
-    &_Unwind_GetTextRelBase,
-};
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index a240663..b55c57f 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -30,8 +30,14 @@
 #define VDSO_GETTIMEOFDAY_SYMBOL  "__vdso_gettimeofday"
 #endif
 
+#include <errno.h>
+#include <limits.h>
+#include <sys/mman.h>
 #include <time.h>
 
+#include "private/bionic_prctl.h"
+#include "private/libc_logging.h"
+
 extern "C" int __clock_gettime(int, timespec*);
 extern "C" int __gettimeofday(timeval*, struct timezone*);
 
@@ -46,28 +52,31 @@
   VDSO_END
 };
 
-static vdso_entry vdso_entries[] = {
+static union {
+  vdso_entry entries[VDSO_END];
+  char padding[PAGE_SIZE];
+} vdso __attribute__((aligned(PAGE_SIZE))) = {{
   [VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, reinterpret_cast<void*>(__clock_gettime) },
   [VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL, reinterpret_cast<void*>(__gettimeofday) },
-};
+}};
 
 int clock_gettime(int clock_id, timespec* tp) {
-  static int (*vdso_clock_gettime)(int, timespec*) =
-      reinterpret_cast<int (*)(int, timespec*)>(vdso_entries[VDSO_CLOCK_GETTIME].fn);
+  int (*vdso_clock_gettime)(int, timespec*) =
+      reinterpret_cast<int (*)(int, timespec*)>(vdso.entries[VDSO_CLOCK_GETTIME].fn);
   return vdso_clock_gettime(clock_id, tp);
 }
 
 int gettimeofday(timeval* tv, struct timezone* tz) {
-  static int (*vdso_gettimeofday)(timeval*, struct timezone*) =
-      reinterpret_cast<int (*)(timeval*, struct timezone*)>(vdso_entries[VDSO_GETTIMEOFDAY].fn);
+  int (*vdso_gettimeofday)(timeval*, struct timezone*) =
+      reinterpret_cast<int (*)(timeval*, struct timezone*)>(vdso.entries[VDSO_GETTIMEOFDAY].fn);
   return vdso_gettimeofday(tv, tz);
 }
 
-void __libc_init_vdso() {
+static void __libc_init_vdso_entries() {
   // Do we have a vdso?
   uintptr_t vdso_ehdr_addr = getauxval(AT_SYSINFO_EHDR);
   ElfW(Ehdr)* vdso_ehdr = reinterpret_cast<ElfW(Ehdr)*>(vdso_ehdr_addr);
-  if (vdso_ehdr == NULL) {
+  if (vdso_ehdr == nullptr) {
     return;
   }
 
@@ -85,7 +94,7 @@
 
   // Where's the dynamic table?
   ElfW(Addr) vdso_addr = 0;
-  ElfW(Dyn)* vdso_dyn = NULL;
+  ElfW(Dyn)* vdso_dyn = nullptr;
   ElfW(Phdr)* vdso_phdr = reinterpret_cast<ElfW(Phdr)*>(vdso_ehdr_addr + vdso_ehdr->e_phoff);
   for (size_t i = 0; i < vdso_ehdr->e_phnum; ++i) {
     if (vdso_phdr[i].p_type == PT_DYNAMIC) {
@@ -94,13 +103,13 @@
       vdso_addr = vdso_ehdr_addr + vdso_phdr[i].p_offset - vdso_phdr[i].p_vaddr;
     }
   }
-  if (vdso_addr == 0 || vdso_dyn == NULL) {
+  if (vdso_addr == 0 || vdso_dyn == nullptr) {
     return;
   }
 
   // Where are the string and symbol tables?
-  const char* strtab = NULL;
-  ElfW(Sym)* symtab = NULL;
+  const char* strtab = nullptr;
+  ElfW(Sym)* symtab = nullptr;
   for (ElfW(Dyn)* d = vdso_dyn; d->d_tag != DT_NULL; ++d) {
     if (d->d_tag == DT_STRTAB) {
       strtab = reinterpret_cast<const char*>(vdso_addr + d->d_un.d_ptr);
@@ -108,20 +117,31 @@
       symtab = reinterpret_cast<ElfW(Sym)*>(vdso_addr + d->d_un.d_ptr);
     }
   }
-  if (strtab == NULL || symtab == NULL) {
+  if (strtab == nullptr || symtab == nullptr) {
     return;
   }
 
   // Are there any symbols we want?
   for (size_t i = 0; i < symbol_count; ++i) {
     for (size_t j = 0; j < VDSO_END; ++j) {
-      if (strcmp(vdso_entries[j].name, strtab + symtab[i].st_name) == 0) {
-        vdso_entries[j].fn = reinterpret_cast<void*>(vdso_addr + symtab[i].st_value);
+      if (strcmp(vdso.entries[j].name, strtab + symtab[i].st_name) == 0) {
+        vdso.entries[j].fn = reinterpret_cast<void*>(vdso_addr + symtab[i].st_value);
       }
     }
   }
 }
 
+void __libc_init_vdso() {
+  __libc_init_vdso_entries();
+
+  // We can't use PR_SET_VMA because this isn't an anonymous region.
+  // Long-term we should be able to replace all of this with ifuncs.
+  static_assert(PAGE_SIZE == sizeof(vdso), "sizeof(vdso) too large");
+  if (mprotect(vdso.entries, sizeof(vdso), PROT_READ) == -1) {
+    __libc_fatal("failed to mprotect PROT_READ vdso function pointer table: %s", strerror(errno));
+  }
+}
+
 #else
 
 void __libc_init_vdso() {
diff --git a/libc/include/sys/syslog.h b/libc/include/sys/syslog.h
new file mode 100644
index 0000000..7761ece
--- /dev/null
+++ b/libc/include/sys/syslog.h
@@ -0,0 +1 @@
+#include <syslog.h>
diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h
index 1f010d4..f60c905 100644
--- a/libc/include/sys/time.h
+++ b/libc/include/sys/time.h
@@ -25,6 +25,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _SYS_TIME_H_
 #define _SYS_TIME_H_
 
@@ -32,6 +33,9 @@
 #include <sys/types.h>
 #include <linux/time.h>
 
+/* POSIX says <sys/time.h> gets you most of <sys/select.h> and may get you all of it. */
+#include <sys/select.h>
+
 __BEGIN_DECLS
 
 extern int gettimeofday(struct timeval *, struct timezone *);
@@ -73,6 +77,15 @@
         }                                             \
     } while (0)
 
+#define TIMEVAL_TO_TIMESPEC(tv, ts) {     \
+    (ts)->tv_sec = (tv)->tv_sec;          \
+    (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+}
+#define TIMESPEC_TO_TIMEVAL(tv, ts) {     \
+    (tv)->tv_sec = (ts)->tv_sec;          \
+    (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+}
+
 __END_DECLS
 
 #endif /* _SYS_TIME_H_ */
diff --git a/libc/include/sys/unistd.h b/libc/include/sys/unistd.h
new file mode 100644
index 0000000..1e823fb
--- /dev/null
+++ b/libc/include/sys/unistd.h
@@ -0,0 +1 @@
+#include <unistd.h>
diff --git a/libc/include/sys/vt.h b/libc/include/sys/vt.h
index b37a869..834abfb 100644
--- a/libc/include/sys/vt.h
+++ b/libc/include/sys/vt.h
@@ -1,28 +1 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
 #include <linux/vt.h>
diff --git a/libc/include/syscall.h b/libc/include/syscall.h
new file mode 100644
index 0000000..4c30578
--- /dev/null
+++ b/libc/include/syscall.h
@@ -0,0 +1 @@
+#include <sys/syscall.h>
diff --git a/libc/include/wait.h b/libc/include/wait.h
new file mode 100644
index 0000000..d01b811
--- /dev/null
+++ b/libc/include/wait.h
@@ -0,0 +1 @@
+#include <sys/wait.h>
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 4993568..f1b26c9 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -68,8 +68,9 @@
 }
 
 static void* dlopen_ext(const char* filename, int flags,
-                        const android_dlextinfo* extinfo, soinfo* caller) {
+                        const android_dlextinfo* extinfo, void* caller_addr) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  soinfo* caller = find_containing_library(caller_addr);
   soinfo* result = do_dlopen(filename, flags, extinfo, caller);
   if (result == nullptr) {
     __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
@@ -80,14 +81,12 @@
 
 void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo) {
   void* caller_addr = __builtin_return_address(0);
-  soinfo* caller = find_containing_library(caller_addr);
-  return dlopen_ext(filename, flags, extinfo, caller);
+  return dlopen_ext(filename, flags, extinfo, caller_addr);
 }
 
 void* dlopen(const char* filename, int flags) {
   void* caller_addr = __builtin_return_address(0);
-  soinfo* caller = find_containing_library(caller_addr);
-  return dlopen_ext(filename, flags, nullptr, caller);
+  return dlopen_ext(filename, flags, nullptr, caller_addr);
 }
 
 void* dlsym(void* handle, const char* symbol) {
diff --git a/tests/libs/Android.build.dt_runpath.mk b/tests/libs/Android.build.dt_runpath.mk
index e9b5265..44c8125 100644
--- a/tests/libs/Android.build.dt_runpath.mk
+++ b/tests/libs/Android.build.dt_runpath.mk
@@ -31,7 +31,7 @@
     empty.cpp
 
 libtest_dt_runpath_b_shared_libraries := libtest_dt_runpath_a
-libtest_dt_runpath_b_ldflags := -Wl,--rpath,\$${ORIGIN}/../dt_runpath_a
+libtest_dt_runpath_b_ldflags := -Wl,--rpath,\$${ORIGIN}/../dt_runpath_a -Wl,--enable-new-dtags
 libtest_dt_runpath_b_relative_path := dt_runpath_b_c_x
 module := libtest_dt_runpath_b
 include $(LOCAL_PATH)/Android.build.testlib.mk
@@ -43,7 +43,7 @@
     empty.cpp
 
 libtest_dt_runpath_c_shared_libraries := libtest_dt_runpath_a
-libtest_dt_runpath_c_ldflags := -Wl,--rpath,\$${ORIGIN}/invalid_dt_runpath
+libtest_dt_runpath_c_ldflags := -Wl,--rpath,\$${ORIGIN}/invalid_dt_runpath -Wl,--enable-new-dtags
 libtest_dt_runpath_c_relative_path := dt_runpath_b_c_x
 module := libtest_dt_runpath_c
 include $(LOCAL_PATH)/Android.build.testlib.mk
@@ -53,7 +53,7 @@
     dlopen_b.cpp
 
 libtest_dt_runpath_d_shared_libraries := libtest_dt_runpath_b libtest_dt_runpath_c
-libtest_dt_runpath_d_ldflags := -Wl,--rpath,\$${ORIGIN}/dt_runpath_b_c_x
+libtest_dt_runpath_d_ldflags := -Wl,--rpath,\$${ORIGIN}/dt_runpath_b_c_x -Wl,--enable-new-dtags
 module := libtest_dt_runpath_d
 include $(LOCAL_PATH)/Android.build.testlib.mk