summaryrefslogtreecommitdiff
path: root/view
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2025-12-10 23:26:46 -0800
committerMark Rowe <mark@vector35.com>2025-12-15 10:33:42 -0800
commitf83b7bd44c3c82cb71237124705d8687e658da4f (patch)
tree3ed047ccd0b1f0e88b811d7c20d6cbdc90fb910e /view
parent352ab7f585797ef8d0d84cfd8a43131d88da5bcc (diff)
[MachO] Fix handling of relocations for self-bound data symbols
Fixes https://github.com/Vector35/binaryninja-api/issues/7781.
Diffstat (limited to 'view')
-rw-r--r--view/macho/machoview.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp
index 1c8d8512..3c558963 100644
--- a/view/macho/machoview.cpp
+++ b/view/macho/machoview.cpp
@@ -2127,14 +2127,26 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
switch (ordinal)
{
case BindSpecialDylibSelf:
- if (auto symbol = GetSymbolByRawName(name, GetInternalNameSpace()); symbol)
+ {
+ // When multiple symbols are defined with the same name, which can happen for a symbol is both in the
+ // symbol table and self-bound, `GetSymbolByRawName` prefers the symbol with the lowest type value.
+ // Since `ImportAddressSymbol` is a lower value than `DataSymbol`, using `GetSymbolByRawName` would
+ // return the symbol representing the import we're binding to rather than the actual symbol definition.
+ auto symbols = GetSymbolsByRawName(name, GetInternalNameSpace());
+ auto it = std::ranges::find_if(symbols, [](const Ref<Symbol>& sym) {
+ return sym->GetType() != ImportAddressSymbol;
+ });
+
+ if (it != symbols.end())
{
+ auto symbol = *it;
DefineRelocation(m_arch, relocation, symbol, relocation.address);
if (objcProcessor)
objcProcessor->AddRelocatedPointer(relocation.address, symbol->GetAddress());
handled = true;
}
break;
+ }
case BindSpecialDylibMainExecutable:
case BindSpecialDylibFlatLookup: