aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf/dwarf2reader.cc
diff options
context:
space:
mode:
authorScott Graham <scottmg@chromium.org>2016-11-01 15:05:10 -0700
committerScott Graham <scottmg@chromium.org>2016-11-02 02:52:37 +0000
commit1f574b52c6c34e457b16bc451a52874dde91e4b0 (patch)
treed0e1072d3924cb969892d0e187af06d3b7275558 /src/common/dwarf/dwarf2reader.cc
parentminidump-2-core: add more control over filenames (diff)
downloadbreakpad-1f574b52c6c34e457b16bc451a52874dde91e4b0.tar.xz
Basic handling of CIE version 4 in dwarf reading
CIE looks like it's been emitted by clang since ~May 2015 [1]. This means that we didn't have any CFI because this parse aborted, which meant that all stack walks reverted to stack scanning. Allow expected values for address size and segment descriptor size through so that dump_syms can generate at least somewhat reasonable data. [1]: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150518/277292.html R=mark@chromium.org BUG=chromium:627529 Change-Id: I6dc92f51c4afd25c2adff92c09ccb8bb03bf9112 Reviewed-on: https://chromium-review.googlesource.com/406012 Reviewed-by: Mark Mentovai <mark@chromium.org>
Diffstat (limited to 'src/common/dwarf/dwarf2reader.cc')
-rw-r--r--src/common/dwarf/dwarf2reader.cc48
1 files changed, 42 insertions, 6 deletions
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc
index a65b43c8..fda049dd 100644
--- a/src/common/dwarf/dwarf2reader.cc
+++ b/src/common/dwarf/dwarf2reader.cc
@@ -2253,11 +2253,11 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
cursor++;
// If we don't recognize the version, we can't parse any more fields of the
- // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a
- // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well;
+ // CIE. For DWARF CFI, we handle versions 1 through 4 (there was never a
+ // version 2 of CFI data). For .eh_frame, we handle versions 1 and 4 as well;
// the difference between those versions seems to be the same as for
// .debug_frame.
- if (cie->version < 1 || cie->version > 3) {
+ if (cie->version < 1 || cie->version > 4) {
reporter_->UnrecognizedVersion(cie->offset, cie->version);
return false;
}
@@ -2287,16 +2287,36 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
}
}
+ if (cie->version >= 4) {
+ uint8_t address_size = *cursor++;
+ if (address_size != 8) {
+ // TODO(scottmg): Only supporting x64 for now.
+ reporter_->UnexpectedAddressSize(cie->offset, address_size);
+ return false;
+ }
+
+ uint8_t segment_size = *cursor++;
+ if (segment_size != 0) {
+ // TODO(scottmg): Only supporting x64 for now.
+ // I would have perhaps expected 4 here, but LLVM emits a 0, near
+ // http://llvm.org/docs/doxygen/html/MCDwarf_8cpp_source.html#l00606. As
+ // we are not using the value, only succeed for now if it's the expected
+ // 0.
+ reporter_->UnexpectedSegmentSize(cie->offset, segment_size);
+ return false;
+ }
+ }
+
// Parse the code alignment factor.
cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len);
if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
cursor += len;
-
+
// Parse the data alignment factor.
cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len);
if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie);
cursor += len;
-
+
// Parse the return address register. This is a ubyte in version 1, and
// a ULEB128 in version 3.
if (cie->version == 1) {
@@ -2407,7 +2427,7 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
return true;
}
-
+
bool CallFrameInfo::ReadFDEFields(FDE *fde) {
const uint8_t *cursor = fde->fields;
size_t size;
@@ -2648,6 +2668,22 @@ void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) {
filename_.c_str(), offset, section_.c_str(), cie_offset);
}
+void CallFrameInfo::Reporter::UnexpectedAddressSize(uint64 offset,
+ uint8_t address_size) {
+ fprintf(stderr,
+ "%s: CFI frame description entry at offset 0x%llx in '%s':"
+ " CIE specifies unexpected address size: %d\n",
+ filename_.c_str(), offset, section_.c_str(), address_size);
+}
+
+void CallFrameInfo::Reporter::UnexpectedSegmentSize(uint64 offset,
+ uint8_t segment_size) {
+ fprintf(stderr,
+ "%s: CFI frame description entry at offset 0x%llx in '%s':"
+ " CIE specifies unexpected segment size: %d\n",
+ filename_.c_str(), offset, section_.c_str(), segment_size);
+}
+
void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
fprintf(stderr,
"%s: CFI frame description entry at offset 0x%llx in '%s':"