13e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// -*- mode: C++ -*- 23e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 33e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// Copyright (c) 2010, Google Inc. 43e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// All rights reserved. 53e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// 63e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// Redistribution and use in source and binary forms, with or without 73e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// modification, are permitted provided that the following conditions are 83e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// met: 93e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// 103e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// * Redistributions of source code must retain the above copyright 113e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// notice, this list of conditions and the following disclaimer. 123e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// * Redistributions in binary form must reproduce the above 133e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// copyright notice, this list of conditions and the following disclaimer 143e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// in the documentation and/or other materials provided with the 153e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// distribution. 163e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// * Neither the name of Google Inc. nor the names of its 173e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// contributors may be used to endorse or promote products derived from 183e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// this software without specific prior written permission. 193e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// 203e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 213e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 223e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 233e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 243e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 253e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 263e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 273e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 283e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 293e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 303e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 313e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 323e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 333e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 344f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek// cfi_assembler.h: Define CFISection, a class for creating properly 353e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy// (and improperly) formatted DWARF CFI data for unit tests. 363e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 373e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy#ifndef PROCESSOR_CFI_ASSEMBLER_H_ 383e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy#define PROCESSOR_CFI_ASSEMBLER_H_ 393e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 403e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy#include <string> 413e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 42a76aaa1442d765410da36d743ef92748ea1b815ejimblandy#include "common/dwarf/dwarf2enums.h" 43865df5af57922a4dc1e2a24e3f5c371d84f0f574jimblandy#include "common/test_assembler.h" 444e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h" 453e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy#include "google_breakpad/common/breakpad_types.h" 463e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 473e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandynamespace google_breakpad { 483e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 49a76aaa1442d765410da36d743ef92748ea1b815ejimblandyusing dwarf2reader::DwarfPointerEncoding; 5035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing google_breakpad::test_assembler::Endianness; 5135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing google_breakpad::test_assembler::Label; 5235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing google_breakpad::test_assembler::Section; 533e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 543e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandyclass CFISection: public Section { 553e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy public: 56a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 57a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // CFI augmentation strings beginning with 'z', defined by the 58a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Linux/IA-64 C++ ABI, can specify interesting encodings for 59a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // addresses appearing in FDE headers and call frame instructions (and 60a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // for additional fields whose presence the augmentation string 61a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // specifies). In particular, pointers can be specified to be relative 62a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // to various base address: the start of the .text section, the 63a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // location holding the address itself, and so on. These allow the 64a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // frame data to be position-independent even when they live in 65a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // write-protected pages. These variants are specified at the 66a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // following two URLs: 67a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // 68a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html 69a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html 70a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // 71a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // CFISection leaves the production of well-formed 'z'-augmented CIEs and 72a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // FDEs to the user, but does provide EncodedPointer, to emit 73a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // properly-encoded addresses for a given pointer encoding. 74a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // EncodedPointer uses an instance of this structure to find the base 75a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // addresses it should use; you can establish a default for all encoded 76a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // pointers appended to this section with SetEncodedPointerBases. 77a76aaa1442d765410da36d743ef92748ea1b815ejimblandy struct EncodedPointerBases { 78a76aaa1442d765410da36d743ef92748ea1b815ejimblandy EncodedPointerBases() : cfi(), text(), data() { } 79a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 80a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // The starting address of this CFI section in memory, for 81a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // DW_EH_PE_pcrel. DW_EH_PE_pcrel pointers may only be used in data 82a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // that has is loaded into the program's address space. 836162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t cfi; 84a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 85a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // The starting address of this file's .text section, for DW_EH_PE_textrel. 866162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t text; 87a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 88a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // The starting address of this file's .got or .eh_frame_hdr section, 89a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // for DW_EH_PE_datarel. 906162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t data; 91a76aaa1442d765410da36d743ef92748ea1b815ejimblandy }; 92a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 933e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Create a CFISection whose endianness is ENDIANNESS, and where 94a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // machine addresses are ADDRESS_SIZE bytes long. If EH_FRAME is 95a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // true, use the .eh_frame format, as described by the Linux 96a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Standards Base Core Specification, instead of the DWARF CFI 97a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // format. 98a76aaa1442d765410da36d743ef92748ea1b815ejimblandy CFISection(Endianness endianness, size_t address_size, 99a76aaa1442d765410da36d743ef92748ea1b815ejimblandy bool eh_frame = false) 100a76aaa1442d765410da36d743ef92748ea1b815ejimblandy : Section(endianness), address_size_(address_size), eh_frame_(eh_frame), 101a76aaa1442d765410da36d743ef92748ea1b815ejimblandy pointer_encoding_(dwarf2reader::DW_EH_PE_absptr), 102a76aaa1442d765410da36d743ef92748ea1b815ejimblandy encoded_pointer_bases_(), entry_length_(NULL), in_fde_(false) { 1033e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // The 'start', 'Here', and 'Mark' members of a CFISection all refer 1043e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // to section offsets. 1053e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy start() = 0; 1063e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy } 1073e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1083e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Return this CFISection's address size. 1093e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy size_t AddressSize() const { return address_size_; } 1103e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 111a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Return true if this CFISection uses the .eh_frame format, or 112a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // false if it contains ordinary DWARF CFI data. 113a76aaa1442d765410da36d743ef92748ea1b815ejimblandy bool ContainsEHFrame() const { return eh_frame_; } 114a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 115a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Use ENCODING for pointers in calls to FDEHeader and EncodedPointer. 116a76aaa1442d765410da36d743ef92748ea1b815ejimblandy void SetPointerEncoding(DwarfPointerEncoding encoding) { 117a76aaa1442d765410da36d743ef92748ea1b815ejimblandy pointer_encoding_ = encoding; 118a76aaa1442d765410da36d743ef92748ea1b815ejimblandy } 119a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 120a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Use the addresses in BASES as the base addresses for encoded 121a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // pointers in subsequent calls to FDEHeader or EncodedPointer. 122a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // This function makes a copy of BASES. 123a76aaa1442d765410da36d743ef92748ea1b815ejimblandy void SetEncodedPointerBases(const EncodedPointerBases &bases) { 124a76aaa1442d765410da36d743ef92748ea1b815ejimblandy encoded_pointer_bases_ = bases; 125a76aaa1442d765410da36d743ef92748ea1b815ejimblandy } 126a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 1273e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Append a Common Information Entry header to this section with the 1283e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // given values. If dwarf64 is true, use the 64-bit DWARF initial 1293e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // length format for the CIE's initial length. Return a reference to 1303e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // this section. You should call FinishEntry after writing the last 1313e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // instruction for the CIE. 1323e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // 1333e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Before calling this function, you will typically want to use Mark 1343e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // or Here to make a label to pass to FDEHeader that refers to this 1353e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // CIE's position in the section. 1366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &CIEHeader(uint64_t code_alignment_factor, 1373e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy int data_alignment_factor, 1383e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy unsigned return_address_register, 1396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t version = 3, 1403e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy const string &augmentation = "", 1413e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy bool dwarf64 = false); 1423e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1433e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Append a Frame Description Entry header to this section with the 1443e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // given values. If dwarf64 is true, use the 64-bit DWARF initial 1453e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // length format for the CIE's initial length. Return a reference to 1463e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // this section. You should call FinishEntry after writing the last 1473e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // instruction for the CIE. 1483e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // 1493e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // This function doesn't support entries that are longer than 1503e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // 0xffffff00 bytes. (The "initial length" is always a 32-bit 1513e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // value.) Nor does it support .debug_frame sections longer than 1523e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // 0xffffff00 bytes. 1533e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &FDEHeader(Label cie_pointer, 1546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t initial_location, 1556162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address_range, 1563e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy bool dwarf64 = false); 1573e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1583e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Note the current position as the end of the last CIE or FDE we 1593e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // started, after padding with DW_CFA_nops for alignment. This 1603e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // defines the label representing the entry's length, cited in the 1613e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // entry's header. Return a reference to this section. 1623e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &FinishEntry(); 1633e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1643e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Append the contents of BLOCK as a DW_FORM_block value: an 1653e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // unsigned LEB128 length, followed by that many bytes of data. 1663e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &Block(const string &block) { 1673e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy ULEB128(block.size()); 1683e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy Append(block); 1693e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy return *this; 1703e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy } 1713e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 172a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Append ADDRESS to this section, in the appropriate size and 173a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // endianness. Return a reference to this section. 1746162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &Address(uint64_t address) { 175a76aaa1442d765410da36d743ef92748ea1b815ejimblandy Section::Append(endianness(), address_size_, address); 176a76aaa1442d765410da36d743ef92748ea1b815ejimblandy return *this; 177a76aaa1442d765410da36d743ef92748ea1b815ejimblandy } 178a76aaa1442d765410da36d743ef92748ea1b815ejimblandy CFISection &Address(Label address) { 179a76aaa1442d765410da36d743ef92748ea1b815ejimblandy Section::Append(endianness(), address_size_, address); 180a76aaa1442d765410da36d743ef92748ea1b815ejimblandy return *this; 181a76aaa1442d765410da36d743ef92748ea1b815ejimblandy } 182a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 183a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Append ADDRESS to this section, using ENCODING and BASES. ENCODING 184a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // defaults to this section's default encoding, established by 185a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // SetPointerEncoding. BASES defaults to this section's bases, set by 186a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // SetEncodedPointerBases. If the DW_EH_PE_indirect bit is set in the 187a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // encoding, assume that ADDRESS is where the true address is stored. 188a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // Return a reference to this section. 189a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // 190a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // (C++ doesn't let me use default arguments here, because I want to 191a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // refer to members of *this in the default argument expression.) 1926162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &EncodedPointer(uint64_t address) { 193a76aaa1442d765410da36d743ef92748ea1b815ejimblandy return EncodedPointer(address, pointer_encoding_, encoded_pointer_bases_); 194a76aaa1442d765410da36d743ef92748ea1b815ejimblandy } 1956162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding) { 196a76aaa1442d765410da36d743ef92748ea1b815ejimblandy return EncodedPointer(address, encoding, encoded_pointer_bases_); 197a76aaa1442d765410da36d743ef92748ea1b815ejimblandy } 1986162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding, 199a76aaa1442d765410da36d743ef92748ea1b815ejimblandy const EncodedPointerBases &bases); 200a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 2013e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Restate some member functions, to keep chaining working nicely. 2023e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &Mark(Label *label) { Section::Mark(label); return *this; } 2036162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &D8(uint8_t v) { Section::D8(v); return *this; } 2046162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &D16(uint16_t v) { Section::D16(v); return *this; } 2053e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &D16(Label v) { Section::D16(v); return *this; } 2066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &D32(uint32_t v) { Section::D32(v); return *this; } 2073e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &D32(const Label &v) { Section::D32(v); return *this; } 2086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &D64(uint64_t v) { Section::D64(v); return *this; } 2093e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &D64(const Label &v) { Section::D64(v); return *this; } 2103e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy CFISection &LEB128(long long v) { Section::LEB128(v); return *this; } 2116162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com CFISection &ULEB128(uint64_t v) { Section::ULEB128(v); return *this; } 2123e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 2133e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy private: 2143e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // A length value that we've appended to the section, but is not yet 2153e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // known. LENGTH is the appended value; START is a label referring 2163e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // to the start of the data whose length was cited. 2173e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy struct PendingLength { 2183e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy Label length; 2193e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy Label start; 2203e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy }; 2213e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 2224f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek // Constants used in CFI/.eh_frame data: 2234f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek 2244f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek // If the first four bytes of an "initial length" are this constant, then 2254f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek // the data uses the 64-bit DWARF format, and the length itself is the 2264f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek // subsequent eight bytes. 2276162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com static const uint32_t kDwarf64InitialLengthMarker = 0xffffffffU; 2284f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek 2294f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek // The CIE identifier for 32- and 64-bit DWARF CFI and .eh_frame data. 2306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com static const uint32_t kDwarf32CIEIdentifier = ~(uint32_t)0; 2316162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com static const uint64_t kDwarf64CIEIdentifier = ~(uint64_t)0; 2326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com static const uint32_t kEHFrame32CIEIdentifier = 0; 2336162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com static const uint64_t kEHFrame64CIEIdentifier = 0; 2344f456b8c0d094d84b83d4c8eedff7937121e9de1ted.mielczarek 2353e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // The size of a machine address for the data in this section. 2363e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy size_t address_size_; 2373e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 238a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // If true, we are generating a Linux .eh_frame section, instead of 239a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // a standard DWARF .debug_frame section. 240a76aaa1442d765410da36d743ef92748ea1b815ejimblandy bool eh_frame_; 241a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 242a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // The encoding to use for FDE pointers. 243a76aaa1442d765410da36d743ef92748ea1b815ejimblandy DwarfPointerEncoding pointer_encoding_; 244a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 245a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // The base addresses to use when emitting encoded pointers. 246a76aaa1442d765410da36d743ef92748ea1b815ejimblandy EncodedPointerBases encoded_pointer_bases_; 247a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 2483e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // The length value for the current entry. 2493e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // 2503e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Oddly, this must be dynamically allocated. Labels never get new 2513e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // values; they only acquire constraints on the value they already 2523e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // have, or assert if you assign them something incompatible. So 2533e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // each header needs truly fresh Label objects to cite in their 2543e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // headers and track their positions. The alternative is explicit 2553e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // destructor invocation and a placement new. Ick. 2563e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy PendingLength *entry_length_; 257a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 258a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // True if we are currently emitting an FDE --- that is, we have 259a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // called FDEHeader but have not yet called FinishEntry. 260a76aaa1442d765410da36d743ef92748ea1b815ejimblandy bool in_fde_; 261a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 262a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // If in_fde_ is true, this is its starting address. We use this for 263a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // emitting DW_EH_PE_funcrel pointers. 2646162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t fde_start_address_; 2653e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy}; 2663e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 2673e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy} // namespace google_breakpad 2683e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 2693e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy#endif // PROCESSOR_CFI_ASSEMBLER_H_ 270