Breakpad Processor: Add new unit tests for google_breakpad::Minidump

This also adds two new test utility class groups, TestAssembler and
SynthMinidump. These are overkill for what I'm doing with them here
(and may simply be overkill, period), but they make it easy to write
unit tests for code that works on binary files or raw memory contents
in a cross-platform way. I'm planning to use them for the DWARF CFI
unwinding tests and the DWARF CFI parser tests.

a=jimblandy, r=nealsid


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@547 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
jimblandy 2010-03-16 16:20:34 +00:00
parent 5431f41508
commit 9244496c6f
10 changed files with 4473 additions and 13 deletions

View file

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
# Copyright (c) 2006, Google Inc.
# Copyright (c) 2010, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -135,7 +135,9 @@ check_PROGRAMS = \
src/processor/minidump_unittest \
src/processor/pathname_stripper_unittest \
src/processor/postfix_evaluator_unittest \
src/processor/range_map_unittest
src/processor/range_map_unittest \
src/processor/synth_minidump_unittest \
src/processor/test_assembler_unittest
if SELFTEST
check_PROGRAMS += \
@ -230,7 +232,10 @@ src_processor_minidump_processor_unittest_LDADD = \
src_processor_minidump_unittest_SOURCES = \
src/processor/minidump_unittest.cc \
src/processor/synth_minidump.cc \
src/processor/test_assembler.cc \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc
src_processor_minidump_unittest_CPPFLAGS = \
-I$(top_srcdir)/src/testing/include \
@ -276,6 +281,34 @@ src_processor_stackwalker_selftest_LDADD = \
src/processor/stackwalker_sparc.lo \
src/processor/stackwalker_x86.lo
src_processor_synth_minidump_unittest_SOURCES = \
src/processor/synth_minidump_unittest.cc \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc \
src/processor/synth_minidump.cc \
src/processor/synth_minidump.h \
src/processor/test_assembler.cc \
src/processor/test_assembler.h
src_processor_synth_minidump_unittest_CPPFLAGS = \
-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_test_assembler_unittest_SOURCES = \
src/processor/test_assembler_unittest.cc \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc \
src/processor/test_assembler.cc \
src/processor/test_assembler.h
src_processor_test_assembler_unittest_CPPFLAGS = \
-I$(top_srcdir)/src/testing/include \
-I$(top_srcdir)/src/testing/gtest/include \
-I$(top_srcdir)/src/testing/gtest \
-I$(top_srcdir)/src/testing
## Non-installables
noinst_PROGRAMS =
noinst_SCRIPTS = $(check_SCRIPTS)

View file

