Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.
/ swift-llvm Public archive

Commit b85b8cd

Browse files
committed
WebAssembly: properly handle MCBinaryExpr in aliased symbols
Swift uses aliased symbols to refer to offsets within metadata structures. eg ``` @"$s12SwiftPrivate28_stdlib_ShardedAtomicCounterVN" = alias %swift.type, bitcast (i32* getelementptr inbounds (<{ i8**, i32, <{ i32, i32, i32, i32, i32, i32, i32 }>*, i32, i32 }>, <{ i8**, i32, <{ i32, i32, i32, i32, i32, i32, i32 }>*, i32, i32 }>* @"$s12SwiftPrivate28_stdlib_ShardedAtomicCounterVMf", i32 0, i32 1) to %swift.type*) ``` My previous commit only got the alias to refer to the correct target symbol, but not at the right offset. This commit properly emits these symbols. With this change, print("hello world") works but print() with anything else is still broken.
1 parent 945cb79 commit b85b8cd

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

lib/MC/WasmObjectWriter.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,23 @@ static bool isInSymtab(const MCSymbolWasm &Sym) {
11871187
return true;
11881188
}
11891189

1190+
// SwiftWasm: takes a MCSymbolWasm that's an alias expression of the form
1191+
// ((targetSymbol + constantA) - constantB) + constantC...)
1192+
// return the final offset from targetSymbol.
1193+
// if no offset, returns 0.
1194+
static int64_t getAliasedSymbolOffset(const MCSymbolWasm &Symbol,
1195+
const MCAsmLayout &Layout) {
1196+
if (!Symbol.isVariable())
1197+
return 0;
1198+
const MCExpr *Expr = Symbol.getVariableValue();
1199+
MCValue Res;
1200+
if (!Expr->evaluateAsRelocatable(Res, &Layout, nullptr)) {
1201+
Expr->dump();
1202+
report_fatal_error("Can't evaluate alias symbol expression");
1203+
}
1204+
return Res.getConstant();
1205+
}
1206+
11901207
uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
11911208
const MCAsmLayout &Layout) {
11921209
uint64_t StartOffset = W.OS.tell();
@@ -1461,6 +1478,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
14611478

14621479
// Find the target symbol of this weak alias and export that index
14631480
const auto &WS = static_cast<const MCSymbolWasm &>(S);
1481+
14641482
const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS);
14651483
LLVM_DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym
14661484
<< "'\n");
@@ -1472,8 +1490,16 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
14721490
LLVM_DEBUG(dbgs() << " -> index:" << WasmIndex << "\n");
14731491
} else if (WS.isData()) {
14741492
assert(DataLocations.count(ResolvedSym) > 0);
1475-
const wasm::WasmDataReference &Ref =
1493+
// SwiftWasm: hack: grab the offset
1494+
// Swift has aliases of the form
1495+
// alias = ((symbol + constant) - constant)
1496+
// so we need to evaluate the constants here using MCExpr
1497+
// there's probably a proper way to do this.
1498+
int64_t Offset = getAliasedSymbolOffset(WS, Layout);
1499+
wasm::WasmDataReference Ref =
14761500
DataLocations.find(ResolvedSym)->second;
1501+
Ref.Offset += Offset;
1502+
Ref.Size -= Offset;
14771503
DataLocations[&WS] = Ref;
14781504
LLVM_DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
14791505
} else {

0 commit comments

Comments
 (0)