Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved coverage: .eh_frame for object files and attribute ELF headers to sections. #168

Merged
merged 9 commits into from
Jun 26, 2019
751 changes: 399 additions & 352 deletions README.md

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions config.bloaty
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
custom_data_source: {
name: "bloaty_package"
base_data_source: "compileunits"

rewrite: {
pattern: "^(\\.\\./)?src"
replacement: "src"
}
rewrite: {
pattern: "^(\\.\\./)?(third_party/\\w+)"
replacement: "\\2"
}
}
61 changes: 46 additions & 15 deletions src/bloaty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ void RollupOutput::PrettyPrintRow(const RollupRow& row, size_t indent,
<< SiPrint(row.vmsize, diff_mode_) << " ";
}

*out << row.name << "\n";
*out << " " << row.name << "\n";
}

bool RollupOutput::IsSame(const std::string& a, const std::string& b) {
Expand Down Expand Up @@ -749,7 +749,7 @@ void RollupOutput::PrettyPrintTree(const RollupRow& row, size_t indent,
}

for (const auto& child : row.sorted_children) {
PrettyPrintTree(child, indent + 4, options, out);
PrettyPrintTree(child, indent + 2, options, out);
}
}

Expand Down Expand Up @@ -1007,47 +1007,78 @@ void RangeSink::AddFileRange(const char* analyzer, string_view name,
}
}

