Use breakpad_getcontext on all Linux platforms missing getcontext

getcontext is also not available on musl libc, so generalize
breakpad_getcontext so it can be used as a fallback for non-Android
platforms as well.

On x86_64 and i386, ucontext_t uses an Android-specific offset for
storage of FP registers, since its sigset_t differs in size. So,
make the definition of MCONTEXT_FPREGS_MEM and UCONTEXT_FPREGS_MEM_OFFSET
conditional on whether we are building for Android.

On glibc and musl, signal.h and asm/sigcontext.h can't be included
together, so in breakpad_context_unittest.cc, only compare the libc
and kernel _fpstate when on Android.

Bug: google-breakpad:631
Change-Id: If81d73c4101bae946e9a3655b8d1c40a34ab6c38
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2102135
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/Makefile.am b/Makefile.am
index cc9f2e9..9a25d9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -186,9 +186,9 @@
 	src/common/linux/linux_libc_support.cc \
 	src/common/linux/memory_mapped_file.cc \
 	src/common/linux/safe_readlink.cc
-if ANDROID_HOST
+if !HAVE_GETCONTEXT
 src_client_linux_libbreakpad_client_a_SOURCES += \
-	src/common/android/breakpad_getcontext.S
+	src/common/linux/breakpad_getcontext.S
 endif
 endif LINUX_HOST
 
@@ -498,9 +498,9 @@
 	src/processor/minidump.cc \
 	src/processor/pathname_stripper.cc \
 	src/processor/proc_maps_linux.cc
-if ANDROID_HOST
+if !HAVE_GETCONTEXT
 src_client_linux_linux_client_unittest_shlib_SOURCES += \
-	src/common/android/breakpad_getcontext.S
+	src/common/linux/breakpad_getcontext.S
 endif
 
 src_client_linux_linux_client_unittest_shlib_CPPFLAGS = \
@@ -531,9 +531,11 @@
 	src/common/string_conversion.o \
 	$(TEST_LIBS) \
 	$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
-if ANDROID_HOST
+if !HAVE_GETCONTEXT
 src_client_linux_linux_client_unittest_shlib_SOURCES += \
-	src/common/android/breakpad_getcontext_unittest.cc
+	src/common/linux/breakpad_getcontext_unittest.cc
+endif
+if ANDROID_HOST
 src_client_linux_linux_client_unittest_shlib_LDFLAGS += \
 	-llog -lm
 endif
diff --git a/Makefile.in b/Makefile.in
index 572a2a4..16b64ca 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -141,8 +141,8 @@
 @DISABLE_PROCESSOR_FALSE@am__append_6 = src/third_party/libdisasm/libdisasm.a
 @LINUX_HOST_TRUE@am__append_7 = src/client/linux/libbreakpad_client.a
 @LINUX_HOST_TRUE@am__append_8 = breakpad-client.pc
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@am__append_9 = \
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@	src/common/android/breakpad_getcontext.S
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@am__append_9 = \
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@	src/common/linux/breakpad_getcontext.S
 
 @DISABLE_PROCESSOR_FALSE@am__append_10 = \
 @DISABLE_PROCESSOR_FALSE@	src/processor/microdump_stackwalk \
@@ -209,8 +209,8 @@
 @DISABLE_PROCESSOR_FALSE@@SELFTEST_TRUE@am__append_19 = \
 @DISABLE_PROCESSOR_FALSE@@SELFTEST_TRUE@	src/processor/stackwalker_selftest
 
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@am__append_20 = src/common/android/breakpad_getcontext.S \
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@	src/common/android/breakpad_getcontext_unittest.cc
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@am__append_20 = src/common/linux/breakpad_getcontext.S \
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@	src/common/linux/breakpad_getcontext_unittest.cc
 @ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@am__append_21 = \
 @ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@	-llog -lm
 
@@ -313,9 +313,9 @@
 	src/common/linux/linux_libc_support.cc \
 	src/common/linux/memory_mapped_file.cc \
 	src/common/linux/safe_readlink.cc \
-	src/common/android/breakpad_getcontext.S
+	src/common/linux/breakpad_getcontext.S
 am__dirstamp = $(am__leading_dot)dirstamp
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@am__objects_1 = src/common/android/breakpad_getcontext.$(OBJEXT)
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@am__objects_1 = src/common/linux/breakpad_getcontext.$(OBJEXT)
 @LINUX_HOST_TRUE@am_src_client_linux_libbreakpad_client_a_OBJECTS = src/client/linux/crash_generation/crash_generation_client.$(OBJEXT) \
 @LINUX_HOST_TRUE@	src/client/linux/crash_generation/crash_generation_server.$(OBJEXT) \
 @LINUX_HOST_TRUE@	src/client/linux/dump_writer_common/thread_info.$(OBJEXT) \