@ -15,7 +15,7 @@
@SET_MAKE@
# Copyright (c) 2006, Google Inc.
# Copyright (c) 2010, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -77,7 +77,9 @@ check_PROGRAMS = src/client/linux/linux_client_unittest$(EXEEXT) \
src/processor/minidump_unittest$(EXEEXT) \
src/processor/pathname_stripper_unittest$(EXEEXT) \
src/processor/postfix_evaluator_unittest$(EXEEXT) \
src/processor/range_map_unittest$(EXEEXT) $(am__EXEEXT_1)
src/processor/range_map_unittest$(EXEEXT) \
src/processor/synth_minidump_unittest$(EXEEXT) \
src/processor/test_assembler_unittest$(EXEEXT) $(am__EXEEXT_1)
@SELFTEST_TRUE@am__append_1 = \
@SELFTEST_TRUE@ src/processor/stackwalker_selftest
@ -236,7 +238,10 @@ src_processor_minidump_stackwalk_DEPENDENCIES = \
src/processor/stackwalker_sparc.lo \
src/processor/stackwalker_x86.lo
am_src_processor_minidump_unittest_OBJECTS = src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT) \
src/processor/src_processor_minidump_unittest-synth_minidump.$(OBJEXT) \
src/processor/src_processor_minidump_unittest-test_assembler.$(OBJEXT) \
src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT) \
src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.$(OBJEXT) \
src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT)
src_processor_minidump_unittest_OBJECTS = \
$(am_src_processor_minidump_unittest_OBJECTS)
@ -276,6 +281,23 @@ src_processor_stackwalker_selftest_DEPENDENCIES = \
src/processor/stackwalker_ppc.lo \
src/processor/stackwalker_sparc.lo \
src/processor/stackwalker_x86.lo
am_src_processor_synth_minidump_unittest_OBJECTS = src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.$(OBJEXT) \
src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.$(OBJEXT) \
src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.$(OBJEXT) \
src/testing/src/src_processor_synth_minidump_unittest-gmock-all.$(OBJEXT) \
src/processor/src_processor_synth_minidump_unittest-synth_minidump.$(OBJEXT) \
src/processor/src_processor_synth_minidump_unittest-test_assembler.$(OBJEXT)
src_processor_synth_minidump_unittest_OBJECTS = \
$(am_src_processor_synth_minidump_unittest_OBJECTS)
src_processor_synth_minidump_unittest_LDADD = $(LDADD)
am_src_processor_test_assembler_unittest_OBJECTS = src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.$(OBJEXT) \
src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.$(OBJEXT) \
src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.$(OBJEXT) \
src/testing/src/src_processor_test_assembler_unittest-gmock-all.$(OBJEXT) \
src/processor/src_processor_test_assembler_unittest-test_assembler.$(OBJEXT)
src_processor_test_assembler_unittest_OBJECTS = \
$(am_src_processor_test_assembler_unittest_OBJECTS)
src_processor_test_assembler_unittest_LDADD = $(LDADD)
SCRIPTS = $(noinst_SCRIPTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp
@ -313,7 +335,9 @@ SOURCES = $(src_client_linux_libbreakpad_client_la_SOURCES) \
$(src_processor_pathname_stripper_unittest_SOURCES) \
$(src_processor_postfix_evaluator_unittest_SOURCES) \
$(src_processor_range_map_unittest_SOURCES) \
$(src_processor_stackwalker_selftest_SOURCES)
$(src_processor_stackwalker_selftest_SOURCES) \
$(src_processor_synth_minidump_unittest_SOURCES) \
$(src_processor_test_assembler_unittest_SOURCES)
DIST_SOURCES = $(src_client_linux_libbreakpad_client_la_SOURCES) \
$(src_libbreakpad_la_SOURCES) \
$(src_client_linux_linux_client_unittest_SOURCES) \
@ -328,7 +352,9 @@ DIST_SOURCES = $(src_client_linux_libbreakpad_client_la_SOURCES) \
$(src_processor_pathname_stripper_unittest_SOURCES) \
$(src_processor_postfix_evaluator_unittest_SOURCES) \
$(src_processor_range_map_unittest_SOURCES) \
$(src_processor_stackwalker_selftest_SOURCES)
$(src_processor_stackwalker_selftest_SOURCES) \
$(src_processor_synth_minidump_unittest_SOURCES) \
$(src_processor_test_assembler_unittest_SOURCES)
DATA = $(dist_doc_DATA)
ETAGS = etags
CTAGS = ctags
@ -641,7 +667,10 @@ src_processor_minidump_processor_unittest_LDADD = \
src_processor_minidump_unittest_SOURCES = \
src/processor/minidump_unittest.cc \
src/processor/synth_minidump.cc \
src/processor/test_assembler.cc \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc
src_processor_minidump_unittest_CPPFLAGS = \
@ -693,6 +722,36 @@ src_processor_stackwalker_selftest_LDADD = \
src/processor/stackwalker_sparc.lo \
src/processor/stackwalker_x86.lo
src_processor_synth_minidump_unittest_SOURCES = \
src/processor/synth_minidump_unittest.cc \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc \
src/processor/synth_minidump.cc \
src/processor/synth_minidump.h \
src/processor/test_assembler.cc \
src/processor/test_assembler.h
src_processor_synth_minidump_unittest_CPPFLAGS = \
-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_test_assembler_unittest_SOURCES = \
src/processor/test_assembler_unittest.cc \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc \
src/processor/test_assembler.cc \
src/processor/test_assembler.h
src_processor_test_assembler_unittest_CPPFLAGS = \
-I$(top_srcdir)/src/testing/include \
-I$(top_srcdir)/src/testing/gtest/include \
-I$(top_srcdir)/src/testing/gtest \
-I$(top_srcdir)/src/testing
noinst_SCRIPTS = $(check_SCRIPTS)
src_processor_minidump_dump_SOURCES = \
src/processor/minidump_dump.cc
@ -1198,9 +1257,18 @@ src/processor/minidump_stackwalk$(EXEEXT): $(src_processor_minidump_stackwalk_OB
src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/src_processor_minidump_unittest-synth_minidump.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/src_processor_minidump_unittest-test_assembler.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT): \
src/testing/gtest/src/$(am__dirstamp) \
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.$(OBJEXT): \
src/testing/gtest/src/$(am__dirstamp) \
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT): \
src/testing/src/$(am__dirstamp) \
src/testing/src/$(DEPDIR)/$(am__dirstamp)
@ -1231,6 +1299,45 @@ src/processor/stackwalker_selftest.$(OBJEXT): \
src/processor/stackwalker_selftest$(EXEEXT): $(src_processor_stackwalker_selftest_OBJECTS) $(src_processor_stackwalker_selftest_DEPENDENCIES) src/processor/$(am__dirstamp)
@rm -f src/processor/stackwalker_selftest$(EXEEXT)
$(CXXLINK) $(src_processor_stackwalker_selftest_OBJECTS) $(src_processor_stackwalker_selftest_LDADD) $(LIBS)
src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.$(OBJEXT): \
src/testing/gtest/src/$(am__dirstamp) \
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.$(OBJEXT): \
src/testing/gtest/src/$(am__dirstamp) \
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
src/testing/src/src_processor_synth_minidump_unittest-gmock-all.$(OBJEXT): \
src/testing/src/$(am__dirstamp) \
src/testing/src/$(DEPDIR)/$(am__dirstamp)
src/processor/src_processor_synth_minidump_unittest-synth_minidump.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/src_processor_synth_minidump_unittest-test_assembler.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/synth_minidump_unittest$(EXEEXT): $(src_processor_synth_minidump_unittest_OBJECTS) $(src_processor_synth_minidump_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
@rm -f src/processor/synth_minidump_unittest$(EXEEXT)
$(CXXLINK) $(src_processor_synth_minidump_unittest_OBJECTS) $(src_processor_synth_minidump_unittest_LDADD) $(LIBS)
src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.$(OBJEXT): \
src/testing/gtest/src/$(am__dirstamp) \
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.$(OBJEXT): \
src/testing/gtest/src/$(am__dirstamp) \
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
src/testing/src/src_processor_test_assembler_unittest-gmock-all.$(OBJEXT): \
src/testing/src/$(am__dirstamp) \
src/testing/src/$(DEPDIR)/$(am__dirstamp)
src/processor/src_processor_test_assembler_unittest-test_assembler.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/test_assembler_unittest$(EXEEXT): $(src_processor_test_assembler_unittest_OBJECTS) $(src_processor_test_assembler_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
@rm -f src/processor/test_assembler_unittest$(EXEEXT)
$(CXXLINK) $(src_processor_test_assembler_unittest_OBJECTS) $(src_processor_test_assembler_unittest_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -1288,6 +1395,13 @@ mostlyclean-compile:
-rm -f src/processor/simple_symbol_supplier.lo
-rm -f src/processor/src_processor_minidump_processor_unittest-minidump_processor_unittest.$(OBJEXT)
-rm -f src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT)
-rm -f src/processor/src_processor_minidump_unittest-synth_minidump.$(OBJEXT)
-rm -f src/processor/src_processor_minidump_unittest-test_assembler.$(OBJEXT)
-rm -f src/processor/src_processor_synth_minidump_unittest-synth_minidump.$(OBJEXT)
-rm -f src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.$(OBJEXT)
-rm -f src/processor/src_processor_synth_minidump_unittest-test_assembler.$(OBJEXT)
-rm -f src/processor/src_processor_test_assembler_unittest-test_assembler.$(OBJEXT)
-rm -f src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.$(OBJEXT)
-rm -f src/processor/stackwalker.$(OBJEXT)
-rm -f src/processor/stackwalker.lo
-rm -f src/processor/stackwalker_amd64.$(OBJEXT)
@ -1305,9 +1419,16 @@ mostlyclean-compile:
-rm -f src/testing/gtest/src/src_client_linux_linux_client_unittest-gtest_main.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_minidump_processor_unittest-gtest-all.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.$(OBJEXT)
-rm -f src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.$(OBJEXT)
-rm -f src/testing/src/src_client_linux_linux_client_unittest-gmock-all.$(OBJEXT)
-rm -f src/testing/src/src_processor_minidump_processor_unittest-gmock-all.$(OBJEXT)
-rm -f src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT)
-rm -f src/testing/src/src_processor_synth_minidump_unittest-gmock-all.$(OBJEXT)
-rm -f src/testing/src/src_processor_test_assembler_unittest-gmock-all.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@ -1347,6 +1468,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/simple_symbol_supplier.Plo@am__quote@
@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_minidump_unittest-test_assembler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_amd64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_arm.Plo@am__quote@
@ -1358,9 +1486,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_client_linux_linux_client_unittest-gtest_main.Po@am__quote@
@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_synth_minidump_unittest-gtest-all.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_client_linux_linux_client_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_synth_minidump_unittest-gmock-all.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -1592,6 +1727,34 @@ src/processor/src_processor_minidump_unittest-minidump_unittest.obj: src/process
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-minidump_unittest.obj `if test -f 'src/processor/minidump_unittest.cc'; then $(CYGPATH_W) 'src/processor/minidump_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/minidump_unittest.cc'; fi`
src/processor/src_processor_minidump_unittest-synth_minidump.o: src/processor/synth_minidump.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_minidump_unittest-synth_minidump.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Tpo -c -o src/processor/src_processor_minidump_unittest-synth_minidump.o `test -f 'src/processor/synth_minidump.cc' || echo '$(srcdir)/'`src/processor/synth_minidump.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Tpo src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/synth_minidump.cc' object='src/processor/src_processor_minidump_unittest-synth_minidump.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-synth_minidump.o `test -f 'src/processor/synth_minidump.cc' || echo '$(srcdir)/'`src/processor/synth_minidump.cc
src/processor/src_processor_minidump_unittest-synth_minidump.obj: src/processor/synth_minidump.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_minidump_unittest-synth_minidump.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Tpo -c -o src/processor/src_processor_minidump_unittest-synth_minidump.obj `if test -f 'src/processor/synth_minidump.cc'; then $(CYGPATH_W) 'src/processor/synth_minidump.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/synth_minidump.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Tpo src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/synth_minidump.cc' object='src/processor/src_processor_minidump_unittest-synth_minidump.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-synth_minidump.obj `if test -f 'src/processor/synth_minidump.cc'; then $(CYGPATH_W) 'src/processor/synth_minidump.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/synth_minidump.cc'; fi`
src/processor/src_processor_minidump_unittest-test_assembler.o: src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_minidump_unittest-test_assembler.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Tpo -c -o src/processor/src_processor_minidump_unittest-test_assembler.o `test -f 'src/processor/test_assembler.cc' || echo '$(srcdir)/'`src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Tpo src/processor/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler.cc' object='src/processor/src_processor_minidump_unittest-test_assembler.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-test_assembler.o `test -f 'src/processor/test_assembler.cc' || echo '$(srcdir)/'`src/processor/test_assembler.cc
src/processor/src_processor_minidump_unittest-test_assembler.obj: src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_minidump_unittest-test_assembler.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Tpo -c -o src/processor/src_processor_minidump_unittest-test_assembler.obj `if test -f 'src/processor/test_assembler.cc'; then $(CYGPATH_W) 'src/processor/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Tpo src/processor/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler.cc' object='src/processor/src_processor_minidump_unittest-test_assembler.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-test_assembler.obj `if test -f 'src/processor/test_assembler.cc'; then $(CYGPATH_W) 'src/processor/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler.cc'; fi`
src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o: src/testing/gtest/src/gtest-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Po
@ -1606,6 +1769,20 @@ src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.obj: src/testing
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_minidump_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_minidump_unittest-gtest_main.o: src/testing/gtest/src/gtest_main.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_minidump_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_minidump_unittest-gtest_main.obj: src/testing/gtest/src/gtest_main.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest_main.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_minidump_unittest-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_minidump_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_minidump_unittest-gmock-all.o: src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_minidump_unittest-gmock-all.o -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_minidump_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Po
@ -1620,6 +1797,160 @@ 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@ $(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_synth_minidump_unittest-synth_minidump_unittest.o: src/processor/synth_minidump_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Tpo -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.o `test -f 'src/processor/synth_minidump_unittest.cc' || echo '$(srcdir)/'`src/processor/synth_minidump_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Tpo src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/synth_minidump_unittest.cc' object='src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.o `test -f 'src/processor/synth_minidump_unittest.cc' || echo '$(srcdir)/'`src/processor/synth_minidump_unittest.cc
src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.obj: src/processor/synth_minidump_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Tpo -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.obj `if test -f 'src/processor/synth_minidump_unittest.cc'; then $(CYGPATH_W) 'src/processor/synth_minidump_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/synth_minidump_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Tpo src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/synth_minidump_unittest.cc' object='src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump_unittest.obj `if test -f 'src/processor/synth_minidump_unittest.cc'; then $(CYGPATH_W) 'src/processor/synth_minidump_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/synth_minidump_unittest.cc'; fi`
src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.o: src/testing/gtest/src/gtest-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_synth_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_synth_minidump_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_synth_minidump_unittest-gtest-all.obj: src/testing/gtest/src/gtest-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_synth_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_synth_minidump_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_synth_minidump_unittest-gtest_main.o: src/testing/gtest/src/gtest_main.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_synth_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_synth_minidump_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_synth_minidump_unittest-gtest_main.obj: src/testing/gtest/src/gtest_main.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_synth_minidump_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gtest_main.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_synth_minidump_unittest-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_synth_minidump_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_synth_minidump_unittest-gmock-all.o: src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_synth_minidump_unittest-gmock-all.o -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_synth_minidump_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gmock-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_synth_minidump_unittest-gmock-all.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_synth_minidump_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_synth_minidump_unittest-gmock-all.obj: src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_synth_minidump_unittest-gmock-all.obj -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_synth_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`
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_synth_minidump_unittest-gmock-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_synth_minidump_unittest-gmock-all.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_synth_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_synth_minidump_unittest-synth_minidump.o: src/processor/synth_minidump.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_synth_minidump_unittest-synth_minidump.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Tpo -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump.o `test -f 'src/processor/synth_minidump.cc' || echo '$(srcdir)/'`src/processor/synth_minidump.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Tpo src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/synth_minidump.cc' object='src/processor/src_processor_synth_minidump_unittest-synth_minidump.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump.o `test -f 'src/processor/synth_minidump.cc' || echo '$(srcdir)/'`src/processor/synth_minidump.cc
src/processor/src_processor_synth_minidump_unittest-synth_minidump.obj: src/processor/synth_minidump.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_synth_minidump_unittest-synth_minidump.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Tpo -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump.obj `if test -f 'src/processor/synth_minidump.cc'; then $(CYGPATH_W) 'src/processor/synth_minidump.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/synth_minidump.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Tpo src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-synth_minidump.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/synth_minidump.cc' object='src/processor/src_processor_synth_minidump_unittest-synth_minidump.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_synth_minidump_unittest-synth_minidump.obj `if test -f 'src/processor/synth_minidump.cc'; then $(CYGPATH_W) 'src/processor/synth_minidump.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/synth_minidump.cc'; fi`
src/processor/src_processor_synth_minidump_unittest-test_assembler.o: src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_synth_minidump_unittest-test_assembler.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Tpo -c -o src/processor/src_processor_synth_minidump_unittest-test_assembler.o `test -f 'src/processor/test_assembler.cc' || echo '$(srcdir)/'`src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Tpo src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler.cc' object='src/processor/src_processor_synth_minidump_unittest-test_assembler.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_synth_minidump_unittest-test_assembler.o `test -f 'src/processor/test_assembler.cc' || echo '$(srcdir)/'`src/processor/test_assembler.cc
src/processor/src_processor_synth_minidump_unittest-test_assembler.obj: src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_synth_minidump_unittest-test_assembler.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Tpo -c -o src/processor/src_processor_synth_minidump_unittest-test_assembler.obj `if test -f 'src/processor/test_assembler.cc'; then $(CYGPATH_W) 'src/processor/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Tpo src/processor/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler.cc' object='src/processor/src_processor_synth_minidump_unittest-test_assembler.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_synth_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_synth_minidump_unittest-test_assembler.obj `if test -f 'src/processor/test_assembler.cc'; then $(CYGPATH_W) 'src/processor/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler.cc'; fi`
src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.o: src/processor/test_assembler_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Tpo -c -o src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.o `test -f 'src/processor/test_assembler_unittest.cc' || echo '$(srcdir)/'`src/processor/test_assembler_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Tpo src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler_unittest.cc' object='src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.o `test -f 'src/processor/test_assembler_unittest.cc' || echo '$(srcdir)/'`src/processor/test_assembler_unittest.cc
src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.obj: src/processor/test_assembler_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Tpo -c -o src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.obj `if test -f 'src/processor/test_assembler_unittest.cc'; then $(CYGPATH_W) 'src/processor/test_assembler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Tpo src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler_unittest.cc' object='src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_test_assembler_unittest-test_assembler_unittest.obj `if test -f 'src/processor/test_assembler_unittest.cc'; then $(CYGPATH_W) 'src/processor/test_assembler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler_unittest.cc'; fi`
src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.o: src/testing/gtest/src/gtest-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_test_assembler_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_test_assembler_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_test_assembler_unittest-gtest-all.obj: src/testing/gtest/src/gtest-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_test_assembler_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_test_assembler_unittest-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_test_assembler_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_test_assembler_unittest-gtest_main.o: src/testing/gtest/src/gtest_main.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_test_assembler_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_test_assembler_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_test_assembler_unittest-gtest_main.obj: src/testing/gtest/src/gtest_main.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Tpo -c -o src/testing/gtest/src/src_processor_test_assembler_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__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_test_assembler_unittest-gtest_main.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest_main.cc' object='src/testing/gtest/src/src_processor_test_assembler_unittest-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_test_assembler_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_test_assembler_unittest-gmock-all.o: src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_test_assembler_unittest-gmock-all.o -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_test_assembler_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_test_assembler_unittest-gmock-all.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_test_assembler_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_test_assembler_unittest-gmock-all.obj: src/testing/src/gmock-all.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_test_assembler_unittest-gmock-all.obj -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_test_assembler_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__mv) src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_test_assembler_unittest-gmock-all.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_test_assembler_unittest-gmock-all.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_test_assembler_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_test_assembler_unittest-test_assembler.o: src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_test_assembler_unittest-test_assembler.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Tpo -c -o src/processor/src_processor_test_assembler_unittest-test_assembler.o `test -f 'src/processor/test_assembler.cc' || echo '$(srcdir)/'`src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Tpo src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler.cc' object='src/processor/src_processor_test_assembler_unittest-test_assembler.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_test_assembler_unittest-test_assembler.o `test -f 'src/processor/test_assembler.cc' || echo '$(srcdir)/'`src/processor/test_assembler.cc
src/processor/src_processor_test_assembler_unittest-test_assembler.obj: src/processor/test_assembler.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_test_assembler_unittest-test_assembler.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Tpo -c -o src/processor/src_processor_test_assembler_unittest-test_assembler.obj `if test -f 'src/processor/test_assembler.cc'; then $(CYGPATH_W) 'src/processor/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Tpo src/processor/$(DEPDIR)/src_processor_test_assembler_unittest-test_assembler.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/test_assembler.cc' object='src/processor/src_processor_test_assembler_unittest-test_assembler.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_test_assembler_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_test_assembler_unittest-test_assembler.obj `if test -f 'src/processor/test_assembler.cc'; then $(CYGPATH_W) 'src/processor/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/test_assembler.cc'; fi`
mostlyclean-libtool:
-rm -f *.lo

View file

@ -1,4 +1,4 @@
// Copyright (c) 2009, Google Inc.
// Copyright (c) 2010, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -30,20 +30,39 @@
// Unit test for Minidump. Uses a pre-generated minidump and
// verifies that certain streams are correct.
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>
#include "breakpad_googletest_includes.h"
#include "google_breakpad/common/minidump_format.h"
#include "google_breakpad/processor/minidump.h"
#include "processor/logging.h"
#include "processor/synth_minidump.h"
namespace {
using google_breakpad::Minidump;
using google_breakpad::MinidumpContext;
using google_breakpad::MinidumpMemoryList;
using google_breakpad::MinidumpMemoryRegion;
using google_breakpad::MinidumpModule;
using google_breakpad::MinidumpModuleList;
using google_breakpad::MinidumpSystemInfo;
using google_breakpad::MinidumpThread;
using google_breakpad::MinidumpThreadList;
using google_breakpad::SynthMinidump::Context;
using google_breakpad::SynthMinidump::Dump;
using google_breakpad::SynthMinidump::Memory;
using google_breakpad::SynthMinidump::Module;
using google_breakpad::SynthMinidump::Stream;
using google_breakpad::SynthMinidump::String;
using google_breakpad::SynthMinidump::SystemInfo;
using google_breakpad::SynthMinidump::Thread;
using google_breakpad::TestAssembler::kBigEndian;
using google_breakpad::TestAssembler::kLittleEndian;
using std::ifstream;
using std::istringstream;
using std::string;
@ -95,9 +114,421 @@ TEST_F(MinidumpTest, TestMinidumpFromStream) {
//TODO: add more checks here
}
} // namespace
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
TEST(Dump, ReadBackEmpty) {
Dump dump(0);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream stream(contents);
Minidump minidump(stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
}
TEST(Dump, ReadBackEmptyBigEndian) {
Dump big_minidump(0, kBigEndian);
big_minidump.Finish();
string contents;
ASSERT_TRUE(big_minidump.GetContents(&contents));
istringstream stream(contents);
Minidump minidump(stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
}
TEST(Dump, OneStream) {
Dump dump(0, kBigEndian);
Stream stream(dump, 0xfbb7fa2bU);
stream.Append("stream contents");
dump.Add(&stream);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
ASSERT_TRUE(dir != NULL);
EXPECT_EQ(0xfbb7fa2bU, dir->stream_type);
u_int32_t stream_length;
ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length));
ASSERT_EQ(15U, stream_length);
char stream_contents[15];
ASSERT_TRUE(minidump.ReadBytes(stream_contents, sizeof(stream_contents)));
EXPECT_EQ(string("stream contents"),
string(stream_contents, sizeof(stream_contents)));
EXPECT_FALSE(minidump.GetThreadList());
EXPECT_FALSE(minidump.GetModuleList());
EXPECT_FALSE(minidump.GetMemoryList());
EXPECT_FALSE(minidump.GetException());
EXPECT_FALSE(minidump.GetAssertion());
EXPECT_FALSE(minidump.GetSystemInfo());
EXPECT_FALSE(minidump.GetMiscInfo());
EXPECT_FALSE(minidump.GetBreakpadInfo());
}
TEST(Dump, OneMemory) {
Dump dump(0, kBigEndian);
Memory memory(dump, 0x309d68010bd21b2cULL);
memory.Append("memory contents");
dump.Add(&memory);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
ASSERT_TRUE(dir != NULL);
EXPECT_EQ((u_int32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);
MinidumpMemoryList *memory_list = minidump.GetMemoryList();
ASSERT_TRUE(memory_list != NULL);
ASSERT_EQ(1U, memory_list->region_count());
MinidumpMemoryRegion *region1 = memory_list->GetMemoryRegionAtIndex(0);
ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase());
ASSERT_EQ(15U, region1->GetSize());
const u_int8_t *region1_bytes = region1->GetMemory();
ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0);
}
// One thread --- and its requisite entourage.
TEST(Dump, OneThread) {
Dump dump(0, kLittleEndian);
Memory stack(dump, 0x2326a0fa);
stack.Append("stack for thread");
MDRawContextX86 raw_context;
raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
raw_context.edi = 0x3ecba80d;
raw_context.esi = 0x382583b9;
raw_context.ebx = 0x7fccc03f;
raw_context.edx = 0xf62f8ec2;
raw_context.ecx = 0x46a6a6a8;
raw_context.eax = 0x6a5025e2;
raw_context.ebp = 0xd9fabb4a;
raw_context.eip = 0x6913f540;
raw_context.cs = 0xbffe6eda;
raw_context.eflags = 0xb2ce1e2d;
raw_context.esp = 0x659caaa4;
raw_context.ss = 0x2e951ef7;
Context context(dump, raw_context);
Thread thread(dump, 0xa898f11b, stack, context,
0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
dump.Add(&stack);
dump.Add(&context);
dump.Add(&thread);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
MinidumpMemoryList *md_memory_list = minidump.GetMemoryList();
ASSERT_TRUE(md_memory_list != NULL);
ASSERT_EQ(1U, md_memory_list->region_count());
MinidumpMemoryRegion *md_region = md_memory_list->GetMemoryRegionAtIndex(0);
ASSERT_EQ(0x2326a0faU, md_region->GetBase());
ASSERT_EQ(16U, md_region->GetSize());
const u_int8_t *region_bytes = md_region->GetMemory();
ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0);
MinidumpThreadList *thread_list = minidump.GetThreadList();
ASSERT_TRUE(thread_list != NULL);
ASSERT_EQ(1U, thread_list->thread_count());
MinidumpThread *md_thread = thread_list->GetThreadAtIndex(0);
ASSERT_TRUE(md_thread != NULL);
u_int32_t thread_id;
ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
ASSERT_EQ(0xa898f11bU, thread_id);
MinidumpMemoryRegion *md_stack = md_thread->GetMemory();
ASSERT_TRUE(md_stack != NULL);
ASSERT_EQ(0x2326a0faU, md_stack->GetBase());
ASSERT_EQ(16U, md_stack->GetSize());
const u_int8_t *md_stack_bytes = md_stack->GetMemory();
ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0);
MinidumpContext *md_context = md_thread->GetContext();
ASSERT_TRUE(md_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
ASSERT_TRUE(md_raw_context != NULL);
ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
(md_raw_context->context_flags
& (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
EXPECT_EQ(0x3ecba80dU, raw_context.edi);
EXPECT_EQ(0x382583b9U, raw_context.esi);
EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
EXPECT_EQ(0x6a5025e2U, raw_context.eax);
EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
EXPECT_EQ(0x6913f540U, raw_context.eip);
EXPECT_EQ(0xbffe6edaU, raw_context.cs);
EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
EXPECT_EQ(0x659caaa4U, raw_context.esp);
EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}
TEST(Dump, OneModule) {
static const MDVSFixedFileInfo fixed_file_info = {
0xb2fba33a, // signature
0x33d7a728, // struct_version
0x31afcb20, // file_version_hi
0xe51cdab1, // file_version_lo
0xd1ea6907, // product_version_hi
0x03032857, // product_version_lo
0x11bf71d7, // file_flags_mask
0x5fb8cdbf, // file_flags
0xe45d0d5d, // file_os
0x107d9562, // file_type
0x5a8844d4, // file_subtype
0xa8d30b20, // file_date_hi
0x651c3e4e // file_date_lo
};
Dump dump(0, kBigEndian);
String module_name(dump, "single module");
Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
module_name,
0xb1054d2a,
0x34571371,
fixed_file_info, // from synth_minidump_unittest_data.h
NULL, NULL);
dump.Add(&module);
dump.Add(&module_name);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
ASSERT_TRUE(dir != NULL);
EXPECT_EQ((u_int32_t) MD_MODULE_LIST_STREAM, dir->stream_type);
MinidumpModuleList *md_module_list = minidump.GetModuleList();
ASSERT_TRUE(md_module_list != NULL);
ASSERT_EQ(1U, md_module_list->module_count());
const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
ASSERT_TRUE(md_module != NULL);
ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
ASSERT_EQ(0xada542bd, md_module->size());
ASSERT_EQ("single module", md_module->code_file());
const MDRawModule *md_raw_module = md_module->module();
ASSERT_TRUE(md_raw_module != NULL);
ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
ASSERT_EQ(0x34571371U, md_raw_module->checksum);
ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
sizeof(fixed_file_info)) == 0);
}
TEST(Dump, OneSystemInfo) {
Dump dump(0, kLittleEndian);
String csd_version(dump, "Petulant Pierogi");
SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
dump.Add(&system_info);
dump.Add(&csd_version);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
ASSERT_TRUE(dir != NULL);
EXPECT_EQ((u_int32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);
MinidumpSystemInfo *md_system_info = minidump.GetSystemInfo();
ASSERT_TRUE(md_system_info != NULL);
ASSERT_EQ("windows", md_system_info->GetOS());
ASSERT_EQ("x86", md_system_info->GetCPU());
ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion());
ASSERT_EQ("GenuineIntel", *md_system_info->GetCPUVendor());
}
TEST(Dump, BigDump) {
Dump dump(0, kLittleEndian);
// A SystemInfo stream.
String csd_version(dump, "Munificent Macaque");
SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
dump.Add(&csd_version);
dump.Add(&system_info);
// Five threads!
Memory stack0(dump, 0x70b9ebfc);
stack0.Append("stack for thread zero");
MDRawContextX86 raw_context0;
raw_context0.context_flags = MD_CONTEXT_X86_INTEGER;
raw_context0.eip = 0xaf0709e4;
Context context0(dump, raw_context0);
Thread thread0(dump, 0xbbef4432, stack0, context0,
0xd0377e7b, 0xdb8eb0cf, 0xd73bc314, 0x09d357bac7f9a163ULL);
dump.Add(&stack0);
dump.Add(&context0);
dump.Add(&thread0);
Memory stack1(dump, 0xf988cc45);
stack1.Append("stack for thread one");
MDRawContextX86 raw_context1;
raw_context1.context_flags = MD_CONTEXT_X86_INTEGER;
raw_context1.eip = 0xe4f56f81;
Context context1(dump, raw_context1);
Thread thread1(dump, 0x657c3f58, stack1, context1,
0xa68fa182, 0x6f3cf8dd, 0xe3a78ccf, 0x78cc84775e4534bbULL);
dump.Add(&stack1);
dump.Add(&context1);
dump.Add(&thread1);
Memory stack2(dump, 0xc8a92e7c);
stack2.Append("stack for thread two");
MDRawContextX86 raw_context2;
raw_context2.context_flags = MD_CONTEXT_X86_INTEGER;
raw_context2.eip = 0xb336a438;
Context context2(dump, raw_context2);
Thread thread2(dump, 0xdf4b8a71, stack2, context2,
0x674c26b6, 0x445d7120, 0x7e700c56, 0xd89bf778e7793e17ULL);
dump.Add(&stack2);
dump.Add(&context2);
dump.Add(&thread2);
Memory stack3(dump, 0x36d08e08);
stack3.Append("stack for thread three");
MDRawContextX86 raw_context3;
raw_context3.context_flags = MD_CONTEXT_X86_INTEGER;
raw_context3.eip = 0xdf99a60c;
Context context3(dump, raw_context3);
Thread thread3(dump, 0x86e6c341, stack3, context3,
0x32dc5c55, 0x17a2aba8, 0xe0cc75e7, 0xa46393994dae83aeULL);
dump.Add(&stack3);
dump.Add(&context3);
dump.Add(&thread3);
Memory stack4(dump, 0x1e0ab4fa);
stack4.Append("stack for thread four");
MDRawContextX86 raw_context4;
raw_context4.context_flags = MD_CONTEXT_X86_INTEGER;
raw_context4.eip = 0xaa646267;
Context context4(dump, raw_context4);
Thread thread4(dump, 0x261a28d4, stack4, context4,
0x6ebd389e, 0xa0cd4759, 0x30168846, 0x164f650a0cf39d35ULL);
dump.Add(&stack4);
dump.Add(&context4);
dump.Add(&thread4);
// Three modules!
String module1_name(dump, "module one");
Module module1(dump, 0xeb77da57b5d4cbdaULL, 0x83cd5a37, module1_name);
dump.Add(&module1_name);
dump.Add(&module1);
String module2_name(dump, "module two");
Module module2(dump, 0x8675884adfe5ac90ULL, 0xb11e4ea3, module2_name);
dump.Add(&module2_name);
dump.Add(&module2);
String module3_name(dump, "module three");
Module module3(dump, 0x95fc1544da321b6cULL, 0x7c2bf081, module3_name);
dump.Add(&module3_name);
dump.Add(&module3);
// Add one more memory region, on top of the five stacks.
Memory memory5(dump, 0x61979e828040e564ULL);
memory5.Append("contents of memory 5");
dump.Add(&memory5);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(4U, minidump.GetDirectoryEntryCount());
// Check the threads.
MinidumpThreadList *thread_list = minidump.GetThreadList();
ASSERT_TRUE(thread_list != NULL);
ASSERT_EQ(5U, thread_list->thread_count());
u_int32_t thread_id;
ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id));
ASSERT_EQ(0xbbef4432U, thread_id);
ASSERT_EQ(0x70b9ebfcU,
thread_list->GetThreadAtIndex(0)->GetMemory()->GetBase());
ASSERT_EQ(0xaf0709e4U,
thread_list->GetThreadAtIndex(0)->GetContext()->GetContextX86()
->eip);
ASSERT_TRUE(thread_list->GetThreadAtIndex(1)->GetThreadID(&thread_id));
ASSERT_EQ(0x657c3f58U, thread_id);
ASSERT_EQ(0xf988cc45U,
thread_list->GetThreadAtIndex(1)->GetMemory()->GetBase());
ASSERT_EQ(0xe4f56f81U,
thread_list->GetThreadAtIndex(1)->GetContext()->GetContextX86()
->eip);
ASSERT_TRUE(thread_list->GetThreadAtIndex(2)->GetThreadID(&thread_id));
ASSERT_EQ(0xdf4b8a71U, thread_id);
ASSERT_EQ(0xc8a92e7cU,
thread_list->GetThreadAtIndex(2)->GetMemory()->GetBase());
ASSERT_EQ(0xb336a438U,
thread_list->GetThreadAtIndex(2)->GetContext()->GetContextX86()
->eip);
ASSERT_TRUE(thread_list->GetThreadAtIndex(3)->GetThreadID(&thread_id));
ASSERT_EQ(0x86e6c341U, thread_id);
ASSERT_EQ(0x36d08e08U,
thread_list->GetThreadAtIndex(3)->GetMemory()->GetBase());
ASSERT_EQ(0xdf99a60cU,
thread_list->GetThreadAtIndex(3)->GetContext()->GetContextX86()
->eip);
ASSERT_TRUE(thread_list->GetThreadAtIndex(4)->GetThreadID(&thread_id));
ASSERT_EQ(0x261a28d4U, thread_id);
ASSERT_EQ(0x1e0ab4faU,
thread_list->GetThreadAtIndex(4)->GetMemory()->GetBase());
ASSERT_EQ(0xaa646267U,
thread_list->GetThreadAtIndex(4)->GetContext()->GetContextX86()
->eip);
// Check the modules.
MinidumpModuleList *md_module_list = minidump.GetModuleList();
ASSERT_TRUE(md_module_list != NULL);
ASSERT_EQ(3U, md_module_list->module_count());
EXPECT_EQ(0xeb77da57b5d4cbdaULL,
md_module_list->GetModuleAtIndex(0)->base_address());
EXPECT_EQ(0x8675884adfe5ac90ULL,
md_module_list->GetModuleAtIndex(1)->base_address());
EXPECT_EQ(0x95fc1544da321b6cULL,
md_module_list->GetModuleAtIndex(2)->base_address());
}
} // namespace

