summaryrefslogtreecommitdiff
path: root/third_party/llvm-project
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-08-07 10:45:15 -0700
committerGitHub <noreply@github.com>2020-08-07 10:45:15 -0700
commita355a7ea6151d4bd6dbb7895317fba0f3e8e422f (patch)
tree5953bc902dfa2c968ba26b614ef8e39eb14e3f70 /third_party/llvm-project
parentcdc38d3162eb62cb313704f264f17d230989084b (diff)
downloadbinaryen-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')
-rw-r--r--third_party/llvm-project/DWARFVisitor.cpp23
-rw-r--r--third_party/llvm-project/dwarf2yaml.cpp2
-rw-r--r--third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h10
3 files changed, 28 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++;
diff --git a/third_party/llvm-project/dwarf2yaml.cpp b/third_party/llvm-project/dwarf2yaml.cpp
index 5e22e1989..7f160f7e5 100644
--- a/third_party/llvm-project/dwarf2yaml.cpp
+++ b/third_party/llvm-project/dwarf2yaml.cpp
@@ -27,6 +27,7 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
auto AbbrevSetPtr = DCtx.getDebugAbbrev();
if (AbbrevSetPtr) {
for (auto AbbrvDeclSet : *AbbrevSetPtr) {
+ auto ListOffset = AbbrvDeclSet.second.getOffset();
for (auto AbbrvDecl : AbbrvDeclSet.second) {
DWARFYAML::Abbrev Abbrv;
Abbrv.Code = AbbrvDecl.getCode();
@@ -41,6 +42,7 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
AttAbrv.Value = Attribute.getImplicitConstValue();
Abbrv.Attributes.push_back(AttAbrv);
}
+ Abbrv.ListOffset = ListOffset;
Y.AbbrevDecls.push_back(Abbrv);
}
// XXX BINARYEN: null-terminate the DeclSet. This is needed to separate
diff --git a/third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h b/third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h
index bd4aa2007..818bddede 100644
--- a/third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h
@@ -55,6 +55,16 @@ struct Abbrev {
llvm::dwarf::Tag Tag;
llvm::dwarf::Constants Children;
std::vector<AttributeAbbrev> Attributes;
+ // XXX BINARYEN: Represent the binary offset in the abbreviation section for
+ // this abbreviation's list. The abbreviation section has multiple lists,
+ // each null-terminated, and those lists are what are referred to by compile
+ // units by offset. We need to match the offset in a compile unit to the
+ // abbreviation at that offset (which must be the beginning of an
+ // abbreviation list, that is, either the very first element, or after a null
+ // terminator). All abbreviations in the same list have the same offset
+ // (DWARFAbbreviationDeclarationSet does not track anything else, and we don't
+ // need it).
+ uint64_t ListOffset;
};
struct ARangeDescriptor {