diff --git a/clang/test/Driver/embed-bitcode-wasm.c b/clang/test/Driver/embed-bitcode-wasm.c new file mode 100644 index 0000000000000..3705a4d24875d --- /dev/null +++ b/clang/test/Driver/embed-bitcode-wasm.c @@ -0,0 +1,6 @@ +// REQUIRES: webassembly-registered-target + +// RUN: %clang -c -target wasm32-unknown-unknown %s -fembed-bitcode -o %t.o +// RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=CHECK %s +// CHECK: Name: .llvmbc +// CHECK: Name: .llvmcmd diff --git a/clang/test/Driver/fembed-bitcode.c b/clang/test/Driver/fembed-bitcode.c index d01ae6cd8c182..970500525a503 100644 --- a/clang/test/Driver/fembed-bitcode.c +++ b/clang/test/Driver/fembed-bitcode.c @@ -30,3 +30,12 @@ // RUN: | FileCheck --check-prefix=CHECK-HEXAGON %s // CHECK-HEXAGON: "-target-feature" // CHECK-HEXAGON: "+reserved-r19" +// +// RUN: %clang -target wasm32-unknown-unknown -fembed-bitcode=all -pthread -c %s -o /dev/null -### 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-WASM %s + +// CHECK-WASM: "-cc1" +// CHECK-WASM: "-target-feature" "+atomics" + +// CHECK-WASM: "-cc1" +// CHECK-WASM: "-target-feature" "+atomics" diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index bd7bd7e6f7e68..1778c9568f6cd 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -110,13 +110,21 @@ void Writer::calculateCustomSections() { for (InputSection *section : file->customSections) { StringRef name = section->getName(); // These custom sections are known the linker and synthesized rather than - // blindly copied + // blindly copied. if (name == "linking" || name == "name" || name == "producers" || name == "target_features" || name.startswith("reloc.")) continue; - // .. or it is a debug section + // These custom sections are generated by `clang -fembed-bitcode`. + // These are used by the rust toolchain to ship LTO data along with + // compiled object code, but they don't want this included in the linker + // output. + if (name == ".llvmbc" || name == ".llvmcmd") + continue; + // Strip debug section in that option was specified. if (stripDebug && name.startswith(".debug_")) continue; + // Otherwise include custom sections by default and concatenate their + // contents. customSectionMapping[name].push_back(section); } } diff --git a/llvm/include/llvm/MC/MCSymbolWasm.h b/llvm/include/llvm/MC/MCSymbolWasm.h index ba2068a460718..1e2503a8d3025 100644 --- a/llvm/include/llvm/MC/MCSymbolWasm.h +++ b/llvm/include/llvm/MC/MCSymbolWasm.h @@ -18,6 +18,7 @@ class MCSymbolWasm : public MCSymbol { bool IsWeak = false; bool IsHidden = false; bool IsComdat = false; + mutable bool IsUsedInInitArray = false; mutable bool IsUsedInGOT = false; Optional ImportModule; Optional ImportName; @@ -95,6 +96,9 @@ class MCSymbolWasm : public MCSymbol { void setUsedInGOT() const { IsUsedInGOT = true; } bool isUsedInGOT() const { return IsUsedInGOT; } + void setUsedInInitArray() const { IsUsedInInitArray = true; } + bool isUsedInInitArray() const { return IsUsedInInitArray; } + const wasm::WasmSignature *getSignature() const { return Signature; } void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; } diff --git a/llvm/include/llvm/Object/Wasm.h b/llvm/include/llvm/Object/Wasm.h index 8af94c4963b66..22ee73198ec74 100644 --- a/llvm/include/llvm/Object/Wasm.h +++ b/llvm/include/llvm/Object/Wasm.h @@ -183,7 +183,6 @@ class WasmObjectFile : public ObjectFile { bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool isSectionBitcode(DataRefImpl Sec) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 8cb9814300d1d..388d39e8bbd3b 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1692,6 +1692,14 @@ static const Comdat *getWasmComdat(const GlobalValue *GV) { } static SectionKind getWasmKindForNamedSection(StringRef Name, SectionKind K) { + // Certain data sections we treat as named custom sections rather than + // segments within the data section. + // This could be avoided if all data segements (the wasm sense) were + // represented as thier own sections (in the llvm sense). + // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138 + if (Name == ".llvmcmd" || Name == ".llvmbc") + return SectionKind::getMetadata(); + // If we're told we have function data, then use that. if (K.isText()) return SectionKind::getText(); diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 321f93d76092b..4df809224edbb 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -436,10 +436,6 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); MCContext &Ctx = Asm.getContext(); - // The .init_array isn't translated as data, so don't do relocations in it. - if (FixupSection.getSectionName().startswith(".init_array")) - return; - if (const MCSymbolRefExpr *RefB = Target.getSymB()) { // 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 @@ -456,6 +452,12 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, const MCSymbolRefExpr *RefA = Target.getSymA(); const auto *SymA = cast(&RefA->getSymbol()); + // The .init_array isn't translated as data, so don't do relocations in it. + if (FixupSection.getSectionName().startswith(".init_array")) { + SymA->setUsedInInitArray(); + return; + } + if (SymA->isVariable()) { const MCExpr *Expr = SymA->getVariableValue(); const auto *Inner = cast(Expr); @@ -1084,16 +1086,13 @@ void WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) { } static bool isInSymtab(const MCSymbolWasm &Sym) { - if (Sym.isUsedInReloc()) + if (Sym.isUsedInReloc() || Sym.isUsedInInitArray()) return true; if (Sym.isComdat() && !Sym.isDefined()) return false; - if (Sym.isTemporary() && Sym.getName().empty()) - return false; - - if (Sym.isTemporary() && Sym.isData() && !Sym.getSize()) + if (Sym.isTemporary()) return false; if (Sym.isSection()) @@ -1565,7 +1564,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, report_fatal_error("fixups in .init_array should be symbol references"); const auto &TargetSym = cast(SymRef->getSymbol()); if (TargetSym.getIndex() == InvalidIndex) - report_fatal_error("symbols in .init_array should exist in symbtab"); + report_fatal_error("symbols in .init_array should exist in symtab"); if (!TargetSym.isFunction()) report_fatal_error("symbols in .init_array should be for functions"); InitFuncs.push_back( diff --git a/llvm/lib/Object/IRObjectFile.cpp b/llvm/lib/Object/IRObjectFile.cpp index 636f1521262fd..931e842edb448 100644 --- a/llvm/lib/Object/IRObjectFile.cpp +++ b/llvm/lib/Object/IRObjectFile.cpp @@ -94,6 +94,7 @@ IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { return Object; case file_magic::elf_relocatable: case file_magic::macho_object: + case file_magic::wasm_object: case file_magic::coff_object: { Expected> ObjFile = ObjectFile::createObjectFile(Object, Type); diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index ab8918ce1919c..25366ab385da1 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -1455,8 +1455,6 @@ bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; } bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; } -bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; } - relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Ref) const { DataRefImpl RelocRef; RelocRef.d.a = Ref.d.a;