View file

@ -0,0 +1,309 @@
// Copyright (c) 2010, 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: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
// synth_minidump.cc: Implementation of SynthMinidump. See synth_minidump.h
#include "processor/synth_minidump.h"
namespace google_breakpad {
namespace SynthMinidump {
Section::Section(const Dump &dump)
: TestAssembler::Section(dump.endianness()) { }
void Section::CiteLocationIn(TestAssembler::Section *section) const {
if (this)
(*section).D32(size_).D32(file_offset_);
else
(*section).D32(0).D32(0);
}
void Stream::CiteStreamIn(TestAssembler::Section *section) const {
section->D32(type_);
CiteLocationIn(section);
}
SystemInfo::SystemInfo(const Dump &dump,
const MDRawSystemInfo &system_info,
const String &csd_version)
: Stream(dump, MD_SYSTEM_INFO_STREAM) {
D16(system_info.processor_architecture);
D16(system_info.processor_level);
D16(system_info.processor_revision);
D8(system_info.number_of_processors);
D8(system_info.product_type);
D32(system_info.major_version);
D32(system_info.minor_version);
D32(system_info.build_number);
D32(system_info.platform_id);
csd_version.CiteStringIn(this);
D16(system_info.suite_mask);
D16(system_info.reserved2); // Well, why not?
// MDCPUInformation cpu;
if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_X86) {
D32(system_info.cpu.x86_cpu_info.vendor_id[0]);
D32(system_info.cpu.x86_cpu_info.vendor_id[1]);
D32(system_info.cpu.x86_cpu_info.vendor_id[2]);
D32(system_info.cpu.x86_cpu_info.version_information);
D32(system_info.cpu.x86_cpu_info.feature_information);
D32(system_info.cpu.x86_cpu_info.amd_extended_cpu_features);
} else {
D64(system_info.cpu.other_cpu_info.processor_features[0]);
D64(system_info.cpu.other_cpu_info.processor_features[1]);
}
}
const MDRawSystemInfo SystemInfo::windows_x86 = {
MD_CPU_ARCHITECTURE_X86, // processor_architecture
6, // processor_level
0xd08, // processor_revision
1, // number_of_processors
1, // product_type
5, // major_version
1, // minor_version
2600, // build_number
2, // platform_id
0xdeadbeef, // csd_version_rva
0x100, // suite_mask
0, // reserved2
{ // cpu
{ // x86_cpu_info
{ 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
0x6d8, // version_information
0xafe9fbff, // feature_information
0xffffffff // amd_extended_cpu_features
}
}
};
const string SystemInfo::windows_x86_csd_version = "Service Pack 2";
String::String(const Dump &dump, const string &contents) : Section(dump) {
D32(contents.size() * 2);
for (string::const_iterator i = contents.begin(); i != contents.end(); i++)
D16(*i);
}
void String::CiteStringIn(TestAssembler::Section *section) const {
section->D32(file_offset_);
}
void Memory::CiteMemoryIn(TestAssembler::Section *section) const {
section->D64(address_);
CiteLocationIn(section);
}
Context::Context(const Dump &dump, const MDRawContextX86 &context)
: Section(dump) {
// The caller should have properly set the CPU type flag.
assert(context.context_flags & MD_CONTEXT_X86);
// It doesn't make sense to store x86 registers in big-endian form.
assert(dump.endianness() == kLittleEndian);
D32(context.context_flags);
D32(context.dr0);
D32(context.dr1);
D32(context.dr2);
D32(context.dr3);
D32(context.dr6);
D32(context.dr7);
D32(context.float_save.control_word);
D32(context.float_save.status_word);
D32(context.float_save.tag_word);
D32(context.float_save.error_offset);
D32(context.float_save.error_selector);
D32(context.float_save.data_offset);
D32(context.float_save.data_selector);
// context.float_save.register_area[] contains 8-bit quantities and
// does not need to be swapped.
Append(context.float_save.register_area,
sizeof(context.float_save.register_area));
D32(context.float_save.cr0_npx_state);
D32(context.gs);
D32(context.fs);
D32(context.es);
D32(context.ds);
D32(context.edi);
D32(context.esi);
D32(context.ebx);
D32(context.edx);
D32(context.ecx);
D32(context.eax);
D32(context.ebp);
D32(context.eip);
D32(context.cs);
D32(context.eflags);
D32(context.esp);
D32(context.ss);
// context.extended_registers[] contains 8-bit quantities and does
// not need to be swapped.
Append(context.extended_registers, sizeof(context.extended_registers));
assert(Size() == sizeof(MDRawContextX86));
}
Thread::Thread(const Dump &dump,
u_int32_t thread_id, const Memory &stack, const Context &context,
u_int32_t suspend_count, u_int32_t priority_class,
u_int32_t priority, u_int64_t teb) : Section(dump) {
D32(thread_id);
D32(suspend_count);
D32(priority_class);
D32(priority);
D64(teb);
stack.CiteMemoryIn(this);
context.CiteLocationIn(this);
assert(Size() == sizeof(MDRawThread));
}
Module::Module(const Dump &dump,
u_int64_t base_of_image,
u_int32_t size_of_image,
const String &name,
u_int32_t time_date_stamp,
u_int32_t checksum,
const MDVSFixedFileInfo &version_info,
const Section *cv_record,
const Section *misc_record) : Section(dump) {
D64(base_of_image);
D32(size_of_image);
D32(checksum);
D32(time_date_stamp);
name.CiteStringIn(this);
D32(version_info.signature);
D32(version_info.struct_version);
D32(version_info.file_version_hi);
D32(version_info.file_version_lo);
D32(version_info.product_version_hi);
D32(version_info.product_version_lo);
D32(version_info.file_flags_mask);
D32(version_info.file_flags);
D32(version_info.file_os);
D32(version_info.file_type);
D32(version_info.file_subtype);
D32(version_info.file_date_hi);
D32(version_info.file_date_lo);
cv_record->CiteLocationIn(this);
misc_record->CiteLocationIn(this);
D64(0).D64(0);
}
const MDVSFixedFileInfo Module::stock_version_info = {
MD_VSFIXEDFILEINFO_SIGNATURE, // signature
MD_VSFIXEDFILEINFO_VERSION, // struct_version
0x11111111, // file_version_hi
0x22222222, // file_version_lo
0x33333333, // product_version_hi
0x44444444, // product_version_lo
MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG, // file_flags_mask
MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG, // file_flags
MD_VSFIXEDFILEINFO_FILE_OS_NT | MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32,
// file_os
MD_VSFIXEDFILEINFO_FILE_TYPE_APP, // file_type
MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN, // file_subtype
0, // file_date_hi
0 // file_date_lo
};
Dump::Dump(u_int64_t flags,
Endianness endianness,
u_int32_t version,
u_int32_t date_time_stamp)
: TestAssembler::Section(endianness),
file_start_(0),
stream_directory_(*this),
stream_count_(0),
thread_list_(*this, MD_THREAD_LIST_STREAM),
module_list_(*this, MD_MODULE_LIST_STREAM),
memory_list_(*this, MD_MEMORY_LIST_STREAM)
{
D32(MD_HEADER_SIGNATURE);
D32(version);
D32(stream_count_label_);
D32(stream_directory_rva_);
D32(0);
D32(date_time_stamp);
D64(flags);
assert(Size() == sizeof(MDRawHeader));
}
Dump &Dump::Add(SynthMinidump::Section *section) {
section->Finish(file_start_ + Size());
Append(*section);
return *this;
}
Dump &Dump::Add(Stream *stream) {
Add(static_cast<SynthMinidump::Section *>(stream));
stream->CiteStreamIn(&stream_directory_);
stream_count_++;
return *this;
}
Dump &Dump::Add(Memory *memory) {
// Add the memory contents themselves to the file.
Add(static_cast<SynthMinidump::Section *>(memory));
// The memory list is a list of MDMemoryDescriptors, not of actual
// memory elements. Produce a descriptor, and add that to the list.
SynthMinidump::Section descriptor(*this);
memory->CiteMemoryIn(&descriptor);
memory_list_.Add(&descriptor);
return *this;
}
Dump &Dump::Add(Thread *thread) {
thread_list_.Add(thread);
return *this;
}
Dump &Dump::Add(Module *module) {
module_list_.Add(module);
return *this;
}
void Dump::Finish() {
if (!thread_list_.Empty()) Add(&thread_list_);
if (!module_list_.Empty()) Add(&module_list_);
if (!memory_list_.Empty()) Add(&memory_list_);
// Create the stream directory. We don't use
// stream_directory_.Finish here, because the stream directory isn't
// cited using a location descriptor; rather, the Minidump header
// has the stream count and MDRVA.
stream_count_label_ = stream_count_;
stream_directory_rva_ = file_start_ + Size();
Append(static_cast<TestAssembler::Section &>(stream_directory_));
}
} // namespace SynthMinidump
} // namespace google_breakpad

