diff options
-rw-r--r-- | test/passes/multi_line_table.bin.txt | 32 | ||||
-rw-r--r-- | test/unit/input/dwarf/cubescript.wasm | bin | 0 -> 193546 bytes | |||
-rw-r--r-- | test/unit/input/dwarf/zlib.wasm | bin | 0 -> 171100 bytes | |||
-rw-r--r-- | test/unit/test_dwarf.py | 16 | ||||
-rw-r--r-- | third_party/llvm-project/DWARFEmitter.cpp | 8 | ||||
-rw-r--r-- | third_party/llvm-project/DWARFVisitor.cpp | 25 | ||||
-rw-r--r-- | third_party/llvm-project/dwarf2yaml.cpp | 8 |
7 files changed, 75 insertions, 14 deletions
diff --git a/test/passes/multi_line_table.bin.txt b/test/passes/multi_line_table.bin.txt index 5d5f53f8b..3212e1c14 100644 --- a/test/passes/multi_line_table.bin.txt +++ b/test/passes/multi_line_table.bin.txt @@ -211,7 +211,7 @@ DWARF debug info ================ Contains section .debug_info (130 bytes) -Contains section .debug_abbrev (99 bytes) +Contains section .debug_abbrev (100 bytes) Contains section .debug_line (145 bytes) Contains section .debug_str (407 bytes) @@ -240,6 +240,7 @@ Abbrev table for offset: 0x00000000 DW_AT_encoding DW_FORM_data1 DW_AT_byte_size DW_FORM_data1 +Abbrev table for offset: 0x00000032 [1] DW_TAG_compile_unit DW_CHILDREN_yes DW_AT_producer DW_FORM_strp DW_AT_language DW_FORM_data2 @@ -291,9 +292,32 @@ Abbrev table for offset: 0x00000000 DW_AT_byte_size [DW_FORM_data1] (0x04) 0x00000040: NULL -0x00000041: Compile Unit: length = 0x0000003d version = 0x0004 addr_size = 0x04 (next unit at 0x00000082) -<compile unit can't be parsed!> +0x00000041: Compile Unit: length = 0x0000003d version = 0x0004 abbr_offset = 0x0032 addr_size = 0x04 (next unit at 0x00000082) + +0x0000004c: DW_TAG_compile_unit [1] * + DW_AT_producer [DW_FORM_strp] ( .debug_str[0x000000cc] = "clang version 10.0.0 (/b/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-llvm-llvm--project 7fcd9e3f70830a9c4bf631a602c2764180b5c3a8)") + DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus) + DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000161] = "third.cpp") + DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000049) + DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000016b] = "/tmp/emscripten_test_wasm0_xkAHBX") + DW_AT_low_pc [DW_FORM_addr] (0x0000000000000016) + DW_AT_high_pc [DW_FORM_data4] (0x0000000b) + +0x00000067: DW_TAG_subprogram [2] + DW_AT_low_pc [DW_FORM_addr] (0x0000000000000016) + DW_AT_high_pc [DW_FORM_data4] (0x0000000b) + DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000018d] = "sidef") + DW_AT_decl_file [DW_FORM_data1] ("/tmp/emscripten_test_wasm0_xkAHBX/third.cpp") + DW_AT_decl_line [DW_FORM_data1] (1) + DW_AT_type [DW_FORM_ref4] (cu + 0x0039 => {0x0000007a} "int") + DW_AT_external [DW_FORM_flag_present] (true) +0x0000007a: DW_TAG_base_type [3] + DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000193] = "int") + DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) + DW_AT_byte_size [DW_FORM_data1] (0x04) + +0x00000081: NULL .debug_line contents: debug_line[0x00000000] @@ -444,7 +468,7 @@ file_names[ 1]: ) ;; custom section "dylink", size 5 ;; custom section ".debug_info", size 130 - ;; custom section ".debug_abbrev", size 99 + ;; custom section ".debug_abbrev", size 100 ;; custom section ".debug_line", size 145 ;; custom section ".debug_str", size 407 ;; custom section "producers", size 180 diff --git a/test/unit/input/dwarf/cubescript.wasm b/test/unit/input/dwarf/cubescript.wasm Binary files differnew file mode 100644 index 000000000..4fcbf2216 --- /dev/null +++ b/test/unit/input/dwarf/cubescript.wasm diff --git a/test/unit/input/dwarf/zlib.wasm b/test/unit/input/dwarf/zlib.wasm Binary files differnew file mode 100644 index 000000000..40674c0a4 --- /dev/null +++ b/test/unit/input/dwarf/zlib.wasm diff --git a/test/unit/test_dwarf.py b/test/unit/test_dwarf.py new file mode 100644 index 000000000..5078efeeb --- /dev/null +++ b/test/unit/test_dwarf.py @@ -0,0 +1,16 @@ +import os + +from scripts.test import shared +from . import utils + + +class DWARFTest(utils.BinaryenTestCase): + def test_no_crash(self): + # run dwarf processing on some interesting large files, too big to be + # worth putting in passes where the text output would be massive. We + # just check that no assertion are hit. + path = self.input_path('dwarf') + for name in os.listdir(path): + args = [os.path.join(path, name)] + \ + ['-g', '--dwarfdump', '--roundtrip', '--dwarfdump'] + shared.run_process(shared.WASM_OPT + args, capture_output=True) diff --git a/third_party/llvm-project/DWARFEmitter.cpp b/third_party/llvm-project/DWARFEmitter.cpp index 92efcdfa0..6e4ee6119 100644 --- a/third_party/llvm-project/DWARFEmitter.cpp +++ b/third_party/llvm-project/DWARFEmitter.cpp @@ -78,6 +78,10 @@ void DWARFYAML::EmitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto AbbrevDecl : DI.AbbrevDecls) { encodeULEB128(AbbrevDecl.Code, OS); + // XXX BINARYEN This is a terminator. + if (!AbbrevDecl.Code) { + continue; + } encodeULEB128(AbbrevDecl.Tag, OS); OS.write(AbbrevDecl.Children); for (auto Attr : AbbrevDecl.Attributes) { @@ -89,10 +93,6 @@ void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { encodeULEB128(0, OS); encodeULEB128(0, OS); } - // XXX BINARYEN: end the list with a zero. LLVM works with or without this, - // but other decoders may error. See - // https://bugs.llvm.org/show_bug.cgi?id=44511 - writeInteger((uint8_t)0, OS, true /* isLittleEndian */); } void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { diff --git a/third_party/llvm-project/DWARFVisitor.cpp b/third_party/llvm-project/DWARFVisitor.cpp index 05c4194e3..44bb33b47 100644 --- a/third_party/llvm-project/DWARFVisitor.cpp +++ b/third_party/llvm-project/DWARFVisitor.cpp @@ -44,25 +44,38 @@ 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). + // 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; + while (AbbrevEnd < DebugInfo.AbbrevDecls.size() && + DebugInfo.AbbrevDecls[AbbrevEnd].Code) { + AbbrevEnd++; + } onStartCompileUnit(Unit); if (Unit.Entries.empty()) { // XXX BINARYEN continue; } auto FirstAbbrevCode = Unit.Entries[0].AbbrCode; - for (auto &Entry : Unit.Entries) { onStartDIE(Unit, Entry); if (Entry.AbbrCode == 0u) continue; // XXX BINARYEN - if (Entry.AbbrCode - FirstAbbrevCode >= DebugInfo.AbbrevDecls.size()) { - errs() << "warning: invalid abbreviation code " << Entry.AbbrCode << - " (range: " << FirstAbbrevCode << "-" << - (DebugInfo.AbbrevDecls.size() - FirstAbbrevCode) << ")\n"; + if (Entry.AbbrCode - FirstAbbrevCode + AbbrevStart >= AbbrevEnd) { + errs() << "warning: invalid abbreviation code " << Entry.AbbrCode + << " (range: " << FirstAbbrevCode << " : " << AbbrevStart + << ".." << AbbrevEnd << ")\n"; continue; } - auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode]; + auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode + AbbrevStart]; auto FormVal = Entry.Values.begin(); auto AbbrForm = Abbrev.Attributes.begin(); for (; diff --git a/third_party/llvm-project/dwarf2yaml.cpp b/third_party/llvm-project/dwarf2yaml.cpp index b43b0e420..52e875637 100644 --- a/third_party/llvm-project/dwarf2yaml.cpp +++ b/third_party/llvm-project/dwarf2yaml.cpp @@ -43,6 +43,14 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) { } Y.AbbrevDecls.push_back(Abbrv); } + // XXX BINARYEN: null-terminate the DeclSet. This is needed to separate + // DeclSets from each other, and to null-terminate the entire list + // (LLVM works with or without this, but other decoders may error, see + // https://bugs.llvm.org/show_bug.cgi?id=44511). + DWARFYAML::Abbrev Abbrv; + Abbrv.Code = 0; + Abbrv.Tag = dwarf::Tag(0); + Y.AbbrevDecls.push_back(Abbrv); } } } |