From 2997f4590734f904190d46ee4ecf7dd4c8e5019b Mon Sep 17 00:00:00 2001 From: "Liu.andrew.x@gmail.com" Date: Tue, 28 Jul 2015 00:53:44 +0000 Subject: [PATCH] Add support for Linux memory mapping stream and remove ELF header usage when checking exploitability rating. Linux minidumps do not support MD_MEMORY_INFO_LIST_STREAM, meaning the processor cannot retrieve its memory mappings. However, it has its own stream, MD_LINUX_MAPS, which contains memory mappings specific to Linux (it contains the contents of /proc/self/maps). This CL allows the minidump to gather information from the memory mappings for Linux minidumps. In addition, exploitability rating for Linux dumps now use memory mappings instead of checking the ELF headers of binaries. The basis for the change is that checking the ELF headers requires the minidumps to store the memory from the ELF headers, while the memory mapping data is already present, meaning the size of a minidump will be unchanged. As a result, of removing ELF header analysis, two unit tests have been removed. Arguably, the cases that those unit tests check do not merit a high exploitability rating and do not warrant a solid conclusion that was given earlier. R=ivanpe@chromium.org Review URL: https://codereview.chromium.org/1251593007 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1476 4c0a9323-5329-0410-9bdc-e9ce6186880e --- Makefile.am | 34 ++- Makefile.in | 194 +++++++++++++- src/google_breakpad/processor/minidump.h | 103 +++++++- .../processor/proc_maps_linux.h | 57 ++++ src/processor/exploitability_linux.cc | 160 +---------- src/processor/exploitability_linux.h | 51 ---- src/processor/exploitability_unittest.cc | 4 - src/processor/minidump.cc | 143 ++++++++++ src/processor/proc_maps_linux.cc | 103 ++++++++ src/processor/proc_maps_linux_unittest.cc | 250 ++++++++++++++++++ ...inux_in_module_outside_executable_part.dmp | Bin 49096 -> 0 bytes .../testdata/linux_inside_elf_header.dmp | Bin 52616 -> 0 bytes 12 files changed, 885 insertions(+), 214 deletions(-) create mode 100644 src/google_breakpad/processor/proc_maps_linux.h create mode 100644 src/processor/proc_maps_linux.cc create mode 100644 src/processor/proc_maps_linux_unittest.cc delete mode 100644 src/processor/testdata/linux_in_module_outside_executable_part.dmp delete mode 100644 src/processor/testdata/linux_inside_elf_header.dmp diff --git a/Makefile.am b/Makefile.am index fe5848d6..25d47185 100644 --- a/Makefile.am +++ b/Makefile.am @@ -174,6 +174,7 @@ src_libbreakpad_a_SOURCES = \ src/google_breakpad/processor/minidump_processor.h \ src/google_breakpad/processor/process_result.h \ src/google_breakpad/processor/process_state.h \ + src/google_breakpad/processor/proc_maps_linux.h \ src/google_breakpad/processor/source_line_resolver_base.h \ src/google_breakpad/processor/source_line_resolver_interface.h \ src/google_breakpad/processor/stack_frame.h \ @@ -226,6 +227,7 @@ src_libbreakpad_a_SOURCES = \ src/processor/postfix_evaluator-inl.h \ src/processor/postfix_evaluator.h \ src/processor/process_state.cc \ + src/processor/proc_maps_linux.cc \ src/processor/range_map-inl.h \ src/processor/range_map.h \ src/processor/simple_serializer-inl.h \ @@ -345,6 +347,7 @@ check_PROGRAMS += \ src/processor/static_range_map_unittest \ src/processor/pathname_stripper_unittest \ src/processor/postfix_evaluator_unittest \ + src/processor/proc_maps_linux_unittest \ src/processor/range_map_unittest \ src/processor/stackwalker_amd64_unittest \ src/processor/stackwalker_arm_unittest \ @@ -435,7 +438,8 @@ src_client_linux_linux_client_unittest_shlib_SOURCES = \ src/processor/dump_object.cc \ src/processor/logging.cc \ src/processor/minidump.cc \ - src/processor/pathname_stripper.cc + src/processor/pathname_stripper.cc \ + src/processor/proc_maps_linux.cc if ANDROID_HOST src_client_linux_linux_client_unittest_shlib_SOURCES += \ src/common/android/breakpad_getcontext.S @@ -710,6 +714,7 @@ src_processor_exploitability_unittest_LDADD = \ src/processor/logging.o \ src/processor/minidump.o \ src/processor/pathname_stripper.o \ + src/processor/proc_maps_linux.o \ src/processor/simple_symbol_supplier.o \ src/processor/source_line_resolver_base.o \ src/processor/stack_frame_cpu.o \ @@ -818,7 +823,7 @@ src_processor_microdump_processor_unittest_LDADD = \ src/processor/stackwalker_sparc.o \ src/processor/stackwalker_x86.o \ src/processor/tokenize.o \ - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) src_processor_minidump_processor_unittest_SOURCES = \ src/processor/minidump_processor_unittest.cc \ @@ -846,6 +851,7 @@ src_processor_minidump_processor_unittest_LDADD = \ src/processor/minidump.o \ src/processor/pathname_stripper.o \ src/processor/process_state.o \ + src/processor/proc_maps_linux.o \ src/processor/source_line_resolver_base.o \ src/processor/stack_frame_cpu.o \ src/processor/stack_frame_symbolizer.o \ @@ -884,6 +890,25 @@ src_processor_minidump_unittest_LDADD = \ src/processor/logging.o \ src/processor/minidump.o \ src/processor/pathname_stripper.o \ + src/processor/proc_maps_linux.o \ + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) + +src_processor_proc_maps_linux_unittest_SOURCES = \ + src/processor/proc_maps_linux.cc \ + src/processor/proc_maps_linux_unittest.cc \ + src/testing/gtest/src/gtest-all.cc \ + src/testing/gtest/src/gtest_main.cc \ + src/testing/src/gmock-all.cc +src_processor_proc_maps_linux_unittest_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/testing/include \ + -I$(top_srcdir)/src/testing/gtest/include \ + -I$(top_srcdir)/src/testing/gtest \ + -I$(top_srcdir)/src/testing +src_processor_proc_maps_linux_unittest_LDADD = \ + src/processor/logging.o \ + src/processor/pathname_stripper.o \ + src/third_party/libdisasm/libdisasm.a \ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) src_processor_static_address_map_unittest_SOURCES = \ @@ -979,6 +1004,7 @@ src_processor_stackwalker_selftest_LDADD = \ src/processor/logging.o \ src/processor/minidump.o \ src/processor/pathname_stripper.o \ + src/processor/proc_maps_linux.o \ src/processor/source_line_resolver_base.o \ src/processor/stack_frame_cpu.o \ src/processor/stack_frame_symbolizer.o \ @@ -1135,7 +1161,8 @@ src_processor_minidump_dump_LDADD = \ src/processor/dump_object.o \ src/processor/logging.o \ src/processor/minidump.o \ - src/processor/pathname_stripper.o + src/processor/pathname_stripper.o \ + src/processor/proc_maps_linux.o src_processor_microdump_stackwalk_SOURCES = \ src/processor/microdump_stackwalk.cc @@ -1190,6 +1217,7 @@ src_processor_minidump_stackwalk_LDADD = \ src/processor/minidump_processor.o \ src/processor/pathname_stripper.o \ src/processor/process_state.o \ + src/processor/proc_maps_linux.o \ src/processor/simple_symbol_supplier.o \ src/processor/source_line_resolver_base.o \ src/processor/stack_frame_cpu.o \ diff --git a/Makefile.in b/Makefile.in index f65165cf..5fb12ad9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -179,6 +179,7 @@ check_PROGRAMS = $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ @DISABLE_PROCESSOR_FALSE@ src/processor/static_range_map_unittest \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest \ @DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest \ @DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest \ @DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest \ @DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest \ @@ -353,6 +354,7 @@ am__src_libbreakpad_a_SOURCES_DIST = \ src/google_breakpad/processor/minidump_processor.h \ src/google_breakpad/processor/process_result.h \ src/google_breakpad/processor/process_state.h \ + src/google_breakpad/processor/proc_maps_linux.h \ src/google_breakpad/processor/source_line_resolver_base.h \ src/google_breakpad/processor/source_line_resolver_interface.h \ src/google_breakpad/processor/stack_frame.h \ @@ -395,7 +397,8 @@ am__src_libbreakpad_a_SOURCES_DIST = \ src/processor/pathname_stripper.h \ src/processor/postfix_evaluator-inl.h \ src/processor/postfix_evaluator.h \ - src/processor/process_state.cc src/processor/range_map-inl.h \ + src/processor/process_state.cc \ + src/processor/proc_maps_linux.cc src/processor/range_map-inl.h \ src/processor/range_map.h \ src/processor/simple_serializer-inl.h \ src/processor/simple_serializer.h \ @@ -458,6 +461,7 @@ am__src_libbreakpad_a_SOURCES_DIST = \ @DISABLE_PROCESSOR_FALSE@ src/processor/module_serializer.$(OBJEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.$(OBJEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.$(OBJEXT) \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.$(OBJEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/simple_symbol_supplier.$(OBJEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.$(OBJEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.$(OBJEXT) \ @@ -548,6 +552,7 @@ src_third_party_libdisasm_libdisasm_a_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/static_range_map_unittest$(EXEEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest$(EXEEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest$(EXEEXT) \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest$(EXEEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest$(EXEEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest$(EXEEXT) \ @DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest$(EXEEXT) \ @@ -589,6 +594,7 @@ am__src_client_linux_linux_client_unittest_shlib_SOURCES_DIST = \ src/processor/dump_context.cc src/processor/dump_object.cc \ 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/client/linux/microdump_writer/microdump_writer_unittest.cc \ src/common/android/breakpad_getcontext_unittest.cc @@ -618,6 +624,7 @@ am__src_client_linux_linux_client_unittest_shlib_SOURCES_DIST = \ @LINUX_HOST_TRUE@ src/processor/src_client_linux_linux_client_unittest_shlib-logging.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/processor/src_client_linux_linux_client_unittest_shlib-minidump.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/processor/src_client_linux_linux_client_unittest_shlib-pathname_stripper.$(OBJEXT) \ +@LINUX_HOST_TRUE@ src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.$(OBJEXT) \ @LINUX_HOST_TRUE@ $(am__objects_2) \ @LINUX_HOST_TRUE@ src/client/linux/microdump_writer/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.$(OBJEXT) \ @LINUX_HOST_TRUE@ $(am__objects_3) @@ -851,6 +858,7 @@ src_processor_exploitability_unittest_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/simple_symbol_supplier.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @@ -987,7 +995,8 @@ src_processor_minidump_dump_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/dump_object.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ -@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o +@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o am__src_processor_minidump_processor_unittest_SOURCES_DIST = \ src/processor/minidump_processor_unittest.cc \ src/testing/gtest/src/gtest-all.cc \ @@ -1013,6 +1022,7 @@ src_processor_minidump_processor_unittest_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_symbolizer.o \ @@ -1053,6 +1063,7 @@ src_processor_minidump_stackwalk_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/simple_symbol_supplier.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @@ -1093,6 +1104,7 @@ src_processor_minidump_unittest_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \ @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) am__src_processor_pathname_stripper_unittest_SOURCES_DIST = \ @@ -1114,6 +1126,25 @@ src_processor_postfix_evaluator_unittest_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \ @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) +am__src_processor_proc_maps_linux_unittest_SOURCES_DIST = \ + src/processor/proc_maps_linux.cc \ + src/processor/proc_maps_linux_unittest.cc \ + src/testing/gtest/src/gtest-all.cc \ + src/testing/gtest/src/gtest_main.cc \ + src/testing/src/gmock-all.cc +@DISABLE_PROCESSOR_FALSE@am_src_processor_proc_maps_linux_unittest_OBJECTS = src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.$(OBJEXT) \ +@DISABLE_PROCESSOR_FALSE@ src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.$(OBJEXT) \ +@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.$(OBJEXT) \ +@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.$(OBJEXT) \ +@DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.$(OBJEXT) +src_processor_proc_maps_linux_unittest_OBJECTS = \ + $(am_src_processor_proc_maps_linux_unittest_OBJECTS) +@DISABLE_PROCESSOR_FALSE@src_processor_proc_maps_linux_unittest_DEPENDENCIES = \ +@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/third_party/libdisasm/libdisasm.a \ +@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \ +@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) am__src_processor_range_map_unittest_SOURCES_DIST = \ src/processor/range_map_unittest.cc @DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_unittest_OBJECTS = src/processor/range_map_unittest.$(OBJEXT) @@ -1225,6 +1256,7 @@ src_processor_stackwalker_selftest_OBJECTS = \ @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_symbolizer.o \ @@ -1491,6 +1523,7 @@ SOURCES = $(src_client_linux_libbreakpad_client_a_SOURCES) \ $(src_processor_minidump_unittest_SOURCES) \ $(src_processor_pathname_stripper_unittest_SOURCES) \ $(src_processor_postfix_evaluator_unittest_SOURCES) \ + $(src_processor_proc_maps_linux_unittest_SOURCES) \ $(src_processor_range_map_unittest_SOURCES) \ $(src_processor_stackwalker_address_list_unittest_SOURCES) \ $(src_processor_stackwalker_amd64_unittest_SOURCES) \ @@ -1536,6 +1569,7 @@ DIST_SOURCES = \ $(am__src_processor_minidump_unittest_SOURCES_DIST) \ $(am__src_processor_pathname_stripper_unittest_SOURCES_DIST) \ $(am__src_processor_postfix_evaluator_unittest_SOURCES_DIST) \ + $(am__src_processor_proc_maps_linux_unittest_SOURCES_DIST) \ $(am__src_processor_range_map_unittest_SOURCES_DIST) \ $(am__src_processor_stackwalker_address_list_unittest_SOURCES_DIST) \ $(am__src_processor_stackwalker_amd64_unittest_SOURCES_DIST) \ @@ -1974,6 +2008,7 @@ lib_LIBRARIES = $(am__append_5) $(am__append_8) @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/minidump_processor.h \ @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/process_result.h \ @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/process_state.h \ +@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/proc_maps_linux.h \ @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/source_line_resolver_base.h \ @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/source_line_resolver_interface.h \ @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/stack_frame.h \ @@ -2026,6 +2061,7 @@ lib_LIBRARIES = $(am__append_5) $(am__append_8) @DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator-inl.h \ @DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator.h \ @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.cc \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.cc \ @DISABLE_PROCESSOR_FALSE@ src/processor/range_map-inl.h \ @DISABLE_PROCESSOR_FALSE@ src/processor/range_map.h \ @DISABLE_PROCESSOR_FALSE@ src/processor/simple_serializer-inl.h \ @@ -2149,6 +2185,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @LINUX_HOST_TRUE@ src/processor/logging.cc \ @LINUX_HOST_TRUE@ src/processor/minidump.cc \ @LINUX_HOST_TRUE@ src/processor/pathname_stripper.cc \ +@LINUX_HOST_TRUE@ src/processor/proc_maps_linux.cc \ @LINUX_HOST_TRUE@ $(am__append_18) \ @LINUX_HOST_TRUE@ src/client/linux/microdump_writer/microdump_writer_unittest.cc \ @LINUX_HOST_TRUE@ $(am__append_19) @@ -2415,6 +2452,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/simple_symbol_supplier.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @@ -2531,7 +2569,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_sparc.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_x86.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/tokenize.o \ -@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) +@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @DISABLE_PROCESSOR_FALSE@src_processor_minidump_processor_unittest_SOURCES = \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor_unittest.cc \ @@ -2561,6 +2599,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_symbolizer.o \ @@ -2601,6 +2640,27 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ +@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) + +@DISABLE_PROCESSOR_FALSE@src_processor_proc_maps_linux_unittest_SOURCES = \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.cc \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest.cc \ +@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/gtest-all.cc \ +@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/gtest_main.cc \ +@DISABLE_PROCESSOR_FALSE@ src/testing/src/gmock-all.cc + +@DISABLE_PROCESSOR_FALSE@src_processor_proc_maps_linux_unittest_CPPFLAGS = \ +@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \ +@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \ +@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest/include \ +@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest \ +@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing + +@DISABLE_PROCESSOR_FALSE@src_processor_proc_maps_linux_unittest_LDADD = \ +@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/third_party/libdisasm/libdisasm.a \ @DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @DISABLE_PROCESSOR_FALSE@src_processor_static_address_map_unittest_SOURCES = \ @@ -2708,6 +2768,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_symbolizer.o \ @@ -2876,7 +2937,8 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/dump_object.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ -@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o +@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o @DISABLE_PROCESSOR_FALSE@src_processor_microdump_stackwalk_SOURCES = \ @DISABLE_PROCESSOR_FALSE@ src/processor/microdump_stackwalk.cc @@ -2933,6 +2995,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.o \ +@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/simple_symbol_supplier.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ @DISABLE_PROCESSOR_FALSE@ src/processor/stack_frame_cpu.o \ @@ -3372,6 +3435,9 @@ src/processor/pathname_stripper.$(OBJEXT): \ src/processor/$(DEPDIR)/$(am__dirstamp) src/processor/process_state.$(OBJEXT): src/processor/$(am__dirstamp) \ src/processor/$(DEPDIR)/$(am__dirstamp) +src/processor/proc_maps_linux.$(OBJEXT): \ + src/processor/$(am__dirstamp) \ + src/processor/$(DEPDIR)/$(am__dirstamp) src/processor/simple_symbol_supplier.$(OBJEXT): \ src/processor/$(am__dirstamp) \ src/processor/$(DEPDIR)/$(am__dirstamp) @@ -3627,6 +3693,9 @@ src/processor/src_client_linux_linux_client_unittest_shlib-minidump.$(OBJEXT): src/processor/src_client_linux_linux_client_unittest_shlib-pathname_stripper.$(OBJEXT): \ src/processor/$(am__dirstamp) \ src/processor/$(DEPDIR)/$(am__dirstamp) +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) @@ -4010,6 +4079,25 @@ src/processor/postfix_evaluator_unittest.$(OBJEXT): \ src/processor/postfix_evaluator_unittest$(EXEEXT): $(src_processor_postfix_evaluator_unittest_OBJECTS) $(src_processor_postfix_evaluator_unittest_DEPENDENCIES) $(EXTRA_src_processor_postfix_evaluator_unittest_DEPENDENCIES) src/processor/$(am__dirstamp) @rm -f src/processor/postfix_evaluator_unittest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(src_processor_postfix_evaluator_unittest_OBJECTS) $(src_processor_postfix_evaluator_unittest_LDADD) $(LIBS) +src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.$(OBJEXT): \ + src/processor/$(am__dirstamp) \ + src/processor/$(DEPDIR)/$(am__dirstamp) +src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.$(OBJEXT): \ + src/processor/$(am__dirstamp) \ + src/processor/$(DEPDIR)/$(am__dirstamp) +src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.$(OBJEXT): \ + src/testing/gtest/src/$(am__dirstamp) \ + src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp) +src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.$(OBJEXT): \ + src/testing/gtest/src/$(am__dirstamp) \ + src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp) +src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.$(OBJEXT): \ + src/testing/src/$(am__dirstamp) \ + src/testing/src/$(DEPDIR)/$(am__dirstamp) + +src/processor/proc_maps_linux_unittest$(EXEEXT): $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_DEPENDENCIES) $(EXTRA_src_processor_proc_maps_linux_unittest_DEPENDENCIES) src/processor/$(am__dirstamp) + @rm -f src/processor/proc_maps_linux_unittest$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_LDADD) $(LIBS) src/processor/range_map_unittest.$(OBJEXT): \ src/processor/$(am__dirstamp) \ src/processor/$(DEPDIR)/$(am__dirstamp) @@ -4493,6 +4581,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/pathname_stripper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/pathname_stripper_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/postfix_evaluator_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/proc_maps_linux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/process_state.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/range_map_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/simple_symbol_supplier.Po@am__quote@ @@ -4503,6 +4592,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-logging.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-minidump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-pathname_stripper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_basic_source_line_resolver_unittest-basic_source_line_resolver_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_binarystream_unittest-binarystream_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_cfi_frame_info_unittest-cfi_frame_info_unittest.Po@am__quote@ @@ -4514,6 +4604,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_processor_unittest-minidump_processor_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-stackwalker_address_list_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-stackwalker_amd64_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_arm64_unittest-stackwalker_arm64_unittest.Po@am__quote@ @@ -4561,6 +4653,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_processor_unittest-gtest-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-gtest-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-gtest_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-gtest-all.Po@am__quote@ @@ -4594,6 +4688,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_microdump_processor_unittest-gmock-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_minidump_processor_unittest-gmock-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-gmock-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-gmock-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_stackwalker_arm64_unittest-gmock-all.Po@am__quote@ @@ -5025,6 +5120,20 @@ src/processor/src_client_linux_linux_client_unittest_shlib-pathname_stripper.obj @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-pathname_stripper.obj `if test -f 'src/processor/pathname_stripper.cc'; then $(CYGPATH_W) 'src/processor/pathname_stripper.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/pathname_stripper.cc'; fi` +src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.o: src/processor/proc_maps_linux.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/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.o -MD -MP -MF src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Tpo -c -o src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.o `test -f 'src/processor/proc_maps_linux.cc' || echo '$(srcdir)/'`src/processor/proc_maps_linux.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Tpo src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/proc_maps_linux.cc' object='src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.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/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.o `test -f 'src/processor/proc_maps_linux.cc' || echo '$(srcdir)/'`src/processor/proc_maps_linux.cc + +src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.obj: src/processor/proc_maps_linux.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/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.obj -MD -MP -MF src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Tpo -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` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Tpo src/processor/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/proc_maps_linux.cc' object='src/processor/src_client_linux_linux_client_unittest_shlib-proc_maps_linux.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/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/client/linux/microdump_writer/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.o: src/client/linux/microdump_writer/microdump_writer_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/client/linux/microdump_writer/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.o -MD -MP -MF src/client/linux/microdump_writer/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.Tpo -c -o src/client/linux/microdump_writer/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.o `test -f 'src/client/linux/microdump_writer/microdump_writer_unittest.cc' || echo '$(srcdir)/'`src/client/linux/microdump_writer/microdump_writer_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/client/linux/microdump_writer/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.Tpo src/client/linux/microdump_writer/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-microdump_writer_unittest.Po @@ -6285,6 +6394,76 @@ src/testing/src/src_processor_minidump_unittest-gmock-all.obj: src/testing/src/g @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_minidump_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi` +src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.o: src/processor/proc_maps_linux.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Tpo -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.o `test -f 'src/processor/proc_maps_linux.cc' || echo '$(srcdir)/'`src/processor/proc_maps_linux.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Tpo src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/proc_maps_linux.cc' object='src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.o `test -f 'src/processor/proc_maps_linux.cc' || echo '$(srcdir)/'`src/processor/proc_maps_linux.cc + +src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.obj: src/processor/proc_maps_linux.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Tpo -c -o src/processor/src_processor_proc_maps_linux_unittest-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` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Tpo src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/proc_maps_linux.cc' object='src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-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/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.o: src/processor/proc_maps_linux_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Tpo -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.o `test -f 'src/processor/proc_maps_linux_unittest.cc' || echo '$(srcdir)/'`src/processor/proc_maps_linux_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Tpo src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/proc_maps_linux_unittest.cc' object='src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.o `test -f 'src/processor/proc_maps_linux_unittest.cc' || echo '$(srcdir)/'`src/processor/proc_maps_linux_unittest.cc + +src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj: src/processor/proc_maps_linux_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Tpo -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj `if test -f 'src/processor/proc_maps_linux_unittest.cc'; then $(CYGPATH_W) 'src/processor/proc_maps_linux_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/proc_maps_linux_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Tpo src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/proc_maps_linux_unittest.cc' object='src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj `if test -f 'src/processor/proc_maps_linux_unittest.cc'; then $(CYGPATH_W) 'src/processor/proc_maps_linux_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/proc_maps_linux_unittest.cc'; fi` + +src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.o: src/testing/gtest/src/gtest-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.o `test -f 'src/testing/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.o `test -f 'src/testing/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest-all.cc + +src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.obj: src/testing/gtest/src/gtest-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.obj `if test -f 'src/testing/gtest/src/gtest-all.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest-all.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest-all.obj `if test -f 'src/testing/gtest/src/gtest-all.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest-all.cc'; fi` + +src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.o: src/testing/gtest/src/gtest_main.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.o `test -f 'src/testing/gtest/src/gtest_main.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest_main.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.o `test -f 'src/testing/gtest/src/gtest_main.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest_main.cc + +src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.obj: src/testing/gtest/src/gtest_main.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.obj `if test -f 'src/testing/gtest/src/gtest_main.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest_main.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gtest_main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_proc_maps_linux_unittest-gtest_main.obj `if test -f 'src/testing/gtest/src/gtest_main.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest_main.cc'; fi` + +src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.o: src/testing/src/gmock-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.o -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc + +src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.obj: src/testing/src/gmock-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.obj -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_proc_maps_linux_unittest-gmock-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.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_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_proc_maps_linux_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi` + src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o: src/common/test_assembler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_stackwalker_address_list_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o -MD -MP -MF src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo -c -o src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o `test -f 'src/common/test_assembler.cc' || echo '$(srcdir)/'`src/common/test_assembler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Po @@ -7556,6 +7735,13 @@ src/processor/postfix_evaluator_unittest.log: src/processor/postfix_evaluator_un --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/proc_maps_linux_unittest.log: src/processor/proc_maps_linux_unittest$(EXEEXT) + @p='src/processor/proc_maps_linux_unittest$(EXEEXT)'; \ + b='src/processor/proc_maps_linux_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/range_map_unittest.log: src/processor/range_map_unittest$(EXEEXT) @p='src/processor/range_map_unittest$(EXEEXT)'; \ b='src/processor/range_map_unittest'; \ diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h index 51f15025..9c8448a3 100644 --- a/src/google_breakpad/processor/minidump.h +++ b/src/google_breakpad/processor/minidump.h @@ -88,12 +88,14 @@ #include #include +#include "common/basictypes.h" #include "common/using_std_string.h" #include "google_breakpad/processor/code_module.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/dump_context.h" #include "google_breakpad/processor/dump_object.h" #include "google_breakpad/processor/memory_region.h" +#include "google_breakpad/processor/proc_maps_linux.h" namespace google_breakpad { @@ -808,7 +810,7 @@ class MinidumpMemoryInfo : public MinidumpObject { // These objects are managed by MinidumpMemoryInfoList. friend class MinidumpMemoryInfoList; - explicit MinidumpMemoryInfo(Minidump* minidump); + explicit MinidumpMemoryInfo(Minidump* minidump_); // This works like MinidumpStream::Read, but is driven by // MinidumpMemoryInfoList. No size checking is done, because @@ -841,7 +843,7 @@ class MinidumpMemoryInfoList : public MinidumpStream { static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM; - explicit MinidumpMemoryInfoList(Minidump* minidump); + explicit MinidumpMemoryInfoList(Minidump* minidump_); bool Read(uint32_t expected_size); @@ -852,6 +854,100 @@ class MinidumpMemoryInfoList : public MinidumpStream { uint32_t info_count_; }; +// MinidumpLinuxMaps wraps information about a single mapped memory region +// from /proc/self/maps. +class MinidumpLinuxMaps : public MinidumpObject { + public: + // The memory address of the base of the mapped region. + uint64_t GetBase() const { return valid_ ? region_.start : 0; } + // The size of the mapped region. + uint64_t GetSize() const { return valid_ ? region_.end - region_.start : 0; } + + // The permissions of the mapped region. + bool IsReadable() const { + return valid_ ? region_.permissions & MappedMemoryRegion::READ : false; + } + bool IsWriteable() const { + return valid_ ? region_.permissions & MappedMemoryRegion::WRITE : false; + } + bool IsExecutable() const { + return valid_ ? region_.permissions & MappedMemoryRegion::EXECUTE : false; + } + bool IsPrivate() const { + return valid_ ? region_.permissions & MappedMemoryRegion::PRIVATE : false; + } + + // The offset of the mapped region. + uint64_t GetOffset() const { return valid_ ? region_.offset : 0; } + + // The major device number. + uint8_t GetMajorDevice() const { return valid_ ? region_.major_device : 0; } + // The minor device number. + uint8_t GetMinorDevice() const { return valid_ ? region_.minor_device : 0; } + + // The inode of the mapped region. + uint64_t GetInode() const { return valid_ ? region_.inode : 0; } + + // The pathname of the mapped region. + const string GetPathname() const { return valid_ ? region_.path : ""; } + + // Print the contents of this mapping. + void Print(); + + private: + // These objects are managed by MinidumpLinuxMapsList. + friend class MinidumpLinuxMapsList; + + // This caller owns the pointer. + explicit MinidumpLinuxMaps(Minidump *minidump); + + // Read data about a single mapping from /proc/self/maps and load the data + // into this object. The input vector is in the same format as a line from + // /proc/self/maps. + + // The memory region struct that this class wraps. + MappedMemoryRegion region_; + + DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMaps); +}; + +// MinidumpLinuxMapsList corresponds to the Linux-exclusive MD_LINUX_MAPS +// stream, which contains the contents of /prod/self/maps, which contains +// the mapped memory regions and their access permissions. +class MinidumpLinuxMapsList : public MinidumpStream { + public: + virtual ~MinidumpLinuxMapsList(); + + // Get mapping at the given memory address. The caller owns the pointer. + const MinidumpLinuxMaps *GetLinuxMapsForAddress(uint64_t address) const; + // Get mapping at the given index. The caller owns the pointer. + const MinidumpLinuxMaps *GetLinuxMapsAtIndex(unsigned int index) const; + + // Print the contents of /proc/self/maps to stdout. + void Print(); + + private: + friend class Minidump; + + typedef vector MinidumpLinuxMappings; + + static const uint32_t kStreamType = MD_LINUX_MAPS; + + // The caller owns the pointer. + explicit MinidumpLinuxMapsList(Minidump *minidump); + + // Read and load the contents of the process mapping data. + // The stream should have data in the form of /proc/self/maps. + // This method returns whether the stream was read successfully. + bool Read(uint32_t expected_size); + + // The list of individual mappings. + MinidumpLinuxMappings *maps_; + // The number of mappings. + uint32_t maps_count_; + + DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMapsList); +}; // Minidump is the user's interface to a minidump file. It wraps MDRawHeader // and provides access to the minidump's top-level stream directory. @@ -912,6 +1008,9 @@ class Minidump { virtual MinidumpBreakpadInfo* GetBreakpadInfo(); virtual MinidumpMemoryInfoList* GetMemoryInfoList(); + // The next method also calls GetStream, but is exclusive for Linux dumps. + virtual MinidumpLinuxMapsList *GetLinuxMapsList(); + // The next set of methods are provided for users who wish to access // data in minidump files directly, while leveraging the rest of // this class and related classes to handle the basic minidump diff --git a/src/google_breakpad/processor/proc_maps_linux.h b/src/google_breakpad/processor/proc_maps_linux.h new file mode 100644 index 00000000..6ddeb038 --- /dev/null +++ b/src/google_breakpad/processor/proc_maps_linux.h @@ -0,0 +1,57 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_DEBUG_PROC_MAPS_LINUX_H_ +#define BASE_DEBUG_PROC_MAPS_LINUX_H_ + +#include +#include + +#include "common/using_std_string.h" +#include "google_breakpad/common/breakpad_types.h" + +namespace google_breakpad { + +// Describes a region of mapped memory and the path of the file mapped. +struct MappedMemoryRegion { + enum Permission { + READ = 1 << 0, + WRITE = 1 << 1, + EXECUTE = 1 << 2, + PRIVATE = 1 << 3, // If set, region is private, otherwise it is shared. + }; + + // The address range [start,end) of mapped memory. + uintptr_t start; + uintptr_t end; + + // Byte offset into |path| of the range mapped into memory. + uint64_t offset; + + // Bitmask of read/write/execute/private/shared permissions. + uint8_t permissions; + + // Major and minor devices. + uint8_t major_device; + uint8_t minor_device; + + // Value of the inode. + uint64_t inode; + + // Name of the file mapped into memory. + // + // NOTE: path names aren't guaranteed to point at valid files. For example, + // "[heap]" and "[stack]" are used to represent the location of the process' + // heap and stack, respectively. + string path; +}; + +// Parses /proc//maps input data and stores in |regions|. Returns true +// and updates |regions| if and only if all of |input| was successfully parsed. +bool ParseProcMaps(const std::string& input, + std::vector* regions); + +} // namespace google_breakpad + +#endif // BASE_DEBUG_PROC_MAPS_LINUX_H_ diff --git a/src/processor/exploitability_linux.cc b/src/processor/exploitability_linux.cc index c1c291ce..3e99f89e 100644 --- a/src/processor/exploitability_linux.cc +++ b/src/processor/exploitability_linux.cc @@ -36,8 +36,6 @@ #include "processor/exploitability_linux.h" -#include - #include "google_breakpad/common/minidump_exception_linux.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/process_state.h" @@ -111,10 +109,6 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { return EXPLOITABILITY_ERR_PROCESSING; } - if (this->ArchitectureType() == UNSUPPORTED_ARCHITECTURE) { - BPLOG(INFO) << "Unsupported architecture."; - return EXPLOITABILITY_ERR_PROCESSING; - } // Getting the instruction pointer. if (!context->GetInstructionPointer(&instruction_ptr)) { BPLOG(INFO) << "Failed to retrieve instruction pointer."; @@ -131,151 +125,17 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { return EXPLOITABILITY_INTERESTING; } -LinuxArchitectureType ExploitabilityLinux::ArchitectureType() { - // GetContextCPU() should have already been successfully called before - // calling this method. Thus there should be a raw exception stream for - // the minidump. - MinidumpException *exception = dump_->GetException(); - const DumpContext *dump_context = - exception ? - exception->GetContext() : NULL; - if (dump_context == NULL) { - BPLOG(INFO) << "No raw dump context."; - return UNSUPPORTED_ARCHITECTURE; - } - - // Check the architecture type. - switch (dump_context->GetContextCPU()) { - case MD_CONTEXT_ARM: - case MD_CONTEXT_X86: - return LINUX_32_BIT; - case MD_CONTEXT_ARM64: - case MD_CONTEXT_AMD64: - return LINUX_64_BIT; - default: - // This should not happen. The four architectures above should be - // the only Linux architectures. - BPLOG(INFO) << "Unsupported architecture."; - return UNSUPPORTED_ARCHITECTURE; - } -} - bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) { - // Get memory mapping. Most minidumps will not contain a memory - // mapping, so processing will commonly resort to checking modules. - MinidumpMemoryInfoList *mem_info_list = dump_->GetMemoryInfoList(); - const MinidumpMemoryInfo *mem_info = - mem_info_list ? - mem_info_list->GetMemoryInfoForAddress(instruction_ptr) : NULL; - - // Check if the memory mapping at the instruction pointer is executable. - // If there is no memory mapping, processing will use modules as reference. - if (mem_info != NULL) { - return mem_info->IsExecutable(); - } - - // If the memory mapping retrieval fails, check the modules - // to see if the instruction pointer is inside a module. - MinidumpModuleList *minidump_module_list = dump_->GetModuleList(); - const MinidumpModule *minidump_module = - minidump_module_list ? - minidump_module_list->GetModuleForAddress(instruction_ptr) : NULL; - - // If the instruction pointer isn't in a module, return false. - if (minidump_module == NULL) { - return false; - } - - // Get ELF header data from the instruction pointer's module. - const uint64_t base_address = minidump_module->base_address(); - MinidumpMemoryList *memory_list = dump_->GetMemoryList(); - MinidumpMemoryRegion *memory_region = - memory_list ? - memory_list->GetMemoryRegionForAddress(base_address) : NULL; - - // The minidump does not have the correct memory region. - // This returns true because even though there is no memory data available, - // the evidence so far suggests that the instruction pointer is not at a - // bad location. - if (memory_region == NULL) { - return true; - } - - // Examine ELF headers. Depending on the architecture, the size of the - // ELF headers can differ. - LinuxArchitectureType architecture = this->ArchitectureType(); - if (architecture == LINUX_32_BIT) { - // Check if the ELF header is within the memory region and if the - // instruction pointer lies within the ELF header. - if (memory_region->GetSize() < sizeof(Elf32_Ehdr) || - instruction_ptr < base_address + sizeof(Elf32_Ehdr)) { - return false; - } - // Load 32-bit ELF header. - Elf32_Ehdr header; - this->LoadElfHeader(memory_region, base_address, &header); - // Check if the program header table is within the memory region, and - // validate that the program header entry size is correct. - if (header.e_phentsize != sizeof(Elf32_Phdr) || - memory_region->GetSize() < - header.e_phoff + - ((uint64_t) header.e_phentsize * (uint64_t) header.e_phnum)) { - return false; - } - // Load 32-bit Program Header Table. - scoped_array program_headers(new Elf32_Phdr[header.e_phnum]); - this->LoadElfHeaderTable(memory_region, - base_address + header.e_phoff, - header.e_phnum, - program_headers.get()); - // Find correct program header that corresponds to the instruction pointer. - for (int i = 0; i < header.e_phnum; i++) { - const Elf32_Phdr& program_header = program_headers[i]; - // Check if instruction pointer lies within this program header's region. - if (instruction_ptr >= program_header.p_vaddr && - instruction_ptr < program_header.p_vaddr + program_header.p_memsz) { - // Return whether this program header region is executable. - return program_header.p_flags & PF_X; - } - } - } else if (architecture == LINUX_64_BIT) { - // Check if the ELF header is within the memory region and if the - // instruction pointer lies within the ELF header. - if (memory_region->GetSize() < sizeof(Elf64_Ehdr) || - instruction_ptr < base_address + sizeof(Elf64_Ehdr)) { - return false; - } - // Load 64-bit ELF header. - Elf64_Ehdr header; - this->LoadElfHeader(memory_region, base_address, &header); - // Check if the program header table is within the memory region, and - // validate that the program header entry size is correct. - if (header.e_phentsize != sizeof(Elf64_Phdr) || - memory_region->GetSize() < - header.e_phoff + - ((uint64_t) header.e_phentsize * (uint64_t) header.e_phnum)) { - return false; - } - // Load 64-bit Program Header Table. - scoped_array program_headers(new Elf64_Phdr[header.e_phnum]); - this->LoadElfHeaderTable(memory_region, - base_address + header.e_phoff, - header.e_phnum, - program_headers.get()); - // Find correct program header that corresponds to the instruction pointer. - for (int i = 0; i < header.e_phnum; i++) { - const Elf64_Phdr& program_header = program_headers[i]; - // Check if instruction pointer lies within this program header's region. - if (instruction_ptr >= program_header.p_vaddr && - instruction_ptr < program_header.p_vaddr + program_header.p_memsz) { - // Return whether this program header region is executable. - return program_header.p_flags & PF_X; - } - } - } - - // The instruction pointer was not in an area identified by the ELF headers. - return false; + // Get Linux memory mapping from /proc/self/maps. Checking whether the + // region the instruction pointer is in has executable permission can tell + // whether it is in a valid code region. If there is no mapping for the + // instruction pointer, it is indicative that the instruction pointer is + // not within a module, which implies that it is outside a valid area. + MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList(); + const MinidumpLinuxMaps *linux_maps = + linux_maps_list ? + linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : NULL; + return linux_maps ? linux_maps->IsExecutable() : false; } bool ExploitabilityLinux::BenignCrashTrigger(const MDRawExceptionStream diff --git a/src/processor/exploitability_linux.h b/src/processor/exploitability_linux.h index 2deb4991..6332b074 100644 --- a/src/processor/exploitability_linux.h +++ b/src/processor/exploitability_linux.h @@ -43,17 +43,6 @@ namespace google_breakpad { -enum LinuxArchitectureType { - // A 32-bit Linux architecture. - LINUX_32_BIT, - - // A 64-bit Linux architecture. - LINUX_64_BIT, - - // Some other architecture that is not Linux. - UNSUPPORTED_ARCHITECTURE -}; - class ExploitabilityLinux : public Exploitability { public: ExploitabilityLinux(Minidump *dump, @@ -69,46 +58,6 @@ class ExploitabilityLinux : public Exploitability { // This method checks the exception that triggered the creation of the // minidump and reports whether the exception suggests no exploitability. bool BenignCrashTrigger(const MDRawExceptionStream *raw_exception_stream); - - // Checks if the minidump architecture is 32-bit or 64-bit. - LinuxArchitectureType ArchitectureType(); - - // Loads ELF header data of the module present in the given memory - // region into the scoped pointer. - // This method takes a scoped pointer in which the ELF header data is - // loaded, the memory region containing the ELF header, and the base - // address of the ELF header. - template - void LoadElfHeader(MinidumpMemoryRegion *memory, - uint64_t base_address, - T *header) { - for (size_t i = 0; i < sizeof(T); i++) { - uint8_t my_byte = 0; - memory->GetMemoryAtAddress(base_address + i, &my_byte); - *(reinterpret_cast(header) + i) = my_byte; - } - } - - // Loads the Program Header Table of the module present in the given - // memory region into the scoped array. - // This method takes a scoped array in which the header table data is - // loaded, the memory region containing the table, the base address of - // the program header table, and the number of entries in the table. - template - void LoadElfHeaderTable(MinidumpMemoryRegion *memory, - uint64_t base_address, - uint16_t e_phnum, - T table[]) { - uint64_t offset = 0; - for (size_t i = 0; i < e_phnum; i++) { - T *entry = &table[i]; - for (size_t j = 0; j < sizeof(T); j++) { - uint8_t my_byte = 0; - memory->GetMemoryAtAddress(base_address + offset++, &my_byte); - *(reinterpret_cast(entry) + j) = my_byte; - } - } - } }; } // namespace google_breakpad diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc index abb5b3ba..8a42baa0 100644 --- a/src/processor/exploitability_unittest.cc +++ b/src/processor/exploitability_unittest.cc @@ -119,14 +119,10 @@ TEST(ExploitabilityTest, TestLinuxEngine) { ExploitabilityFor("linux_null_dereference.dmp")); ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, ExploitabilityFor("linux_jmp_to_0.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_inside_elf_header.dmp")); ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, ExploitabilityFor("linux_outside_module.dmp")); ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, ExploitabilityFor("linux_raise_sigabrt.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_in_module_outside_executable_part.dmp")); ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, ExploitabilityFor("linux_inside_module_exe_region1.dmp")); ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 08f64652..1a997d6a 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "processor/range_map-inl.h" @@ -71,6 +72,7 @@ namespace google_breakpad { using std::istream; using std::ifstream; using std::numeric_limits; +using std::stringstream; using std::vector; // Returns true iff |context_size| matches exactly one of the sizes of the @@ -3972,6 +3974,142 @@ void MinidumpMemoryInfoList::Print() { } } +// +// MinidumpLinuxMaps +// + +MinidumpLinuxMaps::MinidumpLinuxMaps(Minidump *minidump) + : MinidumpObject(minidump) { +} + +void MinidumpLinuxMaps::Print() { + if (!valid_) { + BPLOG(ERROR) << "MinidumpLinuxMaps cannot print invalid data"; + return; + } + std::cout << GetPathname() << std::endl; +} + +// +// MinidumpLinuxMapsList +// + +MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump *minidump) + : MinidumpStream(minidump), + maps_(NULL), + maps_count_(0) { +} + +MinidumpLinuxMapsList::~MinidumpLinuxMapsList() { + for (unsigned int i = 0; i < maps_->size(); i++) { + delete (*maps_)[i]; + } + delete maps_; +} + +const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsForAddress( + uint64_t address) const { + if (!valid_) { + BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsForAddress"; + return NULL; + } + + // Search every memory mapping. + for (unsigned int index = 0; index < maps_count_; index++) { + // Check if address is within bounds of the current memory region. + if ((*maps_)[index]->GetBase() <= address && + (*maps_)[index]->GetBase() + (*maps_)[index]->GetSize() > address) { + return (*maps_)[index]; + } + } + + // No mapping encloses the memory address. + BPLOG(ERROR) << "MinidumpLinuxMapsList has no mapping at " + << HexString(address); + return NULL; +} + +const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsAtIndex( + unsigned int index) const { + if (!valid_) { + BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsAtIndex"; + return NULL; + } + + // Index out of bounds. + if (index >= maps_count_) { + BPLOG(ERROR) << "MinidumpLinuxMapsList index of out range: " + << index + << "/" + << maps_count_; + return NULL; + } + return (*maps_)[index]; +} + +bool MinidumpLinuxMapsList::Read(uint32_t expected_size) { + // Invalidate cached data. + delete maps_; + maps_ = NULL; + maps_count_ = 0; + + valid_ = false; + + // Load and check expected stream length. + uint32_t length = 0; + if (!minidump_->SeekToStreamType(MD_LINUX_MAPS, &length)) { + BPLOG(ERROR) << "MinidumpLinuxMapsList stream type not found"; + return false; + } + if (expected_size != length) { + BPLOG(ERROR) << "MinidumpLinuxMapsList size mismatch: " + << expected_size + << " != " + << length; + return false; + } + + // Create a vector to read stream data. The vector needs to have + // at least enough capacity to read all the data. + vector mapping_bytes(length); + if (!minidump_->ReadBytes(&mapping_bytes[0], length)) { + BPLOG(ERROR) << "MinidumpLinuxMapsList failed to read bytes"; + return false; + } + string map_string(mapping_bytes.begin(), mapping_bytes.end()); + vector all_regions; + + // Parse string into mapping data. + if (!ParseProcMaps(map_string, &all_regions)) { + return false; + } + + scoped_ptr maps(new MinidumpLinuxMappings()); + + // Push mapping data into wrapper classes. + for (size_t i = 0; i < all_regions.size(); i++) { + scoped_ptr ele(new MinidumpLinuxMaps(minidump_)); + ele->region_ = all_regions[i]; + ele->valid_ = true; + maps->push_back(ele.release()); + } + + // Set instance variables. + maps_ = maps.release(); + maps_count_ = maps_->size(); + valid_ = true; + return true; +} + +void MinidumpLinuxMapsList::Print() { + if (!valid_) { + BPLOG(ERROR) << "MinidumpLinuxMapsList cannot print valid data"; + return; + } + for (size_t i = 0; i < maps_->size(); i++) { + (*maps_)[i]->Print(); + } +} // // Minidump @@ -4292,6 +4430,11 @@ MinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { return GetStream(&memory_info_list); } +MinidumpLinuxMapsList *Minidump::GetLinuxMapsList() { + MinidumpLinuxMapsList *linux_maps_list; + return GetStream(&linux_maps_list); +} + static const char* get_stream_name(uint32_t stream_type) { switch (stream_type) { case MD_UNUSED_STREAM: diff --git a/src/processor/proc_maps_linux.cc b/src/processor/proc_maps_linux.cc new file mode 100644 index 00000000..72947286 --- /dev/null +++ b/src/processor/proc_maps_linux.cc @@ -0,0 +1,103 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "google_breakpad/processor/proc_maps_linux.h" + +#include +#include + +#if defined(OS_LINUX) || defined(OS_ANDROID) +#include +#endif + +#include "processor/logging.h" + +#if defined(OS_ANDROID) && !defined(__LP64__) +// In 32-bit mode, Bionic's inttypes.h defines PRI/SCNxPTR as an +// unsigned long int, which is incompatible with Bionic's stdint.h +// defining uintptr_t as an unsigned int: +// https://code.google.com/p/android/issues/detail?id=57218 +#undef SCNxPTR +#define SCNxPTR "x" +#endif + +namespace google_breakpad { + +bool ParseProcMaps(const std::string& input, + std::vector* regions_out) { + std::vector regions; + + // This isn't async safe nor terribly efficient, but it doesn't need to be at + // this point in time. + + // Split the string by newlines. + std::vector lines; + std::string line = ""; + for (size_t i = 0; i < input.size(); i++) { + if (input[i] != '\n' && input[i] != '\r') { + line.push_back(input[i]); + } else if (line.size() > 0) { + lines.push_back(line); + line.clear(); + } + } + if (line.size() > 0) { + BPLOG(ERROR) << "Input doesn't end in newline"; + return false; + } + + for (size_t i = 0; i < lines.size(); ++i) { + MappedMemoryRegion region; + const char* line = lines[i].c_str(); + char permissions[5] = {'\0'}; // Ensure NUL-terminated string. + int path_index = 0; + + // Sample format from man 5 proc: + // + // address perms offset dev inode pathname + // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm + // + // The final %n term captures the offset in the input string, which is used + // to determine the path name. It *does not* increment the return value. + // Refer to man 3 sscanf for details. + if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4c %lx %hhx:%hhx %ld %n", + ®ion.start, ®ion.end, permissions, ®ion.offset, + ®ion.major_device, ®ion.minor_device, ®ion.inode, + &path_index) < 7) { + BPLOG(ERROR) << "sscanf failed for line: " << line; + return false; + } + + region.permissions = 0; + + if (permissions[0] == 'r') + region.permissions |= MappedMemoryRegion::READ; + else if (permissions[0] != '-') + return false; + + if (permissions[1] == 'w') + region.permissions |= MappedMemoryRegion::WRITE; + else if (permissions[1] != '-') + return false; + + if (permissions[2] == 'x') + region.permissions |= MappedMemoryRegion::EXECUTE; + else if (permissions[2] != '-') + return false; + + if (permissions[3] == 'p') + region.permissions |= MappedMemoryRegion::PRIVATE; + else if (permissions[3] != 's' && permissions[3] != 'S') // Shared memory. + return false; + + // Pushing then assigning saves us a string copy. + regions.push_back(region); + regions.back().path.assign(line + path_index); + } + + regions_out->swap(regions); + return true; +} + +} // namespace google_breakpad diff --git a/src/processor/proc_maps_linux_unittest.cc b/src/processor/proc_maps_linux_unittest.cc new file mode 100644 index 00000000..1ff4b031 --- /dev/null +++ b/src/processor/proc_maps_linux_unittest.cc @@ -0,0 +1,250 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "breakpad_googletest_includes.h" +#include "google_breakpad/processor/proc_maps_linux.h" + +namespace { + +TEST(ProcMapsTest, Empty) { + std::vector regions; + EXPECT_TRUE(ParseProcMaps("", ®ions)); + EXPECT_EQ(0u, regions.size()); +} + +TEST(ProcMapsTest, NoSpaces) { + static const char kNoSpaces[] = + "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/cat\n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kNoSpaces, ®ions)); + ASSERT_EQ(1u, regions.size()); + + EXPECT_EQ(0x00400000u, regions[0].start); + EXPECT_EQ(0x0040b000u, regions[0].end); + EXPECT_EQ(0x00002200u, regions[0].offset); + EXPECT_EQ("/bin/cat", regions[0].path); +} + +TEST(ProcMapsTest, Spaces) { + static const char kSpaces[] = + "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/space cat\n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kSpaces, ®ions)); + ASSERT_EQ(1u, regions.size()); + + EXPECT_EQ(0x00400000u, regions[0].start); + EXPECT_EQ(0x0040b000u, regions[0].end); + EXPECT_EQ(0x00002200u, regions[0].offset); + EXPECT_EQ("/bin/space cat", regions[0].path); +} + +TEST(ProcMapsTest, NoNewline) { + static const char kNoSpaces[] = + "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/cat"; + + std::vector regions; + ASSERT_FALSE(ParseProcMaps(kNoSpaces, ®ions)); +} + +TEST(ProcMapsTest, NoPath) { + static const char kNoPath[] = + "00400000-0040b000 rw-p 00000000 00:00 0 \n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kNoPath, ®ions)); + ASSERT_EQ(1u, regions.size()); + + EXPECT_EQ(0x00400000u, regions[0].start); + EXPECT_EQ(0x0040b000u, regions[0].end); + EXPECT_EQ(0x00000000u, regions[0].offset); + EXPECT_EQ("", regions[0].path); +} + +TEST(ProcMapsTest, Heap) { + static const char kHeap[] = + "022ac000-022cd000 rw-p 00000000 00:00 0 [heap]\n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kHeap, ®ions)); + ASSERT_EQ(1u, regions.size()); + + EXPECT_EQ(0x022ac000u, regions[0].start); + EXPECT_EQ(0x022cd000u, regions[0].end); + EXPECT_EQ(0x00000000u, regions[0].offset); + EXPECT_EQ("[heap]", regions[0].path); +} + +#if defined(ARCH_CPU_32_BITS) +TEST(ProcMapsTest, Stack32) { + static const char kStack[] = + "beb04000-beb25000 rw-p 00000000 00:00 0 [stack]\n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kStack, ®ions)); + ASSERT_EQ(1u, regions.size()); + + EXPECT_EQ(0xbeb04000u, regions[0].start); + EXPECT_EQ(0xbeb25000u, regions[0].end); + EXPECT_EQ(0x00000000u, regions[0].offset); + EXPECT_EQ("[stack]", regions[0].path); +} +#elif defined(ARCH_CPU_64_BITS) +TEST(ProcMapsTest, Stack64) { + static const char kStack[] = + "7fff69c5b000-7fff69c7d000 rw-p 00000000 00:00 0 [stack]\n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kStack, ®ions)); + ASSERT_EQ(1u, regions.size()); + + EXPECT_EQ(0x7fff69c5b000u, regions[0].start); + EXPECT_EQ(0x7fff69c7d000u, regions[0].end); + EXPECT_EQ(0x00000000u, regions[0].offset); + EXPECT_EQ("[stack]", regions[0].path); +} +#endif + +TEST(ProcMapsTest, Multiple) { + static const char kMultiple[] = + "00400000-0040b000 r-xp 00000000 fc:00 794418 /bin/cat\n" + "0060a000-0060b000 r--p 0000a000 fc:00 794418 /bin/cat\n" + "0060b000-0060c000 rw-p 0000b000 fc:00 794418 /bin/cat\n"; + + std::vector regions; + ASSERT_TRUE(ParseProcMaps(kMultiple, ®ions)); + ASSERT_EQ(3u, regions.size()); + + EXPECT_EQ(0x00400000u, regions[0].start); + EXPECT_EQ(0x0040b000u, regions[0].end); + EXPECT_EQ(0x00000000u, regions[0].offset); + EXPECT_EQ("/bin/cat", regions[0].path); + + EXPECT_EQ(0x0060a000u, regions[1].start); + EXPECT_EQ(0x0060b000u, regions[1].end); + EXPECT_EQ(0x0000a000u, regions[1].offset); + EXPECT_EQ("/bin/cat", regions[1].path); + + EXPECT_EQ(0x0060b000u, regions[2].start); + EXPECT_EQ(0x0060c000u, regions[2].end); + EXPECT_EQ(0x0000b000u, regions[2].offset); + EXPECT_EQ("/bin/cat", regions[2].path); +} + +TEST(ProcMapsTest, Permissions) { + static struct { + const char* input; + uint8_t permissions; + } kTestCases[] = { + {"00400000-0040b000 ---s 00000000 fc:00 794418 /bin/cat\n", 0}, + {"00400000-0040b000 ---S 00000000 fc:00 794418 /bin/cat\n", 0}, + {"00400000-0040b000 r--s 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::READ}, + {"00400000-0040b000 -w-s 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::WRITE}, + {"00400000-0040b000 --xs 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::EXECUTE}, + {"00400000-0040b000 rwxs 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::READ + | google_breakpad::MappedMemoryRegion::WRITE + | google_breakpad::MappedMemoryRegion::EXECUTE}, + {"00400000-0040b000 ---p 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::PRIVATE}, + {"00400000-0040b000 r--p 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::READ + | google_breakpad::MappedMemoryRegion::PRIVATE}, + {"00400000-0040b000 -w-p 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::WRITE + | google_breakpad::MappedMemoryRegion::PRIVATE}, + {"00400000-0040b000 --xp 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::EXECUTE + | google_breakpad::MappedMemoryRegion::PRIVATE}, + {"00400000-0040b000 rwxp 00000000 fc:00 794418 /bin/cat\n", + google_breakpad::MappedMemoryRegion::READ + | google_breakpad::MappedMemoryRegion::WRITE + | google_breakpad::MappedMemoryRegion::EXECUTE + | google_breakpad::MappedMemoryRegion::PRIVATE}, + }; + + for (size_t i = 0; i < sizeof(kTestCases) / sizeof(kTestCases[0]); ++i) { + std::vector regions; + EXPECT_TRUE(ParseProcMaps(kTestCases[i].input, ®ions)); + EXPECT_EQ(1u, regions.size()); + if (regions.empty()) + continue; + EXPECT_EQ(kTestCases[i].permissions, regions[0].permissions); + } +} + +TEST(ProcMapsTest, MissingFields) { + static const char* kTestCases[] = { + "00400000\n", // Missing end + beyond. + "00400000-0040b000\n", // Missing perms + beyond. + "00400000-0040b000 r-xp\n", // Missing offset + beyond. + "00400000-0040b000 r-xp 00000000\n", // Missing device + beyond. + "00400000-0040b000 r-xp 00000000 fc:00\n", // Missing inode + beyond. + "00400000-0040b000 00000000 fc:00 794418 /bin/cat\n", // Missing perms. + "00400000-0040b000 r-xp fc:00 794418 /bin/cat\n", // Missing offset. + "00400000-0040b000 r-xp 00000000 fc:00 /bin/cat\n", // Missing inode. + "00400000 r-xp 00000000 fc:00 794418 /bin/cat\n", // Missing end. + "-0040b000 r-xp 00000000 fc:00 794418 /bin/cat\n", // Missing start. + "00400000-0040b000 r-xp 00000000 794418 /bin/cat\n", // Missing device. + }; + + for (size_t i = 0; i < sizeof(kTestCases) / sizeof(kTestCases[0]); ++i) { + std::vector regions; + EXPECT_FALSE(ParseProcMaps(kTestCases[i], ®ions)); + } +} + +TEST(ProcMapsTest, InvalidInput) { + static const char* kTestCases[] = { + "thisisal-0040b000 rwxp 00000000 fc:00 794418 /bin/cat\n", + "0040000d-linvalid rwxp 00000000 fc:00 794418 /bin/cat\n", + "00400000-0040b000 inpu 00000000 fc:00 794418 /bin/cat\n", + "00400000-0040b000 rwxp tforproc fc:00 794418 /bin/cat\n", + "00400000-0040b000 rwxp 00000000 ma:ps 794418 /bin/cat\n", + "00400000-0040b000 rwxp 00000000 fc:00 parse! /bin/cat\n", + }; + + for (size_t i = 0; i < sizeof(kTestCases) / sizeof(kTestCases[0]); ++i) { + std::vector regions; + EXPECT_FALSE(ParseProcMaps(kTestCases[i], ®ions)); + } +} + +TEST(ProcMapsTest, ParseProcMapsEmptyString) { + std::vector regions; + EXPECT_TRUE(ParseProcMaps("", ®ions)); + EXPECT_EQ(0ULL, regions.size()); +} + +// Testing a couple of remotely possible weird things in the input: +// - Line ending with \r\n or \n\r. +// - File name contains quotes. +// - File name has whitespaces. +TEST(ProcMapsTest, ParseProcMapsWeirdCorrectInput) { + std::vector regions; + const std::string kContents = + "00400000-0040b000 r-xp 00000000 fc:00 2106562 " + " /bin/cat\r\n" + "7f53b7dad000-7f53b7f62000 r-xp 00000000 fc:00 263011 " + " /lib/x86_64-linux-gnu/libc-2.15.so\n\r" + "7f53b816d000-7f53b818f000 r-xp 00000000 fc:00 264284 " + " /lib/x86_64-linux-gnu/ld-2.15.so\n" + "7fff9c7ff000-7fff9c800000 r-xp 00000000 00:00 0 " + " \"vd so\"\n" + "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 " + " [vsys call]\n"; + EXPECT_TRUE(ParseProcMaps(kContents, ®ions)); + EXPECT_EQ(5ULL, regions.size()); + EXPECT_EQ("/bin/cat", regions[0].path); + EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); + EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); + EXPECT_EQ("\"vd so\"", regions[3].path); + EXPECT_EQ("[vsys call]", regions[4].path); +} + +} // namespace diff --git a/src/processor/testdata/linux_in_module_outside_executable_part.dmp b/src/processor/testdata/linux_in_module_outside_executable_part.dmp deleted file mode 100644 index 23fcc50589ed56ee95ba336542827769ecf50f0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49096 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 CQwm1_ diff --git a/src/processor/testdata/linux_inside_elf_header.dmp b/src/processor/testdata/linux_inside_elf_header.dmp deleted file mode 100644 index 96b6acef167a7fcaf1a7b193276e1282de012d8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52616 zcmeHw3zQpImEiL)u@xK}HUSepsU%Kt2;C}u`{Pm4a<|;2xIaouZMU5mxg?d;a_du3 zmAciQKn#iZL~G1?U=ABtb};NLWHLZJuz)c?6KCQC4rd)$z!}c$7!IEn38a@_JOuFG z`#w^sy4ArXSvZbfw{+{?cYp7`PgOlty*E5C9C`1@2w6)Ak>G>r+HL=1oE;Ie0uH?J zIRT%Q@JRt-y++6?INk^!Jx9nT03U$Q{cwCKz;5{T_#G!98wx0!8TK~-FNYOk)(g=>EGWC^ghrJ;4~DVZx0+mirmTaKKSL+*FOn7Lc@a(e)nydFK{dm zroPBL<$LvG4Stl{&uy$9{Upsl%=Ic$41e&g&r((UIsHV>FDM_=3NgQp>3z)0=-*n? zN3#wWnEd^#8ID9$)B#_@H>4>gRt`x(u21kt8q@oj%HZET&iqGNOv1k4XViubAt&hP zcsT@amlO6x97MTATt)fLLlQa=ig<}Qh&*UIWJVwW|Bc%he)N@9ntK;~V|@sJ-^68< zYx?Ms)WP7~os6GnlfwpYBb*@0bB5D*T=_&(`w(&h3cq#EFXZMpe&qosFZcx%`~u%o zVty&}YpDy%d4?!YFUOt!K6L;H5+NKcC*?%D($g|DVrgjw@$B z{`28KWQ4pO%2xy_N!Uf3i=|ff*7A6tC^|_ymV%IdpuC@xPA4aSp2-9^

)exJi%a=7XrnI0d9 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