diff options
Diffstat (limited to 'lib/MC/WasmObjectWriter.cpp')
-rw-r--r-- | lib/MC/WasmObjectWriter.cpp | 77 |
1 files changed, 27 insertions, 50 deletions
diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp index 098343cd0107..c1ff3cc2480c 100644 --- a/lib/MC/WasmObjectWriter.cpp +++ b/lib/MC/WasmObjectWriter.cpp @@ -258,6 +258,7 @@ class WasmObjectWriter : public MCObjectWriter { // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } + bool isEmscripten() const { return TargetObjectWriter->isEmscripten(); } void startSection(SectionBookkeeping &Section, unsigned SectionId); void startCustomSection(SectionBookkeeping &Section, StringRef Name); @@ -426,9 +427,10 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { - MCAsmBackend &Backend = Asm.getBackend(); - bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & - MCFixupKindInfo::FKF_IsPCRel; + // The WebAssembly backend should never generate FKF_IsPCRel fixups + assert(!(Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel)); + const auto &FixupSection = cast<MCSectionWasm>(*Fragment->getParent()); uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); @@ -439,51 +441,22 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, return; if (const MCSymbolRefExpr *RefB = Target.getSymB()) { - assert(RefB->getKind() == MCSymbolRefExpr::VK_None && - "Should not have constructed this"); - - // Let A, B and C being the components of Target and R be the location of - // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). - // If it is pcrel, we want to compute (A - B + C - R). - - // In general, Wasm has no relocations for -B. It can only represent (A + C) - // or (A + C - R). If B = R + K and the relocation is not pcrel, we can - // replace B to implement it: (A - R - K + C) - if (IsPCRel) { - Ctx.reportError( - Fixup.getLoc(), - "No relocation available to represent this relative expression"); - return; - } - + // To get here the A - B expression must have failed evaluateAsRelocatable. + // This means either A or B must be undefined and in WebAssembly we can't + // support either of those cases. const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol()); - - if (SymB.isUndefined()) { - Ctx.reportError(Fixup.getLoc(), - Twine("symbol '") + SymB.getName() + - "' can not be undefined in a subtraction expression"); - return; - } - - assert(!SymB.isAbsolute() && "Should have been folded"); - const MCSection &SecB = SymB.getSection(); - if (&SecB != &FixupSection) { - Ctx.reportError(Fixup.getLoc(), - "Cannot represent a difference across sections"); - return; - } - - uint64_t SymBOffset = Layout.getSymbolOffset(SymB); - uint64_t K = SymBOffset - FixupOffset; - IsPCRel = true; - C -= K; + Ctx.reportError( + Fixup.getLoc(), + Twine("symbol '") + SymB.getName() + + "': unsupported subtraction expression used in relocation."); + return; } // We either rejected the fixup or folded B into C at this point. const MCSymbolRefExpr *RefA = Target.getSymA(); - const auto *SymA = RefA ? cast<MCSymbolWasm>(&RefA->getSymbol()) : nullptr; + const auto *SymA = cast<MCSymbolWasm>(&RefA->getSymbol()); - if (SymA && SymA->isVariable()) { + if (SymA->isVariable()) { const MCExpr *Expr = SymA->getVariableValue(); const auto *Inner = cast<MCSymbolRefExpr>(Expr); if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) @@ -496,8 +469,6 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, FixedValue = 0; unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup); - assert(!IsPCRel); - assert(SymA); // Absolute offset within a section or a function. // Currently only supported for for metadata sections. @@ -1296,12 +1267,12 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, // Separate out the producers and target features sections if (Name == "producers") { - ProducersSection = llvm::make_unique<WasmCustomSection>(Name, &Section); + ProducersSection = std::make_unique<WasmCustomSection>(Name, &Section); continue; } if (Name == "target_features") { TargetFeaturesSection = - llvm::make_unique<WasmCustomSection>(Name, &Section); + std::make_unique<WasmCustomSection>(Name, &Section); continue; } @@ -1379,7 +1350,9 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, report_fatal_error(".size expression must be evaluatable"); auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection()); - assert(DataSection.isWasmData()); + if (!DataSection.isWasmData()) + report_fatal_error("data symbols must live in a data section: " + + WS.getName()); // For each data symbol, export it in the symtab as a reference to the // corresponding Wasm data segment. @@ -1473,8 +1446,12 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL; if (WS.isUndefined()) Flags |= wasm::WASM_SYMBOL_UNDEFINED; - if (WS.isExported()) - Flags |= wasm::WASM_SYMBOL_EXPORTED; + if (WS.isNoStrip()) { + Flags |= wasm::WASM_SYMBOL_NO_STRIP; + if (isEmscripten()) { + Flags |= wasm::WASM_SYMBOL_EXPORTED; + } + } if (WS.getName() != WS.getImportName()) Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME; @@ -1618,5 +1595,5 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, std::unique_ptr<MCObjectWriter> llvm::createWasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW, raw_pwrite_stream &OS) { - return llvm::make_unique<WasmObjectWriter>(std::move(MOTW), OS); + return std::make_unique<WasmObjectWriter>(std::move(MOTW), OS); } |