@@ -633,13 +633,13 @@
 	src/processor/logging.cc src/processor/minidump.cc \
 	src/processor/pathname_stripper.cc \
 	src/processor/proc_maps_linux.cc \
-	src/common/android/breakpad_getcontext.S \
-	src/common/android/breakpad_getcontext_unittest.cc
+	src/common/linux/breakpad_getcontext.S \
+	src/common/linux/breakpad_getcontext_unittest.cc
 @SYSTEM_TEST_LIBS_FALSE@am__objects_2 = src/testing/googletest/src/src_client_linux_linux_client_unittest_shlib-gtest-all.$(OBJEXT) \
 @SYSTEM_TEST_LIBS_FALSE@	src/testing/googletest/src/src_client_linux_linux_client_unittest_shlib-gtest_main.$(OBJEXT) \
 @SYSTEM_TEST_LIBS_FALSE@	src/testing/googlemock/src/src_client_linux_linux_client_unittest_shlib-gmock-all.$(OBJEXT)
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@am__objects_3 = src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.$(OBJEXT) \
-@ANDROID_HOST_TRUE@@LINUX_HOST_TRUE@	src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.$(OBJEXT)
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@am__objects_3 = src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.$(OBJEXT) \
+@HAVE_GETCONTEXT_FALSE@@LINUX_HOST_TRUE@	src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.$(OBJEXT)
 @LINUX_HOST_TRUE@am_src_client_linux_linux_client_unittest_shlib_OBJECTS =  \
 @LINUX_HOST_TRUE@	$(am__objects_2) \
 @LINUX_HOST_TRUE@	src/client/linux/handler/src_client_linux_linux_client_unittest_shlib-exception_handler_unittest.$(OBJEXT) \
@@ -3700,15 +3700,9 @@
 src/common/linux/safe_readlink.$(OBJEXT):  \
 	src/common/linux/$(am__dirstamp) \
 	src/common/linux/$(DEPDIR)/$(am__dirstamp)
-src/common/android/$(am__dirstamp):
-	@$(MKDIR_P) src/common/android
-	@: > src/common/android/$(am__dirstamp)
-src/common/android/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) src/common/android/$(DEPDIR)
-	@: > src/common/android/$(DEPDIR)/$(am__dirstamp)
-src/common/android/breakpad_getcontext.$(OBJEXT):  \
-	src/common/android/$(am__dirstamp) \
-	src/common/android/$(DEPDIR)/$(am__dirstamp)
+src/common/linux/breakpad_getcontext.$(OBJEXT):  \
+	src/common/linux/$(am__dirstamp) \
+	src/common/linux/$(DEPDIR)/$(am__dirstamp)
 src/client/linux/$(am__dirstamp):
 	@$(MKDIR_P) src/client/linux
 	@: > src/client/linux/$(am__dirstamp)
@@ -4061,12 +4055,12 @@
 src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.$(OBJEXT):  \
 	src/processor/$(am__dirstamp) \
 	src/processor/$(DEPDIR)/$(am__dirstamp)
-src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.$(OBJEXT):  \
-	src/common/android/$(am__dirstamp) \
-	src/common/android/$(DEPDIR)/$(am__dirstamp)
-src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.$(OBJEXT):  \
-	src/common/android/$(am__dirstamp) \
-	src/common/android/$(DEPDIR)/$(am__dirstamp)
+src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.$(OBJEXT):  \
+	src/common/linux/$(am__dirstamp) \
+	src/common/linux/$(DEPDIR)/$(am__dirstamp)
+src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.$(OBJEXT):  \
+	src/common/linux/$(am__dirstamp) \
+	src/common/linux/$(DEPDIR)/$(am__dirstamp)
 
 src/client/linux/linux_client_unittest_shlib$(EXEEXT): $(src_client_linux_linux_client_unittest_shlib_OBJECTS) $(src_client_linux_linux_client_unittest_shlib_DEPENDENCIES) $(EXTRA_src_client_linux_linux_client_unittest_shlib_DEPENDENCIES) src/client/linux/$(am__dirstamp)
 	@rm -f src/client/linux/linux_client_unittest_shlib$(EXEEXT)
