am 7e7d6c48: use local symbols in memset so it doesn\'t screw up profiling

Merge commit '7e7d6c48a064af82f0ec39f47b9eb803a6e1df4c' into eclair-mr2

* commit '7e7d6c48a064af82f0ec39f47b9eb803a6e1df4c':
  use local symbols in memset so it doesn't screw up profiling
diff --git a/libc/unistd/abort.c b/libc/unistd/abort.c
index f323941..3e3aab0 100644
--- a/libc/unistd/abort.c
+++ b/libc/unistd/abort.c
@@ -39,8 +39,13 @@
 #define debug_log(format, ...)  \
     __libc_android_log_print(ANDROID_LOG_DEBUG, "libc-abort", (format), ##__VA_ARGS__ )
 
+#ifdef __arm__
+void
+__libc_android_abort(void)
+#else
 void
 abort(void)
+#endif
 {
 	struct atexit *p = __atexit;
 	static int cleanup_called = 0;
@@ -97,3 +102,29 @@
 	(void)kill(getpid(), SIGABRT);
 	_exit(1);
 }
+
+#ifdef __arm__
+/*
+ * abort() does not return, which gcc interprets to mean that it doesn't
+ * need to preserve any of the callee-save registers.  Unfortunately this
+ * includes the link register, so if LR is used there is no way to determine
+ * which function called abort().
+ *
+ * We work around this by inserting a trivial stub that doesn't alter
+ * any of the "interesting" registers and thus doesn't need to save them.
+ * We can't just call __libc_android_abort from C because gcc uses "bl"
+ * without first saving LR, so we use an asm statement.  This also has
+ * the side-effect of replacing abort() with __libc_android_abort() in
+ * the stack trace.
+ *
+ * Ideally __libc_android_abort would be static, but I haven't figured out
+ * how to tell gcc to call a static function from an asm statement.
+ */
+void
+abort(void)
+{
+    asm ("b __libc_android_abort");
+    _exit(1);       /* suppress gcc noreturn warnings */
+}
+#endif
+
diff --git a/linker/debugger.c b/linker/debugger.c
index 5bb065c..1bd3cc8 100644
--- a/linker/debugger.c
+++ b/linker/debugger.c
@@ -32,6 +32,7 @@
 #include <ctype.h>
 #include <signal.h>
 #include <sys/mman.h>
+#include <errno.h>
 
 #include "linker.h"
 
@@ -40,6 +41,11 @@
 
 void notify_gdb_of_libraries();
 
+#define  RETRY_ON_EINTR(ret,cond) \
+    do { \
+        ret = (cond); \
+    } while (ret < 0 && errno == EINTR)
+
 void debugger_signal_handler(int n)
 {
     unsigned tid;
@@ -58,10 +64,15 @@
          * is paranoid and will verify that we are giving a tid
          * that's actually in our process
          */
-        write(s, &tid, sizeof(unsigned));
+        int  ret;
 
-        read(s, &tid, 1);
-        notify_gdb_of_libraries();
+        RETRY_ON_EINTR(ret, write(s, &tid, sizeof(unsigned)));
+        if (ret == sizeof(unsigned)) {
+            /* if the write failed, there is no point to read on
+             * the file descriptor. */
+            RETRY_ON_EINTR(ret, read(s, &tid, 1));
+            notify_gdb_of_libraries();
+        }
         close(s);
     }