View file

@ -0,0 +1,357 @@
// -*- mode: C++ -*-
// Copyright (c) 2010, 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: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
// synth_minidump.h: Interface to SynthMinidump: fake minidump generator.
//
// We treat a minidump file as the concatenation of a bunch of
// TestAssembler::Sections. The file header, stream directory,
// streams, memory regions, strings, and so on --- each is a Section
// that eventually gets appended to the minidump. Dump, Memory,
// Context, Thread, and so on all inherit from TestAssembler::Section.
// For example:
//
// using google_breakpad::TestAssembler::kLittleEndian;
// using google_breakpad::SynthMinidump::Context;
// using google_breakpad::SynthMinidump::Dump;
// using google_breakpad::SynthMinidump::Memory;
// using google_breakpad::SynthMinidump::Thread;
//
// Dump minidump(MD_NORMAL, kLittleEndian);
//
// Memory stack1(minidump, 0x569eb0a9);
// ... build contents of stack1 with TestAssembler::Section functions ...
//
// MDRawContextX86 x86_context1;
// x86_context1.context_flags = MD_CONTEXT_X86;
// x86_context1.eip = 0x7c90eb94;
// x86_context1.esp = 0x569eb0a9;
// x86_context1.ebp = x86_context1.esp + something appropriate;
// Context context1(minidump, x86_context1);
//
// Thread thread1(minidump, 0xe4a4821d, stack1, context1);
//
// minidump.Add(&stack1);
// minidump.Add(&context1);
// minidump.Add(&thread1);
// minidump.Finish();
//
// string contents;
// EXPECT_TRUE(minidump.GetContents(&contents));
// // contents now holds the bytes of a minidump file
//
// Because the TestAssembler classes let us write Label references to
// sections before the Labels' values are known, this gives us
// flexibility in how we put the dump together: minidump pieces can
// hold the file offsets of other minidump pieces before the
// referents' positions have been decided. As long as everything has
// been placed by the time we call dump.GetContents to obtain the
// bytes, all the Labels' values will be known, and everything will
// get patched up appropriately.
//
// The dump.Add(thing) functions append THINGS's contents to the
// minidump, but they also do two other things:
//
// - dump.Add(thing) invokes thing->Finish, which tells *thing the
// offset within the file at which it was placed, and allows *thing
// to do any final content generation.
//
// - If THING is something which should receive an entry in some sort
// of list or directory, then dump.Add(THING) automatically creates
// the appropriate directory or list entry. Streams must appear in
// the stream directory; memory ranges should be listed in the
// memory list; threads should be placed in the thread list; and so
// on.
//
// By convention, Section subclass constructors that take references
// to other Sections do not take care of 'Add'ing their arguments to
// the dump. For example, although the Thread constructor takes
// references to a Memory and a Context, it does not add them to the
// dump on the caller's behalf. Rather, the caller is responsible for
// 'Add'ing every section they create. This allows Sections to be
// cited from more than one place; for example, Memory ranges are
// cited both from Thread objects (as their stack contents) and by the
// memory list stream.
//
// If you forget to Add some Section, the Dump::GetContents call will
// fail, as the TestAssembler::Labels used to cite the Section's
// contents from elsewhere will still be undefined.
#ifndef PROCESSOR_SYNTH_MINIDUMP_H_
#define PROCESSOR_SYNTH_MINIDUMP_H_
#include <cassert>
#include <iostream>
#include <string>
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/common/minidump_format.h"
#include "processor/test_assembler.h"
namespace google_breakpad {
namespace SynthMinidump {
using std::string;
using TestAssembler::Endianness;
using TestAssembler::kBigEndian;
using TestAssembler::kLittleEndian;
using TestAssembler::kUnsetEndian;
using TestAssembler::Label;
class Dump;
class Memory;
class String;
// A TestAssembler::Section which will be appended to a minidump.
class Section: public TestAssembler::Section {
public:
explicit Section(const Dump &dump);
// Append an MDLocationDescriptor referring to this section to SECTION.
// If 'this' is NULL, append a descriptor with a zero length and MDRVA.
//
// (I couldn't find the language in the C++ standard that says that
// invoking member functions of a NULL pointer to a class type is
// bad, if such language exists. Having this function handle NULL
// 'this' is convenient, but if it causes trouble, it's not hard to
// do differently.)
void CiteLocationIn(TestAssembler::Section *section) const;
// Note that this section's contents are complete, and that it has
// been placed in the minidump file at OFFSET. The 'Add' member
// functions call the Finish member function of the object being
// added for you; if you are 'Add'ing this section, you needn't Finish it.
virtual void Finish(const Label &offset) {
file_offset_ = offset; size_ = Size();
}
protected:
// This section's size and offset within the minidump file.
Label file_offset_, size_;
};
// A stream within a minidump file. 'Add'ing a stream to a minidump
// creates an entry for it in the minidump's stream directory.
class Stream: public Section {
public:
// Create a stream of type TYPE. You can append whatever contents
// you like to this stream using the TestAssembler::Section methods.
Stream(const Dump &dump, u_int32_t type) : Section(dump), type_(type) { }
// Append an MDRawDirectory referring to this stream to SECTION.
void CiteStreamIn(TestAssembler::Section *section) const;
private:
// The type of this stream.
u_int32_t type_;
};
class SystemInfo: public Stream {
public:
// Create an MD_SYSTEM_INFO_STREAM stream belonging to DUMP holding
// an MDRawSystem info structure initialized with the values from
// SYSTEM_INFO, except that the csd_version field is replaced with
// the file offset of the string CSD_VERSION, which can be 'Add'ed
// to the dump at the desired location.
//
// Remember that you are still responsible for 'Add'ing CSD_VERSION
// to the dump yourself.
SystemInfo(const Dump &dump,
const MDRawSystemInfo &system_info,
const String &csd_version);
// Stock MDRawSystemInfo information and associated strings, for
// writing tests.
static const MDRawSystemInfo windows_x86;
static const string windows_x86_csd_version;
};
// An MDString: a string predeced by a 32-bit length.
class String: public Section {
public:
String(const Dump &dump, const string &value);
// Append an MDRVA referring to this string to SECTION.
void CiteStringIn(TestAssembler::Section *section) const;
};
// A range of memory contents. 'Add'ing a memory range to a minidump
// creates n entry for it in the minidump's memory list. By
// convention, the 'start', 'Here', and 'Mark' member functions refer
// to memory addresses.
class Memory: public Section {
public:
Memory(const Dump &dump, u_int64_t address)
: Section(dump), address_(address) { start() = address; }
// Append an MDMemoryDescriptor referring to this memory range to SECTION.
void CiteMemoryIn(TestAssembler::Section *section) const;
private:
// The process address from which these memory contents were taken.
// Shouldn't this be a Label?
u_int64_t address_;
};
class Context: public Section {
public:
// Create a context belonging to DUMP whose contents are a copy of CONTEXT.
Context(const Dump &dump, const MDRawContextX86 &context);
// Add constructors for other architectures here. Remember to byteswap.
};
class Thread: public Section {
public:
// Create a thread belonging to DUMP with the given values, citing
// STACK and CONTEXT (which you must Add to the dump separately).
Thread(const Dump &dump,
u_int32_t thread_id,
const Memory &stack,
const Context &context,
u_int32_t suspend_count = 0,
u_int32_t priority_class = 0,
u_int32_t priority = 0,
u_int64_t teb = 0);
};
class Module: public Section {
public:
// Create a module with the given values. Note that CV_RECORD and
// MISC_RECORD can be NULL, in which case the corresponding location
// descriptior in the minidump will have a length of zero.
Module(const Dump &dump,
u_int64_t base_of_image,
u_int32_t size_of_image,
const String &name,
u_int32_t time_date_stamp = 1262805309,
u_int32_t checksum = 0,
const MDVSFixedFileInfo &version_info = Module::stock_version_info,
const Section *cv_record = NULL,
const Section *misc_record = NULL);
private:
// A standard MDVSFixedFileInfo structure to use as a default for
// minidumps. There's no reason to make users write out all this crap
// over and over.
static const MDVSFixedFileInfo stock_version_info;
};
// A list of entries starting with a 32-bit count, like a memory list
// or a thread list.
template<typename Element>
class List: public Stream {
public:
List(const Dump &dump, u_int32_t type) : Stream(dump, type), count_(0) {
D32(count_label_);
}
// Add ELEMENT to this list.
void Add(Element *element) {
element->Finish(file_offset_ + Size());
Append(*element);
count_++;
}
// Return true if this List is empty, false otherwise.
bool Empty() { return count_ == 0; }
// Finish up the contents of this section, mark it as having been
// placed at OFFSET.
virtual void Finish(const Label &offset) {
Stream::Finish(offset);
count_label_ = count_;
}
private:
size_t count_;
Label count_label_;
};
class Dump: public TestAssembler::Section {
public:
// Create a TestAssembler::Section containing a minidump file whose
// header uses the given values. ENDIANNESS determines the
// endianness of the signature; we set this section's default
// endianness by this.
Dump(u_int64_t flags,
Endianness endianness = kLittleEndian,
u_int32_t version = MD_HEADER_VERSION,
u_int32_t date_time_stamp = 1262805309);
// The following functions call OBJECT->Finish(), and append the
// contents of OBJECT to this minidump. They also record OBJECT in
// whatever directory or list is appropriate for its type. The
// stream directory, memory list, thread list, and module list are
// accumulated this way.
Dump &Add(SynthMinidump::Section *object); // simply append data
Dump &Add(Stream *object); // append, record in stream directory
Dump &Add(Memory *object); // append, record in memory list
Dump &Add(Thread *object); // append, record in thread list
Dump &Add(Module *object); // append, record in module list
// Complete the construction of the minidump, given the Add calls
// we've seen up to this point. After this call, this Dump's
// contents are complete, all labels should be defined if everything
// Cited has been Added, and you may call GetContents on it.
void Finish();
private:
// A label representing the start of the minidump file.
Label file_start_;
// The stream directory. We construct this incrementally from
// Add(Stream *) calls.
SynthMinidump::Section stream_directory_; // The directory's contents.
size_t stream_count_; // The number of streams so far.
Label stream_count_label_; // Cited in file header.
Label stream_directory_rva_; // The directory's file offset.
// This minidump's thread list. We construct this incrementally from
// Add(Thread *) calls.
List<Thread> thread_list_;
// This minidump's module list. We construct this incrementally from
// Add(Module *) calls.
List<Module> module_list_;
// This minidump's memory list. We construct this incrementally from
// Add(Memory *) calls. This is actually a list of MDMemoryDescriptors,
// not memory ranges --- thus the odd type.
List<SynthMinidump::Section> memory_list_;
};
} // namespace SynthMinidump
} // namespace google_breakpad
#endif // PROCESSOR_SYNTH_MINIDUMP_H_

