[BOLT] Skip PLT search for zero-value weak reference symbols (#69136)
Take a common weak reference pattern for example
```
__attribute__((weak)) void undef_weak_fun();
if (&undef_weak_fun)
undef_weak_fun();
```
In this case, an undefined weak symbol `undef_weak_fun` has an address
of zero, and Bolt incorrectly changes the relocation for the
corresponding symbol to symbol@PLT, leading to incorrect runtime
behavior.
This commit is contained in:
@@ -2143,6 +2143,14 @@ bool RewriteInstance::analyzeRelocation(
|
||||
if (!Relocation::isSupported(RType))
|
||||
return false;
|
||||
|
||||
auto IsWeakReference = [](const SymbolRef &Symbol) {
|
||||
Expected<uint32_t> SymFlagsOrErr = Symbol.getFlags();
|
||||
if (!SymFlagsOrErr)
|
||||
return false;
|
||||
return (*SymFlagsOrErr & SymbolRef::SF_Undefined) &&
|
||||
(*SymFlagsOrErr & SymbolRef::SF_Weak);
|
||||
};
|
||||
|
||||
const bool IsAArch64 = BC->isAArch64();
|
||||
|
||||
const size_t RelSize = Relocation::getSizeForType(RType);
|
||||
@@ -2174,7 +2182,8 @@ bool RewriteInstance::analyzeRelocation(
|
||||
// Section symbols are marked as ST_Debug.
|
||||
IsSectionRelocation = (cantFail(Symbol.getType()) == SymbolRef::ST_Debug);
|
||||
// Check for PLT entry registered with symbol name
|
||||
if (!SymbolAddress && (IsAArch64 || BC->isRISCV())) {
|
||||
if (!SymbolAddress && !IsWeakReference(Symbol) &&
|
||||
(IsAArch64 || BC->isRISCV())) {
|
||||
const BinaryData *BD = BC->getPLTBinaryDataByName(SymbolName);
|
||||
SymbolAddress = BD ? BD->getAddress() : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user