@@ -4830,7 +4824,6 @@
 	-rm -f src/client/linux/microdump_writer/*.$(OBJEXT)
 	-rm -f src/client/linux/minidump_writer/*.$(OBJEXT)
 	-rm -f src/common/*.$(OBJEXT)
-	-rm -f src/common/android/*.$(OBJEXT)
 	-rm -f src/common/dwarf/*.$(OBJEXT)
 	-rm -f src/common/linux/*.$(OBJEXT)
 	-rm -f src/common/linux/tests/*.$(OBJEXT)
@@ -4940,9 +4933,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-stabs_reader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-stabs_to_module.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/string_conversion.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/common/android/$(DEPDIR)/breakpad_getcontext.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader_unittest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-cfi_assembler.Po@am__quote@
@@ -4965,6 +4955,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-dwarf2diehandler.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-dwarf2reader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/breakpad_getcontext.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elf_core_dump.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elfutils.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/file_id.Po@am__quote@
@@ -4973,6 +4964,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/linux_libc_support.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/memory_mapped_file.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/safe_readlink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-elf_core_dump.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-linux_libc_support_unittest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-crc32.Po@am__quote@
@@ -5150,19 +5143,19 @@
 @AMDEP_TRUE@@am__fastdepCCAS_FALSE@	DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCCAS_FALSE@	$(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o: src/common/android/breakpad_getcontext.S
-@am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -MT src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o -MD -MP -MF src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o `test -f 'src/common/android/breakpad_getcontext.S' || echo '$(srcdir)/'`src/common/android/breakpad_getcontext.S
-@am__fastdepCCAS_TRUE@	$(AM_V_at)$(am__mv) src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS)source='src/common/android/breakpad_getcontext.S' object='src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o' libtool=no @AMDEPBACKSLASH@
+src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o: src/common/linux/breakpad_getcontext.S
+@am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -MT src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o `test -f 'src/common/linux/breakpad_getcontext.S' || echo '$(srcdir)/'`src/common/linux/breakpad_getcontext.S
+@am__fastdepCCAS_TRUE@	$(AM_V_at)$(am__mv) src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS)source='src/common/linux/breakpad_getcontext.S' object='src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCCAS_FALSE@	DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS@am__nodep@)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o `test -f 'src/common/android/breakpad_getcontext.S' || echo '$(srcdir)/'`src/common/android/breakpad_getcontext.S
+@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS@am__nodep@)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.o `test -f 'src/common/linux/breakpad_getcontext.S' || echo '$(srcdir)/'`src/common/linux/breakpad_getcontext.S
 
-src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj: src/common/android/breakpad_getcontext.S
-@am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -MT src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj -MD -MP -MF src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj `if test -f 'src/common/android/breakpad_getcontext.S'; then $(CYGPATH_W) 'src/common/android/breakpad_getcontext.S'; else $(CYGPATH_W) '$(srcdir)/src/common/android/breakpad_getcontext.S'; fi`
-@am__fastdepCCAS_TRUE@	$(AM_V_at)$(am__mv) src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS)source='src/common/android/breakpad_getcontext.S' object='src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj' libtool=no @AMDEPBACKSLASH@
+src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj: src/common/linux/breakpad_getcontext.S
+@am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -MT src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj -MD -MP -MF src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj `if test -f 'src/common/linux/breakpad_getcontext.S'; then $(CYGPATH_W) 'src/common/linux/breakpad_getcontext.S'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/breakpad_getcontext.S'; fi`
+@am__fastdepCCAS_TRUE@	$(AM_V_at)$(am__mv) src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Tpo src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS)source='src/common/linux/breakpad_getcontext.S' object='src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCCAS_FALSE@	DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS@am__nodep@)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj `if test -f 'src/common/android/breakpad_getcontext.S'; then $(CYGPATH_W) 'src/common/android/breakpad_getcontext.S'; else $(CYGPATH_W) '$(srcdir)/src/common/android/breakpad_getcontext.S'; fi`
+@am__fastdepCCAS_FALSE@	$(AM_V_CPPAS@am__nodep@)$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.obj `if test -f 'src/common/linux/breakpad_getcontext.S'; then $(CYGPATH_W) 'src/common/linux/breakpad_getcontext.S'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/breakpad_getcontext.S'; fi`
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -5616,19 +5609,19 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.obj `if test -f 'src/processor/proc_maps_linux.cc'; then $(CYGPATH_W) 'src/processor/proc_maps_linux.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/proc_maps_linux.cc'; fi`
 
-src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o: src/common/android/breakpad_getcontext_unittest.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o -MD -MP -MF src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o `test -f 'src/common/android/breakpad_getcontext_unittest.cc' || echo '$(srcdir)/'`src/common/android/breakpad_getcontext_unittest.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/common/android/breakpad_getcontext_unittest.cc' object='src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o' libtool=no @AMDEPBACKSLASH@
+src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o: src/common/linux/breakpad_getcontext_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o `test -f 'src/common/linux/breakpad_getcontext_unittest.cc' || echo '$(srcdir)/'`src/common/linux/breakpad_getcontext_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/common/linux/breakpad_getcontext_unittest.cc' object='src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o `test -f 'src/common/android/breakpad_getcontext_unittest.cc' || echo '$(srcdir)/'`src/common/android/breakpad_getcontext_unittest.cc
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.o `test -f 'src/common/linux/breakpad_getcontext_unittest.cc' || echo '$(srcdir)/'`src/common/linux/breakpad_getcontext_unittest.cc
 
-src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj: src/common/android/breakpad_getcontext_unittest.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj -MD -MP -MF src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj `if test -f 'src/common/android/breakpad_getcontext_unittest.cc'; then $(CYGPATH_W) 'src/common/android/breakpad_getcontext_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/android/breakpad_getcontext_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/common/android/breakpad_getcontext_unittest.cc' object='src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj' libtool=no @AMDEPBACKSLASH@
+src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj: src/common/linux/breakpad_getcontext_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj -MD -MP -MF src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj `if test -f 'src/common/linux/breakpad_getcontext_unittest.cc'; then $(CYGPATH_W) 'src/common/linux/breakpad_getcontext_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/breakpad_getcontext_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Tpo src/common/linux/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/common/linux/breakpad_getcontext_unittest.cc' object='src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/android/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj `if test -f 'src/common/android/breakpad_getcontext_unittest.cc'; then $(CYGPATH_W) 'src/common/android/breakpad_getcontext_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/android/breakpad_getcontext_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.obj `if test -f 'src/common/linux/breakpad_getcontext_unittest.cc'; then $(CYGPATH_W) 'src/common/linux/breakpad_getcontext_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/breakpad_getcontext_unittest.cc'; fi`
 
 src/client/linux/minidump_writer/src_client_linux_linux_dumper_unittest_helper-linux_dumper_unittest_helper.o: src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_client_linux_linux_dumper_unittest_helper_CXXFLAGS) $(CXXFLAGS) -MT src/client/linux/minidump_writer/src_client_linux_linux_dumper_unittest_helper-linux_dumper_unittest_helper.o -MD -MP -MF src/client/linux/minidump_writer/$(DEPDIR)/src_client_linux_linux_dumper_unittest_helper-linux_dumper_unittest_helper.Tpo -c -o src/client/linux/minidump_writer/src_client_linux_linux_dumper_unittest_helper-linux_dumper_unittest_helper.o `test -f 'src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc' || echo '$(srcdir)/'`src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
@@ -8811,8 +8804,6 @@
 	-rm -f src/client/linux/minidump_writer/$(am__dirstamp)
 	-rm -f src/common/$(DEPDIR)/$(am__dirstamp)
 	-rm -f src/common/$(am__dirstamp)
-	-rm -f src/common/android/$(DEPDIR)/$(am__dirstamp)
-	-rm -f src/common/android/$(am__dirstamp)
 	-rm -f src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
 	-rm -f src/common/dwarf/$(am__dirstamp)
 	-rm -f src/common/linux/$(DEPDIR)/$(am__dirstamp)
@@ -8854,7 +8845,7 @@
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf src/client/$(DEPDIR) src/client/linux/crash_generation/$(DEPDIR) src/client/linux/dump_writer_common/$(DEPDIR) src/client/linux/handler/$(DEPDIR) src/client/linux/log/$(DEPDIR) src/client/linux/microdump_writer/$(DEPDIR) src/client/linux/minidump_writer/$(DEPDIR) src/common/$(DEPDIR) src/common/android/$(DEPDIR) src/common/dwarf/$(DEPDIR) src/common/linux/$(DEPDIR) src/common/linux/tests/$(DEPDIR) src/common/mac/$(DEPDIR) src/common/tests/$(DEPDIR) src/processor/$(DEPDIR) src/testing/googlemock/src/$(DEPDIR) src/testing/googletest/src/$(DEPDIR) src/third_party/libdisasm/$(DEPDIR) src/tools/linux/core2md/$(DEPDIR) src/tools/linux/dump_syms/$(DEPDIR) src/tools/linux/md2core/$(DEPDIR) src/tools/linux/symupload/$(DEPDIR) src/tools/mac/dump_syms/$(DEPDIR)
+	-rm -rf src/client/$(DEPDIR) src/client/linux/crash_generation/$(DEPDIR) src/client/linux/dump_writer_common/$(DEPDIR) src/client/linux/handler/$(DEPDIR) src/client/linux/log/$(DEPDIR) src/client/linux/microdump_writer/$(DEPDIR) src/client/linux/minidump_writer/$(DEPDIR) src/common/$(DEPDIR) src/common/dwarf/$(DEPDIR) src/common/linux/$(DEPDIR) src/common/linux/tests/$(DEPDIR) src/common/mac/$(DEPDIR) src/common/tests/$(DEPDIR) src/processor/$(DEPDIR) src/testing/googlemock/src/$(DEPDIR) src/testing/googletest/src/$(DEPDIR) src/third_party/libdisasm/$(DEPDIR) src/tools/linux/core2md/$(DEPDIR) src/tools/linux/dump_syms/$(DEPDIR) src/tools/linux/md2core/$(DEPDIR) src/tools/linux/symupload/$(DEPDIR) src/tools/mac/dump_syms/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-tags
@@ -8907,7 +8898,7 @@
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf src/client/$(DEPDIR) src/client/linux/crash_generation/$(DEPDIR) src/client/linux/dump_writer_common/$(DEPDIR) src/client/linux/handler/$(DEPDIR) src/client/linux/log/$(DEPDIR) src/client/linux/microdump_writer/$(DEPDIR) src/client/linux/minidump_writer/$(DEPDIR) src/common/$(DEPDIR) src/common/android/$(DEPDIR) src/common/dwarf/$(DEPDIR) src/common/linux/$(DEPDIR) src/common/linux/tests/$(DEPDIR) src/common/mac/$(DEPDIR) src/common/tests/$(DEPDIR) src/processor/$(DEPDIR) src/testing/googlemock/src/$(DEPDIR) src/testing/googletest/src/$(DEPDIR) src/third_party/libdisasm/$(DEPDIR) src/tools/linux/core2md/$(DEPDIR) src/tools/linux/dump_syms/$(DEPDIR) src/tools/linux/md2core/$(DEPDIR) src/tools/linux/symupload/$(DEPDIR) src/tools/mac/dump_syms/$(DEPDIR)
+	-rm -rf src/client/$(DEPDIR) src/client/linux/crash_generation/$(DEPDIR) src/client/linux/dump_writer_common/$(DEPDIR) src/client/linux/handler/$(DEPDIR) src/client/linux/log/$(DEPDIR) src/client/linux/microdump_writer/$(DEPDIR) src/client/linux/minidump_writer/$(DEPDIR) src/common/$(DEPDIR) src/common/dwarf/$(DEPDIR) src/common/linux/$(DEPDIR) src/common/linux/tests/$(DEPDIR) src/common/mac/$(DEPDIR) src/common/tests/$(DEPDIR) src/processor/$(DEPDIR) src/testing/googlemock/src/$(DEPDIR) src/testing/googletest/src/$(DEPDIR) src/third_party/libdisasm/$(DEPDIR) src/tools/linux/core2md/$(DEPDIR) src/tools/linux/dump_syms/$(DEPDIR) src/tools/linux/md2core/$(DEPDIR) src/tools/linux/symupload/$(DEPDIR) src/tools/mac/dump_syms/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/android/google_breakpad/Android.mk b/android/google_breakpad/Android.mk
index bf38116..8618492 100644
--- a/android/google_breakpad/Android.mk
+++ b/android/google_breakpad/Android.mk
@@ -81,10 +81,10 @@
     src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
     src/client/linux/minidump_writer/minidump_writer.cc \
     src/client/minidump_file_writer.cc \
-    src/common/android/breakpad_getcontext.S \
     src/common/convert_UTF.cc \
     src/common/md5.cc \
     src/common/string_conversion.cc \
+    src/common/linux/breakpad_getcontext.S \
     src/common/linux/elfutils.cc \
     src/common/linux/file_id.cc \
     src/common/linux/guid_creator.cc \
diff --git a/configure b/configure
index a6577dc..5e4b3d2 100755
--- a/configure
+++ b/configure
@@ -650,6 +650,8 @@
 LINUX_HOST_TRUE
 WARN_CXXFLAGS
 HAVE_CXX11
+HAVE_GETCONTEXT_FALSE
+HAVE_GETCONTEXT_TRUE
 PTHREAD_CFLAGS
 PTHREAD_LIBS
 PTHREAD_CC
@@ -6650,7 +6652,7 @@
 
 done
 
-for ac_func in arc4random getrandom
+for ac_func in arc4random getcontext getrandom
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -6662,6 +6664,14 @@
 fi
 done
 
+ if test "x$ac_cv_func_getcontext" = xyes; then
+  HAVE_GETCONTEXT_TRUE=
+  HAVE_GETCONTEXT_FALSE='#'
+else
+  HAVE_GETCONTEXT_TRUE='#'
+  HAVE_GETCONTEXT_FALSE=
+fi
+
 
 
       ax_cxx_compile_cxx11_required=true
@@ -7860,6 +7870,10 @@
   as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_GETCONTEXT_TRUE}" && test -z "${HAVE_GETCONTEXT_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_GETCONTEXT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${LINUX_HOST_TRUE}" && test -z "${LINUX_HOST_FALSE}"; then
   as_fn_error $? "conditional \"LINUX_HOST\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/configure.ac b/configure.ac
index 492d090..0851368 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,7 +73,8 @@
 AC_SYS_LARGEFILE
 AX_PTHREAD
 AC_CHECK_HEADERS([a.out.h sys/random.h])
-AC_CHECK_FUNCS([arc4random getrandom])
+AC_CHECK_FUNCS([arc4random getcontext getrandom])
+AM_CONDITIONAL([HAVE_GETCONTEXT], [test "x$ac_cv_func_getcontext" = xyes])
 
 AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
 
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index ba5b499..c65feaa 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -87,6 +87,7 @@
 #include <vector>
 
 #include "common/basictypes.h"
+#include "common/linux/breakpad_getcontext.h"
 #include "common/linux/linux_libc_support.h"
 #include "common/memory_allocator.h"
 #include "client/linux/log/log.h"
diff --git a/src/client/linux/microdump_writer/microdump_writer_unittest.cc b/src/client/linux/microdump_writer/microdump_writer_unittest.cc
index ca26fbf..6339ac0 100644
--- a/src/client/linux/microdump_writer/microdump_writer_unittest.cc
+++ b/src/client/linux/microdump_writer/microdump_writer_unittest.cc
@@ -40,6 +40,7 @@
 #include "client/linux/handler/exception_handler.h"
 #include "client/linux/handler/microdump_extra_info.h"
 #include "client/linux/microdump_writer/microdump_writer.h"
+#include "common/linux/breakpad_getcontext.h"
 #include "common/linux/eintr_wrapper.h"
 #include "common/linux/ignore_ret.h"
 #include "common/scoped_ptr.h"
diff --git a/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/src/client/linux/minidump_writer/minidump_writer_unittest.cc
index f2b3ba3..3017a49 100644
--- a/src/client/linux/minidump_writer/minidump_writer_unittest.cc
+++ b/src/client/linux/minidump_writer/minidump_writer_unittest.cc
@@ -42,6 +42,7 @@
 #include "client/linux/minidump_writer/linux_dumper.h"
 #include "client/linux/minidump_writer/minidump_writer.h"
 #include "client/linux/minidump_writer/minidump_writer_unittest_utils.h"
+#include "common/linux/breakpad_getcontext.h"
 #include "common/linux/eintr_wrapper.h"
 #include "common/linux/file_id.h"
 #include "common/linux/ignore_ret.h"
diff --git a/src/common/common.gyp b/src/common/common.gyp
index 103554b..c1dbb0f 100644
--- a/src/common/common.gyp
+++ b/src/common/common.gyp
@@ -33,7 +33,13 @@
         'defines': ['HAVE_MACH_O_NLIST_H'],
       }],
       ['OS=="linux"', {
-        'defines': ['HAVE_A_OUT_H'],
+        # Assume glibc.
+        'defines': ['HAVE_A_OUT_H', 'HAVE_GETCONTEXT'],
+        'sources!': [
+          'linux/breakpad_getcontext.S',
+          'linux/breakpad_getcontext.h',
+          'linux/breakpad_getcontext_unittest.cc',
+        ],
       }],
       ['OS!="android"', {'sources/': [['exclude', '(^|/)android/']]}],
       ['OS!="linux"', {'sources/': [['exclude', '(^|/)linux/']]}],
@@ -47,13 +53,11 @@
       'target_name': 'common',
       'type': 'static_library',
       'sources': [
-        'android/breakpad_getcontext.S',
         'android/include/elf.h',
         'android/include/link.h',
         'android/include/stab.h',
         'android/include/sys/procfs.h',
         'android/include/sys/user.h',
-        'android/include/ucontext.h',
         'android/testing/include/wchar.h',
         'android/testing/mkdtemp.h',
         'android/testing/pthread_fixes.h',
@@ -87,6 +91,8 @@
         'dwarf_line_to_module.h',
         'language.cc',
         'language.h',
+        'linux/breakpad_getcontext.S',
+        'linux/breakpad_getcontext.h',
         'linux/crc32.cc',
         'linux/crc32.h',
         'linux/dump_symbols.cc',
@@ -201,7 +207,6 @@
       'target_name': 'common_unittests',
       'type': 'executable',
       'sources': [
-        'android/breakpad_getcontext_unittest.cc',
         'byte_cursor_unittest.cc',
         'dwarf/bytereader_unittest.cc',
         'dwarf/dwarf2diehandler_unittest.cc',
@@ -210,6 +215,7 @@
         'dwarf_cfi_to_module_unittest.cc',
         'dwarf_cu_to_module_unittest.cc',
         'dwarf_line_to_module_unittest.cc',
+        'linux/breakpad_getcontext_unittest.cc',
         'linux/dump_symbols_unittest.cc',
         'linux/elf_core_dump_unittest.cc',
         'linux/elf_symbols_to_module_unittest.cc',
diff --git a/src/common/android/breakpad_getcontext.S b/src/common/linux/breakpad_getcontext.S
similarity index 98%
rename from src/common/android/breakpad_getcontext.S
rename to src/common/linux/breakpad_getcontext.S
index 7f3a3b6..fea0109 100644
--- a/src/common/android/breakpad_getcontext.S
+++ b/src/common/linux/breakpad_getcontext.S
@@ -28,9 +28,9 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // A minimalistic implementation of getcontext() to be used by
-// Google Breakpad on Android.
+// Google Breakpad when getcontext() is not available in libc.
 
-#include "common/android/ucontext_constants.h"
+#include "common/linux/ucontext_constants.h"
 
 /* int getcontext (ucontext_t *ucp) */
 
