Remove libsigchain from LD_PRELOADS

  Link sigchain.cc statically with dalvikvm, app_process,
  surfaceflinger, dex2oat, patchoat and objdump.

  Replace libsigchain.so with dummy implementaions to avoid
  situations when it is used incorrectly.

Bug: 15345057
Bug: 15426766
Change-Id: If0b7f59a59824e30aa0c33dad76c7a44932180de
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index d887acd..e36b006 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -54,7 +54,7 @@
   include $(CLEAR_VARS)
   LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
   LOCAL_MODULE_TAGS := optional
-  LOCAL_SRC_FILES := $$(art_source)
+  LOCAL_SRC_FILES := $$(art_source) ../sigchainlib/sigchain.cc
   LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime $$(art_c_includes)
   LOCAL_SHARED_LIBRARIES += $$(art_shared_libraries)
 
@@ -65,9 +65,11 @@
   endif
 
   LOCAL_CFLAGS := $(ART_EXECUTABLES_CFLAGS)
+  LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
   ifeq ($$(art_target_or_host),target)
   	$(call set-target-local-clang-vars)
   	$(call set-target-local-cflags-vars,$(6))
+    LOCAL_SHARED_LIBRARIES += libdl
   else # host
     LOCAL_CLANG := $(ART_HOST_CLANG)
     LOCAL_CFLAGS += $(ART_HOST_CFLAGS)
@@ -76,7 +78,7 @@
     else
       LOCAL_CFLAGS += $(ART_HOST_NON_DEBUG_CFLAGS)
     endif
-    LOCAL_LDLIBS += -lpthread
+    LOCAL_LDLIBS += -lpthread -ldl
   endif
 
   ifeq ($$(art_ndebug_or_debug),ndebug)
diff --git a/dalvikvm/Android.mk b/dalvikvm/Android.mk
index a06b5c5..b7e649a 100644
--- a/dalvikvm/Android.mk
+++ b/dalvikvm/Android.mk
@@ -24,10 +24,11 @@
 LOCAL_MODULE := dalvikvm
 LOCAL_MODULE_TAGS := optional
 LOCAL_CPP_EXTENSION := cc
-LOCAL_SRC_FILES := dalvikvm.cc
+LOCAL_SRC_FILES := dalvikvm.cc ../sigchainlib/sigchain.cc
 LOCAL_CFLAGS := $(dalvikvm_cflags)
 LOCAL_C_INCLUDES := art/runtime
-LOCAL_SHARED_LIBRARIES := libdl libnativehelper
+LOCAL_SHARED_LIBRARIES := libdl liblog libnativehelper
+LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.common.mk
 LOCAL_MULTILIB := both
@@ -50,11 +51,11 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_CLANG := true
 LOCAL_CPP_EXTENSION := cc
-LOCAL_SRC_FILES := dalvikvm.cc
+LOCAL_SRC_FILES := dalvikvm.cc ../sigchainlib/sigchain.cc
 LOCAL_CFLAGS := $(dalvikvm_cflags)
 LOCAL_C_INCLUDES := art/runtime
 LOCAL_SHARED_LIBRARIES := libnativehelper
-LOCAL_LDFLAGS := -ldl -lpthread
+LOCAL_LDFLAGS := -ldl -lpthread -Wl,--export-dynamic
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
 LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.common.mk
 LOCAL_IS_HOST_MODULE := true
diff --git a/sigchainlib/Android.mk b/sigchainlib/Android.mk
index d86735d..e52adfc 100644
--- a/sigchainlib/Android.mk
+++ b/sigchainlib/Android.mk
@@ -22,10 +22,10 @@
 LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
 LOCAL_MODULE_TAGS := optional
 LOCAL_CFLAGS += $(ART_TARGET_CFLAGS)
-LOCAL_SRC_FILES := sigchain.cc
+LOCAL_SRC_FILES := sigchain_dummy.cc
 LOCAL_CLANG = $(ART_TARGET_CLANG)
 LOCAL_MODULE:= libsigchain
-LOCAL_SHARED_LIBRARIES := liblog libdl
+LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.common_build.mk
 include $(BUILD_SHARED_LIBRARY)
@@ -37,7 +37,7 @@
 LOCAL_IS_HOST_MODULE := true
 LOCAL_CFLAGS += $(ART_HOST_CFLAGS)
 LOCAL_CLANG = $(ART_HOST_CLANG)
-LOCAL_SRC_FILES := sigchain.cc
+LOCAL_SRC_FILES := sigchain_dummy.cc
 LOCAL_MODULE:= libsigchain
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
 LOCAL_LDLIBS = -ldl
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index 74bfb7e..c5015e8 100644
--- a/sigchainlib/sigchain.cc
+++ b/sigchainlib/sigchain.cc
@@ -107,21 +107,20 @@
   }
 }
 
-
 // Claim a signal chain for a particular signal.
-void ClaimSignalChain(int signal, struct sigaction* oldaction) {
+extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction) {
   CheckSignalValid(signal);
   user_sigactions[signal].Claim(*oldaction);
 }
 
-void UnclaimSignalChain(int signal) {
+extern "C" void UnclaimSignalChain(int signal) {
   CheckSignalValid(signal);
 
   user_sigactions[signal].Unclaim(signal);
 }
 
 // Invoke the user's signal handler.
-void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context) {
+extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context) {
   // Check the arguments.
   CheckSignalValid(sig);
 
@@ -148,10 +147,9 @@
   }
 }
 
-extern "C" {
 // These functions are C linkage since they replace the functions in libc.
 
-int sigaction(int signal, const struct sigaction* new_action, struct sigaction* old_action) {
+extern "C" int sigaction(int signal, const struct sigaction* new_action, struct sigaction* old_action) {
   // If this signal has been claimed as a signal chain, record the user's
   // action but don't pass it on to the kernel.
   // Note that we check that the signal number is in range here.  An out of range signal
@@ -187,7 +185,7 @@
   return linked_sigaction(signal, new_action, old_action);
 }
 
-sighandler_t signal(int signal, sighandler_t handler) {
+extern "C" sighandler_t signal(int signal, sighandler_t handler) {
   struct sigaction sa;
   sigemptyset(&sa.sa_mask);
   sa.sa_handler = handler;
@@ -226,7 +224,7 @@
   return reinterpret_cast<sighandler_t>(sa.sa_handler);
 }
 
-int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
+extern "C" int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
   const sigset_t* new_set_ptr = bionic_new_set;
   sigset_t tmpset;
   if (bionic_new_set != NULL) {
@@ -258,9 +256,8 @@
   SigProcMask linked_sigprocmask= reinterpret_cast<SigProcMask>(linked_sigprocmask_sym);
   return linked_sigprocmask(how, new_set_ptr, bionic_old_set);
 }
-}   // extern "C"
 
-void InitializeSignalChain() {
+extern "C" void InitializeSignalChain() {
   // Warning.
   // Don't call this from within a signal context as it makes calls to
   // dlsym.  Calling into the dynamic linker will result in locks being
diff --git a/sigchainlib/sigchain.h b/sigchainlib/sigchain.h
index 5bc4026..0de0d08 100644
--- a/sigchainlib/sigchain.h
+++ b/sigchainlib/sigchain.h
@@ -19,16 +19,12 @@
 
 #include <signal.h>
 
-namespace art {
+extern "C" void InitializeSignalChain();
 
-void InitializeSignalChain();
+extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction);
 
-void ClaimSignalChain(int signal, struct sigaction* oldaction);
+extern "C" void UnclaimSignalChain(int signal);
 
-void UnclaimSignalChain(int signal);
-
-void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context);
-
-}   // namespace art
+extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context);
 
 #endif  // ART_SIGCHAINLIB_SIGCHAIN_H_
diff --git a/sigchainlib/sigchain_dummy.cc b/sigchainlib/sigchain_dummy.cc
new file mode 100644
index 0000000..7176f05
--- /dev/null
+++ b/sigchainlib/sigchain_dummy.cc
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_ANDROID_OS
+#include <android/log.h>
+#else
+#include <stdarg.h>
+#include <iostream>
+#endif
+
+#include <stdlib.h>
+
+#include "sigchain.h"
+
+static void log(const char* format, ...) {
+  char buf[256];
+  va_list ap;
+  va_start(ap, format);
+  vsnprintf(buf, sizeof(buf), format, ap);
+#ifdef HAVE_ANDROID_OS
+  __android_log_write(ANDROID_LOG_ERROR, "libsigchain", buf);
+#else
+  std::cout << buf << "\n";
+#endif
+  va_end(ap);
+}
+
+extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction) {
+  log("ClaimSignalChain is not exported by the main executable.");
+  abort();
+}
+
+extern "C" void UnclaimSignalChain(int signal) {
+  log("UnclaimSignalChain is not exported by the main executable.");
+  abort();
+}
+
+extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context) {
+  log("InvokeUserSignalHandler is not exported by the main executable.");
+  abort();
+}
+
+extern "C" void InitializeSignalChain() {
+  log("InitializeSignalChain is not exported by the main executable.");
+  abort();
+}
diff --git a/sigchainlib/version-script.txt b/sigchainlib/version-script.txt
new file mode 100644
index 0000000..8030da4
--- /dev/null
+++ b/sigchainlib/version-script.txt
@@ -0,0 +1,12 @@
+{
+global:
+  ClaimSignalChain;
+  UnclaimSignalChain;
+  InvokeUserSignalHandler;
+  InitializeSignalChain;
+  sigaction;
+  signal;
+  sigprocmask;
+local:
+  *;
+};
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 59d241a..ea750e1 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -341,12 +341,9 @@
 
     if [ "$USE_GDB" = "y" ]; then
       # When running under gdb, we cannot do piping and grepping...
-      LD_PRELOAD=libsigchain.so $cmdline "$@"
+      $cmdline "$@"
     else
-      # If we are execing /bin/false we might not be on the same ISA as libsigchain.so
-      # ld.so will helpfully warn us of this. Unfortunately this messes up our error
-      # checking so we will just filter out the error with a grep.
-      LD_PRELOAD=libsigchain.so $cmdline "$@" 2>&1 | grep -v -E "^ERROR: ld\.so: object '.+\.so' from LD_PRELOAD cannot be preloaded.*: ignored\.$"
+      $cmdline "$@" 2>&1
       # Add extra detail if time out is enabled.
       if [ ${PIPESTATUS[0]} = 124 ] && [ "$TIME_OUT" = "y" ]; then
         echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2