diff options
Diffstat (limited to 'externals/breakpad/src/common/dwarf/dwarf2reader_lineinfo_unittest.cc')
-rw-r--r-- | externals/breakpad/src/common/dwarf/dwarf2reader_lineinfo_unittest.cc | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/externals/breakpad/src/common/dwarf/dwarf2reader_lineinfo_unittest.cc b/externals/breakpad/src/common/dwarf/dwarf2reader_lineinfo_unittest.cc new file mode 100644 index 0000000000..7de627d3c3 --- /dev/null +++ b/externals/breakpad/src/common/dwarf/dwarf2reader_lineinfo_unittest.cc @@ -0,0 +1,190 @@ +// Copyright 2020 Google LLC +// +// 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 LLC 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: Sterling Augustine <saugustine@google.com> + +// dwarf2reader_lineinfo_unittest.cc: Unit tests for google_breakpad::LineInfo + +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + +#include <stdint.h> +#include <stdlib.h> + +#include <string> +#include <vector> + +#include "breakpad_googletest_includes.h" +#include "common/dwarf/bytereader.h" +#include "common/dwarf/dwarf2reader.h" +#include "google_breakpad/common/breakpad_types.h" + +using std::vector; +using testing::InSequence; +using testing::Return; +using testing::Sequence; +using testing::Test; +using testing::_; + +using namespace google_breakpad; + +namespace { + +const uint8_t dwarf5_line_program[] = { + 0x40, 0x0, 0x0, 0x0, // unit_length (end - begin) + // begin + 0x05, 0x0, // version + 0x8, // address_size + 0x0, // segment_selector_size + 0x26, 0x0, 0x0, 0x0, // header_length (end_header_end - begin_header) + // begin_header: + 0x1, // minimum_instruction_length + 0x1, // maximum_operations_per_instruction + 0x1, // default_is_stmt + 0xfb, // line_base + 0xe, // line_range + 0xd, // opcode_base and lengths + 0x0, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, + 0x1, // directory entry format count + DW_LNCT_path, DW_FORM_strp, + 0x1, // directories count + 0x1, 0x0, 0x0, 0x0, // offset into .debug_line_str + 0x2, // file_name_entry_format_count + DW_LNCT_directory_index, DW_FORM_data1, + DW_LNCT_path, DW_FORM_line_strp, + 0x1, // filename count + 0x0, // directory index + 0x1, 0x0, 0x0, 0x0, // offset into .debug_str + // end_header + DW_LNS_set_file, 0x0, + // set address to 0x0 + 0x0, 0x9, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + // Advance Address by 0 and line by 3 + 0x15, + // Advance PC by 1 + 0x2, 0x1, + 0x0, + DW_LNE_end_sequence, + DW_LNE_end_sequence, + // end +}; + +const uint8_t dwarf4_line_program[] = { + 0x37, 0x0, 0x0, 0x0, // unit_length (end - begin) + // begin + 0x04, 0x0, // version + 0x1d, 0x0, 0x0, 0x0, // header_length (end_header - begin_header) + // begin_header: + 0x1, // minimum_instruction_length + 0x1, // maximum_operations_per_instruction + 0x1, // default_is_stmt + 0xfb, // line_base + 0xe, // line_range + 0xd, // opcode_base and lengths + 0x0, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, + '/', 'a', '\0', // directory entry 1 (zeroth entry implied) + '\0', // end of directory table + 'b', '/', 'c', '\0', // file entry 1 (zeroth entry implied) + 0, // file 1 directory + 0, // file 1 modification time + 0, // file 1 length + '\0', // end of file table + // end_header + DW_LNS_set_file, 0x0, + // set address to 0x0 + 0x0, 0x9, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + // Advance Address by 0 and line by 3 + 0x15, + // Advance PC by 1 + 0x2, 0x1, + 0x0, + DW_LNE_end_sequence, + DW_LNE_end_sequence, + // end +}; + +class MockLineInfoHandler: public LineInfoHandler { + public: + MOCK_METHOD(void, DefineDir, (const string&, uint32_t dir_num), (override)); + MOCK_METHOD(void, DefineFile, (const string& name, int32_t file_num, + uint32_t dir_num, uint64_t mod_time, + uint64_t length), (override)); + MOCK_METHOD(void, AddLine, (uint64_t address, uint64_t length, + uint32_t file_num, uint32_t line_num, + uint32_t column_num), (override)); +}; + +const uint8_t string_section[] = {'x', '/', 'a', '\0'}; +const uint8_t line_string_section[] = {'x', 'b', '/', 'c', '\0' }; + +struct LineProgram: public Test { + MockLineInfoHandler handler_; +}; + +TEST_F(LineProgram, ReadLinesDwarf5) { + ByteReader byte_reader(ENDIANNESS_LITTLE); + // LineTables don't specify the offset size like Compilation Units do. + byte_reader.SetOffsetSize(4); + LineInfo line_reader(dwarf5_line_program, + sizeof(dwarf5_line_program), + &byte_reader, + string_section, + sizeof(string_section), + line_string_section, + sizeof(line_string_section), + &handler_); + EXPECT_CALL(handler_, DefineDir("/a", 0)).Times(1); + EXPECT_CALL(handler_, DefineFile("b/c", 0, 0, 0, 0)).Times(1); + EXPECT_CALL(handler_, AddLine(0, 1, 0, 4, 0)).Times(1); + EXPECT_EQ(line_reader.Start(), sizeof(dwarf5_line_program)); +} + +TEST_F(LineProgram, ReadLinesDwarf4) { + ByteReader byte_reader(ENDIANNESS_LITTLE); + // LineTables don't specify the offset size like Compilation Units do. + byte_reader.SetOffsetSize(4); + // dwarf4 line info headers don't encode the address size. + byte_reader.SetAddressSize(8); + LineInfo line_reader(dwarf4_line_program, + sizeof(dwarf4_line_program), + &byte_reader, + // dwarf4 line tables can't access the string sections + // so pass values likely to make assertions fail if + // the code uses them improperly. + nullptr, 0, nullptr, 0, + &handler_); + EXPECT_CALL(handler_, DefineDir("", 0)).Times(1); + EXPECT_CALL(handler_, DefineDir("/a", 1)).Times(1); + EXPECT_CALL(handler_, DefineFile("", 0, 0, 0, 0)).Times(1); + EXPECT_CALL(handler_, DefineFile("b/c", 1, 0, 0, 0)).Times(1); + EXPECT_CALL(handler_, AddLine(0, 1, 0, 4, 0)).Times(1); + EXPECT_EQ(line_reader.Start(), sizeof(dwarf4_line_program)); +} + +} // anonymous namespace |