View file

@ -0,0 +1,280 @@
// Copyright (c) 2010, 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: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
// test_assembler_unittest.cc: Unit tests for google_breakpad::TestAssembler.
#include <sstream>
#include <string>
#include "breakpad_googletest_includes.h"
#include "google_breakpad/common/minidump_format.h"
#include "processor/synth_minidump.h"
#include "processor/synth_minidump_unittest_data.h"
using google_breakpad::SynthMinidump::Context;
using google_breakpad::SynthMinidump::Dump;
using google_breakpad::SynthMinidump::List;
using google_breakpad::SynthMinidump::Memory;
using google_breakpad::SynthMinidump::Module;
using google_breakpad::SynthMinidump::Section;
using google_breakpad::SynthMinidump::Stream;
using google_breakpad::SynthMinidump::String;
using google_breakpad::SynthMinidump::SystemInfo;
using google_breakpad::SynthMinidump::Thread;
using google_breakpad::TestAssembler::kBigEndian;
using google_breakpad::TestAssembler::kLittleEndian;
using google_breakpad::TestAssembler::Label;
using std::string;
TEST(Section, Simple) {
Dump dump(0);
Section section(dump);
section.L32(0x12345678);
section.Finish(0);
string contents;
ASSERT_TRUE(section.GetContents(&contents));
EXPECT_EQ(string("\x78\x56\x34\x12", 4), contents);
}
TEST(Section, CiteLocationIn) {
Dump dump(0, kBigEndian);
Section section1(dump), section2(dump);
section1.Append("order");
section2.Append("mayhem");
section2.Finish(0x32287ec2);
section2.CiteLocationIn(&section1);
string contents;
ASSERT_TRUE(section1.GetContents(&contents));
string expected("order\0\0\0\x06\x32\x28\x7e\xc2", 13);
EXPECT_EQ(expected, contents);
}
TEST(Stream, CiteStreamIn) {
Dump dump(0, kLittleEndian);
Stream stream(dump, 0x40cae2b3);
Section section(dump);
stream.Append("stream contents");
section.Append("section contents");
stream.Finish(0x41424344);
stream.CiteStreamIn(&section);
string contents;
ASSERT_TRUE(section.GetContents(&contents));
string expected("section contents"
"\xb3\xe2\xca\x40"
"\x0f\0\0\0"
"\x44\x43\x42\x41",
16 + 4 + 4 + 4);
EXPECT_EQ(expected, contents);
}
TEST(Memory, CiteMemoryIn) {
Dump dump(0, kBigEndian);
Memory memory(dump, 0x76d010874ab019f9ULL);
Section section(dump);
memory.Append("memory contents");
section.Append("section contents");
memory.Finish(0x51525354);
memory.CiteMemoryIn(&section);
string contents;
ASSERT_TRUE(section.GetContents(&contents));
string expected("section contents"
"\x76\xd0\x10\x87\x4a\xb0\x19\xf9"
"\0\0\0\x0f"
"\x51\x52\x53\x54",
16 + 8 + 4 + 4);
EXPECT_EQ(contents, expected);
}
TEST(Memory, Here) {
Dump dump(0, kBigEndian);
Memory memory(dump, 0x89979731eb060ed4ULL);
memory.Append(1729, 42);
Label l = memory.Here();
ASSERT_EQ(0x89979731eb060ed4ULL + 1729, l.Value());
}
TEST(Context, X86) {
Dump dump(0, kLittleEndian);
assert(x86_raw_context.context_flags & MD_CONTEXT_X86);
Context context(dump, x86_raw_context);
string contents;
ASSERT_TRUE(context.GetContents(&contents));
EXPECT_EQ(sizeof(x86_expected_contents), contents.size());
EXPECT_TRUE(memcmp(contents.data(), x86_expected_contents, contents.size())
== 0);
}
TEST(ContextDeathTest, X86BadFlags) {
Dump dump(0, kLittleEndian);
MDRawContextX86 raw;
raw.context_flags = 0;
ASSERT_DEATH(Context context(dump, raw);,
"context\\.context_flags & 0x[0-9a-f]+");
}
TEST(ContextDeathTest, X86BadEndianness) {
Dump dump(0, kBigEndian);
MDRawContextX86 raw;
raw.context_flags = MD_CONTEXT_X86;
ASSERT_DEATH(Context context(dump, raw);,
"dump\\.endianness\\(\\) == kLittleEndian");
}
TEST(Thread, Simple) {
Dump dump(0, kLittleEndian);
Context context(dump, x86_raw_context);
context.Finish(0x8665da0c);
Memory stack(dump, 0xaad55a93cc3c0efcULL);
stack.Append("stack contents");
stack.Finish(0xe08cdbd1);
Thread thread(dump, 0x3d7ec360, stack, context,
0x3593f44d, // suspend count
0xab352b82, // priority class
0x2753d838, // priority
0xeb2de4be3f29e3e9ULL); // thread environment block
string contents;
ASSERT_TRUE(thread.GetContents(&contents));
static const u_int8_t expected_bytes[] = {
0x60, 0xc3, 0x7e, 0x3d, // thread id
0x4d, 0xf4, 0x93, 0x35, // suspend count
0x82, 0x2b, 0x35, 0xab, // priority class
0x38, 0xd8, 0x53, 0x27, // priority
0xe9, 0xe3, 0x29, 0x3f, 0xbe, 0xe4, 0x2d, 0xeb, // thread environment block
0xfc, 0x0e, 0x3c, 0xcc, 0x93, 0x5a, 0xd5, 0xaa, // stack address
0x0e, 0x00, 0x00, 0x00, // stack size
0xd1, 0xdb, 0x8c, 0xe0, // stack MDRVA
0xcc, 0x02, 0x00, 0x00, // context size
0x0c, 0xda, 0x65, 0x86 // context MDRVA
};
EXPECT_EQ(sizeof(expected_bytes), contents.size());
EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0);
}
TEST(String, Simple) {
Dump dump(0, kBigEndian);
String s(dump, "All mimsy were the borogoves");
string contents;
ASSERT_TRUE(s.GetContents(&contents));
static const char expected[] =
"\x00\x00\x00\x38\0A\0l\0l\0 \0m\0i\0m\0s\0y\0 \0w\0e\0r\0e"
"\0 \0t\0h\0e\0 \0b\0o\0r\0o\0g\0o\0v\0e\0s";
string expected_string(expected, sizeof(expected) - 1);
EXPECT_EQ(expected_string, contents);
}
TEST(String, CiteStringIn) {
Dump dump(0, kLittleEndian);
String s(dump, "and the mome wraths outgrabe");
Section section(dump);
section.Append("initial");
s.CiteStringIn(&section);
s.Finish(0xdc2bb469);
string contents;
ASSERT_TRUE(section.GetContents(&contents));
EXPECT_EQ(string("initial\x69\xb4\x2b\xdc", 7 + 4), contents);
}
TEST(List, Empty) {
Dump dump(0, kBigEndian);
List<Section> list(dump, 0x2442779c);
EXPECT_TRUE(list.Empty());
list.Finish(0x84e09808);
string contents;
ASSERT_TRUE(list.GetContents(&contents));
EXPECT_EQ(string("\0\0\0\0", 4), contents);
}
TEST(List, Two) {
Dump dump(0, kBigEndian);
List<Section> list(dump, 0x26c9f498);
Section section1(dump);
section1.Append("section one contents");
EXPECT_TRUE(list.Empty());
list.Add(&section1);
EXPECT_FALSE(list.Empty());
Section section2(dump);
section2.Append("section two contents");
list.Add(&section2);
list.Finish(0x1e5bb60e);
string contents;
ASSERT_TRUE(list.GetContents(&contents));
EXPECT_EQ(string("\0\0\0\x02section one contentssection two contents", 44),
contents);
}
TEST(Dump, Header) {
Dump dump(0x9f738b33685cc84cULL, kLittleEndian, 0xb3817faf, 0x2c741c0a);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
ASSERT_EQ(string("\x4d\x44\x4d\x50" // signature
"\xaf\x7f\x81\xb3" // version
"\0\0\0\0" // stream count
"\x20\0\0\0" // directory RVA (could be anything)
"\0\0\0\0" // checksum
"\x0a\x1c\x74\x2c" // time_date_stamp
"\x4c\xc8\x5c\x68\x33\x8b\x73\x9f", // flags
32),
contents);
}
TEST(Dump, HeaderBigEndian) {
Dump dump(0x206ce3cc6fb8e0f0ULL, kBigEndian, 0x161693e2, 0x35667744);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
ASSERT_EQ(string("\x50\x4d\x44\x4d" // signature
"\x16\x16\x93\xe2" // version
"\0\0\0\0" // stream count
"\0\0\0\x20" // directory RVA (could be anything)
"\0\0\0\0" // checksum
"\x35\x66\x77\x44" // time_date_stamp
"\x20\x6c\xe3\xcc\x6f\xb8\xe0\xf0", // flags
32),
contents);
}
TEST(Dump, OneSection) {
Dump dump(0, kLittleEndian);
Section section(dump);
section.Append("section contents");
dump.Add(&section);
dump.Finish();
string dump_contents;
// Just check for undefined labels; don't worry about the contents.
ASSERT_TRUE(dump.GetContents(&dump_contents));
Section referencing_section(dump);
section.CiteLocationIn(&referencing_section);
string contents;
ASSERT_TRUE(referencing_section.GetContents(&contents));
ASSERT_EQ(string("\x10\0\0\0\x20\0\0\0", 8), contents);
}

View file

