Merge branch 'dataquality' of github.com:haberman/bloaty into dataquality
diff --git a/src/bloaty.cc b/src/bloaty.cc
index 58fb7af..9cc0c59 100644
--- a/src/bloaty.cc
+++ b/src/bloaty.cc
@@ -878,8 +878,12 @@
for (auto& pair : outputs_) {
const std::string label = pair.second->Munge(name);
if (translator_) {
- pair.first->file_map.AddRangeWithTranslation(
+ bool ok = pair.first->file_map.AddRangeWithTranslation(
fileoff, filesize, label, translator_->file_map, &pair.first->vm_map);
+ if (!ok) {
+ THROWF("File range ($0, $1) for label $2 extends beyond base map",
+ fileoff, filesize, name);
+ }
} else {
pair.first->file_map.AddRange(fileoff, filesize, label);
}
@@ -902,9 +906,13 @@
std::string label;
uint64_t offset;
if (pair.first->vm_map.TryGetLabel(label_from_vmaddr, &label, &offset)) {
- pair.first->file_map.AddRangeWithTranslation(
+ bool ok = pair.first->file_map.AddRangeWithTranslation(
file_offset, file_range.size(), label, translator_->file_map,
&pair.first->vm_map);
+ if (!ok) {
+ THROWF("File range ($0, $1) for label $2 extends beyond base map",
+ offset, file_range.size(), label);
+ }
} else if (verbose_level > 2) {
printf("No label found for vmaddr %" PRIx64 "\n", label_from_vmaddr);
}
@@ -924,8 +932,12 @@
std::string label;
uint64_t offset;
if (pair.first->vm_map.TryGetLabel(label_from_vmaddr, &label, &offset)) {
- pair.first->vm_map.AddRangeWithTranslation(
+ bool ok = pair.first->vm_map.AddRangeWithTranslation(
addr, size, label, translator_->vm_map, &pair.first->file_map);
+ if (!ok) {
+ THROWF("VM range ($0, $1) for label $2 extends beyond base map", addr,
+ size, label);
+ }
} else if (verbose_level > 2) {
printf("No label found for vmaddr %" PRIx64 "\n", label_from_vmaddr);
}
@@ -942,8 +954,12 @@
assert(translator_);
for (auto& pair : outputs_) {
const std::string label = pair.second->Munge(name);
- pair.first->vm_map.AddRangeWithTranslation(
+ bool ok = pair.first->vm_map.AddRangeWithTranslation(
vmaddr, vmsize, label, translator_->vm_map, &pair.first->file_map);
+ if (!ok) {
+ THROWF("VM range ($0, $1) for label $2 extends beyond base map", vmaddr,
+ vmsize, name);
+ }
}
}
diff --git a/src/elf.cc b/src/elf.cc
index 55989c7..94ce2ad 100644
--- a/src/elf.cc
+++ b/src/elf.cc
@@ -1201,7 +1201,11 @@
});
// The last-line fallback to make sure we cover the entire VM space.
- DoReadELFSegments(sink, kReportByEscapedSegmentName);
+ if (IsObjectFile(sink->input_file().data())) {
+ DoReadELFSections(sink, kReportByEscapedSectionName);
+ } else {
+ DoReadELFSegments(sink, kReportByEscapedSegmentName);
+ }
// The last-line fallback to make sure we cover the entire file.
sink->AddFileRange("elf_catchall", "[Unmapped]", sink->input_file().data());
diff --git a/src/range_map.cc b/src/range_map.cc
index 6e20cf2..abee140 100644
--- a/src/range_map.cc
+++ b/src/range_map.cc
@@ -29,9 +29,6 @@
bool RangeMap::TranslateAndTrimRangeWithEntry(T iter, uint64_t addr,
uint64_t size, uint64_t* out_addr,
uint64_t* out_size) const {
- if (!iter->second.HasTranslation()) {
- return false;
- }
addr = std::max(addr, iter->first);
@@ -40,11 +37,16 @@
} else {
uint64_t end = std::min(addr + size, iter->first + iter->second.size);
if (addr >= end) {
+ *out_size = 0;
return false;
}
*out_size = end - addr;
}
+ if (!iter->second.HasTranslation()) {
+ return false;
+ }
+
*out_addr = TranslateWithEntry(iter, addr);
return true;
}
@@ -226,7 +228,7 @@
// span several section mappings. If we really wanted to get particular here,
// we could pass a parameter indicating whether such spanning is expected, and
// warn if not.
-void RangeMap::AddRangeWithTranslation(uint64_t addr, uint64_t size,
+bool RangeMap::AddRangeWithTranslation(uint64_t addr, uint64_t size,
const std::string& val,
const RangeMap& translator,
RangeMap* other) {
@@ -240,6 +242,7 @@
end = addr + size;
assert(end >= addr);
}
+ uint64_t total_size = 0;
// TODO: optionally warn about when we span ranges of the translator. In some
// cases this would be a bug (ie. symbols VM->file). In other cases it's
@@ -255,8 +258,11 @@
}
other->AddRange(this_addr, this_size, val);
}
+ total_size += this_size;
++it;
}
+
+ return total_size == size;
}
} // namespace bloaty
diff --git a/src/range_map.h b/src/range_map.h
index f2dfc0f..c227382 100644
--- a/src/range_map.h
+++ b/src/range_map.h
@@ -63,7 +63,11 @@
// to |other| (in domain D2), using |translator| (in domain D1) to translate
// D1->D2. The translation is performed using information from previous
// AddDualRange() calls on |translator|.
- void AddRangeWithTranslation(uint64_t addr, uint64_t size,
+ //
+ // Returns true if the entire range [addr, size] was present in the
+ // |translator| map. (This does not necessarily mean that every part of the
+ // range was actually translated).
+ bool AddRangeWithTranslation(uint64_t addr, uint64_t size,
const std::string& val,
const RangeMap& translator, RangeMap* other);
@@ -270,9 +274,24 @@
// Starting a new continuous range: all iterators must start at the same
// place.
current = iters[0]->first;
- for (auto iter : iters) {
- assert(iter->first == current);
- keys.push_back(iter->second.label);
+ for (int i = 0; i < range_maps.size(); i++) {
+ if (range_maps[i]->IterIsEnd(iters[i])) {
+ printf(
+ "Error, no more ranges for index %d but we need one "
+ "to match (%s)\n",
+ i, range_maps[0]->EntryDebugString(iters[0]).c_str());
+ assert(false);
+ throw std::runtime_error("No more ranges.");
+ } else if (iters[i]->first != current) {
+ printf(
+ "Error, range (%s) doesn't cover the beginning of base range "
+ "(%s)\n",
+ range_maps[i]->EntryDebugString(iters[i]).c_str(),
+ range_maps[0]->EntryDebugString(iters[0]).c_str());
+ assert(false);
+ throw std::runtime_error("No more ranges.");
+ }
+ keys.push_back(iters[i]->second.label);
}
}