[lld][WebAssembly] Do not emit relocs against dead symbols (#129346)
When emitting relocs with linked output (i.e. --emit-relocs) skip relocs against dead symbols (which do not appear in the output) and do not emit them.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "lld/Common/LLVM.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/xxhash.h"
|
||||
#include <algorithm>
|
||||
|
||||
#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");
|
||||
|
||||
@@ -77,6 +77,7 @@ public:
|
||||
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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
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;
|
||||
|
||||
@@ -183,7 +183,7 @@ void Symbol::markLive() {
|
||||
}
|
||||
|
||||
uint32_t Symbol::getOutputSymbolIndex() const {
|
||||
assert(outputSymbolIndex != INVALID_INDEX);
|
||||
assert(outputSymbolIndex != INVALID_INDEX || !isLive());
|
||||
return outputSymbolIndex;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user