From c814d82ef1c3a6cb31b18facf023b1086d68bfb4 Mon Sep 17 00:00:00 2001 From: Download-Fritz Date: Tue, 26 Mar 2019 17:18:02 +0100 Subject: [PATCH] OcMachoLib: Introduce GetSymbolbyExternReloc API. --- Include/Library/OcMachoLib.h | 19 ++++++++ Library/OcMachoLib/OcMachoLibInternal.h | 4 +- Library/OcMachoLib/Relocations.c | 33 +++----------- Library/OcMachoLib/Symbols.c | 58 ++++++++++++++++++++----- 4 files changed, 74 insertions(+), 40 deletions(-) diff --git a/Include/Library/OcMachoLib.h b/Include/Library/OcMachoLib.h index 52efcdd2..3b3c7cf1 100644 --- a/Include/Library/OcMachoLib.h +++ b/Include/Library/OcMachoLib.h @@ -357,6 +357,25 @@ MachoGetSymbolByRelocationOffset64 ( OUT MACH_NLIST_64 **Symbol ); +/** + Retrieves the symbol referenced by the extern Relocation targeting Address. + + @param[in,out] Context Context of the Mach-O. + @param[in] Address Address to search for. + @param[out] Symbol Buffer to output the symbol referenced by the + Relocation into. The output is undefined when FALSE + is returned. May be NULL. + + @returns Whether the Relocation exists. + +**/ +BOOLEAN +MachoGetSymbolByExternRelocationOffset64 ( + IN OUT OC_MACHO_CONTEXT *Context, + IN UINT64 Address, + OUT MACH_NLIST_64 **Symbol + ); + /** Relocate Symbol to be against LinkAddress. diff --git a/Library/OcMachoLib/OcMachoLibInternal.h b/Library/OcMachoLib/OcMachoLibInternal.h index bb55e84b..2f11ac7c 100644 --- a/Library/OcMachoLib/OcMachoLibInternal.h +++ b/Library/OcMachoLib/OcMachoLibInternal.h @@ -40,7 +40,7 @@ InternalRetrieveSymtabs64 ( @retval NULL NULL is returned on failure. **/ MACH_RELOCATION_INFO * -InternalGetExternalRelocationByOffset ( +InternalGetExternRelocationByOffset ( IN OUT OC_MACHO_CONTEXT *Context, IN UINT64 Address ); @@ -55,7 +55,7 @@ InternalGetExternalRelocationByOffset ( **/ MACH_RELOCATION_INFO * -InternalGetRelocationByOffset ( +InternalGetLocalRelocationByOffset ( IN OUT OC_MACHO_CONTEXT *Context, IN UINT64 Address ); diff --git a/Library/OcMachoLib/Relocations.c b/Library/OcMachoLib/Relocations.c index 0c856c7b..ab9f776d 100644 --- a/Library/OcMachoLib/Relocations.c +++ b/Library/OcMachoLib/Relocations.c @@ -115,15 +115,11 @@ InternalLookupRelocationByOffset ( **/ MACH_RELOCATION_INFO * -InternalGetExternalRelocationByOffset ( +InternalGetExternRelocationByOffset ( IN OUT OC_MACHO_CONTEXT *Context, IN UINT64 Address ) { - if (!InternalRetrieveSymtabs64 (Context) || (Context->DySymtab == NULL)) { - return NULL; - } - return InternalLookupRelocationByOffset ( Address, Context->DySymtab->NumExternalRelocations, @@ -141,29 +137,14 @@ InternalGetExternalRelocationByOffset ( **/ MACH_RELOCATION_INFO * -InternalGetRelocationByOffset ( +InternalGetLocalRelocationByOffset ( IN OUT OC_MACHO_CONTEXT *Context, IN UINT64 Address ) { - MACH_RELOCATION_INFO *Relocation; - - if (!InternalRetrieveSymtabs64 (Context) || (Context->DySymtab == NULL)) { - return NULL; - } - - Relocation = InternalLookupRelocationByOffset ( - Address, - Context->DySymtab->NumExternalRelocations, - Context->ExternRelocations - ); - if (Relocation == NULL) { - Relocation = InternalLookupRelocationByOffset ( - Address, - Context->DySymtab->NumOfLocalRelocations, - Context->LocalRelocations - ); - } - - return Relocation; + return InternalLookupRelocationByOffset ( + Address, + Context->DySymtab->NumOfLocalRelocations, + Context->LocalRelocations + ); } diff --git a/Library/OcMachoLib/Symbols.c b/Library/OcMachoLib/Symbols.c index 3ec3028a..4e475894 100644 --- a/Library/OcMachoLib/Symbols.c +++ b/Library/OcMachoLib/Symbols.c @@ -325,6 +325,38 @@ InternalGetSymbolByValue ( return NULL; } +/** + Retrieves the symbol referenced by the extern Relocation targeting Address. + + @param[in,out] Context Context of the Mach-O. + @param[in] Address Address to search for. + @param[out] Symbol Buffer to output the symbol referenced by the + Relocation into. The output is undefined when FALSE + is returned. May be NULL. + + @returns Whether the Relocation exists. + +**/ +BOOLEAN +MachoGetSymbolByExternRelocationOffset64 ( + IN OUT OC_MACHO_CONTEXT *Context, + IN UINT64 Address, + OUT MACH_NLIST_64 **Symbol + ) +{ + CONST MACH_RELOCATION_INFO *Relocation; + + ASSERT (Context != NULL); + + Relocation = InternalGetExternRelocationByOffset (Context, Address); + if (Relocation != NULL) { + *Symbol = MachoGetSymbolByIndex64 (Context, Relocation->SymbolNumber); + return TRUE; + } + + return FALSE; +} + /** Retrieves the symbol referenced by the Relocation targeting Address. @@ -344,27 +376,29 @@ MachoGetSymbolByRelocationOffset64 ( OUT MACH_NLIST_64 **Symbol ) { + BOOLEAN Result; CONST MACH_RELOCATION_INFO *Relocation; CONST UINT64 *Data; MACH_NLIST_64 *Sym; ASSERT (Context != NULL); - Relocation = InternalGetRelocationByOffset (Context, Address); + Result = MachoGetSymbolByExternRelocationOffset64 (Context, Address, Symbol); + if (Result) { + return TRUE; + } + + Relocation = InternalGetLocalRelocationByOffset (Context, Address); if (Relocation != NULL) { Sym = NULL; - if (Relocation->Extern != 0) { - Sym = MachoGetSymbolByIndex64 (Context, Relocation->SymbolNumber); - } else { - Data = ((UINT64 *)((UINTN)Context->MachHeader + Address)); - if (((Address + sizeof (UINT64)) <= Context->FileSize) - && OC_ALIGNED (Data)) { - // FIXME: Only C++ symbols. - Sym = InternalGetSymbolByValue (Context, *Data); - if ((Sym != NULL) && !InternalSymbolIsSane (Context, Sym)) { - Sym = NULL; - } + Data = ((UINT64 *)((UINTN)Context->MachHeader + Address)); + if (((Address + sizeof (UINT64)) <= Context->FileSize) + && OC_ALIGNED (Data)) { + // FIXME: Only C++ symbols. + Sym = InternalGetSymbolByValue (Context, *Data); + if ((Sym != NULL) && !InternalSymbolIsSane (Context, Sym)) { + Sym = NULL; } }