diff --git a/src/common/android/include/ucontext.h b/src/common/linux/breakpad_getcontext.h
similarity index 82%
rename from src/common/android/include/ucontext.h
rename to src/common/linux/breakpad_getcontext.h
index 29db8ad..1418cde 100644
--- a/src/common/android/include/ucontext.h
+++ b/src/common/linux/breakpad_getcontext.h
@@ -27,22 +27,22 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
-#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
+#ifndef GOOGLE_BREAKPAD_COMMON_LINUX_INCLUDE_UCONTEXT_H
+#define GOOGLE_BREAKPAD_COMMON_LINUX_INCLUDE_UCONTEXT_H
 
-#include <sys/cdefs.h>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#ifdef __BIONIC_UCONTEXT_H
-#include <ucontext.h>
-#else
+#ifndef HAVE_GETCONTEXT
 
-#include <sys/ucontext.h>
+#include <signal.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif  // __cplusplus
 
-// Provided by src/android/common/breakpad_getcontext.S
+// Provided by src/common/linux/breakpad_getcontext.S
 int breakpad_getcontext(ucontext_t* ucp);
 
 #define getcontext(x)   breakpad_getcontext(x)
@@ -51,6 +51,6 @@
 }  // extern "C"
 #endif  // __cplusplus
 
