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. 46class 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. 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> 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. 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. 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. 108class 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. 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|. 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. 136 TestAbbrevTable &EndAbbrev() { 137 ULEB128(0); 138 ULEB128(0); 139 return *this; 140 } 141 142 // Finish the current abbreviation table. 143 TestAbbrevTable &EndTable() { 144 ULEB128(0); 145 return *this; 146 } 147}; 148 149#endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ 150