@ -0,0 +1,246 @@
// -*- mode: C++ -*-
// Not copyrightable: random test data.
// synth_minidump_unittest_data.h: verbose test data for SynthMinidump tests.
#ifndef PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_
#define PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_
#include "google_breakpad/common/minidump_format.h"
static const MDRawContextX86 x86_raw_context = {
0xded5d71b, // context_flags
0x9fdb432e, // dr0
0x26b7a81a, // dr1
0xcac7e348, // dr2
0xcf99ec09, // dr3
0x7dc8c2cd, // dr6
0x21deb880, // dr7
// float_save
{
0x8a5d2bb0, // control_word
0x0286c4c9, // status_word
0xf1feea21, // tag_word
0xb2d40576, // error_offset
0x48146cde, // error_selector
0x983f9b21, // data_offset
0x475be12c, // data_selector
// register_area
{
0xd9, 0x04, 0x20, 0x6b, 0x88, 0x3a, 0x3f, 0xd5,
0x59, 0x7a, 0xa9, 0xeb, 0xd0, 0x5c, 0xdf, 0xfe,
0xad, 0xdd, 0x4a, 0x8b, 0x10, 0xcc, 0x9a, 0x33,
0xcb, 0xb6, 0xf7, 0x86, 0xcd, 0x69, 0x25, 0xae,
0x25, 0xe5, 0x7a, 0xa1, 0x8f, 0xb2, 0x84, 0xd9,
0xf7, 0x2d, 0x8a, 0xa1, 0x80, 0x81, 0x7f, 0x67,
0x07, 0xa8, 0x23, 0xf1, 0x8c, 0xdc, 0xd8, 0x04,
0x8b, 0x9d, 0xb1, 0xcd, 0x61, 0x0c, 0x9c, 0x69,
0xc7, 0x8d, 0x17, 0xb6, 0xe5, 0x0b, 0x94, 0xf7,
0x78, 0x9b, 0x63, 0x49, 0xba, 0xfc, 0x08, 0x4d
},
0x84c53a90, // cr0_npx_state
},
0x79f71e76, // gs
0x8107bd25, // fs
0x452d2921, // es
0x87ec2875, // ds
0xf8bb73f5, // edi
0xa63ebb88, // esi
0x95d35ebe, // ebx
0x17aa2456, // edx
0x135fa208, // ecx
0x500615e6, // eax
0x66d14205, // ebp
0x000719a5, // eip
0x477b481b, // cs
0x8684dfba, // eflags
0xe33ccddf, // esp
0xc0e65d33, // ss
// extended_registers
{
0x68, 0x63, 0xdf, 0x50, 0xf7, 0x3b, 0xe8, 0xe5,
0xcb, 0xd6, 0x66, 0x60, 0xe5, 0xa3, 0x58, 0xb3,
0x6f, 0x34, 0xca, 0x02, 0x9b, 0x5f, 0xd0, 0x41,
0xbd, 0xc5, 0x2d, 0xf8, 0xff, 0x15, 0xa2, 0xd0,
0xe3, 0x2b, 0x3b, 0x8a, 0x9f, 0xc3, 0x9e, 0x28,
0x0a, 0xc2, 0xac, 0x3b, 0x67, 0x37, 0x01, 0xfd,
0xc3, 0xaf, 0x60, 0xf6, 0x2c, 0x4f, 0xa9, 0x52,
0x92, 0xe5, 0x28, 0xde, 0x34, 0xb6, 0x2e, 0x44,
0x15, 0xa4, 0xb6, 0xe4, 0xc9, 0x1a, 0x14, 0xb9,
0x51, 0x33, 0x3c, 0xe0, 0xc7, 0x94, 0xf0, 0xf7,
0x78, 0xdd, 0xe5, 0xca, 0xb7, 0xa6, 0xe0, 0x14,
0xa6, 0x03, 0xab, 0x77, 0xad, 0xbd, 0xd2, 0x53,
0x3d, 0x07, 0xe7, 0xaf, 0x90, 0x44, 0x71, 0xbe,
0x0c, 0xdf, 0x2b, 0x97, 0x40, 0x48, 0xd5, 0xf9,
0x62, 0x03, 0x91, 0x84, 0xd6, 0xdd, 0x29, 0x97,
0x35, 0x02, 0xfb, 0x59, 0x97, 0xb0, 0xec, 0xa9,
0x39, 0x6f, 0x81, 0x71, 0x2a, 0xf0, 0xe7, 0x2c,
0x4e, 0x93, 0x90, 0xcb, 0x67, 0x69, 0xde, 0xd7,
0x68, 0x3b, 0x0f, 0x69, 0xa8, 0xf4, 0xa8, 0x83,
0x42, 0x80, 0x47, 0x65, 0x7a, 0xc9, 0x19, 0x5d,
0xcb, 0x43, 0xa5, 0xff, 0xf8, 0x9e, 0x62, 0xf4,
0xe2, 0x6c, 0xcc, 0x17, 0x55, 0x7c, 0x0d, 0x5c,
0x8d, 0x16, 0x01, 0xd7, 0x3a, 0x0c, 0xf4, 0x7f,
0x71, 0xdc, 0x48, 0xe9, 0x4b, 0xfe, 0x1a, 0xd0,
0x04, 0x15, 0x33, 0xec, 0x78, 0xc6, 0x7e, 0xde,
0x7c, 0x23, 0x18, 0x8d, 0x8f, 0xc2, 0x74, 0xc1,
0x48, 0xcd, 0x5d, 0xee, 0xee, 0x81, 0x9e, 0x49,
0x47, 0x8a, 0xf8, 0x61, 0xa3, 0x9c, 0x81, 0x96,
0xbe, 0x2b, 0x5e, 0xbc, 0xcd, 0x34, 0x0a, 0x2a,
0x3b, 0x8b, 0x7d, 0xa1, 0xf2, 0x8d, 0xb4, 0x51,
0x9e, 0x14, 0x78, 0xa3, 0x58, 0x65, 0x2d, 0xd6,
0x50, 0x40, 0x36, 0x32, 0x31, 0xd4, 0x3e, 0xc2,
0xe0, 0x87, 0x1c, 0x05, 0x95, 0x80, 0x84, 0x24,
0x08, 0x6f, 0x5b, 0xc7, 0xe1, 0x1d, 0xd5, 0xa3,
0x94, 0x44, 0xa1, 0x7c, 0xd8, 0x4b, 0x86, 0xd2,
0xc6, 0xa9, 0xf3, 0xe2, 0x4d, 0x6e, 0x1f, 0x0e,
0xf2, 0xf5, 0x71, 0xf9, 0x71, 0x05, 0x24, 0xc9,
0xc1, 0xe8, 0x91, 0x42, 0x61, 0x86, 0x57, 0x68,
0xd9, 0xc9, 0x1d, 0xd5, 0x5a, 0xe9, 0xba, 0xe6,
0x15, 0x8f, 0x87, 0xbd, 0x62, 0x56, 0xed, 0xda,
0xc2, 0xa5, 0xd5, 0x39, 0xac, 0x05, 0x10, 0x14,
0x4a, 0xe7, 0xe7, 0x3c, 0x3f, 0xb7, 0xbb, 0xed,
0x01, 0x6e, 0xcd, 0xee, 0x81, 0xb4, 0x62, 0xf4,
0x62, 0x16, 0xff, 0x20, 0xb4, 0xf0, 0xbc, 0xff,
0x7d, 0xd9, 0xcf, 0x95, 0x30, 0x27, 0xe0, 0x2f,
0x98, 0x53, 0x80, 0x15, 0x13, 0xef, 0x44, 0x58,
0x12, 0x16, 0xdb, 0x11, 0xef, 0x73, 0x51, 0xcd,
0x42, 0x3f, 0x98, 0x6c, 0xc9, 0x68, 0xc3, 0xf4,
0x5b, 0x0f, 0x5d, 0x77, 0xed, 0xdf, 0x0f, 0xff,
0xb8, 0x69, 0x98, 0x50, 0x77, 0x7a, 0xe8, 0x90,
0x27, 0x46, 0x10, 0xd2, 0xb5, 0x00, 0x3b, 0x36,
0x43, 0x6d, 0x67, 0x41, 0x20, 0x3a, 0x32, 0xe0,
0x2e, 0x5a, 0xfb, 0x4e, 0x4f, 0xa4, 0xf7, 0xc2,
0xe6, 0x81, 0x1a, 0x51, 0xa8, 0x7c, 0xd4, 0x60,
0x7c, 0x45, 0xe2, 0xba, 0x5b, 0x42, 0xf3, 0xbf,
0x28, 0xaa, 0xf2, 0x90, 0xe4, 0x94, 0xdd, 0xaa,
0x22, 0xd3, 0x71, 0x33, 0xa1, 0x01, 0x43, 0x0e,
0xfa, 0x46, 0xd2, 0x6e, 0x55, 0x5e, 0x49, 0xeb,
0x94, 0xf0, 0xb0, 0xb1, 0x2e, 0xf2, 0x3d, 0x6c,
0x00, 0x5e, 0x01, 0x56, 0x3b, 0xfd, 0x5b, 0xa1,
0x2f, 0x63, 0x1d, 0xbf, 0xf9, 0xd8, 0x13, 0xf7,
0x4d, 0xb7, 0x1e, 0x3d, 0x98, 0xd2, 0xee, 0xb8,
0x48, 0xc8, 0x5b, 0x91, 0x0f, 0x54, 0x9e, 0x26,
0xb2, 0xc7, 0x3a, 0x6c, 0x8a, 0x35, 0xe1, 0xba
}
};
static const u_int8_t x86_expected_contents[] = {
0x1b, 0xd7, 0xd5, 0xde,
0x2e, 0x43, 0xdb, 0x9f,
0x1a, 0xa8, 0xb7, 0x26,
0x48, 0xe3, 0xc7, 0xca,
0x09, 0xec, 0x99, 0xcf,
0xcd, 0xc2, 0xc8, 0x7d,
0x80, 0xb8, 0xde, 0x21,
0xb0, 0x2b, 0x5d, 0x8a,
0xc9, 0xc4, 0x86, 0x02,
0x21, 0xea, 0xfe, 0xf1,
0x76, 0x05, 0xd4, 0xb2,
0xde, 0x6c, 0x14, 0x48,
0x21, 0x9b, 0x3f, 0x98,
0x2c, 0xe1, 0x5b, 0x47,
// float_save.register_area --- unswapped
0xd9, 0x04, 0x20, 0x6b, 0x88, 0x3a, 0x3f, 0xd5,
0x59, 0x7a, 0xa9, 0xeb, 0xd0, 0x5c, 0xdf, 0xfe,
0xad, 0xdd, 0x4a, 0x8b, 0x10, 0xcc, 0x9a, 0x33,
0xcb, 0xb6, 0xf7, 0x86, 0xcd, 0x69, 0x25, 0xae,
0x25, 0xe5, 0x7a, 0xa1, 0x8f, 0xb2, 0x84, 0xd9,
0xf7, 0x2d, 0x8a, 0xa1, 0x80, 0x81, 0x7f, 0x67,
0x07, 0xa8, 0x23, 0xf1, 0x8c, 0xdc, 0xd8, 0x04,
0x8b, 0x9d, 0xb1, 0xcd, 0x61, 0x0c, 0x9c, 0x69,
0xc7, 0x8d, 0x17, 0xb6, 0xe5, 0x0b, 0x94, 0xf7,
0x78, 0x9b, 0x63, 0x49, 0xba, 0xfc, 0x08, 0x4d,
0x90, 0x3a, 0xc5, 0x84,
0x76, 0x1e, 0xf7, 0x79,
0x25, 0xbd, 0x07, 0x81,
0x21, 0x29, 0x2d, 0x45,
0x75, 0x28, 0xec, 0x87,
0xf5, 0x73, 0xbb, 0xf8,
0x88, 0xbb, 0x3e, 0xa6,
0xbe, 0x5e, 0xd3, 0x95,
0x56, 0x24, 0xaa, 0x17,
0x08, 0xa2, 0x5f, 0x13,
0xe6, 0x15, 0x06, 0x50,
0x05, 0x42, 0xd1, 0x66,
0xa5, 0x19, 0x07, 0x00,
0x1b, 0x48, 0x7b, 0x47,
0xba, 0xdf, 0x84, 0x86,
0xdf, 0xcd, 0x3c, 0xe3,
0x33, 0x5d, 0xe6, 0xc0,
// extended_registers --- unswapped
0x68, 0x63, 0xdf, 0x50, 0xf7, 0x3b, 0xe8, 0xe5,
0xcb, 0xd6, 0x66, 0x60, 0xe5, 0xa3, 0x58, 0xb3,
0x6f, 0x34, 0xca, 0x02, 0x9b, 0x5f, 0xd0, 0x41,
0xbd, 0xc5, 0x2d, 0xf8, 0xff, 0x15, 0xa2, 0xd0,
0xe3, 0x2b, 0x3b, 0x8a, 0x9f, 0xc3, 0x9e, 0x28,
0x0a, 0xc2, 0xac, 0x3b, 0x67, 0x37, 0x01, 0xfd,
0xc3, 0xaf, 0x60, 0xf6, 0x2c, 0x4f, 0xa9, 0x52,
0x92, 0xe5, 0x28, 0xde, 0x34, 0xb6, 0x2e, 0x44,
0x15, 0xa4, 0xb6, 0xe4, 0xc9, 0x1a, 0x14, 0xb9,
0x51, 0x33, 0x3c, 0xe0, 0xc7, 0x94, 0xf0, 0xf7,
0x78, 0xdd, 0xe5, 0xca, 0xb7, 0xa6, 0xe0, 0x14,
0xa6, 0x03, 0xab, 0x77, 0xad, 0xbd, 0xd2, 0x53,
0x3d, 0x07, 0xe7, 0xaf, 0x90, 0x44, 0x71, 0xbe,
0x0c, 0xdf, 0x2b, 0x97, 0x40, 0x48, 0xd5, 0xf9,
0x62, 0x03, 0x91, 0x84, 0xd6, 0xdd, 0x29, 0x97,
0x35, 0x02, 0xfb, 0x59, 0x97, 0xb0, 0xec, 0xa9,
0x39, 0x6f, 0x81, 0x71, 0x2a, 0xf0, 0xe7, 0x2c,
0x4e, 0x93, 0x90, 0xcb, 0x67, 0x69, 0xde, 0xd7,
0x68, 0x3b, 0x0f, 0x69, 0xa8, 0xf4, 0xa8, 0x83,
0x42, 0x80, 0x47, 0x65, 0x7a, 0xc9, 0x19, 0x5d,
0xcb, 0x43, 0xa5, 0xff, 0xf8, 0x9e, 0x62, 0xf4,
0xe2, 0x6c, 0xcc, 0x17, 0x55, 0x7c, 0x0d, 0x5c,
0x8d, 0x16, 0x01, 0xd7, 0x3a, 0x0c, 0xf4, 0x7f,
0x71, 0xdc, 0x48, 0xe9, 0x4b, 0xfe, 0x1a, 0xd0,
0x04, 0x15, 0x33, 0xec, 0x78, 0xc6, 0x7e, 0xde,
0x7c, 0x23, 0x18, 0x8d, 0x8f, 0xc2, 0x74, 0xc1,
0x48, 0xcd, 0x5d, 0xee, 0xee, 0x81, 0x9e, 0x49,
0x47, 0x8a, 0xf8, 0x61, 0xa3, 0x9c, 0x81, 0x96,
0xbe, 0x2b, 0x5e, 0xbc, 0xcd, 0x34, 0x0a, 0x2a,
0x3b, 0x8b, 0x7d, 0xa1, 0xf2, 0x8d, 0xb4, 0x51,
0x9e, 0x14, 0x78, 0xa3, 0x58, 0x65, 0x2d, 0xd6,
0x50, 0x40, 0x36, 0x32, 0x31, 0xd4, 0x3e, 0xc2,
0xe0, 0x87, 0x1c, 0x05, 0x95, 0x80, 0x84, 0x24,
0x08, 0x6f, 0x5b, 0xc7, 0xe1, 0x1d, 0xd5, 0xa3,
0x94, 0x44, 0xa1, 0x7c, 0xd8, 0x4b, 0x86, 0xd2,
0xc6, 0xa9, 0xf3, 0xe2, 0x4d, 0x6e, 0x1f, 0x0e,
0xf2, 0xf5, 0x71, 0xf9, 0x71, 0x05, 0x24, 0xc9,
0xc1, 0xe8, 0x91, 0x42, 0x61, 0x86, 0x57, 0x68,
0xd9, 0xc9, 0x1d, 0xd5, 0x5a, 0xe9, 0xba, 0xe6,
0x15, 0x8f, 0x87, 0xbd, 0x62, 0x56, 0xed, 0xda,
0xc2, 0xa5, 0xd5, 0x39, 0xac, 0x05, 0x10, 0x14,
0x4a, 0xe7, 0xe7, 0x3c, 0x3f, 0xb7, 0xbb, 0xed,
0x01, 0x6e, 0xcd, 0xee, 0x81, 0xb4, 0x62, 0xf4,
0x62, 0x16, 0xff, 0x20, 0xb4, 0xf0, 0xbc, 0xff,
0x7d, 0xd9, 0xcf, 0x95, 0x30, 0x27, 0xe0, 0x2f,
0x98, 0x53, 0x80, 0x15, 0x13, 0xef, 0x44, 0x58,
0x12, 0x16, 0xdb, 0x11, 0xef, 0x73, 0x51, 0xcd,
0x42, 0x3f, 0x98, 0x6c, 0xc9, 0x68, 0xc3, 0xf4,
0x5b, 0x0f, 0x5d, 0x77, 0xed, 0xdf, 0x0f, 0xff,
0xb8, 0x69, 0x98, 0x50, 0x77, 0x7a, 0xe8, 0x90,
0x27, 0x46, 0x10, 0xd2, 0xb5, 0x00, 0x3b, 0x36,
0x43, 0x6d, 0x67, 0x41, 0x20, 0x3a, 0x32, 0xe0,
0x2e, 0x5a, 0xfb, 0x4e, 0x4f, 0xa4, 0xf7, 0xc2,
0xe6, 0x81, 0x1a, 0x51, 0xa8, 0x7c, 0xd4, 0x60,
0x7c, 0x45, 0xe2, 0xba, 0x5b, 0x42, 0xf3, 0xbf,
0x28, 0xaa, 0xf2, 0x90, 0xe4, 0x94, 0xdd, 0xaa,
0x22, 0xd3, 0x71, 0x33, 0xa1, 0x01, 0x43, 0x0e,
0xfa, 0x46, 0xd2, 0x6e, 0x55, 0x5e, 0x49, 0xeb,
0x94, 0xf0, 0xb0, 0xb1, 0x2e, 0xf2, 0x3d, 0x6c,
0x00, 0x5e, 0x01, 0x56, 0x3b, 0xfd, 0x5b, 0xa1,
0x2f, 0x63, 0x1d, 0xbf, 0xf9, 0xd8, 0x13, 0xf7,
0x4d, 0xb7, 0x1e, 0x3d, 0x98, 0xd2, 0xee, 0xb8,
0x48, 0xc8, 0x5b, 0x91, 0x0f, 0x54, 0x9e, 0x26,
0xb2, 0xc7, 0x3a, 0x6c, 0x8a, 0x35, 0xe1, 0xba
};
#endif // PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_