-#endif  // __BIONIC_UCONTEXT_H
+#endif  // HAVE_GETCONTEXT
 
-#endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
+#endif  // GOOGLE_BREAKPAD_COMMON_LINUX_INCLUDE_UCONTEXT_H
diff --git a/src/common/android/breakpad_getcontext_unittest.cc b/src/common/linux/breakpad_getcontext_unittest.cc
similarity index 94%
rename from src/common/android/breakpad_getcontext_unittest.cc
rename to src/common/linux/breakpad_getcontext_unittest.cc
index 2c550bf..a57bfed 100644
--- a/src/common/android/breakpad_getcontext_unittest.cc
+++ b/src/common/linux/breakpad_getcontext_unittest.cc
@@ -27,14 +27,18 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#if defined(__x86_64__)
+// asm/sigcontext.h can't be included with signal.h on glibc or
+// musl, so only compare _libc_fpstate and _fpstate on Android.
+#if defined(__ANDROID__) && defined(__x86_64__)
 #include <asm/sigcontext.h>
 #endif
 
 #include <sys/ucontext.h>
 
+#include <type_traits>
+
 #include "breakpad_googletest_includes.h"
-#include "common/android/ucontext_constants.h"
+#include "common/linux/ucontext_constants.h"
 
 template <int left, int right>
 struct CompileAssertEquals {
@@ -139,6 +143,8 @@
   // sigcontext is an analog to mcontext_t. The layout should be the same.
   COMPILE_ASSERT_EQ(offsetof(mcontext_t,fpregs),
                     offsetof(sigcontext,fpstate), sigcontext_fpstate);
+
+#if defined(__ANDROID__)
   // Check that _fpstate from asm/sigcontext.h is essentially the same
   // as _libc_fpstate.
   COMPILE_ASSERT_EQ(sizeof(_libc_fpstate), sizeof(_fpstate),
@@ -164,13 +170,15 @@
                     sigcontext_fpstate_stspace);
   COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,_xmm), offsetof(_fpstate,xmm_space),
                     sigcontext_fpstate_xmm_space);
