diff --git a/lld/test/wasm/emit-relocs.s b/lld/test/wasm/emit-relocs.s index bd136ba810b5e..385344cb23321 100644 --- a/lld/test/wasm/emit-relocs.s +++ b/lld/test/wasm/emit-relocs.s @@ -27,6 +27,12 @@ foo: .int32 0 .size foo, 4 +.section .debug_info,"",@ +.p2align 2 +.int32 unused_function +.int32 _start +.int32 0 + # CHECK: - Type: CODE # CHECK-NEXT: Relocations: # CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB @@ -42,6 +48,15 @@ foo: # CHECK-NEXT: Value: 1024 # CHECK-NEXT: Content: '00000000' +# There should be a single relocation in this section (just the live symbol) +# CHECK-NEXT: - Type: CUSTOM +# CHECK-NEXT: Relocations: +# CHECK-NEXT: - Type: R_WASM_FUNCTION_OFFSET_I32 +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: Offset: 0x4 +# CHECK-NEXT: Name: .debug_info +# CHECK-NEXT: Payload: FFFFFFFF0200000000000000 + # CHECK: - Type: CUSTOM # CHECK-NEXT: Name: linking # CHECK-NEXT: Version: 2 diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index ccdc92f5c8d71..3668697382238 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -14,6 +14,7 @@ #include "lld/Common/LLVM.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/xxhash.h" +#include #define DEBUG_TYPE "lld" @@ -167,6 +168,17 @@ void InputChunk::relocate(uint8_t *buf) const { } } +static bool relocIsLive(const WasmRelocation &rel, ObjFile *file) { + return rel.Type == R_WASM_TYPE_INDEX_LEB || + file->getSymbol(rel.Index)->isLive(); +} + +size_t InputChunk::getNumLiveRelocations() const { + return std::count_if( + relocations.begin(), relocations.end(), + [this](const WasmRelocation &rel) { return relocIsLive(rel, file); }); +} + // Copy relocation entries to a given output stream. // This function is used only when a user passes "-r". For a regular link, // we consume relocations instead of copying them to an output file. @@ -179,6 +191,8 @@ void InputChunk::writeRelocations(raw_ostream &os) const { << " offset=" << Twine(off) << "\n"); for (const WasmRelocation &rel : relocations) { + if (!relocIsLive(rel, file)) + continue; writeUleb128(os, rel.Type, "reloc type"); writeUleb128(os, rel.Offset + off, "reloc offset"); writeUleb128(os, file->calcNewIndex(rel), "reloc index"); diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h index f545449e1246f..1fe78d76631f1 100644 --- a/lld/wasm/InputChunks.h +++ b/lld/wasm/InputChunks.h @@ -77,6 +77,7 @@ class InputChunk { uint32_t getInputSectionOffset() const { return inputSectionOffset; } size_t getNumRelocations() const { return relocations.size(); } + size_t getNumLiveRelocations() const; void writeRelocations(llvm::raw_ostream &os) const; bool generateRelocationCode(raw_ostream &os) const; diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index d679d1e676479..5038cd8ea965b 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -274,7 +274,7 @@ void CustomSection::writeTo(uint8_t *buf) { uint32_t CustomSection::getNumRelocations() const { uint32_t count = 0; for (const InputChunk *inputSect : inputSections) - count += inputSect->getNumRelocations(); + count += inputSect->getNumLiveRelocations(); return count; } diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h index fcc8cf45dc73b..4b0329dd16cf2 100644 --- a/lld/wasm/OutputSections.h +++ b/lld/wasm/OutputSections.h @@ -41,6 +41,7 @@ class OutputSection { virtual void writeTo(uint8_t *buf) = 0; virtual void finalizeContents() = 0; virtual uint32_t getNumRelocations() const { return 0; } + virtual uint32_t getNumLiveRelocations() const { return getNumRelocations(); } virtual void writeRelocations(raw_ostream &os) const {} std::string header; diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index a687fd6d6c4ef..09f110d0885f6 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -183,7 +183,7 @@ void Symbol::markLive() { } uint32_t Symbol::getOutputSymbolIndex() const { - assert(outputSymbolIndex != INVALID_INDEX); + assert(outputSymbolIndex != INVALID_INDEX || !isLive()); return outputSymbolIndex; }