/*
* Copyright ( C ) 2014 The Android Open Source Project
*
* Licensed under the Apache License , Version 2 . 0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
#ifndef ART_LIBELFFILE_DWARF_DEBUG_INFO_ENTRY_WRITER_H_
#define ART_LIBELFFILE_DWARF_DEBUG_INFO_ENTRY_WRITER_H_
#include <cstdint>
#include <unordered_map>
#include "base/casts.h"
#include "base/leb128.h"
#include "dwarf/debug_abbrev_writer.h"
#include "dwarf/dwarf_constants.h"
#include "dwarf/expression.h"
#include "dwarf/writer.h"
namespace art {
namespace dwarf {
/*
* Writer for debug information entries ( DIE ) .
*
* Usage :
* StartTag ( DW_TAG_compile_unit ) ;
* WriteStrp ( DW_AT_producer , " Compiler name " , debug_str ) ;
* StartTag ( DW_TAG_subprogram ) ;
* WriteStrp ( DW_AT_name , " Foo " , debug_str ) ;
* EndTag ( ) ;
* EndTag ( ) ;
*/
template <typename Vector = std::vector<uint8_t>>
class DebugInfoEntryWriter final : private Writer<Vector> {
static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type" );
public :
static constexpr size_t kCompilationUnitHeaderSize = 11 ;
// Start debugging information entry.
// Returns offset of the entry in compilation unit.
size_t StartTag(Tag tag) {
if (inside_entry_) {
// Write abbrev code for the previous entry.
// Parent entry is finalized before any children are written.
this ->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_yes));
inside_entry_ = false ;
}
debug_abbrev_->StartAbbrev(tag);
// Abbrev code placeholder of sufficient size.
abbrev_code_offset_ = this ->data()->size();
this ->PushUleb128(debug_abbrev_->NextAbbrevCode());
depth_++;
inside_entry_ = true ;
return abbrev_code_offset_ + kCompilationUnitHeaderSize;
}
// End debugging information entry.
void EndTag() {
DCHECK_GT(depth_, 0 );
if (inside_entry_) {
// Write abbrev code for this entry.
this ->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_no));
inside_entry_ = false ;
// This entry has no children and so there is no terminator.
} else {
// The entry has been already finalized so it must be parent entry
// and we need to write the terminator required by DW_CHILDREN_yes.
this ->PushUint8(0 );
}
depth_--;
}
void WriteAddr(Attribute attrib, uint64_t value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_addr);
patch_locations_.push_back(this ->data()->size());
if (is64bit_) {
this ->PushUint64(value);
} else {
this ->PushUint32(value);
}
}
void WriteBlock(Attribute attrib, const uint8_t* ptr, size_t num_bytes) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_block);
this ->PushUleb128(num_bytes);
this ->PushData(ptr, num_bytes);
}
void WriteExprLoc(Attribute attrib, const Expression& expr) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_exprloc);
this ->PushUleb128(dchecked_integral_cast<uint32_t>(expr.size()));
this ->PushData(expr.data());
}
void WriteData1(Attribute attrib, uint8_t value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data1);
this ->PushUint8(value);
}
void WriteData2(Attribute attrib, uint16_t value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data2);
this ->PushUint16(value);
}
void WriteData4(Attribute attrib, uint32_t value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data4);
this ->PushUint32(value);
}
void WriteData8(Attribute attrib, uint64_t value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data8);
this ->PushUint64(value);
}
void WriteSecOffset(Attribute attrib, uint32_t offset) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sec_offset);
this ->PushUint32(offset);
}
void WriteSdata(Attribute attrib, int value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sdata);
this ->PushSleb128(value);
}
void WriteUdata(Attribute attrib, int value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata);
this ->PushUleb128(value);
}
void WriteUdata(Attribute attrib, uint32_t value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata);
this ->PushUleb128(value);
}
void WriteFlag(Attribute attrib, bool value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag);
this ->PushUint8(value ? 1 : 0 );
}
void WriteFlagPresent(Attribute attrib) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag_present);
}
void WriteRef4(Attribute attrib, uint32_t cu_offset) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref4);
this ->PushUint32(cu_offset);
}
void WriteRef(Attribute attrib, uint32_t cu_offset) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref_udata);
this ->PushUleb128(cu_offset);
}
void WriteString(Attribute attrib, const char * value) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_string);
this ->PushString(value);
}
void WriteStrp(Attribute attrib, size_t debug_str_offset) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp);
this ->PushUint32(dchecked_integral_cast<uint32_t>(debug_str_offset));
}
void WriteStrp(Attribute attrib, const char * str, size_t len,
std::vector<uint8_t>* debug_str) {
debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp);
this ->PushUint32(debug_str->size());
debug_str->insert(debug_str->end(), str, str + len);
debug_str->push_back(0 );
}
void WriteStrp(Attribute attrib, const char * str, std::vector<uint8_t>* debug_str) {
WriteStrp(attrib, str, strlen(str), debug_str);
}
bool Is64bit() const { return is64bit_; }
const std::vector<uintptr_t>& GetPatchLocations() const {
return patch_locations_;
}
int Depth() const { return depth_; }
using Writer<Vector>::data;
using Writer<Vector>::size;
using Writer<Vector>::UpdateUint32;
DebugInfoEntryWriter(bool is64bitArch,
DebugAbbrevWriter<Vector>* debug_abbrev,
const typename Vector::allocator_type& alloc =
typename Vector::allocator_type())
: Writer<Vector>(&entries_),
debug_abbrev_(debug_abbrev),
entries_(alloc),
is64bit_(is64bitArch) {
}
~DebugInfoEntryWriter() {
DCHECK(!inside_entry_);
DCHECK_EQ(depth_, 0 );
}
private :
DebugAbbrevWriter<Vector>* debug_abbrev_;
Vector entries_;
bool is64bit_;
int depth_ = 0 ;
size_t abbrev_code_offset_ = 0 ; // Location to patch once we know the code.
bool inside_entry_ = false ; // Entry ends at first child (if any).
std::vector<uintptr_t> patch_locations_;
};
} // namespace dwarf
} // namespace art
#endif // ART_LIBELFFILE_DWARF_DEBUG_INFO_ENTRY_WRITER_H_
Messung V0.5 in Prozent C=89 H=96 G=92
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-29)
¤
*© Formatika GbR, Deutschland