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