Fix order of soinfo links (repairs libcxx tests).

(cherry picked from commit b2a30ee8d209154efc367db11b4167a5d6db605f)

Change-Id: I59c5333bc050cbbea14051cea9220be2f64ee383
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 610489e..ac470a5 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1778,8 +1778,8 @@
 
 void soinfo::add_child(soinfo* child) {
   if (has_min_version(0)) {
-    this->children.push_front(child);
-    child->parents.push_front(this);
+    child->parents.push_back(this);
+    this->children.push_back(child);
   }
 }
 
diff --git a/tests/Android.mk b/tests/Android.mk
index 64d3b59..69ff811 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -257,6 +257,7 @@
     -Wl,-u,DlSymTestFunction \
 
 bionic-unit-tests_c_includes := \
+    bionic/libc \
     $(call include-path-for, libpagemap) \
 
 bionic-unit-tests_shared_libraries_target := \
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index b8c33dd..fb3bfc5 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -22,6 +22,8 @@
 #include <stdio.h>
 #include <stdint.h>
 
+#include "private/ScopeGuard.h"
+
 #include <string>
 
 #define ASSERT_SUBSTR(needle, haystack) \
@@ -130,6 +132,32 @@
 }
 #endif
 
+TEST(dlfcn, dlopen_check_relocation_dt_needed_order) {
+  // This is the structure of the test library and
+  // its dt_needed libraries
+  // libtest_relo_check_dt_needed_order.so
+  // |
+  // +-> libtest_relo_check_dt_needed_order_1.so
+  // |
+  // +-> libtest_relo_check_dt_needed_order_2.so
+  //
+  // The root library references relo_test_get_answer_lib - which is defined
+  // in both dt_needed libraries, the correct relocation should
+  // use the function defined in libtest_relo_check_dt_needed_order_1.so
+  void* handle = nullptr;
+  auto guard = create_scope_guard([&]() {
+    dlclose(handle);
+  });
+
+  handle = dlopen("libtest_relo_check_dt_needed_order.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  typedef int (*fn_t) (void);
+  fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "relo_test_get_answer"));
+  ASSERT_TRUE(fn != nullptr) << dlerror();
+  ASSERT_EQ(1, fn());
+}
+
 TEST(dlfcn, dlopen_check_order) {
   // Here is how the test library and its dt_needed
   // libraries are arranged
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index e7a2676..21681ee 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -256,6 +256,29 @@
 include $(TEST_PATH)/Android.build.mk
 
 # -----------------------------------------------------------------------------
+# libtest_relo_check_dt_needed_order.so
+# |
+# +-> libtest_relo_check_dt_needed_order_1.so
+# |
+# +-> libtest_relo_check_dt_needed_order_2.so
+# -----------------------------------------------------------------------------
+libtest_relo_check_dt_needed_order_shared_libraries := \
+    libtest_relo_check_dt_needed_order_1 libtest_relo_check_dt_needed_order_2
+
+libtest_relo_check_dt_needed_order_src_files := dlopen_testlib_relo_check_dt_needed_order.cpp
+libtest_relo_check_dt_needed_order_1_src_files := dlopen_testlib_relo_check_dt_needed_order_1.cpp
+libtest_relo_check_dt_needed_order_2_src_files := dlopen_testlib_relo_check_dt_needed_order_2.cpp
+build_type := target
+build_target := SHARED_LIBRARY
+
+module := libtest_relo_check_dt_needed_order
+include $(TEST_PATH)/Android.build.mk
+module := libtest_relo_check_dt_needed_order_1
+include $(TEST_PATH)/Android.build.mk
+module := libtest_relo_check_dt_needed_order_2
+include $(TEST_PATH)/Android.build.mk
+
+# -----------------------------------------------------------------------------
 # Library with dependency used by dlfcn tests
 # -----------------------------------------------------------------------------
 libtest_with_dependency_src_files := \
diff --git a/tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp b/tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp
new file mode 100644
index 0000000..d8fb543
--- /dev/null
+++ b/tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+extern "C" int relo_test_get_answer_lib();
+
+extern "C" int relo_test_get_answer() {
+  return relo_test_get_answer_lib();
+}
diff --git a/tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.cpp b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.cpp
new file mode 100644
index 0000000..4c877d0
--- /dev/null
+++ b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+extern "C" int relo_test_get_answer_lib() {
+  return 1;
+}
diff --git a/tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.cpp b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.cpp
new file mode 100644
index 0000000..10288a0
--- /dev/null
+++ b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+extern "C" int relo_test_get_answer_lib() {
+  return 2;
+}