@@ -1710,6 +1710,51 @@ bool MachoView::Init()
17101710}
17111711
17121712
1713+ static Ref<Symbol> FindInternalSymbol (BinaryView* view, const std::string& name)
1714+ {
1715+ // When multiple symbols are defined with the same name, which can happen when a symbol is both
1716+ // in the symbol table and self-bound, `GetSymbolByRawName` prefers the symbol with the lowest
1717+ // type value. Since `ImportAddressSymbol` is a lower value than `DataSymbol`/`FunctionSymbol`,
1718+ // it would return the import stub rather than the actual symbol definition. Filter it out.
1719+ auto symbols = view->GetSymbolsByRawName (name, view->GetInternalNameSpace ());
1720+ auto it = std::ranges::find_if (symbols, [](const Ref<Symbol>& sym) {
1721+ return sym->GetType () != ImportAddressSymbol;
1722+ });
1723+ return it != symbols.end () ? *it : nullptr ;
1724+ }
1725+
1726+
1727+ static Ref<Symbol> ResolveBindSymbol (BinaryView* view, const MachOHeader& header, const std::string& name, int32_t ordinal)
1728+ {
1729+ switch (ordinal)
1730+ {
1731+ case BindSpecialDylibSelf:
1732+ return FindInternalSymbol (view, name);
1733+
1734+ case BindSpecialDylibMainExecutable:
1735+ case BindSpecialDylibFlatLookup:
1736+ case BindSpecialDylibWeakLookup:
1737+ {
1738+ Ref<Symbol> symbol;
1739+
1740+ // Prefer internal symbols for executables, and external symbols for everything else.
1741+ if (header.ident .filetype == MH_EXECUTE)
1742+ symbol = FindInternalSymbol (view, name);
1743+ if (!symbol)
1744+ symbol = view->GetSymbolByRawName (name, view->GetExternalNameSpace ());
1745+ if (!symbol && header.ident .filetype != MH_EXECUTE)
1746+ symbol = FindInternalSymbol (view, name);
1747+ return symbol;
1748+ }
1749+
1750+ default :
1751+ if (ordinal > 0 )
1752+ return view->GetSymbolByRawName (name, view->GetExternalNameSpace ());
1753+ return nullptr ;
1754+ }
1755+ }
1756+
1757+
17131758bool MachoView::InitializeHeader (MachOHeader& header, bool isMainHeader, uint64_t preferredImageBase,
17141759 std::string preferredImageBaseDesc, bool platformSetByUser)
17151760{
@@ -2272,86 +2317,19 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
22722317 Ref<Metadata> symbolToLibraryMapping = new Metadata (KeyValueDataType);
22732318 for (auto & [relocation, name, ordinal] : header.bindingRelocations )
22742319 {
2275- bool handled = false ;
2276-
2277- switch (ordinal)
2320+ if (auto symbol = ResolveBindSymbol (this , header, name, ordinal); symbol)
22782321 {
2279- case BindSpecialDylibSelf:
2280- {
2281- // When multiple symbols are defined with the same name, which can happen for a symbol is both in the
2282- // symbol table and self-bound, `GetSymbolByRawName` prefers the symbol with the lowest type value.
2283- // Since `ImportAddressSymbol` is a lower value than `DataSymbol`, using `GetSymbolByRawName` would
2284- // return the symbol representing the import we're binding to rather than the actual symbol definition.
2285- auto symbols = GetSymbolsByRawName (name, GetInternalNameSpace ());
2286- auto it = std::ranges::find_if (symbols, [](const Ref<Symbol>& sym) {
2287- return sym->GetType () != ImportAddressSymbol;
2288- });
2289-
2290- if (it != symbols.end ())
2291- {
2292- auto symbol = *it;
2293- DefineRelocation (m_arch, relocation, symbol, relocation.address );
2294- if (objcProcessor)
2295- objcProcessor->AddRelocatedPointer (relocation.address , symbol->GetAddress ());
2296- handled = true ;
2297- }
2298- break ;
2322+ DefineRelocation (m_arch, relocation, symbol, relocation.address );
2323+ if (objcProcessor && symbol->GetNameSpace () == GetInternalNameSpace ())
2324+ objcProcessor->AddRelocatedPointer (relocation.address , symbol->GetAddress ());
22992325 }
2300-
2301- case BindSpecialDylibMainExecutable:
2302- case BindSpecialDylibFlatLookup:
2303- case BindSpecialDylibWeakLookup:
2304- // In cases where we are the primary executable, flat lookup should find us first,
2305- // it seems like our best course of action is to try and find internally first on
2306- // executables, and externally on libraries.
2307- if (header.ident .filetype == MH_EXECUTE)
2308- {
2309- if (auto symbol = GetSymbolByRawName (name, GetInternalNameSpace ()); symbol)
2310- {
2311- DefineRelocation (m_arch, relocation, symbol, relocation.address );
2312- if (objcProcessor)
2313- objcProcessor->AddRelocatedPointer (relocation.address , symbol->GetAddress ());
2314- handled = true ;
2315- }
2316- else if (auto symbol = GetSymbolByRawName (name, GetExternalNameSpace ()); symbol)
2317- {
2318- DefineRelocation (m_arch, relocation, symbol, relocation.address );
2319- handled = true ;
2320- }
2321- }
2322- else
2323- {
2324- if (auto symbol = GetSymbolByRawName (name, GetExternalNameSpace ()); symbol)
2325- {
2326- DefineRelocation (m_arch, relocation, symbol, relocation.address );
2327- handled = true ;
2328- }
2329- else if (auto symbol = GetSymbolByRawName (name, GetInternalNameSpace ()); symbol)
2330- {
2331- DefineRelocation (m_arch, relocation, symbol, relocation.address );
2332- if (objcProcessor)
2333- objcProcessor->AddRelocatedPointer (relocation.address , symbol->GetAddress ());
2334- handled = true ;
2335- }
2336- }
2337- break ;
2338-
2339- default :
2340- if (ordinal > 0 )
2341- {
2342- if (auto symbol = GetSymbolByRawName (name, GetExternalNameSpace ()))
2343- {
2344- DefineRelocation (m_arch, relocation, symbol, relocation.address );
2345- handled = true ;
2346- }
2347- if (ordinal - 1 < header.dylibs .size ())
2348- symbolToLibraryMapping->SetValueForKey (name, new Metadata (header.dylibs [ordinal - 1 ].first ));
2349- }
2350- break ;
2326+ else
2327+ {
2328+ m_logger->LogErrorF (" Failed to find symbol {:?} for bind at {:#x} (ordinal: {})" , name, relocation.address , ordinal);
23512329 }
23522330
2353- if (!handled )
2354- m_logger-> LogErrorF ( " Failed to find external symbol {:?}, couldn't bind symbol at {:#x} " , name, relocation. address );
2331+ if (ordinal > 0 && ordinal - 1 < header. dylibs . size () )
2332+ symbolToLibraryMapping-> SetValueForKey (name, new Metadata (header. dylibs [ordinal - 1 ]. first ) );
23552333 }
23562334
23572335 StoreMetadata (" SymbolExternalLibraryMapping" , std::move (symbolToLibraryMapping), true );
0 commit comments