+#endif
 
   COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_PTR,
                     offsetof(ucontext_t,uc_mcontext.fpregs),
                     mcontext_fpregs_ptr);
   COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_MEM, offsetof(ucontext_t,__fpregs_mem),
                     mcontext_fpregs_mem);
-  COMPILE_ASSERT_EQ(FPREGS_OFFSET_MXCSR, offsetof(_libc_fpstate,mxcsr),
+  COMPILE_ASSERT_EQ(FPREGS_OFFSET_MXCSR,
+                    offsetof(std::remove_pointer<fpregset_t>::type,mxcsr),
                     fpregs_offset_mxcsr);
   COMPILE_ASSERT_EQ(UCONTEXT_SIGMASK_OFFSET, offsetof(ucontext_t, uc_sigmask),
                     ucontext_sigmask);
diff --git a/src/common/android/ucontext_constants.h b/src/common/linux/ucontext_constants.h
similarity index 91%
rename from src/common/android/ucontext_constants.h
rename to src/common/linux/ucontext_constants.h
index 1932d57..c390508 100644
--- a/src/common/android/ucontext_constants.h
+++ b/src/common/linux/ucontext_constants.h
@@ -31,14 +31,15 @@
 // Its purpose is to contain constants that must match the offsets of
 // various fields in ucontext_t.
 //
-// They should match the definitions from
-// src/common/android/include/sys/ucontext.h
+// They should match the definitions from signal.h.
 //
-// Used by src/common/android/breakpad_getcontext.S
-// Tested by src/common/android/testing/breakpad_getcontext_unittest.cc
+// Used by src/common/linux/breakpad_getcontext.S
+// Tested by src/common/linux/breakpad_getcontext_unittest.cc
+//
+// This header should not be used by anything else.
 
-#ifndef GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H
-#define GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H
+#ifndef GOOGLEBREAKPAD_COMMON_LINUX_UCONTEXT_CONSTANTS_H
+#define GOOGLEBREAKPAD_COMMON_LINUX_UCONTEXT_CONSTANTS_H
 
 #if defined(__arm__)
 
@@ -93,7 +94,11 @@
 #define  UCONTEXT_SIGMASK_OFFSET   108
 
 #define  UCONTEXT_FPREGS_OFFSET       96
+#if defined(__BIONIC__)
 #define  UCONTEXT_FPREGS_MEM_OFFSET   116
+#else
+#define  UCONTEXT_FPREGS_MEM_OFFSET   236
+#endif
 
 #elif defined(__mips__)
 
@@ -134,7 +139,11 @@
 #define MCONTEXT_GREGS_RSP   160
 #define MCONTEXT_GREGS_RIP   168
 #define MCONTEXT_FPREGS_PTR  224
+#if defined(__BIONIC__)
 #define MCONTEXT_FPREGS_MEM  304
+#else
+#define MCONTEXT_FPREGS_MEM  424
+#endif
 #define FPREGS_OFFSET_MXCSR  24
 
 #else
diff --git a/src/config.h.in b/src/config.h.in
index 618e283..0553a24 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -9,6 +9,9 @@
 /* define if the compiler supports basic C++11 syntax */
 #undef HAVE_CXX11
 
+/* Define to 1 if you have the `getcontext' function. */
+#undef HAVE_GETCONTEXT
+
 /* Define to 1 if you have the `getrandom' function. */
 #undef HAVE_GETRANDOM