View file

@ -0,0 +1,357 @@
// Copyright (c) 2010, 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: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
// test_assembler.cc: Implementation of google_breakpad::TestAssembler.
// See test_assembler.h for details.
#include <cassert>
#include <cstdio>
#include <iterator>
#include "processor/test_assembler.h"
namespace google_breakpad {
namespace TestAssembler {
using std::back_insert_iterator;
Label::Label() : value_(new Binding()) { }
Label::Label(u_int64_t value) : value_(new Binding(value)) { }
Label::Label(const Label &label) {
value_ = label.value_;
value_->Acquire();
}
Label::~Label() {
if (value_->Release()) delete value_;
}
Label &Label::operator=(u_int64_t value) {
value_->Set(NULL, value);
return *this;
}
Label &Label::operator=(const Label &label) {
value_->Set(label.value_, 0);
return *this;
}
Label Label::operator+(u_int64_t addend) const {
Label l;
l.value_->Set(this->value_, addend);
return l;
}
Label Label::operator-(u_int64_t subtrahend) const {
Label l;
l.value_->Set(this->value_, -subtrahend);
return l;
}
// When NDEBUG is #defined, assert doesn't evaluate its argument. This
// means you can't simply use assert to check the return value of a
// function with necessary side effects.
//
// ALWAYS_EVALUATE_AND_ASSERT(x) evaluates x regardless of whether
// NDEBUG is #defined; when NDEBUG is not #defined, it further asserts
// that x is true.
#ifdef NDEBUG
#define ALWAYS_EVALUATE_AND_ASSERT(x) x
#else
#define ALWAYS_EVALUATE_AND_ASSERT(x) assert(x)
#endif
u_int64_t Label::operator-(const Label &label) const {
u_int64_t offset;
ALWAYS_EVALUATE_AND_ASSERT(IsKnownOffsetFrom(label, &offset));
return offset;
}
u_int64_t Label::Value() const {
u_int64_t v;
ALWAYS_EVALUATE_AND_ASSERT(IsKnownConstant(&v));
return v;
};
bool Label::IsKnownConstant(u_int64_t *value_p) const {
Binding *base;
u_int64_t addend;
value_->Get(&base, &addend);
if (base != NULL) return false;
if (value_p) *value_p = addend;
return true;
}
bool Label::IsKnownOffsetFrom(const Label &label, u_int64_t *offset_p) const
{
Binding *label_base, *this_base;
u_int64_t label_addend, this_addend;
label.value_->Get(&label_base, &label_addend);
value_->Get(&this_base, &this_addend);
// If this and label are related, Get will find their final
// common ancestor, regardless of how indirect the relation is. This
// comparison also handles the constant vs. constant case.
if (this_base != label_base) return false;
if (offset_p) *offset_p = this_addend - label_addend;
return true;
}
Label::Binding::Binding() : base_(this), addend_(), reference_count_(1) { }
Label::Binding::Binding(u_int64_t addend)
: base_(NULL), addend_(addend), reference_count_(1) { }
Label::Binding::~Binding() {
assert(reference_count_ == 0);
if (base_ && base_ != this && base_->Release())
delete base_;
}
void Label::Binding::Set(Binding *binding, u_int64_t addend) {
if (!base_ && !binding) {
// We're equating two constants. This could be okay.
assert(addend_ == addend);
} else if (!base_) {
// We are a known constant, but BINDING may not be, so turn the
// tables and try to set BINDING's value instead.
binding->Set(NULL, addend_ - addend);
} else {
if (binding) {
// Find binding's final value. Since the final value is always either
// completely unconstrained or a constant, never a reference to
// another variable (otherwise, it wouldn't be final), this
// guarantees we won't create cycles here, even for code like this:
// l = m, m = n, n = l;
u_int64_t binding_addend;
binding->Get(&binding, &binding_addend);
addend += binding_addend;
}
// It seems likely that setting a binding to itself is a bug
// (although I can imagine this might turn out to be helpful to
// permit).
assert(binding != this);
if (base_ != this) {
// Set the other bindings on our chain as well. Note that this
// is sufficient even though binding relationships form trees:
// All binding operations traverse their chains to the end, and
// all bindings related to us share some tail of our chain, so
// they will see the changes we make here.
base_->Set(binding, addend - addend_);
// We're not going to use base_ any more.
if (base_->Release()) delete base_;
}
// Adopt BINDING as our base. Note that it should be correct to
// acquire here, after the release above, even though the usual
// reference-counting rules call for acquiring first, and then
// releasing: the self-reference assertion above should have
// complained if BINDING were 'this' or anywhere along our chain,
// so we didn't release BINDING.
if (binding) binding->Acquire();
base_ = binding;
addend_ = addend;
}
}
void Label::Binding::Get(Binding **base, u_int64_t *addend) {
if (base_ && base_ != this) {
// Recurse to find the end of our reference chain (the root of our
// tree), and then rewrite every binding along the chain to refer
// to it directly, adjusting addends appropriately. (This is why
// this member function isn't this-const.)
Binding *final_base;
u_int64_t final_addend;
base_->Get(&final_base, &final_addend);
if (final_base) final_base->Acquire();
if (base_->Release()) delete base_;
base_ = final_base;
addend_ += final_addend;
}
*base = base_;
*addend = addend_;
}
template<typename Inserter>
static inline void InsertEndian(TestAssembler::Endianness endianness,
size_t size, u_int64_t number, Inserter dest) {
if (endianness == kLittleEndian) {
for (size_t i = 0; i < size; i++) {
*dest++ = (char) (number & 0xff);
number >>= 8;
}
} else {
assert(endianness == kBigEndian);
// The loop condition is odd, but it's correct for size_t.
for (size_t i = size - 1; i < size; i--)
*dest++ = (char) ((number >> (i * 8)) & 0xff);
}
}
Section &Section::Append(Endianness endianness, size_t size, u_int64_t number) {
InsertEndian(endianness, size, number,
back_insert_iterator<string>(contents_));
return *this;
}
Section &Section::Append(Endianness endianness, size_t size,
const Label &label) {
// If this label's value is known, there's no reason to waste an
// entry in references_ on it.
u_int64_t value;
if (label.IsKnownConstant(&value))
return Append(endianness, size, value);
// This will get caught when the references are resolved, but it's
// nicer to find out earlier.
assert(endianness != kUnsetEndian);
references_.push_back(Reference(contents_.size(), endianness, size, label));
contents_.append(size, 0);
return *this;
}
#define ENDIANNESS_L kLittleEndian
#define ENDIANNESS_B kBigEndian
#define ENDIANNESS(e) ENDIANNESS_ ## e
#define DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits) \
Section &Section::e ## bits(u_int ## bits ## _t v) { \
InsertEndian(ENDIANNESS(e), bits / 8, v, \
back_insert_iterator<string>(contents_)); \
return *this; \
}
#define DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits) \
Section &Section::e ## bits(const Label &v) { \
return Append(ENDIANNESS(e), bits / 8, v); \
}
// Define L16, B32, and friends.
#define DEFINE_SHORT_APPEND_ENDIAN(e, bits) \
DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits) \
DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits)
DEFINE_SHORT_APPEND_LABEL_ENDIAN(L, 8);
DEFINE_SHORT_APPEND_LABEL_ENDIAN(B, 8);
DEFINE_SHORT_APPEND_ENDIAN(L, 16);
DEFINE_SHORT_APPEND_ENDIAN(L, 32);
DEFINE_SHORT_APPEND_ENDIAN(L, 64);
DEFINE_SHORT_APPEND_ENDIAN(B, 16);
DEFINE_SHORT_APPEND_ENDIAN(B, 32);
DEFINE_SHORT_APPEND_ENDIAN(B, 64);
#define DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits) \
Section &Section::D ## bits(u_int ## bits ## _t v) { \
InsertEndian(endianness_, bits / 8, v, \
back_insert_iterator<string>(contents_)); \
return *this; \
}
#define DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits) \
Section &Section::D ## bits(const Label &v) { \
return Append(endianness_, bits / 8, v); \
}
#define DEFINE_SHORT_APPEND_DEFAULT(bits) \
DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits) \
DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits)
DEFINE_SHORT_APPEND_LABEL_DEFAULT(8)
DEFINE_SHORT_APPEND_DEFAULT(16);
DEFINE_SHORT_APPEND_DEFAULT(32);
DEFINE_SHORT_APPEND_DEFAULT(64);
Section &Section::Append(const Section &section) {
size_t base = contents_.size();
contents_.append(section.contents_);
for (vector<Reference>::const_iterator it = section.references_.begin();
it != section.references_.end(); it++)
references_.push_back(Reference(base + it->offset, it->endianness,
it->size, it->label));
return *this;
}
Section &Section::LEB128(long long value) {
while (value < -0x40 || 0x3f < value) {
contents_ += (value & 0x7f) | 0x80;
if (value < 0)
value = (value >> 7) | ~(((unsigned long long) -1) >> 7);
else
value = (value >> 7);
}
contents_ += value & 0x7f;
return *this;
}
Section &Section::ULEB128(u_int64_t value) {
while (value > 0x7f) {
contents_ += (value & 0x7f) | 0x80;
value = (value >> 7);
}
contents_ += value;
return *this;
}
Section &Section::Align(size_t alignment, u_int8_t pad_byte) {
// ALIGNMENT must be a power of two.
assert(((alignment - 1) & alignment) == 0);
size_t new_size = (contents_.size() + alignment - 1) & ~(alignment - 1);
contents_.append(new_size - contents_.size(), pad_byte);
assert((contents_.size() & (alignment - 1)) == 0);
return *this;
}
void Section::Clear() {
contents_.clear();
references_.clear();
}
bool Section::GetContents(string *contents) {
// For each label reference, find the label's value, and patch it into
// the section's contents.
for (size_t i = 0; i < references_.size(); i++) {
Reference &r = references_[i];
u_int64_t value;
if (!r.label.IsKnownConstant(&value)) {
fprintf(stderr, "Undefined label #%d at offset 0x%x\n", i, r.offset);
return false;
}
assert(r.offset < contents_.size());
assert(contents_.size() - r.offset >= r.size);
InsertEndian(r.endianness, r.size, value, contents_.begin() + r.offset);
}
contents->clear();
std::swap(contents_, *contents);
references_.clear();
return true;
}
} // namespace TestAssembler
} // namespace google_breakpad

View file

