diff options
author | Alon Zakai <azakai@google.com> | 2020-08-07 10:45:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-07 10:45:15 -0700 |
commit | a355a7ea6151d4bd6dbb7895317fba0f3e8e422f (patch) | |
tree | 5953bc902dfa2c968ba26b614ef8e39eb14e3f70 /third_party/llvm-project/DWARFVisitor.cpp | |
parent | cdc38d3162eb62cb313704f264f17d230989084b (diff) | |
download | binaryen-a355a7ea6151d4bd6dbb7895317fba0f3e8e422f.tar.gz binaryen-a355a7ea6151d4bd6dbb7895317fba0f3e8e422f.tar.bz2 binaryen-a355a7ea6151d4bd6dbb7895317fba0f3e8e422f.zip |
DWARF: Fix debug_info references to the abbreviations section (#2997)
The previous code assumed that each compile unit had its own
abbreviation section, and they are all in order. That's normally how
LLVM emits things, but in #2992 there is a testcase in which linking
of object files with IR files somehow ends up with a different order.
The proper fix is to track the binary offsets of abbreviations in the
abbreviation section. That section is comprised of null-terminated
lists, which each CU has an offset to the beginning of. With those
offsets, we can match things properly.
Add a testcase that crashes without this, to prevent regressions.
Fixes #2992
Fixes #3007
Diffstat (limited to 'third_party/llvm-project/DWARFVisitor.cpp')
-rw-r--r-- | third_party/llvm-project/DWARFVisitor.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/third_party/llvm-project/DWARFVisitor.cpp b/third_party/llvm-project/DWARFVisitor.cpp index ba3d1e0c5..1f4403563 100644 --- a/third_party/llvm-project/DWARFVisitor.cpp +++ b/third_party/llvm-project/DWARFVisitor.cpp @@ -44,17 +44,26 @@ static unsigned getRefSize(const DWARFYAML::Unit &Unit) { } template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() { - // XXX BINARYEN: Handle multiple linked compile units. Each one has its own - // range of values, terminated by a zero. AbbrevStart refers to the start - // index for the current unit, and AbbrevEnd to one past the last one - // (which is the index of the 0 terminator). + // XXX BINARYEN: Handle multiple linked compile units, each of which can + // refer to a different abbreviation list. // TODO: This code appears to assume that abbreviation codes increment by 1 // so that lookups are linear. In LLVM output that is true, but it might not // be in general. - size_t AbbrevStart = 0, AbbrevEnd = -1; for (auto &Unit : DebugInfo.CompileUnits) { - // Skip the 0 terminator. - AbbrevEnd = AbbrevStart = AbbrevEnd + 1; + // AbbrOffset is the byte offset into the abbreviation section, which we + // need to find among the Abbrev's ListOffsets (which are the byte offsets + // of where that abbreviation list begins). + // TODO: Optimize this to not be O(#CUs * #abbrevs). + size_t AbbrevStart = -1; + for (size_t i = 0; i < DebugInfo.AbbrevDecls.size(); i++) { + if (DebugInfo.AbbrevDecls[i].ListOffset == Unit.AbbrOffset) { + AbbrevStart = i; + break; + } + } + assert(AbbrevStart != -1); // must find the list + // Find the last entry in this abbreviation list. + size_t AbbrevEnd = AbbrevStart; while (AbbrevEnd < DebugInfo.AbbrevDecls.size() && DebugInfo.AbbrevDecls[AbbrevEnd].Code) { AbbrevEnd++; |