Merge "Fix streaming(memcpy) performance on Cortex-A7"
diff --git a/libc/Android.bp b/libc/Android.bp
index 3f7e94c..33fa447 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1201,6 +1201,13 @@
     name: "libc_bionic",
 }
 
+genrule {
+    name: "generated_android_ids",
+    out: [ "generated_android_ids.h" ],
+    tool_files: [ "fs_config_generator.py" ],
+    cmd: "$(location fs_config_generator.py) aidarray system/core/include/private/android_filesystem_config.h > $(out)",
+}
+
 // ========================================================
 // libc_bionic_ndk.a- The portions of libc_bionic that can
 // be safely used in libc_ndk.a (no troublesome global data
@@ -1389,6 +1396,7 @@
     local_include_dirs: ["stdio"],
     include_dirs: ["bionic/libstdc++/include"],
     name: "libc_bionic_ndk",
+    generated_headers: ["generated_android_ids"],
 }
 
 // ========================================================
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index 9aefd44..cf8fa8e 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -31,8 +31,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-extern "C" int tgkill(int tgid, int tid, int sig);
-
 void abort() {
   // Don't block SIGABRT to give any signal handler a chance; we ignore
   // any errors -- X311J doesn't allow abort to return anyway.
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index db0f777..e99eaca 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -43,6 +43,9 @@
 #include "private/libc_logging.h"
 #include "private/ThreadLocalBuffer.h"
 
+// Generated android_ids array
+#include "generated_android_ids.h"
+
 // POSIX seems to envisage an implementation where the <pwd.h> functions are
 // implemented by brute-force searching with getpwent(3), and the <grp.h>
 // functions are implemented similarly with getgrent(3). This means that it's
diff --git a/libc/bionic/pthread_kill.cpp b/libc/bionic/pthread_kill.cpp
index 93513fa..72a6ed1 100644
--- a/libc/bionic/pthread_kill.cpp
+++ b/libc/bionic/pthread_kill.cpp
@@ -32,8 +32,6 @@
 #include "private/ErrnoRestorer.h"
 #include "pthread_internal.h"
 
-extern "C" int tgkill(int tgid, int tid, int sig);
-
 int pthread_kill(pthread_t t, int sig) {
   ErrnoRestorer errno_restorer;
 
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index 0f68431..e925d23 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -1046,7 +1046,7 @@
 int __system_property_area_init()
 {
     free_and_unmap_contexts();
-    mkdir(property_filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+    mkdir(property_filename, S_IRWXU | S_IXGRP | S_IXOTH);
     if (!initialize_properties()) {
         return -1;
     }
diff --git a/libc/fs_config_generator.py b/libc/fs_config_generator.py
new file mode 120000
index 0000000..aafb7dc
--- /dev/null
+++ b/libc/fs_config_generator.py
@@ -0,0 +1 @@
+../../build/tools/fs_config/fs_config_generator.py
\ No newline at end of file
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 7ae50de..ffce1fa 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -150,6 +150,7 @@
 int raise(int);
 int kill(pid_t, int);
 int killpg(int, int);
+int tgkill(int tgid, int tid, int sig) __INTRODUCED_IN_32(16);
 
 int sigaltstack(const stack_t*, stack_t*);
 
diff --git a/libc/upstream-freebsd/README.txt b/libc/upstream-freebsd/README.md
similarity index 100%
rename from libc/upstream-freebsd/README.txt
rename to libc/upstream-freebsd/README.md
diff --git a/libc/upstream-netbsd/README.txt b/libc/upstream-netbsd/README.md
similarity index 100%
rename from libc/upstream-netbsd/README.txt
rename to libc/upstream-netbsd/README.md
diff --git a/libc/upstream-openbsd/README.txt b/libc/upstream-openbsd/README.md
similarity index 100%
rename from libc/upstream-openbsd/README.txt
rename to libc/upstream-openbsd/README.md
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 13edfe1..dad7409 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -306,9 +306,21 @@
   si->dynamic = nullptr;
 
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
+
+  // We haven't supported non-PIE since Lollipop for security reasons.
   if (elf_hdr->e_type != ET_DYN) {
-    __libc_fatal("\"%s\": error: only position independent executables (PIE) are supported.",
-                 g_argv[0]);
+    // We don't use __libc_fatal here because we don't want a tombstone: it's
+    // been several years now but we still find ourselves on app compatibility
+    // investigations because some app's trying to launch an executable that
+    // hasn't worked in at least three years, and we've "helpfully" dropped a
+    // tombstone for them. The tombstone never provided any detail relevant to
+    // fixing the problem anyway, and the utility of drawing extra attention
+    // to the problem is non-existent at this late date.
+    __libc_format_fd(STDERR_FILENO,
+                     "\"%s\": error: Android 5.0 and later only support "
+                     "position-independent executables (-fPIE).\n",
+                     g_argv[0]);
+    exit(0);
   }
 
   // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 973fcf5..a453bef 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -373,21 +373,37 @@
   }
 
   if (pt_dynamic_offset != dynamic_shdr->sh_offset) {
-    DL_ERR("\"%s\" .dynamic section has invalid offset: 0x%zx, "
-           "expected to match PT_DYNAMIC offset: 0x%zx",
-           name_.c_str(),
-           static_cast<size_t>(dynamic_shdr->sh_offset),
-           pt_dynamic_offset);
-    return false;
+    if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+      DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid offset: 0x%zx, "
+                     "expected to match PT_DYNAMIC offset: 0x%zx",
+                     name_.c_str(),
+                     static_cast<size_t>(dynamic_shdr->sh_offset),
+                     pt_dynamic_offset);
+      return false;
+    }
+    DL_WARN("\"%s\" .dynamic section has invalid offset: 0x%zx, "
+            "expected to match PT_DYNAMIC offset: 0x%zx",
+            name_.c_str(),
+            static_cast<size_t>(dynamic_shdr->sh_offset),
+            pt_dynamic_offset);
+    add_dlwarning(name_.c_str(), "invalid .dynamic section");
   }
 
   if (pt_dynamic_filesz != dynamic_shdr->sh_size) {
-    DL_ERR("\"%s\" .dynamic section has invalid size: 0x%zx, "
-           "expected to match PT_DYNAMIC filesz: 0x%zx",
-           name_.c_str(),
-           static_cast<size_t>(dynamic_shdr->sh_size),
-           pt_dynamic_filesz);
-    return false;
+    if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+      DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid size: 0x%zx, "
+                     "expected to match PT_DYNAMIC filesz: 0x%zx",
+                     name_.c_str(),
+                     static_cast<size_t>(dynamic_shdr->sh_size),
+                     pt_dynamic_filesz);
+      return false;
+    }
+    DL_WARN("\"%s\" .dynamic section has invalid size: 0x%zx, "
+            "expected to match PT_DYNAMIC filesz: 0x%zx",
+            name_.c_str(),
+            static_cast<size_t>(dynamic_shdr->sh_size),
+            pt_dynamic_filesz);
+    add_dlwarning(name_.c_str(), "invalid .dynamic section");
   }
 
   if (dynamic_shdr->sh_link >= shdr_num_) {
diff --git a/tests/Android.bp b/tests/Android.bp
index da90a92..84be7bc 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -155,6 +155,8 @@
     shared: {
         enabled: false,
     },
+
+    generated_headers: ["generated_android_ids"],
 }
 
 // -----------------------------------------------------------------------------
