--- /dev/null
+// 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
// 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"
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);
}
}
bool IsWeak = false;
bool IsHidden = false;
bool IsComdat = false;
+ mutable bool IsUsedInInitArray = false;
mutable bool IsUsedInGOT = false;
Optional<StringRef> ImportModule;
Optional<StringRef> ImportName;
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; }
StringRef Name = GO->getSection();
+ // 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")
+ Kind = SectionKind::getMetadata();
+
StringRef Group = "";
if (const Comdat *C = getWasmComdat(GO)) {
Group = C->getName();
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
const MCSymbolRefExpr *RefA = Target.getSymA();
const auto *SymA = cast<MCSymbolWasm>(&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<MCSymbolRefExpr>(Expr);
}
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())
report_fatal_error("fixups in .init_array should be symbol references");
const auto &TargetSym = cast<const MCSymbolWasm>(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(