xref: /aosp_15_r20/external/google-breakpad/src/common/dwarf/dwarf2reader_test_common.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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