1 // -*- mode: c++ -*- 2 3 // Copyright 2012 Google LLC 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google LLC nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Original author: Jim Blandy <[email protected]> <[email protected]> 32 33 // dwarf2reader_test_common.h: Define TestCompilationUnit and 34 // TestAbbrevTable, classes for creating properly (and improperly) 35 // formatted DWARF compilation unit data for unit tests. 36 37 #ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ 38 #define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ 39 40 #include "common/test_assembler.h" 41 #include "common/dwarf/dwarf2enums.h" 42 43 // A subclass of test_assembler::Section, specialized for constructing 44 // DWARF compilation units. 45 class TestCompilationUnit: public google_breakpad::test_assembler::Section { 46 public: 47 typedef google_breakpad::DwarfTag DwarfTag; 48 typedef google_breakpad::DwarfAttribute DwarfAttribute; 49 typedef google_breakpad::DwarfForm DwarfForm; 50 typedef google_breakpad::test_assembler::Label Label; 51 52 // Set the section's DWARF format size (the 32-bit DWARF format or the 53 // 64-bit DWARF format, for lengths and section offsets --- not the 54 // address size) to format_size. set_format_size(size_t format_size)55 void set_format_size(size_t format_size) { 56 assert(format_size == 4 || format_size == 8); 57 format_size_ = format_size; 58 } 59 60 // Append a DWARF section offset value, of the appropriate size for this 61 // compilation unit. 62 template<typename T> SectionOffset(T offset)63 void SectionOffset(T offset) { 64 if (format_size_ == 4) 65 D32(offset); 66 else 67 D64(offset); 68 } 69 70 // Append a DWARF compilation unit header to the section, with the given 71 // DWARF version, abbrev table offset, and address size. Header(int version,const Label & abbrev_offset,size_t address_size,int header_type)72 TestCompilationUnit& Header(int version, const Label& abbrev_offset, 73 size_t address_size, int header_type) { 74 if (format_size_ == 4) { 75 D32(length_); 76 } else { 77 D32(0xffffffff); 78 D64(length_); 79 } 80 post_length_offset_ = Size(); 81 D16(version); 82 if (version <= 4) { 83 SectionOffset(abbrev_offset); 84 D8(address_size); 85 } else { 86 D8(header_type); // DW_UT_compile, DW_UT_type, etc. 87 D8(address_size); 88 SectionOffset(abbrev_offset); 89 if (header_type == google_breakpad::DW_UT_type) { 90 uint64_t dummy_type_signature = 0xdeadbeef; 91 uint64_t dummy_type_offset = 0x2b; 92 D64(dummy_type_signature); 93 if (format_size_ == 4) 94 D32(dummy_type_offset); 95 else 96 D64(dummy_type_offset); 97 } 98 } 99 return *this; 100 } 101 102 // Mark the end of this header's DIEs. Finish()103 TestCompilationUnit& Finish() { 104 length_ = Size() - post_length_offset_; 105 return *this; 106 } 107 108 private: 109 // The DWARF format size for this compilation unit. 110 size_t format_size_; 111 112 // The offset of the point in the compilation unit header immediately 113 // after the initial length field. 114 uint64_t post_length_offset_; 115 116 // The length of the compilation unit, not including the initial length field. 117 Label length_; 118 }; 119 120 // A subclass of test_assembler::Section specialized for constructing DWARF 121 // abbreviation tables. 122 class TestAbbrevTable: public google_breakpad::test_assembler::Section { 123 public: 124 typedef google_breakpad::DwarfTag DwarfTag; 125 typedef google_breakpad::DwarfAttribute DwarfAttribute; 126 typedef google_breakpad::DwarfForm DwarfForm; 127 typedef google_breakpad::DwarfHasChild DwarfHasChild; 128 typedef google_breakpad::test_assembler::Label Label; 129 130 // Start a new abbreviation table entry for abbreviation code |code|, 131 // encoding a DIE whose tag is |tag|, and which has children if and only 132 // if |has_children| is true. Abbrev(int code,DwarfTag tag,DwarfHasChild has_children)133 TestAbbrevTable& Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) { 134 assert(code != 0); 135 ULEB128(code); 136 ULEB128(static_cast<unsigned>(tag)); 137 D8(static_cast<unsigned>(has_children)); 138 return *this; 139 }; 140 141 // Add an attribute to the current abbreviation code whose name is |name| 142 // and whose form is |form|. Attribute(DwarfAttribute name,DwarfForm form)143 TestAbbrevTable& Attribute(DwarfAttribute name, DwarfForm form) { 144 ULEB128(static_cast<unsigned>(name)); 145 ULEB128(static_cast<unsigned>(form)); 146 return *this; 147 } 148 149 // Finish the current abbreviation code. EndAbbrev()150 TestAbbrevTable& EndAbbrev() { 151 ULEB128(0); 152 ULEB128(0); 153 return *this; 154 } 155 156 // Finish the current abbreviation table. EndTable()157 TestAbbrevTable& EndTable() { 158 ULEB128(0); 159 return *this; 160 } 161 }; 162 163 #endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ 164