diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1037,7 +1037,7 @@ ELFKind K = Config->EKind; uint16_t M = Config->EMachine; - Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs); + Config->CopyRelocs = Config->Relocatable || Config->EmitRelocs; Config->Is64 = (K == ELF64LEKind || K == ELF64BEKind); Config->IsLE = (K == ELF32LEKind || K == ELF64LEKind); Config->Endianness = Config->IsLE ? endianness::little : endianness::big; diff --git a/lld/test/wasm/emit-relocs.ll b/lld/test/wasm/emit-relocs.ll new file mode 100644 --- /dev/null +++ b/lld/test/wasm/emit-relocs.ll @@ -0,0 +1,35 @@ +; RUN: llc -filetype=obj %s -o %t.o +; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o +; RUN: wasm-ld --emit-relocs -o %t.wasm %t.o %t.ret32.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare i32 @ret32(float) + +define hidden void @_start() local_unnamed_addr #0 { +entry: + call i32 @ret32(float 0.0) + ret void +} + +; CHECK: - Type: CODE +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Offset: 0x00000009 + +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: Version: 2 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: _start +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Function: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: ret32 +; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: Function: 1 diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -27,6 +27,7 @@ bool CompressRelocations; bool Demangle; bool DisableVerify; + bool EmitRelocs; bool ExportAll; bool ExportDynamic; bool ExportTable; @@ -65,6 +66,10 @@ // The following config options do not directly correspond to any // particualr command line options. + // True if we need to pass through relocations in input files to the + // output file. Usually false because we consume relocations. + bool CopyRelocs; + // True if we are creating position-independent code. bool Pic; }; diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -302,6 +302,7 @@ Config->CompressRelocations = Args.hasArg(OPT_compress_relocations); Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); Config->DisableVerify = Args.hasArg(OPT_disable_verify); + Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); Config->Entry = getEntry(Args); Config->ExportAll = Args.hasArg(OPT_export_all); Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic, @@ -360,6 +361,7 @@ // This function initialize such members. See Config.h for the details // of these values. static void setConfigs() { + Config->CopyRelocs = Config->Relocatable || Config->EmitRelocs; Config->Pic = Config->Pie || Config->Shared; if (Config->Pic) { diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td --- a/lld/wasm/Options.td +++ b/lld/wasm/Options.td @@ -31,6 +31,8 @@ "Demangle symbol names", "Do not demangle symbol names">; +def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">; + defm export_dynamic: B<"export-dynamic", "Put symbols in the dynamic symbol table", "Do not put symbols in the dynamic symbol table (default)">; diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h --- a/lld/wasm/SyntheticSections.h +++ b/lld/wasm/SyntheticSections.h @@ -246,7 +246,9 @@ const std::vector &DataSegments) : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "linking"), InitFunctions(InitFunctions), DataSegments(DataSegments) {} - bool isNeeded() const override { return Config->Relocatable; } + bool isNeeded() const override { + return Config->Relocatable || Config->EmitRelocs; + } void writeBody() override; void addToSymtab(Symbol *Sym); diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -129,7 +129,7 @@ LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); OutputSection *Sec = make(Name, Pair.second); - if (Config->Relocatable) { + if (Config->CopyRelocs) { auto *Sym = make(Sec); Out.LinkingSec->addToSymtab(Sym); Sec->SectionSym = Sym; @@ -330,7 +330,7 @@ createCustomSections(); addSection(Out.LinkingSec); - if (Config->Relocatable) { + if (Config->CopyRelocs) { createRelocSections(); } @@ -493,7 +493,7 @@ } void Writer::populateSymtab() { - if (!Config->Relocatable) + if (!Config->CopyRelocs) return; for (Symbol *Sym : Symtab->getSymbols())