[PATCH] D63974: [ELF] Only allow the binding of SharedSymbol to change for the first undef ref
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 1 09:40:22 PDT 2019
MaskRay marked 4 inline comments as done.
MaskRay added inline comments.
================
Comment at: ELF/Symbols.cpp:413
- if (isShared() || isLazy() || (isUndefined() && Other.Binding != STB_WEAK))
+ if (auto *S = dyn_cast<SharedSymbol>(this)) {
+ if (Other.Binding != STB_WEAK || !S->BindingFinalized)
----------------
peter.smith wrote:
> Coming at this part of the code with fresh eyes, I think a comment, or reference to a comment elsewhere, explaining why we are setting the binding of an existing shared symbol to weak would be helpful here. I managed to find one in Symbols.h that helped but I had to search for it:
>
> ```
> // Symbol binding. This is not overwritten by replace() to track
> // changes during resolution. In particular:
> // - An undefined weak is still weak when it resolves to a shared library.
> // - An undefined weak will not fetch archive members, but we have to
> // remember it is weak.
> ```
>
> One other thing that might be worth mentioning is why lazy symbols don't need the same treatment. As I understand it a non-weak reference would immediately fetch the member to define the symbol so there isn't a case where the undefined weak reference changes the binding.
Just refactored the code a bit to dispatch on symbol kinds:
if (undefined) {
} else if (SharedSymbol) {
} else if (lazy) {
}
I hope the logic will become clearer.
================
Comment at: ELF/Symbols.h:370
+ // change to STB_WEAK if the first undefined reference is weak.
+ bool BindingFinalized = false;
};
----------------
peter.smith wrote:
> I think BindingFinalized implies that it never changes but it can if we see a weak refrence first and then see a non-weak reference. As I understand the implementation, this will be set to true on first reference of the shared symbol. Some possible alternatives:
> ```
> // This is true if no undefined reference to the symbol has been seen. We use this
> bool Unreferenced = true;
> ```
> Note: this would need the logic reversed in the rest of the code.
> ```
> if (Other.Binding != STB_WEAK || S->Unreferenced)
> Binding = Other.Binding;
> S->Unreferenced = false;
> ```
> Alternative retaining the existing logic.
> ```
> // This is true if there has been at least one undefined reference to the symbol
> bool Referenced = false;
> ```
>
Thanks for the suggestions! I'll go with `Referenced` (preferring positive forms to avoid double negative).
Repository:
rLLD LLVM Linker
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63974/new/
https://reviews.llvm.org/D63974
More information about the llvm-commits
mailing list