Go to the documentation of this file.
19 #include <initializer_list>
24 #include <unordered_map>
25 #include <unordered_set>
28 #include "absl/base/attributes.h"
29 #include "absl/base/macros.h"
30 #include "absl/strings/string_view.h"
31 #include "absl/strings/substitute.h"
32 #include "absl/types/optional.h"
34 #include "bloaty.pb.h"
89 bool AddressRanges::NextRange() {
90 if (unit_remaining_.empty()) {
94 const char*
start = unit_remaining_.data();
95 address_ = sizes_.ReadAddress(&unit_remaining_);
96 length_ = sizes_.ReadAddress(&unit_remaining_);
101 bool AddressRanges::NextUnit() {
102 if (next_unit_.empty()) {
106 unit_remaining_ = sizes_.ReadInitialLength(&next_unit_);
107 sizes_.ReadDWARFVersion(&unit_remaining_);
109 if (sizes_.dwarf_version() > 4) {
110 THROW(
"DWARF data is too new for us");
113 debug_info_offset_ = sizes_.ReadDWARFOffset(&unit_remaining_);
117 sizes_.SetAddressSize(ReadFixed<uint8_t>(&unit_remaining_));
118 segment_size = ReadFixed<uint8_t>(&unit_remaining_);
121 THROW(
"we don't know how to handle segmented addresses.");
124 size_t ofs = unit_remaining_.data() - section_.data();
125 size_t aligned_ofs =
AlignUp(ofs, sizes_.address_size() * 2);
126 SkipBytes(aligned_ofs - ofs, &unit_remaining_);
150 bool LocationList::NextEntry() {
186 }
else if (
start == max_address) {
190 sink->AddVMRangeIgnoreDuplicate(
"dwarf_rangelist", low_pc +
start,
size,
197 if (
name ==
"aranges") {
198 return &debug_aranges;
199 }
else if (
name ==
"addr") {
201 }
else if (
name ==
"str") {
203 }
else if (
name ==
"str_offsets") {
204 return &debug_str_offsets;
205 }
else if (
name ==
"info") {
207 }
else if (
name ==
"types") {
209 }
else if (
name ==
"abbrev") {
210 return &debug_abbrev;
211 }
else if (
name ==
"line") {
213 }
else if (
name ==
"loc") {
215 }
else if (
name ==
"pubnames") {
216 return &debug_pubnames;
217 }
else if (
name ==
"pubtypes") {
218 return &debug_pubtypes;
219 }
else if (
name ==
"ranges") {
220 return &debug_ranges;
221 }
else if (
name ==
"rnglists") {
222 return &debug_rnglists;
243 : info_reader_(
file),
244 missing_(
"[DWARF is missing filename]") {}
247 auto&
name = map_[compilation_unit_offset];
249 name = LookupFilename(compilation_unit_offset);
256 auto sec = dwarf::InfoReader::Section::kDebugInfo;
259 if (!
iter.NextCU(info_reader_, &cu)) {
268 if (ReadName(&
name, compilation_unit_offset)) {
276 std::unordered_map<uint64_t, std::string> map_;
287 sink->AddVMRangeIgnoreDuplicate(
"dwarf_aranges", ranges.
address(),
308 bool declaration =
false;
337 switch (val.
form()) {
356 fprintf(
stderr,
"Unexpected form for high_pc: %d\n", val.
form());
388 if (!die.
low_pc)
return 0;
419 addr = ReadFixed<uint32_t>(&location);
421 addr = ReadFixed<uint64_t>(&location);
430 sink->AddVMRangeIgnoreDuplicate(
"dwarf_location",
addr,
size,
435 "bloaty: warning: couldn't find DWARF location in symbol "
436 "table, address: %" PRIx64
", name: %s\n",
449 sink->AddFileRange(
"dwarf_locrange", cu.
unit_name(), loc_range);
452 "bloaty: warning: DWARF location out of range, location=%" PRIx64
473 switch (ReadFixed<uint8_t>(&
data)) {
520 ranges_offset = *die.
ranges;
534 "bloaty: warning: DWARF debug range out of range, "
535 "ranges_offset=%" PRIx64
"\n",
546 while (remaining.
size() > 0) {
556 dwarf::InfoReader::Section::kDebugInfo, debug_info_offset);
559 sink->AddFileRange(
"dwarf_pubnames", cu.
unit_name(), full_unit);
572 0,
data.size() + (
data.data() - data_with_length.
data()));
591 auto* abbrev = die_reader.
ReadCode(cu);
603 AddDIE(cu, compileunit_die, symbol_map,
sink);
611 while (
auto abbrev = die_reader.
ReadCode(cu)) {
633 THROW(
"missing debug info");
667 const auto& line_info = line_info_reader->
lineinfo();
668 auto addr = line_info.address;
669 auto number = line_info.line;
671 line_info.end_sequence
675 if (!span_startaddr) {
676 span_startaddr =
addr;
677 }
else if (line_info.end_sequence ||
678 (!last_source.empty() &&
name != last_source)) {
679 sink->AddVMRange(
"dwarf_stmtlist", span_startaddr,
addr - span_startaddr,
681 if (line_info.end_sequence) {
684 span_startaddr =
addr;
694 THROW(
"no debug info");
704 THROW(
"debug info is present, but empty");
707 while (
auto abbrev = die_reader.
ReadCode(cu)) {
712 stmt_list = val.
ToUint(cu);
const AbbrevTable::Abbrev * ReadCode(const CU &cu)
absl::string_view abbrev_data() const
static void ReadDWARFStmtList(bool include_line, dwarf::LineInfoReader *line_info_reader, RangeSink *sink)
string_view unit_remaining_
uint64_t GetUint(const CU &cu) const
AddressRanges(string_view data)
absl::string_view debug_rnglists
uint8_t address_size() const
OPENSSL_EXPORT const char * section
const grpc_generator::File * file
void ReadGeneralDIEAttr(uint16_t tag, dwarf::AttrValue val, const dwarf::CU &cu, GeneralDIE *die)
static bool ReadDWARFAddressRanges(const dwarf::File &file, RangeSink *sink)
void ReadAttributes(const CU &cu, const AbbrevTable::Abbrev *code, T &&func)
absl::optional< uint64_t > high_pc_size
CompilationUnitSizes sizes_
uint64_t ReadDWARFOffset(absl::string_view *data) const
constexpr size_t AlignUp(size_t x, size_t align)
string_view GetLocationListRange(CompilationUnitSizes sizes, string_view available)
uint64_t range_lists_base() const
absl::optional< uint64_t > ranges
uint64_t ReadAddress(absl::string_view *data) const
absl::optional< uint64_t > low_pc
void SkipBytes(size_t bytes, absl::string_view *data)
const AbbrevTable & unit_abbrev() const
constexpr size_type size() const noexcept
static void * tag(intptr_t t)
LocationList(CompilationUnitSizes sizes, string_view data)
bool TryGetSize(uint64_t addr, uint64_t *size) const
absl::optional< string_view > location_string
void ReadRangeList(const CU &cu, uint64_t low_pc, string_view name, RangeSink *sink, string_view *data)
unsigned __int64 uint64_t
const std::string & unit_name() const
const LineInfo & lineinfo() const
uint64_t MaxAddress() const
CompilationUnitSizes sizes_
const std::string & GetExpandedFilename(size_t index)
absl::string_view debug_loc
absl::optional< uint64_t > start_scope
bool IsValidDwarfAddress(uint64_t addr) const
static void ReadDWARFDebugInfo(dwarf::InfoReader &reader, dwarf::InfoReader::Section section, const DualMap &symbol_map, RangeSink *sink)
void AddDIE(const dwarf::CU &cu, const GeneralDIE &die, const DualMap &symbol_map, RangeSink *sink)
absl::string_view GetString(const CU &cu) const
static void ReadDWARFPubNames(dwarf::InfoReader &reader, string_view section, RangeSink *sink)
uint64_t TryReadPcPair(const dwarf::CU &cu, const GeneralDIE &die, RangeSink *sink)
bool IsValidDwarfAddress(uint64_t addr, uint8_t address_size)
absl::string_view entire_unit() const
void SeekToOffset(uint64_t offset, uint8_t address_size)
uint64_t debug_info_offset_
absl::string_view ReadInitialLength(absl::string_view *remaining)
#define BLOATY_UNREACHABLE()
uint8_t address_size() const
void SetIndirectStringCallback(std::function< void(absl::string_view)> strp_sink)
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n)
const char * read_offset() const
absl::string_view string_view
void SkipChildren(const CU &cu, const AbbrevTable::Abbrev *code)
static void ReadDWARFStmtListRange(const dwarf::CU &cu, uint64_t offset, RangeSink *sink)
const File & dwarf() const
const CompilationUnitSizes & unit_sizes() const
uint64_t debug_info_offset()
absl::string_view debug_line
absl::optional< uint64_t > high_pc_addr
void ReadDWARFVersion(absl::string_view *data)
uint64_t ReadIndirectAddress(const CU &cu, uint64_t val)
absl::optional< uint64_t > rnglistx
absl::string_view debug_ranges
absl::optional< uint64_t > location_uint64
uint64_t addr_base() const
absl::optional< string_view > name
constexpr const_pointer data() const noexcept
static std::string LineInfoKey(const std::string &file, uint32_t line, bool include_line)
static bool to_string(zval *from)
absl::string_view StrictSubstr(absl::string_view data, size_t off, size_t n)
constexpr string_view substr(size_type pos=0, size_type n=npos) const
absl::optional< uint64_t > ToUint(const CU &cu) const
void ReadDWARFInlines(const dwarf::File &file, RangeSink *sink, bool include_line)
absl::optional< uint64_t > stmt_list
void ReadDWARFCompileUnits(const dwarf::File &file, const DualMap &map, RangeSink *sink)
grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:13