@@ -422,6 +424,9 @@
     defaults: ["bionic_tests_defaults"],
     host_supported: false,
 
+    srcs: [
+        "gtest_preinit_debuggerd.cpp",
+    ],
     whole_static_libs: [
         "libBionicTests",
         "libBionicGtestMain",
@@ -435,6 +440,7 @@
         "libtinyxml2",
         "liblog",
         "libbase",
+        "libdebuggerd_client",
     ],
 
     static_executable: true,
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index cc236f8..f8232aa 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -30,6 +30,9 @@
 
 #include <private/android_filesystem_config.h>
 
+// Generated android_ids array
+#include "generated_android_ids.h"
+
 enum uid_type_t {
   TYPE_SYSTEM,
   TYPE_APP
diff --git a/tests/gtest_preinit_debuggerd.cpp b/tests/gtest_preinit_debuggerd.cpp
new file mode 100644
index 0000000..aac2e3f
--- /dev/null
+++ b/tests/gtest_preinit_debuggerd.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "debuggerd/client.h"
+
+void __gtest_preinit() {
+  debuggerd_init(nullptr);
+}
+
+__attribute__((section(".preinit_array"), __used__))
+void (*__local_gtest_preinit)(void) = __gtest_preinit;
diff --git a/tests/wctype_test.cpp b/tests/wctype_test.cpp
index 84a0e65..1bc4128 100644
--- a/tests/wctype_test.cpp
+++ b/tests/wctype_test.cpp
@@ -29,7 +29,9 @@
 
 // bionic's dlsym doesn't work in static binaries, so we can't access icu,
 // so any unicode test case will fail.
-static bool have_dl = (dlopen("libc.so", 0) != nullptr);
+static bool have_dl() {
+  return (dlopen("libc.so", 0) != nullptr);
+}
 
 static void TestIsWideFn(int fn(wint_t),
                          int fn_l(wint_t, locale_t),
@@ -37,7 +39,7 @@
                          const wchar_t* falses) {
   UtfLocale l;
   for (const wchar_t* p = trues; *p; ++p) {
-    if (!have_dl && *p > 0x7f) {
+    if (!have_dl() && *p > 0x7f) {
       GTEST_LOG_(INFO) << "skipping unicode test " << *p;
       continue;
     }
@@ -45,7 +47,7 @@
     EXPECT_TRUE(fn_l(*p, l.l)) << *p;
   }
   for (const wchar_t* p = falses; *p; ++p) {
-    if (!have_dl && *p > 0x7f) {
+    if (!have_dl() && *p > 0x7f) {
       GTEST_LOG_(INFO) << "skipping unicode test " << *p;
       continue;
     }
@@ -107,7 +109,7 @@
   EXPECT_EQ(wint_t('!'), towlower(L'!'));
   EXPECT_EQ(wint_t('a'), towlower(L'a'));
   EXPECT_EQ(wint_t('a'), towlower(L'A'));
-  if (have_dl) {
+  if (have_dl()) {
     EXPECT_EQ(wint_t(L'ç'), towlower(L'ç'));
     EXPECT_EQ(wint_t(L'ç'), towlower(L'Ç'));
     EXPECT_EQ(wint_t(L'δ'), towlower(L'δ'));
@@ -123,7 +125,7 @@
   EXPECT_EQ(wint_t('!'), towlower_l(L'!', l.l));
   EXPECT_EQ(wint_t('a'), towlower_l(L'a', l.l));
   EXPECT_EQ(wint_t('a'), towlower_l(L'A', l.l));
-  if (have_dl) {
+  if (have_dl()) {
     EXPECT_EQ(wint_t(L'ç'), towlower_l(L'ç', l.l));
     EXPECT_EQ(wint_t(L'ç'), towlower_l(L'Ç', l.l));
     EXPECT_EQ(wint_t(L'δ'), towlower_l(L'δ', l.l));
@@ -138,7 +140,7 @@
   EXPECT_EQ(wint_t('!'), towupper(L'!'));
   EXPECT_EQ(wint_t('A'), towupper(L'a'));
   EXPECT_EQ(wint_t('A'), towupper(L'A'));
-  if (have_dl) {
+  if (have_dl()) {
     EXPECT_EQ(wint_t(L'Ç'), towupper(L'ç'));
     EXPECT_EQ(wint_t(L'Ç'), towupper(L'Ç'));
     EXPECT_EQ(wint_t(L'Δ'), towupper(L'δ'));
@@ -154,7 +156,7 @@
   EXPECT_EQ(wint_t('!'), towupper_l(L'!', l.l));
   EXPECT_EQ(wint_t('A'), towupper_l(L'a', l.l));
   EXPECT_EQ(wint_t('A'), towupper_l(L'A', l.l));
-  if (have_dl) {
+  if (have_dl()) {
     EXPECT_EQ(wint_t(L'Ç'), towupper_l(L'ç', l.l));
     EXPECT_EQ(wint_t(L'Ç'), towupper_l(L'Ç', l.l));
     EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'δ', l.l));