michael@0: // -*- mode: c++ -*- michael@0: michael@0: // Copyright (c) 2012, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: michael@0: // Original author: Jim Blandy michael@0: michael@0: // dwarf2reader_test_common.h: Define TestCompilationUnit and michael@0: // TestAbbrevTable, classes for creating properly (and improperly) michael@0: // formatted DWARF compilation unit data for unit tests. michael@0: michael@0: #ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ michael@0: #define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ michael@0: michael@0: #include "common/test_assembler.h" michael@0: #include "common/dwarf/dwarf2enums.h" michael@0: michael@0: // A subclass of test_assembler::Section, specialized for constructing michael@0: // DWARF compilation units. michael@0: class TestCompilationUnit: public google_breakpad::test_assembler::Section { michael@0: public: michael@0: typedef dwarf2reader::DwarfTag DwarfTag; michael@0: typedef dwarf2reader::DwarfAttribute DwarfAttribute; michael@0: typedef dwarf2reader::DwarfForm DwarfForm; michael@0: typedef google_breakpad::test_assembler::Label Label; michael@0: michael@0: // Set the section's DWARF format size (the 32-bit DWARF format or the michael@0: // 64-bit DWARF format, for lengths and section offsets --- not the michael@0: // address size) to format_size. michael@0: void set_format_size(size_t format_size) { michael@0: assert(format_size == 4 || format_size == 8); michael@0: format_size_ = format_size; michael@0: } michael@0: michael@0: // Append a DWARF section offset value, of the appropriate size for this michael@0: // compilation unit. michael@0: template michael@0: void SectionOffset(T offset) { michael@0: if (format_size_ == 4) michael@0: D32(offset); michael@0: else michael@0: D64(offset); michael@0: } michael@0: michael@0: // Append a DWARF compilation unit header to the section, with the given michael@0: // DWARF version, abbrev table offset, and address size. michael@0: TestCompilationUnit &Header(int version, const Label &abbrev_offset, michael@0: size_t address_size) { michael@0: if (format_size_ == 4) { michael@0: D32(length_); michael@0: } else { michael@0: D32(0xffffffff); michael@0: D64(length_); michael@0: } michael@0: post_length_offset_ = Size(); michael@0: D16(version); michael@0: SectionOffset(abbrev_offset); michael@0: D8(address_size); michael@0: return *this; michael@0: } michael@0: michael@0: // Mark the end of this header's DIEs. michael@0: TestCompilationUnit &Finish() { michael@0: length_ = Size() - post_length_offset_; michael@0: return *this; michael@0: } michael@0: michael@0: private: michael@0: // The DWARF format size for this compilation unit. michael@0: size_t format_size_; michael@0: michael@0: // The offset of the point in the compilation unit header immediately michael@0: // after the initial length field. michael@0: uint64_t post_length_offset_; michael@0: michael@0: // The length of the compilation unit, not including the initial length field. michael@0: Label length_; michael@0: }; michael@0: michael@0: // A subclass of test_assembler::Section specialized for constructing DWARF michael@0: // abbreviation tables. michael@0: class TestAbbrevTable: public google_breakpad::test_assembler::Section { michael@0: public: michael@0: typedef dwarf2reader::DwarfTag DwarfTag; michael@0: typedef dwarf2reader::DwarfAttribute DwarfAttribute; michael@0: typedef dwarf2reader::DwarfForm DwarfForm; michael@0: typedef dwarf2reader::DwarfHasChild DwarfHasChild; michael@0: typedef google_breakpad::test_assembler::Label Label; michael@0: michael@0: // Start a new abbreviation table entry for abbreviation code |code|, michael@0: // encoding a DIE whose tag is |tag|, and which has children if and only michael@0: // if |has_children| is true. michael@0: TestAbbrevTable &Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) { michael@0: assert(code != 0); michael@0: ULEB128(code); michael@0: ULEB128(static_cast(tag)); michael@0: D8(static_cast(has_children)); michael@0: return *this; michael@0: }; michael@0: michael@0: // Add an attribute to the current abbreviation code whose name is |name| michael@0: // and whose form is |form|. michael@0: TestAbbrevTable &Attribute(DwarfAttribute name, DwarfForm form) { michael@0: ULEB128(static_cast(name)); michael@0: ULEB128(static_cast(form)); michael@0: return *this; michael@0: } michael@0: michael@0: // Finish the current abbreviation code. michael@0: TestAbbrevTable &EndAbbrev() { michael@0: ULEB128(0); michael@0: ULEB128(0); michael@0: return *this; michael@0: } michael@0: michael@0: // Finish the current abbreviation table. michael@0: TestAbbrevTable &EndTable() { michael@0: ULEB128(0); michael@0: return *this; michael@0: } michael@0: }; michael@0: michael@0: #endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__