void RangeSink::AddFileRangeFor(const char* analyzer,
uint64_t label_from_vmaddr,
string_view file_range) {
void RangeSink::AddFileRangeForVMAddr(const char* analyzer,
uint64_t label_from_vmaddr,
string_view file_range) {
uint64_t file_offset = file_range.data() - file_->data().data();
bool verbose = IsVerboseForFileRange(file_offset, file_range.size());
if (verbose) {
printf("[%s, %s] AddFileRangeFor(%" PRIx64 ", [%" PRIx64 ", %zx])\n",
printf("[%s, %s] AddFileRangeForVMAddr(%" PRIx64 ", [%" PRIx64 ", %zx])\n",
GetDataSourceLabel(data_source_), analyzer, label_from_vmaddr,
file_offset, file_range.size());
}
assert(translator_);
for (auto& pair : outputs_) {
std::string label;
uint64_t offset;
if (pair.first->vm_map.TryGetLabel(label_from_vmaddr, &label, &offset)) {
if (pair.first->vm_map.TryGetLabel(label_from_vmaddr, &label)) {
bool ok = pair.first->file_map.AddRangeWithTranslation(
file_offset, file_range.size(), label, translator_->file_map, verbose,
&pair.first->vm_map);
if (!ok) {
WARN("File range ($0, $1) for label $2 extends beyond base map", offset,
file_range.size(), label);
WARN("File range ($0, $1) for label $2 extends beyond base map",
file_offset, file_range.size(), label);
}
} else if (verbose_level > 2) {
printf("No label found for vmaddr %" PRIx64 "\n", label_from_vmaddr);
}
}
}

void RangeSink::AddVMRangeFor(const char* analyzer, uint64_t label_from_vmaddr,
uint64_t addr, uint64_t size) {
void RangeSink::AddFileRangeForFileRange(const char* analyzer,
absl::string_view from_file_range,
absl::string_view file_range) {
uint64_t file_offset = file_range.data() - file_->data().data();
uint64_t from_file_offset = from_file_range.data() - file_->data().data();
bool verbose = IsVerboseForFileRange(file_offset, file_range.size());
if (verbose) {
printf("[%s, %s] AddFileRangeForFileRange([%" PRIx64 ", %zx], [%" PRIx64
", %zx])\n",
GetDataSourceLabel(data_source_), analyzer, from_file_offset,
from_file_range.size(), file_offset, file_range.size());
}
assert(translator_);
for (auto& pair : outputs_) {
std::string label;
if (pair.first->file_map.TryGetLabelForRange(
from_file_offset, from_file_range.size(), &label)) {
bool ok = pair.first->file_map.AddRangeWithTranslation(
file_offset, file_range.size(), label, translator_->file_map, verbose,
&pair.first->vm_map);
if (!ok) {
WARN("File range ($0, $1) for label $2 extends beyond base map",
file_offset, file_range.size(), label);
}
} else if (verbose_level > 2) {
printf("No label found for file range [%" PRIx64 ", %zx]\n",
from_file_offset, from_file_range.size());
}
}
}

void RangeSink::AddVMRangeForVMAddr(const char* analyzer,
uint64_t label_from_vmaddr, uint64_t addr,
uint64_t size) {
bool verbose = IsVerboseForVMRange(addr, size);
if (verbose) {
printf("[%s, %s] AddVMRangeFor(%" PRIx64 ", [%" PRIx64 ", %" PRIx64 "])\n",
printf("[%s, %s] AddVMRangeForVMAddr(%" PRIx64 ", [%" PRIx64 ", %" PRIx64
"])\n",
GetDataSourceLabel(data_source_), analyzer, label_from_vmaddr, addr,
size);
}
assert(translator_);
for (auto& pair : outputs_) {
std::string label;
uint64_t offset;
if (pair.first->vm_map.TryGetLabel(label_from_vmaddr, &label, &offset)) {
if (pair.first->vm_map.TryGetLabel(label_from_vmaddr, &label)) {
bool ok = pair.first->vm_map.AddRangeWithTranslation(
addr, size, label, translator_->vm_map, verbose,
&pair.first->file_map);
Expand Down
15 changes: 11 additions & 4 deletions src/bloaty.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class RangeSink {

DataSource data_source() const { return data_source_; }
const InputFile& input_file() const { return *file_; }
bool IsBaseMap() const { return translator_ == nullptr; }

// If vmsize or filesize is zero, this mapping is presumed not to exist in
// that domain. For example, .bss mappings don't exist in the file, and
Expand All @@ -166,10 +167,16 @@ class RangeSink {
// Like AddFileRange(), but the label is whatever label was previously
// assigned to VM address |label_from_vmaddr|. If no existing label is
// assigned to |label_from_vmaddr|, this function does nothing.
void AddFileRangeFor(const char* analyzer, uint64_t label_from_vmaddr,
absl::string_view file_range);
void AddVMRangeFor(const char* analyzer, uint64_t label_from_vmaddr,
uint64_t addr, uint64_t size);
void AddFileRangeForVMAddr(const char* analyzer, uint64_t label_from_vmaddr,
absl::string_view file_range);
void AddVMRangeForVMAddr(const char* analyzer, uint64_t label_from_vmaddr,
uint64_t addr, uint64_t size);

// Applies this label from |from_file_range| to |file_range|, but only if the
// entire |from_file_range| has a single label. If not, this does nothing.
void AddFileRangeForFileRange(const char* analyzer,
absl::string_view from_file_range,
absl::string_view file_range);

void AddFileRange(const char* analyzer, absl::string_view name,
absl::string_view file_range) {
Expand Down
7 changes: 3 additions & 4 deletions src/disassemble.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ void DisassembleFindReferences(const DisassemblyInfo& info, RangeSink* sink) {
op->mem.index == X86_REG_INVALID) {
uint64_t to_address = in->address + in->size + op->mem.disp;
if (to_address) {
sink->AddVMRangeFor("x86_disassemble", in->address, to_address,
RangeSink::kUnknownSize);
sink->AddVMRangeForVMAddr("x86_disassemble", in->address, to_address,
RangeSink::kUnknownSize);
}
}
}
Expand Down Expand Up @@ -210,14 +210,13 @@ std::string DisassembleFunction(const DisassemblyInfo& info) {
if (TryGetJumpTarget(info.arch, in, &target)) {
auto iter = local_labels.find(target);
std::string label;
uint64_t offset;
if (iter != local_labels.end()) {
if (target > in->address) {
op_str = ">" + std::to_string(iter->second);
} else {
op_str = "<" + std::to_string(iter->second);
}
} else if (info.symbol_map.vm_map.TryGetLabel(target, &label, &offset)) {
} else if (info.symbol_map.vm_map.TryGetLabel(target, &label)) {
op_str = label;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/dwarf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ void ReadEhFrame(string_view data, RangeSink* sink) {
}
*/

sink->AddFileRangeFor("dwarf_fde", address, full_entry);
sink->AddFileRangeForVMAddr("dwarf_fde", address, full_entry);
}
}
}
Expand Down Expand Up @@ -1887,7 +1887,8 @@ void ReadEhFrameHdr(string_view data, RangeSink* sink) {
ReadEncodedPointer(table_enc, true, &data, base, sink);
uint64_t fde_addr = ReadEncodedPointer(table_enc, true, &data, base, sink);
entry_data.remove_suffix(data.size());
sink->AddFileRangeFor("dwarf_fde_table", initial_location, entry_data);
sink->AddFileRangeForVMAddr("dwarf_fde_table", initial_location,
entry_data);

// We could add fde_addr with an unknown length if we wanted to skip reading
// eh_frame. We can't count on this table being available though, so we
Expand Down
Loading