Add partial unit tests for dwarf2reader::CompilationUnit.
This is really incomplete --- it's just what's needed to get started testing support for the DWARF 4 attribute forms. git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@910 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
e06ebb4817
commit
6eccfe32b1
4 changed files with 549 additions and 0 deletions
|
@ -398,6 +398,7 @@ src_common_dumper_unittest_SOURCES = \
|
|||
src/common/dwarf/dwarf2diehandler_unittest.cc \
|
||||
src/common/dwarf/dwarf2reader.cc \
|
||||
src/common/dwarf/dwarf2reader_cfi_unittest.cc \
|
||||
src/common/dwarf/dwarf2reader_die_unittest.cc \
|
||||
src/common/linux/dump_symbols.cc \
|
||||
src/common/linux/dump_symbols_unittest.cc \
|
||||
src/common/linux/elf_core_dump.cc \
|
||||
|
|
22
Makefile.in
22
Makefile.in
|
@ -455,6 +455,7 @@ am__src_common_dumper_unittest_SOURCES_DIST = \
|
|||
src/common/dwarf/dwarf2diehandler_unittest.cc \
|
||||
src/common/dwarf/dwarf2reader.cc \
|
||||
src/common/dwarf/dwarf2reader_cfi_unittest.cc \
|
||||
src/common/dwarf/dwarf2reader_die_unittest.cc \
|
||||
src/common/linux/dump_symbols.cc \
|
||||
src/common/linux/dump_symbols_unittest.cc \
|
||||
src/common/linux/elf_core_dump.cc \
|
||||
|
@ -497,6 +498,7 @@ am__src_common_dumper_unittest_SOURCES_DIST = \
|
|||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler_unittest.$(OBJEXT) \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader.$(OBJEXT) \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.$(OBJEXT) \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.$(OBJEXT) \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-dump_symbols.$(OBJEXT) \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-dump_symbols_unittest.$(OBJEXT) \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-elf_core_dump.$(OBJEXT) \
|
||||
|
@ -1481,6 +1483,7 @@ TESTS_ENVIRONMENT =
|
|||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler_unittest.cc \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_cfi_unittest.cc \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_die_unittest.cc \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.cc \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols_unittest.cc \
|
||||
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_core_dump.cc \
|
||||
|
@ -2604,6 +2607,9 @@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader.$(OBJEXT): \
|
|||
src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.$(OBJEXT): \
|
||||
src/common/dwarf/$(am__dirstamp) \
|
||||
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
|
||||
src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.$(OBJEXT): \
|
||||
src/common/dwarf/$(am__dirstamp) \
|
||||
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
|
||||
src/common/linux/src_common_dumper_unittest-dump_symbols.$(OBJEXT): \
|
||||
src/common/linux/$(am__dirstamp) \
|
||||
src/common/linux/$(DEPDIR)/$(am__dirstamp)
|
||||
|
@ -3107,6 +3113,7 @@ mostlyclean-compile:
|
|||
-rm -f src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler_unittest.$(OBJEXT)
|
||||
-rm -f src/common/dwarf/src_common_dumper_unittest-dwarf2reader.$(OBJEXT)
|
||||
-rm -f src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.$(OBJEXT)
|
||||
-rm -f src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.$(OBJEXT)
|
||||
-rm -f src/common/dwarf_cfi_to_module.$(OBJEXT)
|
||||
-rm -f src/common/dwarf_cu_to_module.$(OBJEXT)
|
||||
-rm -f src/common/dwarf_line_to_module.$(OBJEXT)
|
||||
|
@ -3359,6 +3366,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2diehandler_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_cfi_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/dump_symbols.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elf_core_dump.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elf_symbols_to_module.Po@am__quote@
|
||||
|
@ -4123,6 +4131,20 @@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.obj: src/c
|
|||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.obj `if test -f 'src/common/dwarf/dwarf2reader_cfi_unittest.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader_cfi_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader_cfi_unittest.cc'; fi`
|
||||
|
||||
src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.o: src/common/dwarf/dwarf2reader_die_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Tpo -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.o `test -f 'src/common/dwarf/dwarf2reader_die_unittest.cc' || echo '$(srcdir)/'`src/common/dwarf/dwarf2reader_die_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Tpo src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/dwarf/dwarf2reader_die_unittest.cc' object='src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.o `test -f 'src/common/dwarf/dwarf2reader_die_unittest.cc' || echo '$(srcdir)/'`src/common/dwarf/dwarf2reader_die_unittest.cc
|
||||
|
||||
src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.obj: src/common/dwarf/dwarf2reader_die_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.obj -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Tpo -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.obj `if test -f 'src/common/dwarf/dwarf2reader_die_unittest.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader_die_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader_die_unittest.cc'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Tpo src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/dwarf/dwarf2reader_die_unittest.cc' object='src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.obj `if test -f 'src/common/dwarf/dwarf2reader_die_unittest.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader_die_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader_die_unittest.cc'; fi`
|
||||
|
||||
src/common/linux/src_common_dumper_unittest-dump_symbols.o: src/common/linux/dump_symbols.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-dump_symbols.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-dump_symbols.Tpo -c -o src/common/linux/src_common_dumper_unittest-dump_symbols.o `test -f 'src/common/linux/dump_symbols.cc' || echo '$(srcdir)/'`src/common/linux/dump_symbols.cc
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-dump_symbols.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-dump_symbols.Po
|
||||
|
|
377
src/common/dwarf/dwarf2reader_die_unittest.cc
Normal file
377
src/common/dwarf/dwarf2reader_die_unittest.cc
Normal file
|
@ -0,0 +1,377 @@
|
|||
// Copyright (c) 2012, 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>
|
||||
|
||||
// dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "breakpad_googletest_includes.h"
|
||||
#include "common/dwarf/bytereader-inl.h"
|
||||
#include "common/dwarf/dwarf2reader_test_common.h"
|
||||
#include "common/dwarf/dwarf2reader.h"
|
||||
#include "google_breakpad/common/breakpad_types.h"
|
||||
|
||||
using google_breakpad::test_assembler::Endianness;
|
||||
using google_breakpad::test_assembler::Label;
|
||||
using google_breakpad::test_assembler::Section;
|
||||
using google_breakpad::test_assembler::kBigEndian;
|
||||
using google_breakpad::test_assembler::kLittleEndian;
|
||||
|
||||
using dwarf2reader::AttributeList;
|
||||
using dwarf2reader::ByteReader;
|
||||
using dwarf2reader::CompilationUnit;
|
||||
using dwarf2reader::Dwarf2Handler;
|
||||
using dwarf2reader::DwarfAttribute;
|
||||
using dwarf2reader::DwarfForm;
|
||||
using dwarf2reader::DwarfHasChild;
|
||||
using dwarf2reader::DwarfTag;
|
||||
using dwarf2reader::ENDIANNESS_BIG;
|
||||
using dwarf2reader::ENDIANNESS_LITTLE;
|
||||
using dwarf2reader::SectionMap;
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using testing::InSequence;
|
||||
using testing::Pointee;
|
||||
using testing::Return;
|
||||
using testing::Sequence;
|
||||
using testing::Test;
|
||||
using testing::TestWithParam;
|
||||
using testing::_;
|
||||
|
||||
class MockDwarf2Handler: public Dwarf2Handler {
|
||||
public:
|
||||
MOCK_METHOD5(StartCompilationUnit, bool(uint64 offset, uint8 address_size,
|
||||
uint8 offset_size, uint64 cu_length,
|
||||
uint8 dwarf_version));
|
||||
MOCK_METHOD3(StartDIE, bool(uint64 offset, enum DwarfTag tag,
|
||||
const AttributeList& attrs));
|
||||
MOCK_METHOD4(ProcessAttributeUnsigned, void(uint64 offset,
|
||||
DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 data));
|
||||
MOCK_METHOD4(ProcessAttributeSigned, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
int64 data));
|
||||
MOCK_METHOD4(ProcessAttributeReference, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 data));
|
||||
MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const char* data,
|
||||
uint64 len));
|
||||
MOCK_METHOD4(ProcessAttributeString, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const std::string& data));
|
||||
MOCK_METHOD1(EndDIE, void(uint64 offset));
|
||||
};
|
||||
|
||||
struct DIEFixture {
|
||||
|
||||
DIEFixture() {
|
||||
// Fix the initial offset of the .debug_info and .debug_abbrev sections.
|
||||
info.start() = 0;
|
||||
abbrevs.start() = 0;
|
||||
|
||||
// Default expectations for the data handler.
|
||||
EXPECT_CALL(handler, StartCompilationUnit(_, _, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, StartDIE(_, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeUnsigned(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeSigned(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeReference(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, _, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeString(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, EndDIE(_)).Times(0);
|
||||
}
|
||||
|
||||
// Return a reference to a section map whose .debug_info section refers
|
||||
// to |info|, and whose .debug_abbrev section refers to |abbrevs|. This
|
||||
// function returns a reference to the same SectionMap each time; new
|
||||
// calls wipe out maps established by earlier calls.
|
||||
const SectionMap &MakeSectionMap() {
|
||||
// Copy the sections' contents into strings that will live as long as
|
||||
// the map itself.
|
||||
assert(info.GetContents(&info_contents));
|
||||
assert(abbrevs.GetContents(&abbrevs_contents));
|
||||
section_map.clear();
|
||||
section_map[".debug_info"].first = info_contents.data();
|
||||
section_map[".debug_info"].second = info_contents.size();
|
||||
section_map[".debug_abbrev"].first = abbrevs_contents.data();
|
||||
section_map[".debug_abbrev"].second = abbrevs_contents.size();
|
||||
return section_map;
|
||||
}
|
||||
|
||||
TestCompilationUnit info;
|
||||
TestAbbrevTable abbrevs;
|
||||
MockDwarf2Handler handler;
|
||||
string abbrevs_contents, info_contents;
|
||||
SectionMap section_map;
|
||||
};
|
||||
|
||||
struct DwarfHeaderParams {
|
||||
DwarfHeaderParams(Endianness endianness, size_t format_size,
|
||||
int version, size_t address_size)
|
||||
: endianness(endianness), format_size(format_size),
|
||||
version(version), address_size(address_size) { }
|
||||
Endianness endianness;
|
||||
size_t format_size; // 4-byte or 8-byte DWARF offsets
|
||||
int version;
|
||||
size_t address_size;
|
||||
};
|
||||
|
||||
class DwarfHeader: public DIEFixture,
|
||||
public TestWithParam<DwarfHeaderParams> { };
|
||||
|
||||
TEST_P(DwarfHeader, Header) {
|
||||
Label abbrev_table = abbrevs.Here();
|
||||
abbrevs.Abbrev(1, dwarf2reader::DW_TAG_compile_unit,
|
||||
dwarf2reader::DW_children_yes)
|
||||
.Attribute(dwarf2reader::DW_AT_name, dwarf2reader::DW_FORM_string)
|
||||
.EndAbbrev()
|
||||
.EndTable();
|
||||
|
||||
info.set_format_size(GetParam().format_size);
|
||||
info.set_endianness(GetParam().endianness);
|
||||
|
||||
info.Header(GetParam().version, abbrev_table, GetParam().address_size)
|
||||
.ULEB128(1) // DW_TAG_compile_unit, with children
|
||||
.AppendCString("sam") // DW_AT_name, DW_FORM_string
|
||||
.D8(0); // end of children
|
||||
info.Finish();
|
||||
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(handler,
|
||||
StartCompilationUnit(0, GetParam().address_size,
|
||||
GetParam().format_size, _,
|
||||
GetParam().version))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit, _))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, ProcessAttributeString(_, dwarf2reader::DW_AT_name,
|
||||
dwarf2reader::DW_FORM_string,
|
||||
"sam"))
|
||||
.WillOnce(Return());
|
||||
EXPECT_CALL(handler, EndDIE(_))
|
||||
.WillOnce(Return());
|
||||
}
|
||||
|
||||
ByteReader byte_reader(GetParam().endianness == kLittleEndian ?
|
||||
ENDIANNESS_LITTLE : ENDIANNESS_BIG);
|
||||
CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler);
|
||||
EXPECT_EQ(parser.Start(), info_contents.size());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
HeaderVariants, DwarfHeader,
|
||||
::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 8)));
|
||||
|
||||
struct DwarfFormsFixture: public DIEFixture {
|
||||
// Start a compilation unit, as directed by |params|, containing one
|
||||
// childless DIE of the given tag, with one attribute of the given name
|
||||
// and form. The 'info' fixture member is left just after the abbrev
|
||||
// code, waiting for the attribute value to be appended.
|
||||
void StartSingleAttributeDIE(const DwarfHeaderParams ¶ms,
|
||||
DwarfTag tag, DwarfAttribute name,
|
||||
DwarfForm form) {
|
||||
// Create the abbreviation table.
|
||||
Label abbrev_table = abbrevs.Here();
|
||||
abbrevs.Abbrev(1, tag, dwarf2reader::DW_children_no)
|
||||
.Attribute(name, form)
|
||||
.EndAbbrev()
|
||||
.EndTable();
|
||||
|
||||
// Create the compilation unit, up to the attribute value.
|
||||
info.set_format_size(params.format_size);
|
||||
info.set_endianness(params.endianness);
|
||||
info.Header(params.version, abbrev_table, params.address_size)
|
||||
.ULEB128(1); // abbrev code
|
||||
}
|
||||
|
||||
// Set up handler to expect a compilation unit matching |params|,
|
||||
// containing one childless DIE of the given tag, in the sequence s. Stop
|
||||
// just before the expectations.
|
||||
void ExpectBeginCompilationUnit(const DwarfHeaderParams ¶ms,
|
||||
DwarfTag tag) {
|
||||
EXPECT_CALL(handler,
|
||||
StartCompilationUnit(0, params.address_size,
|
||||
params.format_size, _,
|
||||
params.version))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, StartDIE(_, tag, _))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return(true));
|
||||
}
|
||||
|
||||
void ExpectEndCompilationUnit() {
|
||||
EXPECT_CALL(handler, EndDIE(_))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
}
|
||||
|
||||
void ParseCompilationUnit(const DwarfHeaderParams ¶ms) {
|
||||
ByteReader byte_reader(params.endianness == kLittleEndian ?
|
||||
ENDIANNESS_LITTLE : ENDIANNESS_BIG);
|
||||
CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler);
|
||||
EXPECT_EQ(parser.Start(), info_contents.size());
|
||||
}
|
||||
|
||||
// The sequence to which the fixture's methods append expectations.
|
||||
Sequence s;
|
||||
};
|
||||
|
||||
struct DwarfForms: public DwarfFormsFixture,
|
||||
public TestWithParam<DwarfHeaderParams> { };
|
||||
|
||||
TEST_P(DwarfForms, addr) {
|
||||
StartSingleAttributeDIE(GetParam(), dwarf2reader::DW_TAG_compile_unit,
|
||||
dwarf2reader::DW_AT_low_pc,
|
||||
dwarf2reader::DW_FORM_addr);
|
||||
u_int64_t value;
|
||||
if (GetParam().address_size == 4) {
|
||||
value = 0xc8e9ffcc;
|
||||
info.D32(value);
|
||||
} else {
|
||||
value = 0xe942517fc2768564ULL;
|
||||
info.D64(value);
|
||||
}
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), dwarf2reader::DW_TAG_compile_unit);
|
||||
EXPECT_CALL(handler, ProcessAttributeUnsigned(_, dwarf2reader::DW_AT_low_pc,
|
||||
dwarf2reader::DW_FORM_addr,
|
||||
value))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, block2_empty) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7,
|
||||
(DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2);
|
||||
info.D16(0);
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2,
|
||||
_, 0))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, block2) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7,
|
||||
(DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2);
|
||||
unsigned char data[258];
|
||||
memset(data, '*', sizeof(data));
|
||||
info.D16(sizeof(data))
|
||||
.Append(data, sizeof(data));
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2,
|
||||
Pointee('*'), 258))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
// Tests for the other attribute forms could go here.
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
HeaderVariants, DwarfForms,
|
||||
::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 8)));
|
149
src/common/dwarf/dwarf2reader_test_common.h
Normal file
149
src/common/dwarf/dwarf2reader_test_common.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
// -*- mode: c++ -*-
|
||||
|
||||
// Copyright (c) 2012, 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>
|
||||
|
||||
// dwarf2reader_test_common.h: Define TestCompilationUnit and
|
||||
// TestAbbrevTable, classes for creating properly (and improperly)
|
||||
// formatted DWARF compilation unit data for unit tests.
|
||||
|
||||
#ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
|
||||
#define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
|
||||
|
||||
#include "common/test_assembler.h"
|
||||
#include "common/dwarf/dwarf2enums.h"
|
||||
|
||||
// A subclass of test_assembler::Section, specialized for constructing
|
||||
// DWARF compilation units.
|
||||
class TestCompilationUnit: public google_breakpad::test_assembler::Section {
|
||||
public:
|
||||
typedef dwarf2reader::DwarfTag DwarfTag;
|
||||
typedef dwarf2reader::DwarfAttribute DwarfAttribute;
|
||||
typedef dwarf2reader::DwarfForm DwarfForm;
|
||||
typedef google_breakpad::test_assembler::Label Label;
|
||||
|
||||
// Set the section's DWARF format size (the 32-bit DWARF format or the
|
||||
// 64-bit DWARF format, for lengths and section offsets --- not the
|
||||
// address size) to format_size.
|
||||
void set_format_size(size_t format_size) {
|
||||
assert(format_size == 4 || format_size == 8);
|
||||
format_size_ = format_size;
|
||||
}
|
||||
|
||||
// Append a DWARF section offset value, of the appropriate size for this
|
||||
// compilation unit.
|
||||
template<typename T>
|
||||
void SectionOffset(T offset) {
|
||||
if (format_size_ == 4)
|
||||
D32(offset);
|
||||
else
|
||||
D64(offset);
|
||||
}
|
||||
|
||||
// Append a DWARF compilation unit header to the section, with the given
|
||||
// DWARF version, abbrev table offset, and address size.
|
||||
TestCompilationUnit &Header(int version, const Label &abbrev_offset,
|
||||
size_t address_size) {
|
||||
if (format_size_ == 4) {
|
||||
D32(length_);
|
||||
} else {
|
||||
D32(0xffffffff);
|
||||
D64(length_);
|
||||
}
|
||||
post_length_offset_ = Size();
|
||||
D16(version);
|
||||
SectionOffset(abbrev_offset);
|
||||
D8(address_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Mark the end of this header's DIEs.
|
||||
TestCompilationUnit &Finish() {
|
||||
length_ = Size() - post_length_offset_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// The DWARF format size for this compilation unit.
|
||||
size_t format_size_;
|
||||
|
||||
// The offset of the point in the compilation unit header immediately
|
||||
// after the initial length field.
|
||||
u_int64_t post_length_offset_;
|
||||
|
||||
// The length of the compilation unit, not including the initial length field.
|
||||
Label length_;
|
||||
};
|
||||
|
||||
// A subclass of test_assembler::Section specialized for constructing DWARF
|
||||
// abbreviation tables.
|
||||
class TestAbbrevTable: public google_breakpad::test_assembler::Section {
|
||||
public:
|
||||
typedef dwarf2reader::DwarfTag DwarfTag;
|
||||
typedef dwarf2reader::DwarfAttribute DwarfAttribute;
|
||||
typedef dwarf2reader::DwarfForm DwarfForm;
|
||||
typedef dwarf2reader::DwarfHasChild DwarfHasChild;
|
||||
typedef google_breakpad::test_assembler::Label Label;
|
||||
|
||||
// Start a new abbreviation table entry for abbreviation code |code|,
|
||||
// encoding a DIE whose tag is |tag|, and which has children if and only
|
||||
// if |has_children| is true.
|
||||
TestAbbrevTable &Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) {
|
||||
assert(code != 0);
|
||||
ULEB128(code);
|
||||
ULEB128(static_cast<unsigned>(tag));
|
||||
D8(static_cast<unsigned>(has_children));
|
||||
return *this;
|
||||
};
|
||||
|
||||
// Add an attribute to the current abbreviation code whose name is |name|
|
||||
// and whose form is |form|.
|
||||
TestAbbrevTable &Attribute(DwarfAttribute name, DwarfForm form) {
|
||||
ULEB128(static_cast<unsigned>(name));
|
||||
ULEB128(static_cast<unsigned>(form));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Finish the current abbreviation code.
|
||||
TestAbbrevTable &EndAbbrev() {
|
||||
ULEB128(0);
|
||||
ULEB128(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Finish the current abbreviation table.
|
||||
TestAbbrevTable &EndTable() {
|
||||
ULEB128(0);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
|
Loading…
Reference in a new issue