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

Commit e5a7798

Browse files
zhuoweiMaxDesiatov
authored andcommitted
WebAssembly: attempt to fix non-SymbolExpr relocations
Also try hard to extract a symbol from a MCExpr when writing relocations I doubt this is the right way, but hey it emits an object now
1 parent f4445ac commit e5a7798

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

lib/MC/WasmObjectWriter.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,8 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
493493

494494
if (SymA && SymA->isVariable()) {
495495
const MCExpr *Expr = SymA->getVariableValue();
496-
const auto *Inner = cast<MCSymbolRefExpr>(Expr);
497-
if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
496+
const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
497+
if (Inner && Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
498498
llvm_unreachable("weakref used in reloc not yet implemented");
499499
}
500500

@@ -556,6 +556,50 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
556556
}
557557
}
558558

559+
// Write X as an (unsigned) LEB value at offset Offset in Stream, padded
560+
// to allow patching.
561+
static void WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X,
562+
uint64_t Offset) {
563+
uint8_t Buffer[5];
564+
unsigned SizeLen = encodeULEB128(X, Buffer, 5);
565+
assert(SizeLen == 5);
566+
Stream.pwrite((char *)Buffer, SizeLen, Offset);
567+
}
568+
569+
// Write X as an signed LEB value at offset Offset in Stream, padded
570+
// to allow patching.
571+
static void WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X,
572+
uint64_t Offset) {
573+
uint8_t Buffer[5];
574+
unsigned SizeLen = encodeSLEB128(X, Buffer, 5);
575+
assert(SizeLen == 5);
576+
Stream.pwrite((char *)Buffer, SizeLen, Offset);
577+
}
578+
579+
// Write X as a plain integer value at offset Offset in Stream.
580+
static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
581+
uint8_t Buffer[4];
582+
support::endian::write32le(Buffer, X);
583+
Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
584+
}
585+
586+
static const MCSymbolRefExpr* pullSymbol(const MCExpr *TheExpr) {
587+
if (!TheExpr) return nullptr;
588+
const MCSymbolRefExpr* S = dyn_cast<MCSymbolRefExpr>(TheExpr);
589+
if (S) return S;
590+
const MCBinaryExpr* Expr = dyn_cast<MCBinaryExpr>(TheExpr);
591+
if (!Expr) return nullptr;
592+
S = dyn_cast_or_null<MCSymbolRefExpr>(Expr->getLHS());
593+
if (S) return S;
594+
S = dyn_cast_or_null<MCSymbolRefExpr>(Expr->getRHS());
595+
if (S) return S;
596+
S = pullSymbol(Expr->getLHS());
597+
if (S) return S;
598+
S = pullSymbol(Expr->getRHS());
599+
if (S) return S;
600+
return nullptr;
601+
}
602+
559603
static const MCSymbolWasm *resolveSymbol(const MCSymbolWasm &Symbol) {
560604
const MCSymbolWasm* Ret = &Symbol;
561605
while (Ret->isVariable()) {

0 commit comments

Comments
 (0)