1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBELFFILE_DWARF_DEBUG_INFO_ENTRY_WRITER_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_LIBELFFILE_DWARF_DEBUG_INFO_ENTRY_WRITER_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <cstdint> 21*795d594fSAndroid Build Coastguard Worker #include <unordered_map> 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker #include "base/casts.h" 24*795d594fSAndroid Build Coastguard Worker #include "base/leb128.h" 25*795d594fSAndroid Build Coastguard Worker #include "dwarf/debug_abbrev_writer.h" 26*795d594fSAndroid Build Coastguard Worker #include "dwarf/dwarf_constants.h" 27*795d594fSAndroid Build Coastguard Worker #include "dwarf/expression.h" 28*795d594fSAndroid Build Coastguard Worker #include "dwarf/writer.h" 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art { 31*795d594fSAndroid Build Coastguard Worker namespace dwarf { 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker /* 34*795d594fSAndroid Build Coastguard Worker * Writer for debug information entries (DIE). 35*795d594fSAndroid Build Coastguard Worker * 36*795d594fSAndroid Build Coastguard Worker * Usage: 37*795d594fSAndroid Build Coastguard Worker * StartTag(DW_TAG_compile_unit); 38*795d594fSAndroid Build Coastguard Worker * WriteStrp(DW_AT_producer, "Compiler name", debug_str); 39*795d594fSAndroid Build Coastguard Worker * StartTag(DW_TAG_subprogram); 40*795d594fSAndroid Build Coastguard Worker * WriteStrp(DW_AT_name, "Foo", debug_str); 41*795d594fSAndroid Build Coastguard Worker * EndTag(); 42*795d594fSAndroid Build Coastguard Worker * EndTag(); 43*795d594fSAndroid Build Coastguard Worker */ 44*795d594fSAndroid Build Coastguard Worker template <typename Vector = std::vector<uint8_t>> 45*795d594fSAndroid Build Coastguard Worker class DebugInfoEntryWriter final : private Writer<Vector> { 46*795d594fSAndroid Build Coastguard Worker static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type"); 47*795d594fSAndroid Build Coastguard Worker 48*795d594fSAndroid Build Coastguard Worker public: 49*795d594fSAndroid Build Coastguard Worker static constexpr size_t kCompilationUnitHeaderSize = 11; 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker // Start debugging information entry. 52*795d594fSAndroid Build Coastguard Worker // Returns offset of the entry in compilation unit. StartTag(Tag tag)53*795d594fSAndroid Build Coastguard Worker size_t StartTag(Tag tag) { 54*795d594fSAndroid Build Coastguard Worker if (inside_entry_) { 55*795d594fSAndroid Build Coastguard Worker // Write abbrev code for the previous entry. 56*795d594fSAndroid Build Coastguard Worker // Parent entry is finalized before any children are written. 57*795d594fSAndroid Build Coastguard Worker this->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_yes)); 58*795d594fSAndroid Build Coastguard Worker inside_entry_ = false; 59*795d594fSAndroid Build Coastguard Worker } 60*795d594fSAndroid Build Coastguard Worker debug_abbrev_->StartAbbrev(tag); 61*795d594fSAndroid Build Coastguard Worker // Abbrev code placeholder of sufficient size. 62*795d594fSAndroid Build Coastguard Worker abbrev_code_offset_ = this->data()->size(); 63*795d594fSAndroid Build Coastguard Worker this->PushUleb128(debug_abbrev_->NextAbbrevCode()); 64*795d594fSAndroid Build Coastguard Worker depth_++; 65*795d594fSAndroid Build Coastguard Worker inside_entry_ = true; 66*795d594fSAndroid Build Coastguard Worker return abbrev_code_offset_ + kCompilationUnitHeaderSize; 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker // End debugging information entry. EndTag()70*795d594fSAndroid Build Coastguard Worker void EndTag() { 71*795d594fSAndroid Build Coastguard Worker DCHECK_GT(depth_, 0); 72*795d594fSAndroid Build Coastguard Worker if (inside_entry_) { 73*795d594fSAndroid Build Coastguard Worker // Write abbrev code for this entry. 74*795d594fSAndroid Build Coastguard Worker this->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_no)); 75*795d594fSAndroid Build Coastguard Worker inside_entry_ = false; 76*795d594fSAndroid Build Coastguard Worker // This entry has no children and so there is no terminator. 77*795d594fSAndroid Build Coastguard Worker } else { 78*795d594fSAndroid Build Coastguard Worker // The entry has been already finalized so it must be parent entry 79*795d594fSAndroid Build Coastguard Worker // and we need to write the terminator required by DW_CHILDREN_yes. 80*795d594fSAndroid Build Coastguard Worker this->PushUint8(0); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker depth_--; 83*795d594fSAndroid Build Coastguard Worker } 84*795d594fSAndroid Build Coastguard Worker WriteAddr(Attribute attrib,uint64_t value)85*795d594fSAndroid Build Coastguard Worker void WriteAddr(Attribute attrib, uint64_t value) { 86*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_addr); 87*795d594fSAndroid Build Coastguard Worker patch_locations_.push_back(this->data()->size()); 88*795d594fSAndroid Build Coastguard Worker if (is64bit_) { 89*795d594fSAndroid Build Coastguard Worker this->PushUint64(value); 90*795d594fSAndroid Build Coastguard Worker } else { 91*795d594fSAndroid Build Coastguard Worker this->PushUint32(value); 92*795d594fSAndroid Build Coastguard Worker } 93*795d594fSAndroid Build Coastguard Worker } 94*795d594fSAndroid Build Coastguard Worker WriteBlock(Attribute attrib,const uint8_t * ptr,size_t num_bytes)95*795d594fSAndroid Build Coastguard Worker void WriteBlock(Attribute attrib, const uint8_t* ptr, size_t num_bytes) { 96*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_block); 97*795d594fSAndroid Build Coastguard Worker this->PushUleb128(num_bytes); 98*795d594fSAndroid Build Coastguard Worker this->PushData(ptr, num_bytes); 99*795d594fSAndroid Build Coastguard Worker } 100*795d594fSAndroid Build Coastguard Worker WriteExprLoc(Attribute attrib,const Expression & expr)101*795d594fSAndroid Build Coastguard Worker void WriteExprLoc(Attribute attrib, const Expression& expr) { 102*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_exprloc); 103*795d594fSAndroid Build Coastguard Worker this->PushUleb128(dchecked_integral_cast<uint32_t>(expr.size())); 104*795d594fSAndroid Build Coastguard Worker this->PushData(expr.data()); 105*795d594fSAndroid Build Coastguard Worker } 106*795d594fSAndroid Build Coastguard Worker WriteData1(Attribute attrib,uint8_t value)107*795d594fSAndroid Build Coastguard Worker void WriteData1(Attribute attrib, uint8_t value) { 108*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data1); 109*795d594fSAndroid Build Coastguard Worker this->PushUint8(value); 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker WriteData2(Attribute attrib,uint16_t value)112*795d594fSAndroid Build Coastguard Worker void WriteData2(Attribute attrib, uint16_t value) { 113*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data2); 114*795d594fSAndroid Build Coastguard Worker this->PushUint16(value); 115*795d594fSAndroid Build Coastguard Worker } 116*795d594fSAndroid Build Coastguard Worker WriteData4(Attribute attrib,uint32_t value)117*795d594fSAndroid Build Coastguard Worker void WriteData4(Attribute attrib, uint32_t value) { 118*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data4); 119*795d594fSAndroid Build Coastguard Worker this->PushUint32(value); 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker WriteData8(Attribute attrib,uint64_t value)122*795d594fSAndroid Build Coastguard Worker void WriteData8(Attribute attrib, uint64_t value) { 123*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data8); 124*795d594fSAndroid Build Coastguard Worker this->PushUint64(value); 125*795d594fSAndroid Build Coastguard Worker } 126*795d594fSAndroid Build Coastguard Worker WriteSecOffset(Attribute attrib,uint32_t offset)127*795d594fSAndroid Build Coastguard Worker void WriteSecOffset(Attribute attrib, uint32_t offset) { 128*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sec_offset); 129*795d594fSAndroid Build Coastguard Worker this->PushUint32(offset); 130*795d594fSAndroid Build Coastguard Worker } 131*795d594fSAndroid Build Coastguard Worker WriteSdata(Attribute attrib,int value)132*795d594fSAndroid Build Coastguard Worker void WriteSdata(Attribute attrib, int value) { 133*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sdata); 134*795d594fSAndroid Build Coastguard Worker this->PushSleb128(value); 135*795d594fSAndroid Build Coastguard Worker } 136*795d594fSAndroid Build Coastguard Worker WriteUdata(Attribute attrib,int value)137*795d594fSAndroid Build Coastguard Worker void WriteUdata(Attribute attrib, int value) { 138*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata); 139*795d594fSAndroid Build Coastguard Worker this->PushUleb128(value); 140*795d594fSAndroid Build Coastguard Worker } 141*795d594fSAndroid Build Coastguard Worker WriteUdata(Attribute attrib,uint32_t value)142*795d594fSAndroid Build Coastguard Worker void WriteUdata(Attribute attrib, uint32_t value) { 143*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata); 144*795d594fSAndroid Build Coastguard Worker this->PushUleb128(value); 145*795d594fSAndroid Build Coastguard Worker } 146*795d594fSAndroid Build Coastguard Worker WriteFlag(Attribute attrib,bool value)147*795d594fSAndroid Build Coastguard Worker void WriteFlag(Attribute attrib, bool value) { 148*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag); 149*795d594fSAndroid Build Coastguard Worker this->PushUint8(value ? 1 : 0); 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker WriteFlagPresent(Attribute attrib)152*795d594fSAndroid Build Coastguard Worker void WriteFlagPresent(Attribute attrib) { 153*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag_present); 154*795d594fSAndroid Build Coastguard Worker } 155*795d594fSAndroid Build Coastguard Worker WriteRef4(Attribute attrib,uint32_t cu_offset)156*795d594fSAndroid Build Coastguard Worker void WriteRef4(Attribute attrib, uint32_t cu_offset) { 157*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref4); 158*795d594fSAndroid Build Coastguard Worker this->PushUint32(cu_offset); 159*795d594fSAndroid Build Coastguard Worker } 160*795d594fSAndroid Build Coastguard Worker WriteRef(Attribute attrib,uint32_t cu_offset)161*795d594fSAndroid Build Coastguard Worker void WriteRef(Attribute attrib, uint32_t cu_offset) { 162*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref_udata); 163*795d594fSAndroid Build Coastguard Worker this->PushUleb128(cu_offset); 164*795d594fSAndroid Build Coastguard Worker } 165*795d594fSAndroid Build Coastguard Worker WriteString(Attribute attrib,const char * value)166*795d594fSAndroid Build Coastguard Worker void WriteString(Attribute attrib, const char* value) { 167*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_string); 168*795d594fSAndroid Build Coastguard Worker this->PushString(value); 169*795d594fSAndroid Build Coastguard Worker } 170*795d594fSAndroid Build Coastguard Worker WriteStrp(Attribute attrib,size_t debug_str_offset)171*795d594fSAndroid Build Coastguard Worker void WriteStrp(Attribute attrib, size_t debug_str_offset) { 172*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp); 173*795d594fSAndroid Build Coastguard Worker this->PushUint32(dchecked_integral_cast<uint32_t>(debug_str_offset)); 174*795d594fSAndroid Build Coastguard Worker } 175*795d594fSAndroid Build Coastguard Worker WriteStrp(Attribute attrib,const char * str,size_t len,std::vector<uint8_t> * debug_str)176*795d594fSAndroid Build Coastguard Worker void WriteStrp(Attribute attrib, const char* str, size_t len, 177*795d594fSAndroid Build Coastguard Worker std::vector<uint8_t>* debug_str) { 178*795d594fSAndroid Build Coastguard Worker debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp); 179*795d594fSAndroid Build Coastguard Worker this->PushUint32(debug_str->size()); 180*795d594fSAndroid Build Coastguard Worker debug_str->insert(debug_str->end(), str, str + len); 181*795d594fSAndroid Build Coastguard Worker debug_str->push_back(0); 182*795d594fSAndroid Build Coastguard Worker } 183*795d594fSAndroid Build Coastguard Worker WriteStrp(Attribute attrib,const char * str,std::vector<uint8_t> * debug_str)184*795d594fSAndroid Build Coastguard Worker void WriteStrp(Attribute attrib, const char* str, std::vector<uint8_t>* debug_str) { 185*795d594fSAndroid Build Coastguard Worker WriteStrp(attrib, str, strlen(str), debug_str); 186*795d594fSAndroid Build Coastguard Worker } 187*795d594fSAndroid Build Coastguard Worker Is64bit()188*795d594fSAndroid Build Coastguard Worker bool Is64bit() const { return is64bit_; } 189*795d594fSAndroid Build Coastguard Worker GetPatchLocations()190*795d594fSAndroid Build Coastguard Worker const std::vector<uintptr_t>& GetPatchLocations() const { 191*795d594fSAndroid Build Coastguard Worker return patch_locations_; 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker Depth()194*795d594fSAndroid Build Coastguard Worker int Depth() const { return depth_; } 195*795d594fSAndroid Build Coastguard Worker 196*795d594fSAndroid Build Coastguard Worker using Writer<Vector>::data; 197*795d594fSAndroid Build Coastguard Worker using Writer<Vector>::size; 198*795d594fSAndroid Build Coastguard Worker using Writer<Vector>::UpdateUint32; 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker DebugInfoEntryWriter(bool is64bitArch, 201*795d594fSAndroid Build Coastguard Worker DebugAbbrevWriter<Vector>* debug_abbrev, 202*795d594fSAndroid Build Coastguard Worker const typename Vector::allocator_type& alloc = 203*795d594fSAndroid Build Coastguard Worker typename Vector::allocator_type()) 204*795d594fSAndroid Build Coastguard Worker : Writer<Vector>(&entries_), 205*795d594fSAndroid Build Coastguard Worker debug_abbrev_(debug_abbrev), 206*795d594fSAndroid Build Coastguard Worker entries_(alloc), 207*795d594fSAndroid Build Coastguard Worker is64bit_(is64bitArch) { 208*795d594fSAndroid Build Coastguard Worker } 209*795d594fSAndroid Build Coastguard Worker ~DebugInfoEntryWriter()210*795d594fSAndroid Build Coastguard Worker ~DebugInfoEntryWriter() { 211*795d594fSAndroid Build Coastguard Worker DCHECK(!inside_entry_); 212*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(depth_, 0); 213*795d594fSAndroid Build Coastguard Worker } 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker private: 216*795d594fSAndroid Build Coastguard Worker DebugAbbrevWriter<Vector>* debug_abbrev_; 217*795d594fSAndroid Build Coastguard Worker Vector entries_; 218*795d594fSAndroid Build Coastguard Worker bool is64bit_; 219*795d594fSAndroid Build Coastguard Worker int depth_ = 0; 220*795d594fSAndroid Build Coastguard Worker size_t abbrev_code_offset_ = 0; // Location to patch once we know the code. 221*795d594fSAndroid Build Coastguard Worker bool inside_entry_ = false; // Entry ends at first child (if any). 222*795d594fSAndroid Build Coastguard Worker std::vector<uintptr_t> patch_locations_; 223*795d594fSAndroid Build Coastguard Worker }; 224*795d594fSAndroid Build Coastguard Worker 225*795d594fSAndroid Build Coastguard Worker } // namespace dwarf 226*795d594fSAndroid Build Coastguard Worker } // namespace art 227*795d594fSAndroid Build Coastguard Worker 228*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBELFFILE_DWARF_DEBUG_INFO_ENTRY_WRITER_H_ 229