-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Object] Provide operator< for ELFSymbolRef #89861
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
Normally, operator< accepting DataRefImpl is used when comparing SymbolRef/ELFSymbolRef. However, it uses std::memcmp which interprets DataRefImpl union as char string. For ELFSymbolRef it's known that it uses the struct view of the union, therefore a specialized operator< can be used instead.
@llvm/pr-subscribers-llvm-binary-utilities Author: Amir Ayupov (aaupov) ChangesNormally, operator< accepting DataRefImpl is used when comparing Full diff: https://github.com/llvm/llvm-project/pull/89861.diff 1 Files Affected:
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 1d457be93741f2..8ec0e3fe15dc9d 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -199,6 +199,14 @@ class ELFSymbolRef : public SymbolRef {
}
};
+inline bool operator<(const ELFSymbolRef &A, const ELFSymbolRef &B) {
+ const DataRefImpl &DRIA = A.getRawDataRefImpl();
+ const DataRefImpl &DRIB = B.getRawDataRefImpl();
+ if (DRIA.d.a == DRIB.d.a)
+ return DRIA.d.b < DRIB.d.b;
+ return DRIA.d.a < DRIB.d.b;
+}
+
class elf_symbol_iterator : public symbol_iterator {
public:
elf_symbol_iterator(const basic_symbol_iterator &B)
|
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 this could use some simple unit tests in the ELFObjectFileTest.cppp file.
I've not really looked myself, but are there instances where you actually have two ELFSymbolRef objects that are compared (using |
I'm going to use it in FILE symbol lookup using upper_bound on ELFSymbolRefs here, instead of using DRI.d.b (symbol index) directly: #89648
DataRefImpl's |
Simplify lookups and comparisons using llvm#89861
Why is DataRefImpl's Also, please try to avoid force pushes in active reviews, per the LLVM guidelines. If rebasing is necessary, consider merging |
Sorry, I've made the commit message more clear. DataRefImpl's
Noted, thank you. |
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.
Thanks for the explanation about why this whole thing is important, the new commit message is certainly clearer. I think the last sentence of the description would be clearer saying:
"For ELFSymbolRef a specialized operator< can be used instead to produce consistent ordering regardless of endianness by comparing the symbol table index and symbol index fields separately."
One other thing: does DataRefImpl
have an operator>
? If so, you'll need that here too as otherwise two ELFSymbolRefs will not have inconsistent orderings based on which comparison operator is being used.
Thanks, updated.
No, it doesn't: llvm-project/llvm/include/llvm/Object/SymbolicFile.h Lines 53 to 67 in 2d09ac4
|
@jh7370: thank you for extensive comments, the test is a lot more readable now. Hope it's good to go now :) |
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.
LGTM, with one nit.
Fragment matching relies on symbol names to identify and register split function fragments. However, as split fragments are often local symbols, name aliasing is possible. For such cases, use symbol table to resolve ambiguities. This requires the presence of FILE symbols in the input binary. As BOLT requires non-stripped binary, this is a reasonable assumption. Note that `strip -g` removes FILE symbols by default, but `--keep-file-symbols` can be used to preserve them. Depends on: #89861 Test Plan: Updated X86/fragment-lite.s
Normally, operator< accepting DataRefImpl is used when comparing
SymbolRef/ELFSymbolRef. However, it uses std::memcmp which interprets
DataRefImpl union as char string so that the result depends on host endianness.
For ELFSymbolRef a specialized operator< can be used instead to produce
consistent ordering regardless of endianness by comparing the symbol table index
and symbol index fields separately.