Merge changes Ia0c0018c,I2f1fc8b4,Ibe964c3b,I791da8ac

* changes:
  linker: stop relocating R_ARM_REL32
  Factor out R_GENERIC_COPY
  Factor out R_GENERIC_ABSOLUTE
  Remove broken arm64 PREL/ABS relocations
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 70f7bab..a7be965 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -29,6 +29,7 @@
         "bionic_benchmarks.cpp",
         "atomic_benchmark.cpp",
         "ctype_benchmark.cpp",
+        "dlfcn_benchmark.cpp",
         "get_heap_size_benchmark.cpp",
         "inttypes_benchmark.cpp",
         "malloc_benchmark.cpp",
diff --git a/benchmarks/dlfcn_benchmark.cpp b/benchmarks/dlfcn_benchmark.cpp
new file mode 100644
index 0000000..6a2bb57
--- /dev/null
+++ b/benchmarks/dlfcn_benchmark.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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 <android-base/strings.h>
+#include <benchmark/benchmark.h>
+#include <dlfcn.h>
+
+#include "util.h"
+
+void local_function() {}
+
+template<typename F>
+int bm_dladdr(F fun) {
+    const void* addr = reinterpret_cast<void*>(fun);
+    Dl_info info;
+    int res = dladdr(addr, &info);
+    if (res == 0) abort();
+    if (info.dli_fname == nullptr) abort();
+
+    // needed for DoNotOptimize
+    return res;
+}
+BIONIC_TRIVIAL_BENCHMARK(BM_dladdr_libc_printf, bm_dladdr(printf));
+BIONIC_TRIVIAL_BENCHMARK(BM_dladdr_libdl_dladdr, bm_dladdr(dladdr));
+BIONIC_TRIVIAL_BENCHMARK(BM_dladdr_local_function, bm_dladdr(local_function));
+BIONIC_TRIVIAL_BENCHMARK(BM_dladdr_libbase_split, bm_dladdr(android::base::Split));
diff --git a/docs/native_allocator.md b/docs/native_allocator.md
index 82a98fe..7695470 100644
--- a/docs/native_allocator.md
+++ b/docs/native_allocator.md
@@ -263,21 +263,22 @@
 To generate these traces, see the [Malloc Debug documentation](https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md),
 the option [record\_allocs](https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md#record_allocs_total_entries).
 
-To run these benchmarks, first copy the trace files to the target and
-unzip them using these commands:
+To run these benchmarks, first copy the trace files to the target using
+these commands:
 
     adb shell push system/extras/traces /data/local/tmp
-    adb shell 'cd /data/local/tmp/traces && for name in *.zip; do unzip $name; done'
 
 Since all of the traces come from applications, the `memory_replay` program
 will always call `mallopt(M_DECAY_TIME, 1)' before running the trace.
 
 Run the benchmark thusly:
 
-    adb shell memory_replay64 /data/local/tmp/traces/XXX.txt
-    adb shell memory_replay32 /data/local/tmp/traces/XXX.txt
+    adb shell memory_replay64 /data/local/tmp/traces/XXX.zip
+    adb shell memory_replay32 /data/local/tmp/traces/XXX.zip
 
-Where XXX.txt is the name of a trace file.
+Where XXX.zip is the name of a zipped trace file. The `memory_replay`
+program also can process text files, but all trace files are currently
+checked in as zip files.
 
 Every 100000 allocation operations, a dump of the RSS and VA space will be
 performed. At the end, a final RSS and VA space number will be printed.
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 9351279..dec575b 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -4076,7 +4076,7 @@
   if (insert_pos == std::string::npos) {
     insert_pos = ld_config_file_vndk.length();
   }
-  ld_config_file_vndk.insert(insert_pos, Config::get_vndk_version_string("."));
+  ld_config_file_vndk.insert(insert_pos, Config::get_vndk_version_string('.'));
   return ld_config_file_vndk;
 }
 
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 450d0e6..46c91a3 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -408,7 +408,7 @@
       params.push_back({ "SDK_VER", buf });
     }
 
-    static std::string vndk = Config::get_vndk_version_string("");
+    static std::string vndk = Config::get_vndk_version_string('-');
     params.push_back({ "VNDK_VER", vndk });
 
     for (auto& path : paths) {
@@ -596,11 +596,11 @@
   return true;
 }
 
-std::string Config::get_vndk_version_string(const std::string& prefix) {
+std::string Config::get_vndk_version_string(const char delimiter) {
   std::string version = android::base::GetProperty("ro.vndk.version", "");
   if (version != "" && version != "current") {
-    //add the prefix in front of the string and return it.
-    return version.insert(0, prefix);
+    //add the delimiter char in front of the string and return it.
+    return version.insert(0, 1, delimiter);
   }
   return "";
 }
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 547c62e..75d9378 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -164,7 +164,7 @@
                                  const Config** config,
                                  std::string* error_msg);
 
-  static std::string get_vndk_version_string(const std::string& prefix);
+  static std::string get_vndk_version_string(const char delimiter);
  private:
   void clear();