Merge "Updates for glibc 2.17."
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..376c250
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,52 @@
+//
+// 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.
+//
+
+bionic_mountpoint {
+    name: "libc.mountpoint",
+    stem: "libc.so",
+    src: "dummy_mountpoint",
+    library: true,
+    symlinks: ["libc.so"],
+}
+
+bionic_mountpoint {
+    name: "libdl.mountpoint",
+    stem: "libdl.so",
+    src: "dummy_mountpoint",
+    library: true,
+    symlinks: ["libdl.so"],
+}
+
+bionic_mountpoint {
+    name: "libm.mountpoint",
+    stem: "libm.so",
+    src: "dummy_mountpoint",
+    library: true,
+    symlinks: ["libm.so"],
+}
+
+bionic_mountpoint {
+    name: "linker.mountpoint",
+    stem: "linker",
+    multilib: {
+        lib64: {
+            suffix: "64",
+        },
+    },
+    src: "dummy_mountpoint",
+    binary: true,
+    symlinks: ["linker", "linker_asan"],
+}
diff --git a/build/Android.bp b/build/Android.bp
new file mode 100644
index 0000000..6cc160a
--- /dev/null
+++ b/build/Android.bp
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+
+bootstrap_go_package {
+    name: "soong-bionic",
+    pkgPath: "android/soong/bionic",
+    deps: [
+        "blueprint",
+        "blueprint-pathtools",
+        "blueprint-proptools",
+        "soong",
+        "soong-android",
+    ],
+    srcs: [
+        "bionic.go",
+    ],
+    pluginFor: ["soong_build"],
+}
diff --git a/build/bionic.go b/build/bionic.go
new file mode 100644
index 0000000..3522aca
--- /dev/null
+++ b/build/bionic.go
@@ -0,0 +1,164 @@
+// 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.
+
+package bionic
+
+import (
+	"fmt"
+	"io"
+	"strings"
+
+	"github.com/google/blueprint/proptools"
+
+	"android/soong/android"
+)
+
+// bionic_mountpoint is a module type that is specialized to create
+// mount points for Bionic files (libc, libdl, libm, and linker).
+//
+// With following description,
+//
+// bionic_mountpoint {
+//    name: "libc.mountpoint",
+//    stem: "libc.so",
+//    src: "dummy_mountpoint",
+//    library: true,
+//    symlinks: ["libc.so"],
+// }
+//
+// , the build system does following jobs:
+//
+// A mount point /bionic/lib[64]/libc.so is created. Its content
+// is from the file 'dummy_mountpoint'.
+//
+// Then a symlink is created at /system/lib[64]/libc.so which points to
+// the created mountpoint.
+//
+// At runtime, on the mount point, either bootstrap Bionic or default Bionic
+// (which is from the runtime APEX) is mounted by the init process. The
+// symlink exists to provide consistent legacy path for compatibility
+// reason.
+func init() {
+	android.RegisterModuleType("bionic_mountpoint", bionicMountpointFactory)
+}
+
+type bionicMountpoint struct {
+	android.ModuleBase
+	properties bionicMountpointProperties
+
+	outputFile android.Path
+	pathInPartition string
+	stem string
+}
+
+type bionicMountpointProperties struct {
+	// The file that is installed as the mount point
+	Src *string
+
+	// True if the mount point is for a Bionic library such libc.so
+	Library *bool
+	// True if the mount point is for a Bionic binary such as linker
+	Binary *bool
+
+	// Base name of the mount point
+	Stem *string `android:"arch_variant"`
+
+	// Append to the name of the output
+	Suffix *string `android:"arch_variant"`
+
+	// Symlinks to the mountpoints from the system and recovery partitions
+	// Symlinks names will have the same suffix as the mount point
+	Symlinks []string
+}
+
+func (m *bionicMountpoint) DepsMutator(ctx android.BottomUpMutatorContext) {
+	if Bool(m.properties.Library) == Bool(m.properties.Binary) {
+		ctx.ModuleErrorf("either binary or library must be set to true")
+		return
+	}
+	if m.properties.Stem == nil {
+		ctx.PropertyErrorf("stem", "stem must be set")
+		return
+	}
+	if m.properties.Src == nil {
+		ctx.PropertyErrorf("src", "src must be set")
+	}
+	android.ExtractSourceDeps(ctx, m.properties.Src)
+}
+
+func (m *bionicMountpoint) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if Bool(m.properties.Library) {
+		m.pathInPartition = "lib"
+		if m.Arch().ArchType.Multilib == "lib64" {
+			m.pathInPartition = "lib64"
+		}
+	} else if Bool(m.properties.Binary) {
+		m.pathInPartition = "bin"
+	}
+
+	m.stem = String(m.properties.Stem) + String(m.properties.Suffix)
+
+	m.outputFile = ctx.ExpandSource(String(m.properties.Src), "src")
+}
+
+func (m *bionicMountpoint) AndroidMk() android.AndroidMkData {
+	return android.AndroidMkData {
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+			if !m.Arch().Native {
+				return
+			}
+			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+			fmt.Fprintln(w, "LOCAL_USE_CLANG_LLD := false")
+			fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
+			if Bool(m.properties.Library) {
+				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := SHARED_LIBRARIES")
+			} else if Bool(m.properties.Binary) {
+				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := EXECUTABLES")
+			}
+			fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
+			fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputFile.String())
+			fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", m.Arch().ArchType.String())
+			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_ROOT_OUT)/bionic/" + m.pathInPartition)
+			fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem)
+
+			if len(m.properties.Symlinks) > 0 {
+				symlink_dir_in_system := "$(TARGET_OUT)/" + m.pathInPartition + "/"
+				symlink_dir_in_recovery := "$(TARGET_RECOVERY_ROOT_OUT)/system/" + m.pathInPartition + "/"
+				symlink_target := "/bionic/" + m.pathInPartition + "/" + m.stem
+				cmds := []string{}
+				cmds = append(cmds, "$(hide) mkdir -p " + symlink_dir_in_system)
+				cmds = append(cmds, "mkdir -p " + symlink_dir_in_recovery)
+				for _, s := range m.properties.Symlinks {
+					symlink := s + String(m.properties.Suffix)
+					cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_system +  symlink)
+					cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_recovery +  symlink)
+				}
+				fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := " + strings.Join(cmds, " && "))
+			}
+			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
+		},
+	}
+}
+
+func bionicMountpointFactory() android.Module {
+	m := &bionicMountpoint{}
+        m.AddProperties(&m.properties)
+	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
+	return m
+}
+
+var Bool = proptools.Bool
+var String = proptools.String
diff --git a/dummy_mountpoint b/dummy_mountpoint
new file mode 100644
index 0000000..2d13c55
--- /dev/null
+++ b/dummy_mountpoint
@@ -0,0 +1 @@
+This file serves as a mount point for bionic files either from /system partition or from /apex/com.android.runtime. This file is never meant to be accessed directly.
diff --git a/libc/Android.bp b/libc/Android.bp
index 226a81f..4cf31bc 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1548,7 +1548,7 @@
         ],
     },
 
