-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lld][WebAssembly] Do not emit relocs against dead symbols #129346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When emitting relocs with linked output (i.e. --emit-relocs) skip relocs against dead symbols (which donot appear in the output) and do not emit them.
@llvm/pr-subscribers-lld-wasm Author: Derek Schuff (dschuff) ChangesWhen emitting relocs with linked output (i.e. --emit-relocs) Full diff: https://github.com/llvm/llvm-project/pull/129346.diff 6 Files Affected:
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..0558f64aa7c42 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -167,6 +167,19 @@ 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 {
+ size_t result = 0;
+ for (const WasmRelocation& rel : relocations) {
+ if (relocIsLive(rel, file)) result ++;
+ }
+ return result;
+}
+
// 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 +192,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;
}
|
@llvm/pr-subscribers-lld Author: Derek Schuff (dschuff) ChangesWhen emitting relocs with linked output (i.e. --emit-relocs) Full diff: https://github.com/llvm/llvm-project/pull/129346.diff 6 Files Affected:
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..0558f64aa7c42 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -167,6 +167,19 @@ 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 {
+ size_t result = 0;
+ for (const WasmRelocation& rel : relocations) {
+ if (relocIsLive(rel, file)) result ++;
+ }
+ return result;
+}
+
// 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 +192,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;
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
lld/wasm/InputChunks.cpp
Outdated
if (relocIsLive(rel, file)) | ||
result++; | ||
} | ||
return result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a modern C++ way to write an accumulator like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the alternative would be something like
return std::count_if(relocations.begin(), relocations.end(),
[&](const WasmRelocation &rel) {
return relocIsLive(rel, file);
});
That's... a little shorter, I guess?
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.
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.