[lld] 067f005 - [lld][WebAssembly] Fix segfault in map file support
Thomas Lively via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 9 14:42:51 PST 2021
Author: Thomas Lively
Date: 2021-02-09T14:42:43-08:00
New Revision: 067f005500af3093ee23d3c044f9b009c5bd94cf
URL: https://github.com/llvm/llvm-project/commit/067f005500af3093ee23d3c044f9b009c5bd94cf
DIFF: https://github.com/llvm/llvm-project/commit/067f005500af3093ee23d3c044f9b009c5bd94cf.diff
LOG: [lld][WebAssembly] Fix segfault in map file support
The code previously assumed that `getChunk` would return a non-null pointer for
every symbol, but in fact it only returns non-null pointers for DefinedFunction
and DefinedData symbols. This patch fixes the segfault by checking whether
`getChunk` returns a null for each symbol and skipping the mapping output for
any symbols for which it does.
Differential Revision: https://reviews.llvm.org/D88369
Added:
Modified:
lld/test/wasm/map-file.s
lld/wasm/MapFile.cpp
lld/wasm/SyntheticSections.h
Removed:
################################################################################
diff --git a/lld/test/wasm/map-file.s b/lld/test/wasm/map-file.s
index a5bd01605695..a215cc14d4cc 100644
--- a/lld/test/wasm/map-file.s
+++ b/lld/test/wasm/map-file.s
@@ -4,15 +4,25 @@
# RUN: wasm-ld %t1.o -o %t -Map=%t.map
# RUN: FileCheck --match-full-lines --strict-whitespace %s < %t.map
+.globaltype wasm_global, i32, immutable
+wasm_global:
+
bar:
.functype bar () -> ()
i32.const somedata
end_function
+write_global:
+ .functype write_global (i32) -> ()
+ local.get 0
+ global.set wasm_global
+ end_function
+
.globl _start
_start:
.functype _start () -> ()
call bar
+ call write_global
end_function
.section .data.somedata,"",@
@@ -24,23 +34,27 @@ somedata:
.int32 bar
# CHECK: Addr Off Size Out In Symbol
-# CHECK-NEXT: - 8 6 TYPE
-# CHECK-NEXT: - e 5 FUNCTION
-# CHECK-NEXT: - 13 7 TABLE
-# CHECK-NEXT: - 1a 5 MEMORY
-# CHECK-NEXT: - 1f a GLOBAL
-# CHECK-NEXT: - 29 15 EXPORT
-# CHECK-NEXT: - 3e 15 CODE
-# CHECK-NEXT: - 3f 9 {{.*}}{{/|\\}}map-file.s.tmp1.o:(bar)
-# CHECK-NEXT: - 3f 9 bar
-# CHECK-NEXT: - 48 9 {{.*}}{{/|\\}}map-file.s.tmp1.o:(_start)
-# CHECK-NEXT: - 48 9 _start
-# CHECK-NEXT: - 53 d DATA
-# CHECK-NEXT: 400 54 4 .data
-# CHECK-NEXT: 400 5a 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.data.somedata)
-# CHECK-NEXT: 400 5a 4 somedata
-# CHECK-NEXT: - 60 12 CUSTOM(.debug_info)
-# CHECK-NEXT: - 72 35 CUSTOM(name)
+# CHECK-NEXT: - 8 a TYPE
+# CHECK-NEXT: - 12 6 FUNCTION
+# CHECK-NEXT: - 18 7 TABLE
+# CHECK-NEXT: - 1f 5 MEMORY
+# CHECK-NEXT: - 24 f GLOBAL
+# 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)
# 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 a08d2a97d74a..29fa0d0b505a 100644
--- a/lld/wasm/MapFile.cpp
+++ b/lld/wasm/MapFile.cpp
@@ -20,6 +20,7 @@
#include "MapFile.h"
#include "InputFiles.h"
+#include "InputGlobal.h"
#include "OutputSections.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
@@ -76,8 +77,10 @@ getSymbolStrings(ArrayRef<Symbol *> syms) {
std::vector<std::string> str(syms.size());
parallelForEachN(0, syms.size(), [&](size_t i) {
raw_string_ostream os(str[i]);
- auto &chunk = *syms[i]->getChunk();
- uint64_t fileOffset = chunk.outputSec->getOffset() + chunk.outputOffset;
+ auto *chunk = syms[i]->getChunk();
+ if (chunk == nullptr)
+ return;
+ uint64_t fileOffset = chunk->outputSec->getOffset() + chunk->outputOffset;
uint64_t vma = -1;
uint64_t size = 0;
if (auto *DD = dyn_cast<DefinedData>(syms[i])) {
@@ -143,6 +146,12 @@ void lld::wasm::writeMapFile(ArrayRef<OutputSection *> outputSections) {
os << symStr[sym] << '\n';
}
}
+ } else if (auto *globals = dyn_cast<GlobalSection>(osec)) {
+ for (auto *global : globals->inputGlobals) {
+ writeHeader(os, global->getGlobalIndex(), 0, 0);
+ os.indent(8) << global->getName() << '\n';
+ }
}
+ // TODO: other section/symbol types
}
}
diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h
index 3795b38228d0..5b753d441178 100644
--- a/lld/wasm/SyntheticSections.h
+++ b/lld/wasm/SyntheticSections.h
@@ -191,6 +191,11 @@ class EventSection : public SyntheticSection {
class GlobalSection : public SyntheticSection {
public:
GlobalSection() : SyntheticSection(llvm::wasm::WASM_SEC_GLOBAL) {}
+
+ static bool classof(const OutputSection *sec) {
+ return sec->type == llvm::wasm::WASM_SEC_GLOBAL;
+ }
+
uint32_t numGlobals() const {
assert(isSealed);
return inputGlobals.size() + dataAddressGlobals.size() +
More information about the llvm-commits
mailing list