-    required: ["tzdata"],
+    required: ["tzdata", "libc.mountpoint"],
 
     // Leave the symbols in the shared library so that stack unwinders can produce
     // meaningful name resolution.
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 262da6c..c17e72e 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -105,6 +105,7 @@
         symbol_file: "libdl.map.txt",
         versions: ["10000"],
     },
+    required: ["libdl.mountpoint"],
 }
 
 ndk_library {
diff --git a/libm/Android.bp b/libm/Android.bp
index 28cf1fd..079220b 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -515,6 +515,7 @@
         symbol_file: "libm.map.txt",
         versions: ["10000"],
     },
+    required: ["libm.mountpoint"],
 }
 
 ndk_library {
diff --git a/linker/Android.bp b/linker/Android.bp
index 033860a..fed921d 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -283,6 +283,8 @@
 
     name: "linker",
     symlinks: ["linker_asan"],
+    // The linker in the system partition is now only for bootstrapping
+    relative_install_path: "bootstrap",
     recovery_available: true,
     multilib: {
         lib32: {
@@ -301,6 +303,7 @@
     },
     compile_multilib: "both",
     xom: false,
+    required: ["linker.mountpoint"],
 }
 
 cc_library {
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index 27f1e38..d72cad3 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -55,8 +55,7 @@
   : block_size_(
       round_up(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size, 16)),
     page_list_(nullptr),
-    free_block_list_(nullptr),
-    allocated_(0)
+    free_block_list_(nullptr)
 {}
 
 void* LinkerBlockAllocator::alloc() {
@@ -77,8 +76,6 @@
 
   memset(block_info, 0, block_size_);
 
-  ++allocated_;
-
   return block_info;
 }
 
@@ -107,11 +104,6 @@
   block_info->num_free_blocks = 1;
 
   free_block_list_ = block_info;
-
-  --allocated_;
-  if (allocated_ == 0) {
-    free_all_pages();
-  }
 }
 
 void LinkerBlockAllocator::protect_all(int prot) {
@@ -162,18 +154,3 @@
 
   abort();
 }
-
-void LinkerBlockAllocator::free_all_pages() {
-  if (allocated_) {
-    abort();
-  }
-
-  LinkerBlockAllocatorPage* page = page_list_;
-  while (page) {
-    LinkerBlockAllocatorPage* next = page->next;
-    munmap(page, kAllocateSize);
-    page = next;
-  }
-  page_list_ = nullptr;
-  free_block_list_ = nullptr;
-}
diff --git a/linker/linker_block_allocator.h b/linker/linker_block_allocator.h
index 458d092..0c54b93 100644
--- a/linker/linker_block_allocator.h
+++ b/linker/linker_block_allocator.h
@@ -53,12 +53,10 @@
  private:
   void create_new_page();
   LinkerBlockAllocatorPage* find_page(void* block);
-  void free_all_pages();
 
   size_t block_size_;
   LinkerBlockAllocatorPage* page_list_;
   void* free_block_list_;
-  size_t allocated_;
 
   DISALLOW_COPY_AND_ASSIGN(LinkerBlockAllocator);
 };
@@ -75,8 +73,7 @@
  *    513 this allocator will use 516 (520 for lp64) bytes of data where
  *    generalized implementation is going to use 1024 sized blocks.
  *
- * 2. Unless all allocated memory is freed, this allocator does not munmap
- *    allocated memory, where BionicAllocator does.
+ * 2. This allocator does not munmap allocated memory, where BionicAllocator does.
  *
  * 3. This allocator provides mprotect services to the user, where BionicAllocator
  *    always treats its memory as READ|WRITE.