// -*- mode: c++ -*- // Copyright (c) 2012, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> // dwarf2reader_test_common.h: Define TestCompilationUnit and // TestAbbrevTable, classes for creating properly (and improperly) // formatted DWARF compilation unit data for unit tests. #ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ #define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ #include "common/test_assembler.h" #include "common/dwarf/dwarf2enums.h" // A subclass of test_assembler::Section, specialized for constructing // DWARF compilation units. class TestCompilationUnit: public google_breakpad::test_assembler::Section { public: typedef dwarf2reader::DwarfTag DwarfTag; typedef dwarf2reader::DwarfAttribute DwarfAttribute; typedef dwarf2reader::DwarfForm DwarfForm; typedef google_breakpad::test_assembler::Label Label; // Set the section's DWARF format size (the 32-bit DWARF format or the // 64-bit DWARF format, for lengths and section offsets --- not the // address size) to format_size. void set_format_size(size_t format_size) { assert(format_size == 4 || format_size == 8); format_size_ = format_size; } // Append a DWARF section offset value, of the appropriate size for this // compilation unit. template<typename T> void SectionOffset(T offset) { if (format_size_ == 4) D32(offset); else D64(offset); } // Append a DWARF compilation unit header to the section, with the given // DWARF version, abbrev table offset, and address size. TestCompilationUnit &Header(int version, const Label &abbrev_offset, size_t address_size) { if (format_size_ == 4) { D32(length_); } else { D32(0xffffffff); D64(length_); } post_length_offset_ = Size(); D16(version); SectionOffset(abbrev_offset); D8(address_size); return *this; } // Mark the end of this header's DIEs. TestCompilationUnit &Finish() { length_ = Size() - post_length_offset_; return *this; } private: // The DWARF format size for this compilation unit. size_t format_size_; // The offset of the point in the compilation unit header immediately // after the initial length field. uint64_t post_length_offset_; // The length of the compilation unit, not including the initial length field. Label length_; }; // A subclass of test_assembler::Section specialized for constructing DWARF // abbreviation tables. class TestAbbrevTable: public google_breakpad::test_assembler::Section { public: typedef dwarf2reader::DwarfTag DwarfTag; typedef dwarf2reader::DwarfAttribute DwarfAttribute; typedef dwarf2reader::DwarfForm DwarfForm; typedef dwarf2reader::DwarfHasChild DwarfHasChild; typedef google_breakpad::test_assembler::Label Label; // Start a new abbreviation table entry for abbreviation code |code|, // encoding a DIE whose tag is |tag|, and which has children if and only // if |has_children| is true. TestAbbrevTable &Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) { assert(code != 0); ULEB128(code); ULEB128(static_cast<unsigned>(tag)); D8(static_cast<unsigned>(has_children)); return *this; }; // Add an attribute to the current abbreviation code whose name is |name| // and whose form is |form|. TestAbbrevTable &Attribute(DwarfAttribute name, DwarfForm form) { ULEB128(static_cast<unsigned>(name)); ULEB128(static_cast<unsigned>(form)); return *this; } // Finish the current abbreviation code. TestAbbrevTable &EndAbbrev() { ULEB128(0); ULEB128(0); return *this; } // Finish the current abbreviation table. TestAbbrevTable &EndTable() { ULEB128(0); return *this; } }; #endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__