@ -0,0 +1,472 @@
// -*- mode: C++ -*-
// Copyright (c) 2010, 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: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
// test-assembler.h: interface to class for building complex binary streams.
// To test the Breakpad symbol dumper and processor thoroughly, for
// all combinations of host system and minidump processor
// architecture, we need to be able to easily generate complex test
// data like debugging information and minidump files.
//
// For example, if we want our unit tests to provide full code
// coverage for stack walking, it may be difficult to persuade the
// compiler to generate every possible sort of stack walking
// information that we want to support; there are probably DWARF CFI
// opcodes that GCC never emits. Similarly, if we want to test our
// error handling, we will need to generate damaged minidumps or
// debugging information that (we hope) the client or compiler will
// never produce on its own.
//
// google_breakpad::TestAssembler provides a predictable and
// (relatively) simple way to generate complex formatted data streams
// like minidumps and CFI. Furthermore, because TestAssembler is
// portable, developers without access to (say) Visual Studio or a
// SPARC assembler can still work on test data for those targets.
#ifndef PROCESSOR_TEST_ASSEMBLER_H_
#define PROCESSOR_TEST_ASSEMBLER_H_
#include <list>
#include <vector>
#include <string>
#include "google_breakpad/common/breakpad_types.h"
namespace google_breakpad {
using std::list;
using std::string;
using std::vector;
namespace TestAssembler {
// A Label represents a value not yet known that we need to store in a
// section. As long as all the labels a section refers to are defined
// by the time we retrieve its contents as bytes, we can use undefined
// labels freely in that section's construction.
//
// A label can be in one of three states:
// - undefined,
// - defined as the sum of some other label and a constant, or
// - a constant.
//
// A label's value never changes, but it can accumulate constraints.
// Adding labels and integers is permitted, and yields a label.
// Subtracting a constant from a label is permitted, and also yields a
// label. Subtracting two labels that have some relationship to each
// other is permitted, and yields a constant.
//
// For example:
//
// Label a; // a's value is undefined
// Label b; // b's value is undefined
// {
// Label c = a + 4; // okay, even though a's value is unknown
// b = c + 4; // also okay; b is now a+8
// }
// Label d = b - 2; // okay; d == a+6, even though c is gone
// d.Value(); // error: d's value is not yet known
// d - a; // is 6, even though their values are not known
// a = 12; // now b == 20, and d == 18
// d.Value(); // 18: no longer an error
// b.Value(); // 20
// d = 10; // error: d is already defined.
//
// Label objects' lifetimes are unconstrained: notice that, in the
// above example, even though a and b are only related through c, and
// c goes out of scope, the assignment to a sets b's value as well. In
// particular, it's not necessary to ensure that a Label lives beyond
// Sections that refer to it.
class Label {
public:
Label(); // An undefined label.
Label(u_int64_t value); // A label with a fixed value
Label(const Label &value); // A label equal to another.
~Label();
// Return this label's value; it must be known.
//
// Providing this as a cast operator is nifty, but the conversions
// happen in unexpected places. In particular, ISO C++ says that
// Label + size_t becomes ambigious, because it can't decide whether
// to convert the Label to a u_int64_t and then to a size_t, or use
// the overloaded operator that returns a new label, even though the
// former could fail if the label is not yet defined and the latter won't.
u_int64_t Value() const;
Label &operator=(u_int64_t value);
Label &operator=(const Label &value);
Label operator+(u_int64_t addend) const;
Label operator-(u_int64_t subtrahend) const;
u_int64_t operator-(const Label &subtrahend) const;
// We could also provide == and != that work on undefined, but
// related, labels.
// Return true if this label's value is known. If VALUE_P is given,
// set *VALUE_P to the known value if returning true.
bool IsKnownConstant(u_int64_t *value_p = NULL) const;
// Return true if the offset from LABEL to this label is known. If
// OFFSET_P is given, set *OFFSET_P to the offset when returning true.
//
// You can think of l.KnownOffsetFrom(m, &d) as being like 'd = l-m',
// except that it also returns a value indicating whether the
// subtraction is possible given what we currently know of l and m.
// It can be possible even if we don't know l and m's values. For
// example:
//
// Label l, m;
// m = l + 10;
// l.IsKnownConstant(); // false
// m.IsKnownConstant(); // false
// u_int64_t d;
// l.IsKnownOffsetFrom(m, &d); // true, and sets d to -10.
// l-m // -10
// m-l // 10
// m.Value() // error: m's value is not known
bool IsKnownOffsetFrom(const Label &label, u_int64_t *offset_p = NULL) const;
private:
// A label's value, or if that is not yet known, how the value is
// related to other labels' values. A binding may be:
// - a known constant,
// - constrained to be equal to some other binding plus a constant, or
// - unconstrained, and free to take on any value.
//
// Many labels may point to a single binding, and each binding may
// refer to another, so bindings and labels form trees whose leaves
// are labels, whose interior nodes (and roots) are bindings, and
// where links point from children to parents. Bindings are
// reference counted, allowing labels to be lightweight, copyable,
// assignable, placed in containers, and so on.
class Binding {
public:
Binding();
Binding(u_int64_t addend);
~Binding();
// Increment our reference count.
void Acquire() { reference_count_++; };
// Decrement our reference count, and return true if it is zero.
bool Release() { return --reference_count_ == 0; }
// Set this binding to be equal to BINDING + ADDEND. If BINDING is
// NULL, then set this binding to the known constant ADDEND.
// Update every binding on this binding's chain to point directly
// to BINDING, or to be a constant, with addends adjusted
// appropriately.
void Set(Binding *binding, u_int64_t value);
// Return what we know about the value of this binding.
// - If this binding's value is a known constant, set BASE to
// NULL, and set ADDEND to its value.
// - If this binding is not a known constant but related to other
// bindings, set BASE to the binding at the end of the relation
// chain (which will always be unconstrained), and set ADDEND to the
// value to add to that binding's value to get this binding's
// value.
// - If this binding is unconstrained, set BASE to this, and leave
// ADDEND unchanged.
void Get(Binding **base, u_int64_t *addend);
private:
// There are three cases:
//
// - A binding representing a known constant value has base_ NULL,
// and addend_ equal to the value.
//
// - A binding representing a completely unconstrained value has
// base_ pointing to this; addend_ is unused.
//
// - A binding whose value is related to some other binding's
// value has base_ pointing to that other binding, and addend_
// set to the amount to add to that binding's value to get this
// binding's value. We only represent relationships of the form
// x = y+c.
//
// Thus, the bind_ links form a chain terminating in either a
// known constant value or a completely unconstrained value. Most
// operations on bindings do path compression: they change every
// binding on the chain to point directly to the final value,
// adjusting addends as appropriate.
Binding *base_;
u_int64_t addend_;
// The number of Labels and Bindings pointing to this binding.
// (When a binding points to itself, indicating a completely
// unconstrained binding, that doesn't count as a reference.)
int reference_count_;
};
// This label's value.
Binding *value_;
};
inline Label operator+(u_int64_t a, const Label &l) { return l + a; }
// Note that int-Label isn't defined, as negating a Label is not an
// operation we support.
// Conventions for representing larger numbers as sequences of bytes.
enum Endianness {
kBigEndian, // Big-endian: the most significant byte comes first.
kLittleEndian, // Little-endian: the least significant byte comes first.
kUnsetEndian, // used internally
};
// A section is a sequence of bytes, constructed by appending bytes
// to the end. Sections have a convenient and flexible set of member
// functions for appending data in various formats: big-endian and
// little-endian signed and unsigned values of different sizes;
// LEB128 and ULEB128 values (see below), and raw blocks of bytes.
//
// If you need to append a value to a section that is not convenient
// to compute immediately, you can create a label, append the
// label's value to the section, and then set the label's value
// later, when it's convenient to do so. Once a label's value is
// known, the section class takes care of updating all previously
// appended references to it.
//
// Once all the labels to which a section refers have had their
// values determined, you can get a copy of the section's contents
// as a string.
//
// Note that there is no specified "start of section" label. This is
// because there are typically several different meanings for "the
// start of a section": the offset of the section within an object
// file, the address in memory at which the section's content appear,
// and so on. It's up to the code that uses the Section class to
// keep track of these explicitly, as they depend on the application.
class Section {
public:
Section(Endianness endianness = kUnsetEndian)
: endianness_(endianness) { };
~Section() { };
// Set the default endianness of this section to ENDIANNESS. This
// sets the behavior of the D<N> appending functions. If the
// assembler's default endianness was set, this is the
void set_endianness(Endianness endianness) {
endianness_ = endianness;
}
// Return the default endianness of this section.
Endianness endianness() const { return endianness_; }
// Append the SIZE bytes at DATA or the contents of STRING to the
// end of this section. Return a reference to this section.
Section &Append(const u_int8_t *data, size_t size) {
contents_.append(reinterpret_cast<const char *>(data), size);
return *this;
};
Section &Append(const string &data) {
contents_.append(data);
return *this;
};
// Append SIZE copies of BYTE to the end of this section. Return a
// reference to this section.
Section &Append(size_t size, u_int8_t byte) {
contents_.append(size, (char) byte);
return *this;
}
// Append NUMBER to this section. ENDIANNESS is the endianness to
// use to write the number. SIZE is the length of the number in
// bytes. Return a reference to this section.
Section &Append(Endianness endianness, size_t size, u_int64_t number);
Section &Append(Endianness endianness, size_t size, const Label &label);
// Append SECTION to the end of this section. The labels SECTION
// refers to need not be defined yet.
//
// Note that this has no effect on any Labels' values, or on
// SECTION. If placing SECTION within 'this' provides new
// constraints on existing labels' values, then it's up to the
// caller to fiddle with those labels as needed.
Section &Append(const Section &section);
// Append the contents of DATA as a series of bytes terminated by
// a NULL character.
Section &AppendCString(const string &data) {
Append(data);
contents_ += '\0';
return *this;
}
// Append VALUE or LABEL to this section, with the given bit width and
// endianness. Return a reference to this section.
//
// The names of these functions have the form <ENDIANNESS><BITWIDTH>:
// <ENDIANNESS> is either 'L' (little-endian, least significant byte first),
// 'B' (big-endian, most significant byte first), or
// 'D' (default, the section's default endianness)
// <BITWIDTH> is 8, 16, 32, or 64.
//
// Since endianness doesn't matter for a single byte, all the
// <BITWIDTH>=8 functions are equivalent.
//
// These can be used to write both signed and unsigned values, as
// the compiler will properly sign-extend a signed value before
// passing it to the function, at which point the function's
// behavior is the same either way.
Section &L8(u_int8_t value) { contents_ += value; return *this; }
Section &B8(u_int8_t value) { contents_ += value; return *this; }
Section &D8(u_int8_t value) { contents_ += value; return *this; }
Section &L16(u_int16_t), &L32(u_int32_t), &L64(u_int64_t),
&B16(u_int16_t), &B32(u_int32_t), &B64(u_int64_t),
&D16(u_int16_t), &D32(u_int32_t), &D64(u_int64_t);
Section &L8(const Label &label), &L16(const Label &label),
&L32(const Label &label), &L64(const Label &label),
&B8(const Label &label), &B16(const Label &label),
&B32(const Label &label), &B64(const Label &label),
&D8(const Label &label), &D16(const Label &label),
&D32(const Label &label), &D64(const Label &label);
// Append VALUE in a signed LEB128 (Little-Endian Base 128) form.
//
// The signed LEB128 representation of an integer N is a variable
// number of bytes:
//
// - If N is between -0x40 and 0x3f, then its signed LEB128
// representation is a single byte whose value is N.
//
// - Otherwise, its signed LEB128 representation is (N & 0x7f) |
// 0x80, followed by the signed LEB128 representation of N / 128,
// rounded towards negative infinity.
//
// In other words, we break VALUE into groups of seven bits, put
// them in little-endian order, and then write them as eight-bit
// bytes with the high bit on all but the last.
//
// Note that VALUE cannot be a Label (we would have to implement
// relaxation).
Section &LEB128(long long value);
// Append VALUE in unsigned LEB128 (Little-Endian Base 128) form.
//
// The unsigned LEB128 representation of an integer N is a variable
// number of bytes:
//
// - If N is between 0 and 0x7f, then its unsigned LEB128
// representation is a single byte whose value is N.
//
// - Otherwise, its unsigned LEB128 representation is (N & 0x7f) |
// 0x80, followed by the unsigned LEB128 representation of N /
// 128, rounded towards negative infinity.
//
// Note that VALUE cannot be a Label (we would have to implement
// relaxation).
Section &ULEB128(u_int64_t value);
// Jump to the next location aligned on an ALIGNMENT-byte boundary,
// relative to the start of the section. Fill the gap with PAD_BYTE.
// ALIGNMENT must be a power of two. Return a reference to this
// section.
Section &Align(size_t alignment, u_int8_t pad_byte = 0);
// Clear the contents of this section.
void Clear();
// Return the current size of the section.
size_t Size() const { return contents_.size(); }
// Return a label representing the start of the section.
//
// It is up to the user whether this label represents the section's
// position in an object file, the section's address in memory, or
// what have you; some applications may need both, in which case
// this simple-minded interface won't be enough. This class only
// provides a single start label, for use with the Here and Mark
// member functions.
//
// Ideally, we'd provide this in a subclass that actually knows more
// about the application at hand and can provide an appropriate
// collection of start labels. But then the appending member
// functions like Append and D32 would return a reference to the
// base class, not the derived class, and the chaining won't work.
// Since the only value here is in pretty notation, that's a fatal
// flaw.
Label start() const { return start_; }
// Return a label representing the point at which the next Appended
// item will appear in the section, relative to start().
Label Here() const { return start_ + Size(); }
// Set *LABEL to Here, and return a reference to this section.
Section &Mark(Label *label) { *label = Here(); return *this; }
// If there are no undefined label references left in this
// section, set CONTENTS to the contents of this section, as a
// string, and clear this section. Return true on success, or false
// if there were still undefined labels.
bool GetContents(string *contents);
private:
// Used internally. A reference to a label's value.
struct Reference {
Reference(size_t set_offset, Endianness set_endianness, size_t set_size,
const Label &set_label)
: offset(set_offset), endianness(set_endianness), size(set_size),
label(set_label) { }
// The offset of the reference within the section.
size_t offset;
// The endianness of the reference.
Endianness endianness;
// The size of the reference.
size_t size;
// The label to which this is a reference.
Label label;
};
// The default endianness of this section.
Endianness endianness_;
// The contents of the section.
string contents_;
// References to labels within those contents.
vector<Reference> references_;
// A label referring to the beginning of the section.
Label start_;
};
} // namespace TestAssembler
} // namespace google_breakpad
#endif // PROCESSOR_TEST_ASSEMBLER_H_

File diff suppressed because it is too large Load diff