From 0fd5e7b2d8ca4ed46d76187feb4b903ed0a3ea75 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 7 Jul 2021 23:31:48 -0700 Subject: [PATCH] [WebAssembly][lld] Fix segfault on .bss sections in mapfile When memory is declared in the Wasm module, we rely on the implicit zero initialization behavior and do not explicitly output .bss sections. The means that they do not have associated `outputSec` entries, which was causing segfaults in the mapfile support. Fix the issue by guarding against null `outputSec` and falling back to using a zero offset. Differential Revision: https://reviews.llvm.org/D102951 --- lld/test/wasm/map-file.s | 38 +++++++++++++++++++++++++------------- lld/wasm/MapFile.cpp | 12 ++++++++---- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lld/test/wasm/map-file.s b/lld/test/wasm/map-file.s index a215cc1..9ca2f19 100644 --- a/lld/test/wasm/map-file.s +++ b/lld/test/wasm/map-file.s @@ -10,6 +10,9 @@ wasm_global: bar: .functype bar () -> () i32.const somedata + i32.const somezeroes + drop + drop end_function write_global: @@ -30,9 +33,15 @@ somedata: .int32 123 .size somedata, 4 +.section .bss.somezeroes,"",@ +somezeroes: + .int32 0 +.size somezeroes, 4 + .section .debug_info,"",@ .int32 bar + # CHECK: Addr Off Size Out In Symbol # CHECK-NEXT: - 8 a TYPE # CHECK-NEXT: - 12 6 FUNCTION @@ -42,19 +51,22 @@ somedata: # CHECK-NEXT: 0 0 0 __stack_pointer # CHECK-NEXT: 1 0 0 wasm_global # CHECK-NEXT: - 33 15 EXPORT -# CHECK-NEXT: - 48 26 CODE -# CHECK-NEXT: - 49 9 {{.*}}{{/|\\}}map-file.s.tmp1.o:(bar) -# CHECK-NEXT: - 49 9 bar -# CHECK-NEXT: - 52 b {{.*}}{{/|\\}}map-file.s.tmp1.o:(write_global) -# CHECK-NEXT: - 52 b write_global -# CHECK-NEXT: - 5d f {{.*}}{{/|\\}}map-file.s.tmp1.o:(_start) -# CHECK-NEXT: - 5d f _start -# CHECK-NEXT: - 6e d DATA -# CHECK-NEXT: 400 6f 4 .data -# CHECK-NEXT: 400 75 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.data.somedata) -# CHECK-NEXT: 400 75 4 somedata -# CHECK-NEXT: - 7b 12 CUSTOM(.debug_info) -# CHECK-NEXT: - 8d 50 CUSTOM(name) +# CHECK-NEXT: - 48 2e CODE +# CHECK-NEXT: - 49 11 {{.*}}{{/|\\}}map-file.s.tmp1.o:(bar) +# CHECK-NEXT: - 49 11 bar +# CHECK-NEXT: - 5a b {{.*}}{{/|\\}}map-file.s.tmp1.o:(write_global) +# CHECK-NEXT: - 5a b write_global +# CHECK-NEXT: - 65 f {{.*}}{{/|\\}}map-file.s.tmp1.o:(_start) +# CHECK-NEXT: - 65 f _start +# CHECK-NEXT: - 76 d DATA +# CHECK-NEXT: 400 77 4 .data +# CHECK-NEXT: 400 7d 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.data.somedata) +# CHECK-NEXT: 400 7d 4 somedata +# CHECK-NEXT: 404 76 4 .bss +# CHECK-NEXT: 404 0 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.bss.somezeroes) +# CHECK-NEXT: 404 0 4 somezeroes +# CHECK-NEXT: - 83 12 CUSTOM(.debug_info) +# CHECK-NEXT: - 95 50 CUSTOM(name) # RUN: not wasm-ld %t1.o -o /dev/null -Map=/ 2>&1 \ # RUN: | FileCheck -check-prefix=FAIL %s diff --git a/lld/wasm/MapFile.cpp b/lld/wasm/MapFile.cpp index c964efe..9dbab50 100644 --- a/lld/wasm/MapFile.cpp +++ b/lld/wasm/MapFile.cpp @@ -80,7 +80,9 @@ getSymbolStrings(ArrayRef syms) { auto *chunk = syms[i]->getChunk(); if (chunk == nullptr) return; - uint64_t fileOffset = chunk->outputSec->getOffset() + chunk->outSecOff; + uint64_t fileOffset = chunk->outputSec != nullptr + ? chunk->outputSec->getOffset() + chunk->outSecOff + : 0; uint64_t vma = -1; uint64_t size = 0; if (auto *DD = dyn_cast(syms[i])) { @@ -138,9 +140,11 @@ void lld::wasm::writeMapFile(ArrayRef outputSections) { oseg->size); os << oseg->name << '\n'; for (auto *chunk : oseg->inputSegments) { - writeHeader(os, chunk->getVA(), - chunk->outputSec->getOffset() + chunk->outSecOff, - chunk->getSize()); + uint64_t offset = + chunk->outputSec != nullptr + ? chunk->outputSec->getOffset() + chunk->outSecOff + : 0; + writeHeader(os, chunk->getVA(), offset, chunk->getSize()); os.indent(8) << toString(chunk) << '\n'; for (Symbol *sym : sectionSyms[chunk]) os << symStr[sym] << '\n'; -- 2.7.4