[PATCH] D63974: [ELF] Only allow the binding of SharedSymbol to change for the first undef ref

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 1 07:17:15 PDT 2019


peter.smith 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)
----------------
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.


================
Comment at: ELF/Symbols.h:368
+
+  // This is true if no undefined reference has been seen yet. The binding may
+  // change to STB_WEAK if the first undefined reference is weak.
----------------
I'd have thought it was false if no undefined reference has been seen yet?


================
Comment at: ELF/Symbols.h:370
+  // change to STB_WEAK if the first undefined reference is weak.
+  bool BindingFinalized = false;
 };
----------------
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;
```



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