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,39 @@ +; 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 void @unused_function() { + ret void +} + +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; 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, 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->Relocatable || Config->EmitRelocs) { auto *Sym = make(Sec); Out.LinkingSec->addToSymtab(Sym); Sec->SectionSym = Sym; @@ -330,7 +330,7 @@ createCustomSections(); addSection(Out.LinkingSec); - if (Config->Relocatable) { + if (Config->EmitRelocs || Config->Relocatable) { createRelocSections(); } @@ -493,17 +493,17 @@ } void Writer::populateSymtab() { - if (!Config->Relocatable) + if (!Config->Relocatable && !Config->EmitRelocs) return; for (Symbol *Sym : Symtab->getSymbols()) - if (Sym->IsUsedInRegularObj) + if (Sym->IsUsedInRegularObj && Sym->isLive()) Out.LinkingSec->addToSymtab(Sym); for (ObjFile *File : Symtab->ObjectFiles) { LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); for (Symbol *Sym : File->getSymbols()) - if (Sym->isLocal() && !isa(Sym)) + if (Sym->isLocal() && !isa(Sym) && Sym->isLive()) Out.LinkingSec->addToSymtab(Sym); } }