Merge "Remove some <sys/cdefs.h> cruft."
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 3b91e6a..6a39a21 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -130,8 +130,13 @@
  */
 #define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ)
 
-/* Leave room for a guard page in the internally created signal stacks. */
+// Leave room for a guard page in the internally created signal stacks.
+#if defined(__LP64__)
+// SIGSTKSZ is not big enough for 64-bit arch. See http://b/23041777.
+#define SIGNAL_STACK_SIZE (16 * 1024 + PAGE_SIZE)
+#else
 #define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE)
+#endif
 
 /* Needed by fork. */
 __LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
diff --git a/libc/include/netinet/udp.h b/libc/include/netinet/udp.h
index 25e0dfc..d4eb368 100644
--- a/libc/include/netinet/udp.h
+++ b/libc/include/netinet/udp.h
@@ -25,31 +25,29 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _NETINET_UDP_H
 #define _NETINET_UDP_H
 
-/*
- * We would include linux/udp.h, but it brings in too much other stuff
- */
+#include <sys/types.h>
 
-#ifdef __FAVOR_BSD
+#include <linux/udp.h>
 
 struct udphdr {
-    u_int16_t uh_sport;	/* source port */
-    u_int16_t uh_dport;	/* destination port */
-    u_int16_t uh_ulen;	/* udp length */
-    u_int16_t uh_sum;	/* udp checksum */
+    __extension__ union {
+        struct /* BSD names */ {
+            u_int16_t uh_sport;
+            u_int16_t uh_dport;
+            u_int16_t uh_ulen;
+            u_int16_t uh_sum;
+        };
+        struct /* Linux names */ {
+            u_int16_t source;
+            u_int16_t dest;
+            u_int16_t len;
+            u_int16_t check;
+        };
+    };
 };
 
-#else
-
-struct udphdr {
-    __u16  source;
-    __u16  dest;
-    __u16  len;
-    __u16  check;
-};
-
-#endif /* __FAVOR_BSD */
-
 #endif /* _NETINET_UDP_H */
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 1b6853e..773d22f 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -64,6 +64,8 @@
     # The kernel's SIGRTMIN/SIGRTMAX are absolute limits; userspace steals a few.
     "SIGRTMIN": "__SIGRTMIN",
     "SIGRTMAX": "__SIGRTMAX",
+    # We want to support both BSD and Linux member names in struct udphdr.
+    "udphdr": "__kernel_udphdr",
     }
 
 # this is the set of known static inline functions that we want to keep
diff --git a/libc/kernel/uapi/linux/udp.h b/libc/kernel/uapi/linux/udp.h
index e1d546c..a3e9e97 100644
--- a/libc/kernel/uapi/linux/udp.h
+++ b/libc/kernel/uapi/linux/udp.h
@@ -19,7 +19,7 @@
 #ifndef _UAPI_LINUX_UDP_H
 #define _UAPI_LINUX_UDP_H
 #include <linux/types.h>
-struct udphdr {
+struct __kernel_udphdr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 source;
   __be16 dest;
diff --git a/tests/Android.mk b/tests/Android.mk
index 3f2fb91..68c4149 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -69,6 +69,7 @@
     math_test.cpp \
     mntent_test.cpp \
     netdb_test.cpp \
+    netinet_udp_test.cpp \
     pthread_test.cpp \
     pty_test.cpp \
     regex_test.cpp \
diff --git a/tests/netinet_udp_test.cpp b/tests/netinet_udp_test.cpp
new file mode 100644
index 0000000..661458e
--- /dev/null
+++ b/tests/netinet_udp_test.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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 <netinet/udp.h>
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+  #define UDPHDR_USES_ANON_UNION
+#elif defined(__GLIBC_PREREQ)
+  #if __GLIBC_PREREQ(2, 18)
+    #define UDPHDR_USES_ANON_UNION
+  #endif
+#endif
+
+TEST(netinet_udp, compat) {
+#if defined(UDPHDR_USES_ANON_UNION)
+    static_assert(offsetof(udphdr, uh_sport) == offsetof(udphdr, source), "udphdr::source");
+    static_assert(offsetof(udphdr, uh_dport) == offsetof(udphdr, dest), "udphdr::dest");
+    static_assert(offsetof(udphdr, uh_ulen) == offsetof(udphdr, len), "udphdr::len");
+    static_assert(offsetof(udphdr, uh_sum) == offsetof(udphdr, check), "udphdr::check");
+
+    udphdr u;
+    u.uh_sport = 0x1111;
+    u.uh_dport = 0x2222;
+    u.uh_ulen = 0x3333;
+    u.uh_sum = 0x4444;
+    ASSERT_EQ(0x1111, u.source);
+    ASSERT_EQ(0x2222, u.dest);
+    ASSERT_EQ(0x3333, u.len);
+    ASSERT_EQ(0x4444, u.check);
+#endif
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 3c686ef..11afad1 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -27,6 +27,7 @@
 #include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
+#include <unwind.h>
 
 #include <atomic>
 #include <regex>
@@ -1632,3 +1633,26 @@
   GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
 #endif
 }
+
+extern _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx, void* arg);
+
+static volatile bool signal_handler_on_altstack_done;
+
+static void SignalHandlerOnAltStack(int signo, siginfo_t*, void*) {
+  ASSERT_EQ(SIGUSR1, signo);
+  // Check if we have enough stack space for unwinding.
+  int count = 0;
+  _Unwind_Backtrace(FrameCounter, &count);
+  ASSERT_GT(count, 0);
+  // Check if we have enough stack space for logging.
+  std::string s(2048, '*');
+  GTEST_LOG_(INFO) << s;
+  signal_handler_on_altstack_done = true;
+}
+
+TEST(pthread, big_enough_signal_stack_for_64bit_arch) {
+  signal_handler_on_altstack_done = false;
+  ScopedSignalHandler handler(SIGUSR1, SignalHandlerOnAltStack, SA_SIGINFO | SA_ONSTACK);
+  kill(getpid(), SIGUSR1);
+  ASSERT_TRUE(signal_handler_on_altstack_done);
+}
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index d1b3402..afd9e7f 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -34,7 +34,7 @@
 #define noinline __attribute__((__noinline__))
 #define __unused __attribute__((__unused__))
 
-static _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) {
+_Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) {
   int* count_ptr = reinterpret_cast<int*>(arg);
 
 #if SHOW_FRAME_LOCATIONS