1b536247b1ce5de640eec81dddac47802cd074363David Srbecky/* 2b536247b1ce5de640eec81dddac47802cd074363David Srbecky * Copyright (C) 2015 The Android Open Source Project 3b536247b1ce5de640eec81dddac47802cd074363David Srbecky * 4b536247b1ce5de640eec81dddac47802cd074363David Srbecky * Licensed under the Apache License, Version 2.0 (the "License"); 5b536247b1ce5de640eec81dddac47802cd074363David Srbecky * you may not use this file except in compliance with the License. 6b536247b1ce5de640eec81dddac47802cd074363David Srbecky * You may obtain a copy of the License at 7b536247b1ce5de640eec81dddac47802cd074363David Srbecky * 8b536247b1ce5de640eec81dddac47802cd074363David Srbecky * http://www.apache.org/licenses/LICENSE-2.0 9b536247b1ce5de640eec81dddac47802cd074363David Srbecky * 10b536247b1ce5de640eec81dddac47802cd074363David Srbecky * Unless required by applicable law or agreed to in writing, software 11b536247b1ce5de640eec81dddac47802cd074363David Srbecky * distributed under the License is distributed on an "AS IS" BASIS, 12b536247b1ce5de640eec81dddac47802cd074363David Srbecky * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b536247b1ce5de640eec81dddac47802cd074363David Srbecky * See the License for the specific language governing permissions and 14b536247b1ce5de640eec81dddac47802cd074363David Srbecky * limitations under the License. 15b536247b1ce5de640eec81dddac47802cd074363David Srbecky */ 16b536247b1ce5de640eec81dddac47802cd074363David Srbecky 174fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#ifndef ART_COMPILER_DEBUG_DWARF_HEADERS_H_ 184fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#define ART_COMPILER_DEBUG_DWARF_HEADERS_H_ 19b536247b1ce5de640eec81dddac47802cd074363David Srbecky 202f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky#include <cstdint> 212f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky 224fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/debug_frame_opcode_writer.h" 234fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/debug_info_entry_writer.h" 244fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/debug_line_opcode_writer.h" 254fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/dwarf_constants.h" 264fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/register.h" 274fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/writer.h" 2835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "utils/array_ref.h" 29b536247b1ce5de640eec81dddac47802cd074363David Srbecky 30b536247b1ce5de640eec81dddac47802cd074363David Srbeckynamespace art { 31b536247b1ce5de640eec81dddac47802cd074363David Srbeckynamespace dwarf { 32b536247b1ce5de640eec81dddac47802cd074363David Srbecky 332f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky// Note that all headers start with 32-bit length. 342f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky// DWARF also supports 64-bit lengths, but we never use that. 352f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky// It is intended to support very large debug sections (>4GB), 362f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky// and compilers are expected *not* to use it by default. 372f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky// In particular, it is not related to machine architecture. 382f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky 39ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// Write common information entry (CIE) to .debug_frame or .eh_frame section. 40ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Markotemplate<typename Vector> 416d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbeckyvoid WriteCIE(bool is64bit, 426d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky Reg return_address_register, 436d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky const DebugFrameOpCodeWriter<Vector>& opcodes, 446d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky CFIFormat format, 456d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky std::vector<uint8_t>* buffer) { 46ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type"); 47ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko 486d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky Writer<> writer(buffer); 49b536247b1ce5de640eec81dddac47802cd074363David Srbecky size_t cie_header_start_ = writer.data()->size(); 502f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky writer.PushUint32(0); // Length placeholder. 51ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky writer.PushUint32((format == DW_EH_FRAME_FORMAT) ? 0 : 0xFFFFFFFF); // CIE id. 52b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint8(1); // Version. 53b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushString("zR"); 54ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko writer.PushUleb128(DebugFrameOpCodeWriter<Vector>::kCodeAlignmentFactor); 55ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko writer.PushSleb128(DebugFrameOpCodeWriter<Vector>::kDataAlignmentFactor); 56b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUleb128(return_address_register.num()); // ubyte in DWARF2. 57b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUleb128(1); // z: Augmentation data size. 58b536247b1ce5de640eec81dddac47802cd074363David Srbecky if (is64bit) { 596d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky if (format == DW_EH_FRAME_FORMAT) { 6017065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky writer.PushUint8(DW_EH_PE_pcrel | DW_EH_PE_sdata8); // R: Pointer encoding. 6117065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky } else { 626d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky DCHECK(format == DW_DEBUG_FRAME_FORMAT); 6317065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata8); // R: Pointer encoding. 6417065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky } 65b536247b1ce5de640eec81dddac47802cd074363David Srbecky } else { 666d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky if (format == DW_EH_FRAME_FORMAT) { 6717065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky writer.PushUint8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); // R: Pointer encoding. 6817065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky } else { 696d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky DCHECK(format == DW_DEBUG_FRAME_FORMAT); 7017065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata4); // R: Pointer encoding. 7117065880693d1b15ffeb60b9955a2d092839977fDavid Srbecky } 72b536247b1ce5de640eec81dddac47802cd074363David Srbecky } 7391cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky writer.PushData(opcodes.data()); 74b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.Pad(is64bit ? 8 : 4); 752f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky writer.UpdateUint32(cie_header_start_, writer.data()->size() - cie_header_start_ - 4); 76b536247b1ce5de640eec81dddac47802cd074363David Srbecky} 77b536247b1ce5de640eec81dddac47802cd074363David Srbecky 78ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// Write frame description entry (FDE) to .debug_frame or .eh_frame section. 7935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoinline 806d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbeckyvoid WriteFDE(bool is64bit, 816d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint64_t section_address, // Absolute address of the section. 826d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint64_t cie_address, // Absolute address of last CIE. 836d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint64_t code_address, 846d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint64_t code_size, 856d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky const ArrayRef<const uint8_t>& opcodes, 866d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky CFIFormat format, 876d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint64_t buffer_address, // Address of buffer in linked application. 886d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky std::vector<uint8_t>* buffer, 896d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky std::vector<uintptr_t>* patch_locations) { 906d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky CHECK_GE(cie_address, section_address); 916d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky CHECK_GE(buffer_address, section_address); 926d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky 936d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky Writer<> writer(buffer); 94b536247b1ce5de640eec81dddac47802cd074363David Srbecky size_t fde_header_start = writer.data()->size(); 952f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky writer.PushUint32(0); // Length placeholder. 96ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky if (format == DW_EH_FRAME_FORMAT) { 976d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint32_t cie_pointer = (buffer_address + buffer->size()) - cie_address; 98ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky writer.PushUint32(cie_pointer); 99ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky } else { 1006d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky DCHECK(format == DW_DEBUG_FRAME_FORMAT); 1016d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky uint32_t cie_pointer = cie_address - section_address; 102ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky writer.PushUint32(cie_pointer); 103ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky } 1046d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky if (format == DW_EH_FRAME_FORMAT) { 1056d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky // .eh_frame encodes the location as relative address. 1066d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky code_address -= buffer_address + buffer->size(); 1076d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky } else { 1086d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky DCHECK(format == DW_DEBUG_FRAME_FORMAT); 1096d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky // Relocate code_address if it has absolute value. 1106d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky patch_locations->push_back(buffer_address + buffer->size() - section_address); 1116d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky } 112b536247b1ce5de640eec81dddac47802cd074363David Srbecky if (is64bit) { 1136d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky writer.PushUint64(code_address); 1146d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky writer.PushUint64(code_size); 115b536247b1ce5de640eec81dddac47802cd074363David Srbecky } else { 1166d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky writer.PushUint32(code_address); 1176d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky writer.PushUint32(code_size); 118b536247b1ce5de640eec81dddac47802cd074363David Srbecky } 119b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUleb128(0); // Augmentation data size. 12091cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky writer.PushData(opcodes.data(), opcodes.size()); 121b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.Pad(is64bit ? 8 : 4); 1222f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky writer.UpdateUint32(fde_header_start, writer.data()->size() - fde_header_start - 4); 123b536247b1ce5de640eec81dddac47802cd074363David Srbecky} 124b536247b1ce5de640eec81dddac47802cd074363David Srbecky 125b536247b1ce5de640eec81dddac47802cd074363David Srbecky// Write compilation unit (CU) to .debug_info section. 126ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Markotemplate<typename Vector> 127b536247b1ce5de640eec81dddac47802cd074363David Srbeckyvoid WriteDebugInfoCU(uint32_t debug_abbrev_offset, 128ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko const DebugInfoEntryWriter<Vector>& entries, 129b851b49eee0a77720347a4f777c07d4531302655David Srbecky size_t debug_info_offset, // offset from start of .debug_info. 1302f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky std::vector<uint8_t>* debug_info, 1312f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky std::vector<uintptr_t>* debug_info_patches) { 132ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type"); 133ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko 134b536247b1ce5de640eec81dddac47802cd074363David Srbecky Writer<> writer(debug_info); 135b536247b1ce5de640eec81dddac47802cd074363David Srbecky size_t start = writer.data()->size(); 136b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint32(0); // Length placeholder. 1370fd295f8663e658de429f85f241a142169477335David Srbecky writer.PushUint16(4); // Version. 138b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint32(debug_abbrev_offset); 1392f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky writer.PushUint8(entries.Is64bit() ? 8 : 4); 1402f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky size_t entries_offset = writer.data()->size(); 14104b0526d60de4e9979fc486d2ba655247d211d0bDavid Srbecky DCHECK_EQ(entries_offset, DebugInfoEntryWriter<Vector>::kCompilationUnitHeaderSize); 14291cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky writer.PushData(entries.data()); 143b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.UpdateUint32(start, writer.data()->size() - start - 4); 1442f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky // Copy patch locations and make them relative to .debug_info section. 1452f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky for (uintptr_t patch_location : entries.GetPatchLocations()) { 146b851b49eee0a77720347a4f777c07d4531302655David Srbecky debug_info_patches->push_back(debug_info_offset + entries_offset + patch_location); 1472f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky } 148b536247b1ce5de640eec81dddac47802cd074363David Srbecky} 149b536247b1ce5de640eec81dddac47802cd074363David Srbecky 150b536247b1ce5de640eec81dddac47802cd074363David Srbeckystruct FileEntry { 151b536247b1ce5de640eec81dddac47802cd074363David Srbecky std::string file_name; 152b536247b1ce5de640eec81dddac47802cd074363David Srbecky int directory_index; 153b536247b1ce5de640eec81dddac47802cd074363David Srbecky int modification_time; 154b536247b1ce5de640eec81dddac47802cd074363David Srbecky int file_size; 155b536247b1ce5de640eec81dddac47802cd074363David Srbecky}; 156b536247b1ce5de640eec81dddac47802cd074363David Srbecky 157b536247b1ce5de640eec81dddac47802cd074363David Srbecky// Write line table to .debug_line section. 158ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Markotemplate<typename Vector> 159b536247b1ce5de640eec81dddac47802cd074363David Srbeckyvoid WriteDebugLineTable(const std::vector<std::string>& include_directories, 160b536247b1ce5de640eec81dddac47802cd074363David Srbecky const std::vector<FileEntry>& files, 161ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko const DebugLineOpCodeWriter<Vector>& opcodes, 162b851b49eee0a77720347a4f777c07d4531302655David Srbecky size_t debug_line_offset, // offset from start of .debug_line. 1632f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky std::vector<uint8_t>* debug_line, 1642f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky std::vector<uintptr_t>* debug_line_patches) { 165ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type"); 166ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko 167b536247b1ce5de640eec81dddac47802cd074363David Srbecky Writer<> writer(debug_line); 168b536247b1ce5de640eec81dddac47802cd074363David Srbecky size_t header_start = writer.data()->size(); 169b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint32(0); // Section-length placeholder. 1700fd295f8663e658de429f85f241a142169477335David Srbecky writer.PushUint16(3); // .debug_line version. 171b536247b1ce5de640eec81dddac47802cd074363David Srbecky size_t header_length_pos = writer.data()->size(); 172b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint32(0); // Header-length placeholder. 173b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint8(1 << opcodes.GetCodeFactorBits()); 174ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko writer.PushUint8(DebugLineOpCodeWriter<Vector>::kDefaultIsStmt ? 1 : 0); 175ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko writer.PushInt8(DebugLineOpCodeWriter<Vector>::kLineBase); 176ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko writer.PushUint8(DebugLineOpCodeWriter<Vector>::kLineRange); 177ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko writer.PushUint8(DebugLineOpCodeWriter<Vector>::kOpcodeBase); 178ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko static const int opcode_lengths[DebugLineOpCodeWriter<Vector>::kOpcodeBase] = { 179b536247b1ce5de640eec81dddac47802cd074363David Srbecky 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 }; 180ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko for (int i = 1; i < DebugLineOpCodeWriter<Vector>::kOpcodeBase; i++) { 181b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint8(opcode_lengths[i]); 182b536247b1ce5de640eec81dddac47802cd074363David Srbecky } 183b536247b1ce5de640eec81dddac47802cd074363David Srbecky for (const std::string& directory : include_directories) { 184b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushData(directory.data(), directory.size() + 1); 185b536247b1ce5de640eec81dddac47802cd074363David Srbecky } 186b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint8(0); // Terminate include_directories list. 187b536247b1ce5de640eec81dddac47802cd074363David Srbecky for (const FileEntry& file : files) { 188b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushData(file.file_name.data(), file.file_name.size() + 1); 189b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUleb128(file.directory_index); 190b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUleb128(file.modification_time); 191b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUleb128(file.file_size); 192b536247b1ce5de640eec81dddac47802cd074363David Srbecky } 193b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.PushUint8(0); // Terminate file list. 194b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.UpdateUint32(header_length_pos, writer.data()->size() - header_length_pos - 4); 1952f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky size_t opcodes_offset = writer.data()->size(); 19691cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky writer.PushData(opcodes.data()); 197b536247b1ce5de640eec81dddac47802cd074363David Srbecky writer.UpdateUint32(header_start, writer.data()->size() - header_start - 4); 1982f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky // Copy patch locations and make them relative to .debug_line section. 1992f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky for (uintptr_t patch_location : opcodes.GetPatchLocations()) { 200b851b49eee0a77720347a4f777c07d4531302655David Srbecky debug_line_patches->push_back(debug_line_offset + opcodes_offset + patch_location); 2012f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky } 202b536247b1ce5de640eec81dddac47802cd074363David Srbecky} 203b536247b1ce5de640eec81dddac47802cd074363David Srbecky 204b536247b1ce5de640eec81dddac47802cd074363David Srbecky} // namespace dwarf 205b536247b1ce5de640eec81dddac47802cd074363David Srbecky} // namespace art 206b536247b1ce5de640eec81dddac47802cd074363David Srbecky 2074fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#endif // ART_COMPILER_DEBUG_DWARF_HEADERS_H_ 208