Add a test to check debug information for split functions.

With optimizations such as -fsplit-machine-functions (clang) and
-freorder-blocks-and-partition (gcc), the function body may be
discontiguous in the binary. Control flow between the parts are routed
using jumps. This test ensures that breakpad consumes debuginfo
generated by the -fsplit-machine-functions optimization and the line
table for the cold function part is correct.

Change-Id: I44d59704864ee940dd429c5249d5d793fe081d6a
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2591951
Reviewed-by: Sterling Augustine <saugustine@google.com>
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
diff --git a/Makefile.am b/Makefile.am
index 48fa4dc..fd9875b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -376,6 +376,7 @@
 check_PROGRAMS += \
 	src/common/test_assembler_unittest \
 	src/common/dwarf/dwarf2reader_lineinfo_unittest \
+	src/common/dwarf/dwarf2reader_splitfunctions_unittest \
 	src/processor/address_map_unittest \
 	src/processor/basic_source_line_resolver_unittest \
 	src/processor/cfi_frame_info_unittest \
@@ -1234,6 +1235,17 @@
 	$(TEST_LIBS) \
 	$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
 
+src_common_dwarf_dwarf2reader_splitfunctions_unittest_SOURCES = \
+	src/common/dwarf/dwarf2reader.h \
+	src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+src_common_dwarf_dwarf2reader_splitfunctions_unittest_CPPFLAGS = \
+	$(AM_CPPFLAGS) $(TEST_CFLAGS)
+src_common_dwarf_dwarf2reader_splitfunctions_unittest_LDADD = \
+  src/common/dwarf/bytereader.o \
+  src/common/dwarf/dwarf2reader.o \
+  src/common/dwarf/elf_reader.o \
+	$(TEST_LIBS) \
+	$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
 
 ## Non-installables
 noinst_PROGRAMS =
diff --git a/Makefile.in b/Makefile.in
index 84ce986..24cbfc2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -171,6 +171,7 @@
 @DISABLE_PROCESSOR_FALSE@am__append_16 = \
 @DISABLE_PROCESSOR_FALSE@	src/common/test_assembler_unittest \
 @DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader_lineinfo_unittest \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader_splitfunctions_unittest \
 @DISABLE_PROCESSOR_FALSE@	src/processor/address_map_unittest \
 @DISABLE_PROCESSOR_FALSE@	src/processor/basic_source_line_resolver_unittest \
 @DISABLE_PROCESSOR_FALSE@	src/processor/cfi_frame_info_unittest \
