[WebAssembly][lld] Fix segfault on .bss sections in mapfile
authorThomas Lively <tlively@google.com>
Thu, 8 Jul 2021 06:31:48 +0000 (23:31 -0700)
committerThomas Lively <tlively@google.com>
Thu, 8 Jul 2021 06:31:48 +0000 (23:31 -0700)
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
lld/wasm/MapFile.cpp

index a215cc1..9ca2f19 100644 (file)
@@ -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
index c964efe..9dbab50 100644 (file)
@@ -80,7 +80,9 @@ getSymbolStrings(ArrayRef<Symbol *> 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<DefinedData>(syms[i])) {
@@ -138,9 +140,11 @@ void lld::wasm::writeMapFile(ArrayRef<OutputSection *> 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';