diff --git a/lld/test/wasm/Inputs/explicit-section.ll b/lld/test/wasm/Inputs/explicit-section.ll new file mode 100644 --- /dev/null +++ b/lld/test/wasm/Inputs/explicit-section.ll @@ -0,0 +1,4 @@ +target triple = "wasm32-unknown-unknown" + +@var1 = global i32 42, section "mysection", align 4 +@var2 = global i32 43, section "mysection", align 4 diff --git a/lld/test/wasm/startstop.ll b/lld/test/wasm/startstop.ll --- a/lld/test/wasm/startstop.ll +++ b/lld/test/wasm/startstop.ll @@ -1,5 +1,6 @@ ; RUN: llc -filetype=obj -o %t.o %s -; RUN: wasm-ld --no-gc-sections %t.o -o %t.wasm +; RUN: llc -filetype=obj %p/Inputs/explicit-section.ll -o %t2.o +; RUN: wasm-ld --export=get_start --export=get_end --export=foo --export=var1 %t.o %t2.o -o %t.wasm ; RUN: obj2yaml %t.wasm | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -26,15 +27,12 @@ ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 0B +; CHECK-NEXT: Body: 4180888080000B ; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 4180888080000B +; CHECK-NEXT: Body: 4190888080000B ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 4188888080000B -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Locals: [] ; CHECK-NEXT: Body: 0B ; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Segments: @@ -43,15 +41,13 @@ ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 1024 -; CHECK-NEXT: Content: '0300000004000000' +; CHECK-NEXT: Content: 03000000040000002A0000002B000000 ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: name ; CHECK-NEXT: FunctionNames: ; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Name: __wasm_call_ctors -; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Name: get_start -; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Name: get_end -; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Name: _start diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -107,8 +107,10 @@ for (const WasmRelocation &Rel : Relocations) { uint8_t *Loc = Buf + Rel.Offset + Off; uint32_t Value = File->calcNewValue(Rel); - LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(Rel.Type) - << " addend=" << Rel.Addend << " index=" << Rel.Index + LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(Rel.Type)); + if (Rel.Type != R_WASM_TYPE_INDEX_LEB) + LLVM_DEBUG(dbgs() << " sym=" << File->getSymbols()[Rel.Index]->getName()); + LLVM_DEBUG(dbgs() << " addend=" << Rel.Addend << " index=" << Rel.Index << " value=" << Value << " offset=" << Rel.Offset << "\n"); diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -228,6 +228,7 @@ LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n"); auto *rtn = replaceSymbol(S, Name, Flags); rtn->setVirtualAddress(Value); + rtn->Referenced = true; return rtn; } diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -131,9 +131,10 @@ uint32_t OutputSymbolIndex = INVALID_INDEX; uint32_t GOTIndex = INVALID_INDEX; Kind SymbolKind; - unsigned Referenced : 1; public: + unsigned Referenced : 1; + // True if the symbol was used for linking and thus need to be added to the // output file's symbol table. This is true for all symbols except for // unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -74,7 +74,6 @@ void addSection(OutputSection *Sec); void addSections(); - void addStartStopSymbols(const InputSegment *Seg); void createCustomSections(); void createSyntheticSections(); @@ -303,15 +302,15 @@ // __stop_ symbols. They are at beginning and end of the section, // respectively. This is not requested by the ELF standard, but GNU ld and // gold provide the feature, and used by many programs. -void Writer::addStartStopSymbols(const InputSegment *Seg) { - StringRef S = Seg->getName(); - LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n"); - if (!isValidCIdentifier(S)) +static void addStartStopSymbols(const OutputSegment *Seg) { + StringRef Name = Seg->Name; + LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << Name << "\n"); + if (!isValidCIdentifier(Name)) return; - uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset; - uint32_t Stop = Start + Seg->getSize(); - Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start); - Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop); + uint32_t Start = Seg->StartVA; + uint32_t Stop = Start + Seg->Size; + Symtab->addOptionalDataSymbol(Saver.save("__start_" + Name), Start); + Symtab->addOptionalDataSymbol(Saver.save("__stop_" + Name), Stop); } void Writer::addSections() { @@ -811,8 +810,7 @@ // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols // This has to be done after memory layout is performed. for (const OutputSegment *Seg : Segments) - for (const InputSegment *S : Seg->InputSegments) - addStartStopSymbols(S); + addStartStopSymbols(Seg); } log("-- scanRelocations");