@@ -270,6 +271,7 @@
 	"$(DESTDIR)$(includelssdir)" "$(DESTDIR)$(includepdir)"
 @DISABLE_PROCESSOR_FALSE@am__EXEEXT_5 = src/common/test_assembler_unittest$(EXEEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader_lineinfo_unittest$(EXEEXT) \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader_splitfunctions_unittest$(EXEEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/address_map_unittest$(EXEEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/basic_source_line_resolver_unittest$(EXEEXT) \
 @DISABLE_PROCESSOR_FALSE@	src/processor/cfi_frame_info_unittest$(EXEEXT) \
@@ -804,9 +806,21 @@
 src_common_dwarf_dwarf2reader_lineinfo_unittest_OBJECTS =  \
 	$(am_src_common_dwarf_dwarf2reader_lineinfo_unittest_OBJECTS)
 @DISABLE_PROCESSOR_FALSE@src_common_dwarf_dwarf2reader_lineinfo_unittest_DEPENDENCIES =  \
-@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/elf_reader.o \
 @DISABLE_PROCESSOR_FALSE@	src/common/dwarf/bytereader.o \
 @DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader.o \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/elf_reader.o \
+@DISABLE_PROCESSOR_FALSE@	$(am__DEPENDENCIES_2) \
+@DISABLE_PROCESSOR_FALSE@	$(am__DEPENDENCIES_1) \
+@DISABLE_PROCESSOR_FALSE@	$(am__DEPENDENCIES_1)
+am__src_common_dwarf_dwarf2reader_splitfunctions_unittest_SOURCES_DIST =  \
+	src/common/dwarf/dwarf2reader.h \
+	src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+@DISABLE_PROCESSOR_FALSE@am_src_common_dwarf_dwarf2reader_splitfunctions_unittest_OBJECTS = src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.$(OBJEXT)
+src_common_dwarf_dwarf2reader_splitfunctions_unittest_OBJECTS = $(am_src_common_dwarf_dwarf2reader_splitfunctions_unittest_OBJECTS)
+@DISABLE_PROCESSOR_FALSE@src_common_dwarf_dwarf2reader_splitfunctions_unittest_DEPENDENCIES =  \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/bytereader.o \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader.o \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/elf_reader.o \
 @DISABLE_PROCESSOR_FALSE@	$(am__DEPENDENCIES_2) \
 @DISABLE_PROCESSOR_FALSE@	$(am__DEPENDENCIES_1) \
 @DISABLE_PROCESSOR_FALSE@	$(am__DEPENDENCIES_1)
@@ -1705,6 +1719,7 @@
 	src/common/dwarf/$(DEPDIR)/dumper_unittest-dwarf2reader_die_unittest.Po \
 	src/common/dwarf/$(DEPDIR)/dumper_unittest-elf_reader.Po \
 	src/common/dwarf/$(DEPDIR)/dwarf2reader_lineinfo_unittest-dwarf2reader_lineinfo_unittest.Po \
+	src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Po \
 	src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-bytereader.Po \
 	src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-cfi_assembler.Po \
 	src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-dwarf2diehandler.Po \
@@ -1937,6 +1952,7 @@
 	$(src_client_linux_linux_dumper_unittest_helper_SOURCES) \
 	$(src_common_dumper_unittest_SOURCES) \
 	$(src_common_dwarf_dwarf2reader_lineinfo_unittest_SOURCES) \
+	$(src_common_dwarf_dwarf2reader_splitfunctions_unittest_SOURCES) \
 	$(src_common_linux_google_crashdump_uploader_test_SOURCES) \
 	$(src_common_mac_macho_reader_unittest_SOURCES) \
 	$(src_common_test_assembler_unittest_SOURCES) \
@@ -1992,6 +2008,7 @@
 	$(am__src_client_linux_linux_dumper_unittest_helper_SOURCES_DIST) \
 	$(am__src_common_dumper_unittest_SOURCES_DIST) \
 	$(am__src_common_dwarf_dwarf2reader_lineinfo_unittest_SOURCES_DIST) \
+	$(am__src_common_dwarf_dwarf2reader_splitfunctions_unittest_SOURCES_DIST) \
 	$(am__src_common_linux_google_crashdump_uploader_test_SOURCES_DIST) \
 	$(am__src_common_mac_macho_reader_unittest_SOURCES_DIST) \
 	$(am__src_common_test_assembler_unittest_SOURCES_DIST) \
@@ -3479,9 +3496,23 @@
 @DISABLE_PROCESSOR_FALSE@	$(AM_CPPFLAGS) $(TEST_CFLAGS)
 
 @DISABLE_PROCESSOR_FALSE@src_common_dwarf_dwarf2reader_lineinfo_unittest_LDADD = \
-@DISABLE_PROCESSOR_FALSE@  src/common/dwarf/elf_reader.o \
 @DISABLE_PROCESSOR_FALSE@  src/common/dwarf/bytereader.o \
 @DISABLE_PROCESSOR_FALSE@  src/common/dwarf/dwarf2reader.o \
+@DISABLE_PROCESSOR_FALSE@  src/common/dwarf/elf_reader.o \
+@DISABLE_PROCESSOR_FALSE@	$(TEST_LIBS) \
+@DISABLE_PROCESSOR_FALSE@	$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+
+@DISABLE_PROCESSOR_FALSE@src_common_dwarf_dwarf2reader_splitfunctions_unittest_SOURCES = \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader.h \
+@DISABLE_PROCESSOR_FALSE@	src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+
+@DISABLE_PROCESSOR_FALSE@src_common_dwarf_dwarf2reader_splitfunctions_unittest_CPPFLAGS = \
+@DISABLE_PROCESSOR_FALSE@	$(AM_CPPFLAGS) $(TEST_CFLAGS)
+
+@DISABLE_PROCESSOR_FALSE@src_common_dwarf_dwarf2reader_splitfunctions_unittest_LDADD = \
+@DISABLE_PROCESSOR_FALSE@  src/common/dwarf/bytereader.o \
+@DISABLE_PROCESSOR_FALSE@  src/common/dwarf/dwarf2reader.o \
+@DISABLE_PROCESSOR_FALSE@  src/common/dwarf/elf_reader.o \
 @DISABLE_PROCESSOR_FALSE@	$(TEST_LIBS) \
 @DISABLE_PROCESSOR_FALSE@	$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
 
@@ -4633,6 +4664,13 @@
 src/common/dwarf/dwarf2reader_lineinfo_unittest$(EXEEXT): $(src_common_dwarf_dwarf2reader_lineinfo_unittest_OBJECTS) $(src_common_dwarf_dwarf2reader_lineinfo_unittest_DEPENDENCIES) $(EXTRA_src_common_dwarf_dwarf2reader_lineinfo_unittest_DEPENDENCIES) src/common/dwarf/$(am__dirstamp)
 	@rm -f src/common/dwarf/dwarf2reader_lineinfo_unittest$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(src_common_dwarf_dwarf2reader_lineinfo_unittest_OBJECTS) $(src_common_dwarf_dwarf2reader_lineinfo_unittest_LDADD) $(LIBS)
+src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.$(OBJEXT):  \
+	src/common/dwarf/$(am__dirstamp) \
+	src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
+
+src/common/dwarf/dwarf2reader_splitfunctions_unittest$(EXEEXT): $(src_common_dwarf_dwarf2reader_splitfunctions_unittest_OBJECTS) $(src_common_dwarf_dwarf2reader_splitfunctions_unittest_DEPENDENCIES) $(EXTRA_src_common_dwarf_dwarf2reader_splitfunctions_unittest_DEPENDENCIES) src/common/dwarf/$(am__dirstamp)
+	@rm -f src/common/dwarf/dwarf2reader_splitfunctions_unittest$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(src_common_dwarf_dwarf2reader_splitfunctions_unittest_OBJECTS) $(src_common_dwarf_dwarf2reader_splitfunctions_unittest_LDADD) $(LIBS)
 src/common/linux/google_crashdump_uploader_test-google_crashdump_uploader.$(OBJEXT):  \
 	src/common/linux/$(am__dirstamp) \
 	src/common/linux/$(DEPDIR)/$(am__dirstamp)
@@ -5378,6 +5416,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dumper_unittest-dwarf2reader_die_unittest.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dumper_unittest-elf_reader.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dwarf2reader_lineinfo_unittest-dwarf2reader_lineinfo_unittest.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-bytereader.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-cfi_assembler.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-dwarf2diehandler.Po@am__quote@ # am--include-marker
@@ -6782,6 +6821,20 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dwarf_dwarf2reader_lineinfo_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/dwarf2reader_lineinfo_unittest-dwarf2reader_lineinfo_unittest.obj `if test -f 'src/common/dwarf/dwarf2reader_lineinfo_unittest.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader_lineinfo_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader_lineinfo_unittest.cc'; fi`
 
+src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.o: src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dwarf_dwarf2reader_splitfunctions_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Tpo -c -o src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.o `test -f 'src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc' || echo '$(srcdir)/'`src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Tpo src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc' object='src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_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_common_dwarf_dwarf2reader_splitfunctions_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.o `test -f 'src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc' || echo '$(srcdir)/'`src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+
+src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.obj: src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dwarf_dwarf2reader_splitfunctions_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.obj -MD -MP -MF src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Tpo -c -o src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.obj `if test -f 'src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Tpo src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc' object='src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_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_common_dwarf_dwarf2reader_splitfunctions_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.obj `if test -f 'src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc'; fi`
+
 src/common/linux/google_crashdump_uploader_test-google_crashdump_uploader.o: src/common/linux/google_crashdump_uploader.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_linux_google_crashdump_uploader_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/google_crashdump_uploader_test-google_crashdump_uploader.o -MD -MP -MF src/common/linux/$(DEPDIR)/google_crashdump_uploader_test-google_crashdump_uploader.Tpo -c -o src/common/linux/google_crashdump_uploader_test-google_crashdump_uploader.o `test -f 'src/common/linux/google_crashdump_uploader.cc' || echo '$(srcdir)/'`src/common/linux/google_crashdump_uploader.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/common/linux/$(DEPDIR)/google_crashdump_uploader_test-google_crashdump_uploader.Tpo src/common/linux/$(DEPDIR)/google_crashdump_uploader_test-google_crashdump_uploader.Po
@@ -8753,6 +8806,13 @@
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/common/dwarf/dwarf2reader_splitfunctions_unittest.log: src/common/dwarf/dwarf2reader_splitfunctions_unittest$(EXEEXT)
+	@p='src/common/dwarf/dwarf2reader_splitfunctions_unittest$(EXEEXT)'; \
+	b='src/common/dwarf/dwarf2reader_splitfunctions_unittest'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 src/processor/address_map_unittest.log: src/processor/address_map_unittest$(EXEEXT)
 	@p='src/processor/address_map_unittest$(EXEEXT)'; \
 	b='src/processor/address_map_unittest'; \
@@ -9425,6 +9485,7 @@
 	-rm -f src/common/dwarf/$(DEPDIR)/dumper_unittest-dwarf2reader_die_unittest.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/dumper_unittest-elf_reader.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/dwarf2reader_lineinfo_unittest-dwarf2reader_lineinfo_unittest.Po
+	-rm -f src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-bytereader.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-cfi_assembler.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-dwarf2diehandler.Po
@@ -9766,6 +9827,7 @@
 	-rm -f src/common/dwarf/$(DEPDIR)/dumper_unittest-dwarf2reader_die_unittest.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/dumper_unittest-elf_reader.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/dwarf2reader_lineinfo_unittest-dwarf2reader_lineinfo_unittest.Po
+	-rm -f src/common/dwarf/$(DEPDIR)/dwarf2reader_splitfunctions_unittest-dwarf2reader_splitfunctions_unittest.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-bytereader.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-cfi_assembler.Po
 	-rm -f src/common/dwarf/$(DEPDIR)/mac_macho_reader_unittest-dwarf2diehandler.Po
diff --git a/src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc b/src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
new file mode 100644
index 0000000..8c93e27
--- /dev/null
+++ b/src/common/dwarf/dwarf2reader_splitfunctions_unittest.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2020, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Original author: Snehasish Kumar <snehasishk@google.com>
+
+// dwarf2reader_splitfunctions_unittest.cc: Unit tests for with a focus on debug
+// information generated when with splitting optimizations such as
+// -fsplit-machine-functions (clang) -freorder-blocks-and-partition (gcc).
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <string>
+
+#include "breakpad_googletest_includes.h"
+#include "common/dwarf/bytereader.h"
+#include "common/dwarf/dwarf2reader.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+using testing::_;
+using namespace dwarf2reader;
+
+namespace {
+
+class MockLineInfoHandler: public LineInfoHandler {
+ public:
+  MOCK_METHOD(void, DefineFile, (const string& name, int32_t file_num,
+                                 uint32_t dir_num, uint64_t mod_time,
+                                 uint64_t length), (override));
+  MOCK_METHOD(void, AddLine, (uint64_t address, uint64_t length,
+                              uint32_t file_num, uint32_t line_num,
+                              uint32_t column_num), (override));
+};
+
+struct LineProgram: public testing::Test {
+  MockLineInfoHandler handler_;
+};
+
+// The debug information is generated from the following program --
+// $ cat -n split_functions.c
+//   1  #include <stdio.h>
+//   2
+//   3  __attribute__((noinline)) int foo(int i)  {
+//   4    if (i % 100) {
+//   5      return i + 1;
+//   6    } else {
+//   7      return i * 10 % 3;
+//   8    }
+//   9  }
+//  10
+//  11
+//  12  int main(int argc, char *argv[]) {
+//  13    int total = 0;
+//  14    for (int i = 0; i < 1000; ++i) {
+//  15      total += foo(i);
+//  16    }
+//  17    printf("%d\n", total);
+//  18  }
+//
+// $ bin/clang -fprofile-generate -O2 split_functions.c
+// $ ./a.out > /dev/null
+// $ bin/llvm-profdata merge -o default.profdata default_*.profraw
+// $ bin/clang -fprofile-use -O2 -gmlt -gdwarf-5 -fsplit-machine-functions \
+//             split_functions.c -o split.out
+//
+//  For the test we pick the first instruction in foo.cold which should be the
+//  else part of the function foo above.
+
+const uint8_t debug_line[] = {
+  0xb0,0x0,0x0,0x0,0x5,0x0,0x8,0x0,0x37,0x0,0x0,0x0,0x1,0x1,0x1,0xfb,0xe,0xd,0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x1,0x1,0x1f,0x1,0x0,0x0,0x0,0x0,0x3,0x1,0x1f,0x2,0xf,0x5,0x1e,0x1,0x3d,0x0,0x0,0x0,0x0,0x24,0xb2,0xb6,0xb5,0xbb,0xf,0xf7,0x6d,0x27,0x92,0xab,0x55,0x3a,0x29,0x48,0x81,0x4,0x0,0x0,0x9,0x2,0x40,0x10,0x40,0x0,0x0,0x0,0x0,0x0,0x14,0x5,0x9,0xa,0x2f,0x5,0x7,0x6,0x8,0x4a,0x5,0xe,0x6,0x67,0x5,0x1,0x40,0x5,0x0,0xf5,0x5,0xe,0xa,0xf5,0x5,0xb,0x6,0x74,0x5,0x1d,0x6,0x2d,0x5,0x15,0x6,0x3c,0x5,0x3,0x66,0x2,0x7,0x0,0x1,0x1,0x4,0x0,0x5,0xe,0x0,0x9,0x2,0x84,0x11,0x40,0x0,0x0,0x0,0x0,0x0,0x18,0x5,0x13,0x6,0x58,0x5,0x1,0x6,0x8,0xa0,0x2,0x1,0x0,0x1,0x1,0x4,0x0,0x5,0x3,0x0,0x9,0x2,0xa5,0x11,0x40,0x0,0x0,0x0,0x0,0x0,0x3,0x10,0x1,0x5,0x1,0xd7,0x2,0x9,0x0,0x1,0x1
+};
+
+const uint8_t debug_str[] = {
+  0x63,0x6c,0x61,0x6e,0x67,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x32,0x2e,0x30,0x2e,0x30,0x20,0x28,0x67,0x69,0x74,0x40,0x67,0x69,0x74,0x68,0x75,0x62,0x2e,0x63,0x6f,0x6d,0x3a,0x6c,0x6c,0x76,0x6d,0x2f,0x6c,0x6c,0x76,0x6d,0x2d,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x67,0x69,0x74,0x20,0x63,0x37,0x35,0x61,0x30,0x61,0x31,0x65,0x39,0x64,0x63,0x32,0x39,0x62,0x65,0x34,0x65,0x30,0x30,0x64,0x33,0x37,0x64,0x30,0x64,0x30,0x30,0x32,0x38,0x38,0x61,0x66,0x63,0x31,0x61,0x36,0x31,0x35,0x33,0x66,0x29,0x0,0x73,0x70,0x6c,0x69,0x74,0x5f,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x73,0x2e,0x63,0x0,0x2f,0x75,0x73,0x72,0x2f,0x6c,0x6f,0x63,0x61,0x6c,0x2f,0x67,0x6f,0x6f,0x67,0x6c,0x65,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x73,0x6e,0x65,0x68,0x61,0x73,0x69,0x73,0x68,0x6b,0x2f,0x77,0x6f,0x72,0x6b,0x69,0x6e,0x67,0x2f,0x6c,0x6c,0x76,0x6d,0x2d,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2f,0x62,0x75,0x69,0x6c,0x64,0x0,0x66,0x6f,0x6f,0x0,0x69,0x6e,0x74,0x0,0x6d,0x61,0x69,0x6e,0x0,0x69,0x0,0x61,0x72,0x67,0x63,0x0,0x61,0x72,0x67,0x76,0x0,0x63,0x68,0x61,0x72,0x0,0x74,0x6f,0x74,0x61,0x6c,0x0
+};
+
+const uint8_t debug_line_str[] = {
+  0x2f,0x75,0x73,0x72,0x2f,0x6c,0x6f,0x63,0x61,0x6c,0x2f,0x67,0x6f,0x6f,0x67,0x6c,0x65,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x73,0x6e,0x65,0x68,0x61,0x73,0x69,0x73,0x68,0x6b,0x2f,0x77,0x6f,0x72,0x6b,0x69,0x6e,0x67,0x2f,0x6c,0x6c,0x76,0x6d,0x2d,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2f,0x62,0x75,0x69,0x6c,0x64,0x0,0x73,0x70,0x6c,0x69,0x74,0x5f,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x73,0x2e,0x63,0x0
+};
+
+TEST_F(LineProgram, ReadLinesSplitFunctions) {
+  ByteReader byte_reader(ENDIANNESS_LITTLE);
+  // LineTables don't specify the offset size like Compilation Units do.
+  byte_reader.SetOffsetSize(4);
+  LineInfo line_reader(debug_line,
+                       sizeof(debug_line),
+                       &byte_reader,
+                       debug_str,
+                       sizeof(debug_str),
+                       debug_line_str,
+                       sizeof(debug_line_str),
+                       &handler_);
+  EXPECT_CALL(handler_, DefineFile("split_functions.c", 0, 0, 0, 0)).Times(1);
+  EXPECT_CALL(handler_, AddLine(_, _, _, _, _)).Times(testing::AtLeast(1));
+  // Pick the first address from the foo.cold symbol and check the line number.
+  EXPECT_CALL(handler_, AddLine(testing::Eq(0x401184lu), _, _, /*line_num*/ 7, _)).Times(1);
+  EXPECT_EQ(line_reader.Start(), sizeof(debug_line));
+}
+
+}  // anonymous namespace