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