OcMachoLib: Introduce Context concept.

This commit is contained in:
Download-Fritz 2018-10-19 05:55:38 +02:00
parent be5fdd2b83
commit c6bf9d0590
5 changed files with 247 additions and 157 deletions

View File

@ -17,21 +17,46 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <IndustryStandard/AppleMachoImage.h>
///
/// Context used to refer to a MACH-O.
///
typedef struct {
CONST MACH_HEADER_64 *MachHeader;
UINTN FileSize;
} OC_MACHO_CONTEXT;
/**
Initializes a MACH-O Context.
@param[in] MachHeader Header of the MACH-O.
@param[in] FileSize File size of the MACH-O.
@param[out] Context MACH-O Context to initialize.
@return Whether Context has been initialized successfully.
**/
BOOLEAN
MachoInitializeContext (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINTN FileSize,
OUT OC_MACHO_CONTEXT *Context
);
/**
Returns the last virtual address of a MACH-O.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
**/
UINT64
MachoGetLastAddress64 (
IN CONST MACH_HEADER_64 *MachHeader
IN CONST OC_MACHO_CONTEXT *Context
);
/**
Retrieves the first Load Command of type LoadCommandType.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] LoadCommandType Type of the Load Command to retrieve.
@retval NULL NULL is returned on failure.
@ -39,14 +64,14 @@ MachoGetLastAddress64 (
**/
MACH_LOAD_COMMAND *
MachoGetFirstCommand64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN MACH_LOAD_COMMAND_TYPE LoadCommandType
);
/**
Retrieves the first Load Command of type LoadCommandType.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] LoadCommandType Type of the Load Command to retrieve.
@param[in] LoadCommand Previous Load Command.
@ -55,7 +80,7 @@ MachoGetFirstCommand64 (
**/
MACH_LOAD_COMMAND *
MachoGetNextCommand64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN MACH_LOAD_COMMAND_TYPE LoadCommandType,
IN CONST MACH_LOAD_COMMAND *LoadCommand
);
@ -63,20 +88,20 @@ MachoGetNextCommand64 (
/**
Retrieves the first UUID Load Command.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@retval NULL NULL is returned on failure.
**/
MACH_UUID_COMMAND *
MachoGetUuid64 (
IN CONST MACH_HEADER_64 *MachHeader
IN CONST OC_MACHO_CONTEXT *Context
);
/**
Retrieves the first segment by the name of SegmentName.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] SegmentName Segment name to search for.
@retval NULL NULL is returned on failure.
@ -84,14 +109,14 @@ MachoGetUuid64 (
**/
MACH_SEGMENT_COMMAND_64 *
MachoGetSegmentByName64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST CHAR8 *SegmentName
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST CHAR8 *SegmentName
);
/**
Retrieves the first section by the name of SectionName.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] Segment Segment to search in.
@param[in] SectionName Section name to search for.
@ -100,7 +125,7 @@ MachoGetSegmentByName64 (
**/
MACH_SECTION_64 *
MachoGetSectionByName64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST MACH_SEGMENT_COMMAND_64 *Segment,
IN CONST CHAR8 *SectionName
);
@ -108,7 +133,7 @@ MachoGetSectionByName64 (
/**
Retrieves a section within a segment by the name of SegmentName.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] SegmentName The name of the segment to search in.
@param[in] SectionName The name of the section to search for.
@ -117,36 +142,36 @@ MachoGetSectionByName64 (
**/
MACH_SECTION_64 *
MachoGetSegmentSectionByName64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST CHAR8 *SegmentName,
IN CONST CHAR8 *SectionName
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST CHAR8 *SegmentName,
IN CONST CHAR8 *SectionName
);
/**
Retrieves the first segment.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@retval NULL NULL is returned on failure.
**/
MACH_SEGMENT_COMMAND_64 *
MachoGetFirstSegment64 (
IN CONST MACH_HEADER_64 *MachHeader
IN CONST OC_MACHO_CONTEXT *Context
);
/**
Retrieves the next segment.
@param[in] MachHeader Header of the MACH-O.
@param[in] Segment Segment to retrieve the successor of.
@param[in] Context Context of the MACH-O.
@param[in] Segment Segment to retrieve the successor of.
@retal NULL NULL is returned on failure.
**/
MACH_SEGMENT_COMMAND_64 *
MachoGetNextSegment64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST MACH_SEGMENT_COMMAND_64 *Segment
);
@ -181,31 +206,31 @@ MachoGetNextSection64 (
/**
Retrieves a section by its index.
@param[in] MachHeader Header of the MACH-O.
@param[in] Index Index of the section to retrieve.
@param[in] Context Context of the MACH-O.
@param[in] Index Index of the section to retrieve.
@retval NULL NULL is returned on failure.
**/
CONST MACH_SECTION_64 *
MachoGetSectionByIndex64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINTN Index
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN Index
);
/**
Retrieves a section by its address.
@param[in] MachHeader Header of the MACH-O.
@param[in] Address Address of the section to retrieve.
@param[in] Context Context of the MACH-O.
@param[in] Address Address of the section to retrieve.
@retval NULL NULL is returned on failure.
**/
CONST MACH_SECTION_64 *
MachoGetSectionByAddress64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINT64 Address
IN CONST OC_MACHO_CONTEXT *Context,
IN UINT64 Address
);
/**
@ -233,7 +258,7 @@ MachoSymbolIsDefined (
/**
Returns whether Symbol is defined locally.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] SymbolTable Symbol Table of the MACH-O.
@param[in] DySymtab Dynamic Symbol Table of the MACH-O.
@param[in] Symbol Symbol to evaluate.
@ -241,7 +266,7 @@ MachoSymbolIsDefined (
**/
BOOLEAN
MachoSymbolIsLocalDefined (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST MACH_NLIST_64 *SymbolTable,
IN CONST MACH_DYSYMTAB_COMMAND *DySymtab,
IN CONST MACH_NLIST_64 *Symbol
@ -286,7 +311,7 @@ MachoGetLocalDefinedSymbolByName (
/**
Relocate Symbol to be against LinkAddress.
@param[in] MachHeader MACH-O header of the KEXT to relocate.
@param[in] Context Context of the MACH-O.
@param[in] LinkAddress The address to be linked against.
@param[in,out] Symbol The symbol to be relocated.
@ -295,15 +320,15 @@ MachoGetLocalDefinedSymbolByName (
**/
BOOLEAN
MachoRelocateSymbol64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINT64 LinkAddress,
IN OUT MACH_NLIST_64 *Symbol
IN CONST OC_MACHO_CONTEXT *Context,
IN UINT64 LinkAddress,
IN OUT MACH_NLIST_64 *Symbol
);
/**
Retrieves a symbol by the Relocation it is referenced by.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] NumberOfSymbols Number of symbols in SymbolTable.
@param[in] SymbolTable Symbol Table of the MACH-O.
@param[in] StringTable String Table of the MACH-O.
@ -314,7 +339,7 @@ MachoRelocateSymbol64 (
**/
CONST MACH_NLIST_64 *
MachoGetCxxSymbolByRelocation64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN NumberOfSymbols,
IN CONST MACH_NLIST_64 *SymbolTable,
IN CONST CHAR8 *StringTable,
@ -513,20 +538,20 @@ MachoIsSymbolNameCxx (
/**
Returns the number of VTable entires in VtableData.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] VtableData The VTable's data.
**/
UINTN
MachoVtableGetNumberOfEntries64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST UINT64 *VtableData
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST UINT64 *VtableData
);
/**
Retrieves Metaclass symbol of a SMCP.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] NumberOfSymbols Number of symbols in SymbolTable.
@param[in] SymbolTable Symbol Table of the MACH-O.
@param[in] StringTable String Table of the MACH-O.
@ -539,7 +564,7 @@ MachoVtableGetNumberOfEntries64 (
**/
CONST MACH_NLIST_64 *
MachoGetMetaclassSymbolFromSmcpSymbol64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN NumberOfSymbols,
IN CONST MACH_NLIST_64 *SymbolTable,
IN CONST CHAR8 *StringTable,
@ -608,7 +633,7 @@ MachoPreserveRelocationIntel64 (
/**
Retrieves a Relocation by the address it targets.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] NumberOfRelocations Number of Relocations in Relocations.
@param[in] Relocations The Relocations to search.
@param[in] Address The address to search for.
@ -618,7 +643,7 @@ MachoPreserveRelocationIntel64 (
**/
CONST MACH_RELOCATION_INFO *
MachoGetRelocationByOffset (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN NumberOfRelocations,
IN CONST MACH_RELOCATION_INFO *Relocations,
IN UINT64 Address

View File

@ -499,30 +499,28 @@ MachoIsSymbolNameCxx (
/**
Returns the number of VTable entires in VtableData.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] VtableData The VTable's data.
**/
UINTN
MachoVtableGetNumberOfEntries64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST UINT64 *VtableData
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST UINT64 *VtableData
)
{
UINTN Index;
UINTN NumberOfEntries;
ASSERT (Context != NULL);
ASSERT (VtableData != NULL);
NumberOfEntries = 0;
if ((MachHeader->CpuType != MachCpuTypeArm)
&& (MachHeader->CpuType != MachCpuTypeArm64)) {
for (Index = VTABLE_HEADER_LEN_64; VtableData[Index] != 0; ++Index) {
++NumberOfEntries;
}
} else {
ASSERT (FALSE);
//
// Assumption: Not ARM. Currently verified by the Context initialization.
//
for (Index = VTABLE_HEADER_LEN_64; VtableData[Index] != 0; ++Index) {
++NumberOfEntries;
}
return NumberOfEntries;
@ -531,7 +529,7 @@ MachoVtableGetNumberOfEntries64 (
/**
Retrieves Metaclass symbol of a SMCP.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] NumberOfSymbols Number of symbols in SymbolTable.
@param[in] SymbolTable Symbol Table of the MACH-O.
@param[in] StringTable String Table of the MACH-O.
@ -544,7 +542,7 @@ MachoVtableGetNumberOfEntries64 (
**/
CONST MACH_NLIST_64 *
MachoGetMetaclassSymbolFromSmcpSymbol64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN NumberOfSymbols,
IN CONST MACH_NLIST_64 *SymbolTable,
IN CONST CHAR8 *StringTable,
@ -555,14 +553,14 @@ MachoGetMetaclassSymbolFromSmcpSymbol64 (
{
CONST MACH_RELOCATION_INFO *Relocation;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (SymbolTable != NULL);
ASSERT (StringTable != NULL);
ASSERT (Relocations != NULL);
ASSERT (Smcp != NULL);
Relocation = MachoGetRelocationByOffset (
MachHeader,
Context,
NumberOfRelocations,
Relocations,
Smcp->Value
@ -572,7 +570,7 @@ MachoGetMetaclassSymbolFromSmcpSymbol64 (
}
return MachoGetCxxSymbolByRelocation64 (
MachHeader,
Context,
NumberOfSymbols,
SymbolTable,
StringTable,

View File

@ -20,15 +20,82 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/DebugLib.h>
#include <Library/OcMachoLib.h>
/**
Initializes a MACH-O Context.
@param[in] MachHeader Header of the MACH-O.
@param[in] FileSize File size of the MACH-O.
@param[out] Context MACH-O Context to initialize.
@return Whether Context has been initialized successfully.
**/
BOOLEAN
MachoInitializeContext (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINTN FileSize,
OUT OC_MACHO_CONTEXT *Context
)
{
UINTN TopOfCommands;
UINTN Index;
CONST MACH_LOAD_COMMAND *Command;
UINTN CommandsSize;
//
// Verify MACH-O Header sanity.
//
TopOfCommands = ((UINTN)MachHeader->Commands + MachHeader->CommandsSize);
if ((MachHeader->Signature != MACH_HEADER_64_SIGNATURE)
|| (TopOfCommands > ((UINTN)MachHeader + FileSize))) {
return FALSE;
}
CommandsSize = 0;
for (
Index = 0, Command = MachHeader->Commands;
Index < MachHeader->NumberOfCommands;
++Index, Command = NEXT_MACH_LOAD_COMMAND (Command)
) {
if (((UINTN)Command >= ((UINTN)MachHeader + MachHeader->CommandsSize))
|| (Command->Size < sizeof (*Command))
|| ((Command->Size % 8) != 0) // Assumption: 64-bit, see below.
) {
return FALSE;
}
CommandsSize += Command->Size;
}
if (MachHeader->CommandsSize != CommandsSize) {
return FALSE;
}
//
// Verify assumptions made by this library.
// Carefully audit all "Assumption:" remarks before modifying these checks.
//
if ((MachHeader->CpuType != MachCpuTypeX8664)
|| ((MachHeader->FileType != MachHeaderFileTypeKextBundle)
&& (MachHeader->FileType != MachHeaderFileTypeExecute))) {
ASSERT (FALSE);
return FALSE;
}
Context->MachHeader = MachHeader;
Context->FileSize = FileSize;
return TRUE;
}
/**
Returns the last virtual address of a MACH-O.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
**/
UINT64
MachoGetLastAddress64 (
IN CONST MACH_HEADER_64 *MachHeader
IN CONST OC_MACHO_CONTEXT *Context
)
{
UINT64 LastAddress;
@ -36,14 +103,14 @@ MachoGetLastAddress64 (
CONST MACH_SEGMENT_COMMAND_64 *Segment;
UINT64 Address;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
LastAddress = 0;
for (
Segment = MachoGetFirstSegment64 (MachHeader);
Segment = MachoGetFirstSegment64 (Context);
Segment != NULL;
Segment = MachoGetNextSegment64 (MachHeader, Segment)
Segment = MachoGetNextSegment64 (Context, Segment)
) {
Address = (Segment->VirtualAddress + Segment->Hdr.Size);
@ -58,7 +125,7 @@ MachoGetLastAddress64 (
/**
Retrieves the first Load Command of type LoadCommandType.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] LoadCommandType Type of the Load Command to retrieve.
@param[in] LoadCommand Previous Load Command.
@ -67,30 +134,28 @@ MachoGetLastAddress64 (
**/
MACH_LOAD_COMMAND *
MachoGetNextCommand64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN MACH_LOAD_COMMAND_TYPE LoadCommandType,
IN CONST MACH_LOAD_COMMAND *LoadCommand
)
{
CONST MACH_LOAD_COMMAND *Command;
CONST MACH_HEADER_64 *MachHeader;
UINTN TopOfCommands;
ASSERT (MachHeader != NULL);
//
// LoadCommand being past the MachHeader Load Commands is implicitly caught
// by the while-loop.
//
if ((MachHeader->Signature != MACH_HEADER_64_SIGNATURE)
|| (LoadCommand < MachHeader->Commands)) {
return NULL;
}
ASSERT (Context != NULL);
MachHeader = Context->MachHeader;
TopOfCommands = ((UINTN)MachHeader->Commands + MachHeader->CommandsSize);
ASSERT (
(LoadCommand >= &MachHeader->Commands[0])
&& ((UINTN)LoadCommand <= TopOfCommands)
);
for (
Command = NEXT_MACH_LOAD_COMMAND (LoadCommand);
((UINTN)Command < TopOfCommands)
&& (((UINTN)Command + Command->Size) <= TopOfCommands);
(UINTN)Command < TopOfCommands;
Command = NEXT_MACH_LOAD_COMMAND (Command)
) {
if (Command->Type == LoadCommandType) {
@ -104,7 +169,7 @@ MachoGetNextCommand64 (
/**
Retrieves the first Load Command of type LoadCommandType.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] LoadCommandType Type of the Load Command to retrieve.
@retval NULL NULL is returned on failure.
@ -112,14 +177,17 @@ MachoGetNextCommand64 (
**/
MACH_LOAD_COMMAND *
MachoGetFirstCommand64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN MACH_LOAD_COMMAND_TYPE LoadCommandType
)
{
ASSERT (MachHeader != NULL);
CONST MACH_HEADER_64 *MachHeader;
if ((MachHeader->Signature != MACH_HEADER_64_SIGNATURE)
|| (MachHeader->NumberOfCommands == 0)) {
ASSERT (Context != NULL);
MachHeader = Context->MachHeader;
if (MachHeader->NumberOfCommands == 0) {
return NULL;
}
@ -128,7 +196,7 @@ MachoGetFirstCommand64 (
}
return MachoGetNextCommand64 (
MachHeader,
Context,
LoadCommandType,
&MachHeader->Commands[0]
);
@ -137,27 +205,27 @@ MachoGetFirstCommand64 (
/**
Retrieves the first UUID Load Command.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@retval NULL NULL is returned on failure.
**/
MACH_UUID_COMMAND *
MachoGetUuid64 (
IN CONST MACH_HEADER_64 *MachHeader
IN CONST OC_MACHO_CONTEXT *Context
)
{
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
return (MACH_UUID_COMMAND *)(
MachoGetFirstCommand64 (MachHeader, MACH_LOAD_COMMAND_UUID)
MachoGetFirstCommand64 (Context, MACH_LOAD_COMMAND_UUID)
);
}
/**
Retrieves the first segment by the name of SegmentName.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] SegmentName Segment name to search for.
@retval NULL NULL is returned on failure.
@ -165,20 +233,20 @@ MachoGetUuid64 (
**/
MACH_SEGMENT_COMMAND_64 *
MachoGetSegmentByName64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST CHAR8 *SegmentName
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST CHAR8 *SegmentName
)
{
CONST MACH_SEGMENT_COMMAND_64 *Segment;
INTN Result;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (SegmentName != NULL);
for (
Segment = MachoGetFirstSegment64 (MachHeader);
Segment = MachoGetFirstSegment64 (Context);
Segment != NULL;
Segment = MachoGetNextSegment64 (MachHeader, Segment)
Segment = MachoGetNextSegment64 (Context, Segment)
) {
if (Segment->Hdr.Type == MACH_LOAD_COMMAND_SEGMENT_64) {
Result = AsciiStrnCmp (
@ -198,7 +266,7 @@ MachoGetSegmentByName64 (
/**
Retrieves the first section by the name of SectionName.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] Segment Segment to search in.
@param[in] SectionName Section name to search for.
@ -207,7 +275,7 @@ MachoGetSegmentByName64 (
**/
MACH_SECTION_64 *
MachoGetSectionByName64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST MACH_SEGMENT_COMMAND_64 *Segment,
IN CONST CHAR8 *SectionName
)
@ -216,22 +284,10 @@ MachoGetSectionByName64 (
UINTN Index;
INTN Result;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (Segment != NULL);
ASSERT (SectionName != NULL);
if (MachHeader->Signature != MACH_HEADER_64_SIGNATURE) {
return NULL;
}
//
// MH_OBJECT might have sections in segments they do not belong in for
// performance reasons. We do not support intermediate objects.
//
if (MachHeader->FileType == MachHeaderFileTypeObject) {
ASSERT (FALSE);
return NULL;
}
SectionWalker = &Segment->Sections[0];
for (Index = 0; Index < Segment->NumberOfSections; ++Index) {
@ -241,6 +297,12 @@ MachoGetSectionByName64 (
ARRAY_SIZE (SectionWalker->SegmentName)
);
if (Result == 0) {
//
// Assumption: MACH-O is not of type MH_OBJECT.
// MH_OBJECT might have sections in segments they do not belong in for
// performance reasons. This library does not support intermediate
// objects.
//
DEBUG_CODE (
Result = AsciiStrnCmp (
SectionWalker->SegmentName,
@ -265,7 +327,7 @@ MachoGetSectionByName64 (
/**
Retrieves a section within a segment by the name of SegmentName.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] SegmentName The name of the segment to search in.
@param[in] SectionName The name of the section to search for.
@ -274,21 +336,21 @@ MachoGetSectionByName64 (
**/
MACH_SECTION_64 *
MachoGetSegmentSectionByName64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST CHAR8 *SegmentName,
IN CONST CHAR8 *SectionName
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST CHAR8 *SegmentName,
IN CONST CHAR8 *SectionName
)
{
CONST MACH_SEGMENT_COMMAND_64 *Segment;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (SegmentName != NULL);
ASSERT (SectionName != NULL);
Segment = MachoGetSegmentByName64 (MachHeader, SegmentName);
Segment = MachoGetSegmentByName64 (Context, SegmentName);
if (Segment != NULL) {
return MachoGetSectionByName64 (MachHeader, Segment, SectionName);
return MachoGetSectionByName64 (Context, Segment, SectionName);
}
return NULL;
@ -297,39 +359,39 @@ MachoGetSegmentSectionByName64 (
/**
Retrieves the first segment.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@retval NULL NULL is returned on failure.
**/
MACH_SEGMENT_COMMAND_64 *
MachoGetFirstSegment64 (
IN CONST MACH_HEADER_64 *MachHeader
IN CONST OC_MACHO_CONTEXT *Context
)
{
return (MACH_SEGMENT_COMMAND_64 *)(
MachoGetFirstCommand64 (MachHeader, MACH_LOAD_COMMAND_SEGMENT_64)
MachoGetFirstCommand64 (Context, MACH_LOAD_COMMAND_SEGMENT_64)
);
}
/**
Retrieves the next segment.
@param[in] MachHeader Header of the MACH-O.
@param[in] Segment Segment to retrieve the successor of.
@param[in] Context Context of the MACH-O.
@param[in] Segment Segment to retrieve the successor of.
@retal NULL NULL is returned on failure.
**/
MACH_SEGMENT_COMMAND_64 *
MachoGetNextSegment64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST MACH_SEGMENT_COMMAND_64 *Segment
)
{
return (MACH_SEGMENT_COMMAND_64 *)(
MachoGetNextCommand64 (
MachHeader,
Context,
MACH_LOAD_COMMAND_SEGMENT_64,
&Segment->Hdr
)
@ -388,29 +450,29 @@ MachoGetNextSection64 (
/**
Retrieves a section by its index.
@param[in] MachHeader Header of the MACH-O.
@param[in] Index Index of the section to retrieve.
@param[in] Context Context of the MACH-O.
@param[in] Index Index of the section to retrieve.
@retval NULL NULL is returned on failure.
**/
CONST MACH_SECTION_64 *
MachoGetSectionByIndex64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINTN Index
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN Index
)
{
CONST MACH_SEGMENT_COMMAND_64 *Segment;
UINTN SectionIndex;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
SectionIndex = 0;
for (
Segment = MachoGetFirstSegment64 (MachHeader);
Segment = MachoGetFirstSegment64 (Context);
Segment != NULL;
Segment = MachoGetNextSegment64 (MachHeader, Segment)
Segment = MachoGetNextSegment64 (Context, Segment)
) {
if (Index <= (SectionIndex + (Segment->NumberOfSections - 1))) {
return &Segment->Sections[Index - SectionIndex];
@ -425,28 +487,28 @@ MachoGetSectionByIndex64 (
/**
Retrieves a section by its address.
@param[in] MachHeader Header of the MACH-O.
@param[in] Address Address of the section to retrieve.
@param[in] Context Context of the MACH-O.
@param[in] Address Address of the section to retrieve.
@retval NULL NULL is returned on failure.
**/
CONST MACH_SECTION_64 *
MachoGetSectionByAddress64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINT64 Address
IN CONST OC_MACHO_CONTEXT *Context,
IN UINT64 Address
)
{
CONST MACH_SEGMENT_COMMAND_64 *Segment;
CONST MACH_SECTION_64 *Section;
UINTN Index;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
for (
Segment = MachoGetFirstSegment64 (MachHeader);
Segment = MachoGetFirstSegment64 (Context);
Segment != NULL;
Segment = MachoGetNextSegment64 (MachHeader, Segment)
Segment = MachoGetNextSegment64 (Context, Segment)
) {
if ((Address >= Segment->VirtualAddress)
&& (Address < (Segment->VirtualAddress + Address >= Segment->FileSize))) {

View File

@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <IndustryStandard/AppleMachoImage.h>
#include <Library/DebugLib.h>
#include <Library/OcMachoLib.h>
/**
Returns whether the Relocation's type indicates a Pair for the Intel 64
@ -65,7 +66,7 @@ MachoPreserveRelocationIntel64 (
/**
Retrieves a Relocation by the address it targets.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] NumberOfRelocations Number of Relocations in Relocations.
@param[in] Relocations The Relocations to search.
@param[in] Address The address to search for.
@ -75,7 +76,7 @@ MachoPreserveRelocationIntel64 (
**/
CONST MACH_RELOCATION_INFO *
MachoGetRelocationByOffset (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN NumberOfRelocations,
IN CONST MACH_RELOCATION_INFO *Relocations,
IN UINT64 Address
@ -84,6 +85,7 @@ MachoGetRelocationByOffset (
UINTN Index;
CONST MACH_RELOCATION_INFO *Relocation;
ASSERT (Context != NULL);
ASSERT (Relocations != NULL);
for (
@ -106,9 +108,10 @@ MachoGetRelocationByOffset (
}
//
// Relocation Pairs can be skipped.
// Assumption: Intel X64. Currently verified by the Context
// initialization.
//
if ((MachHeader->CpuType == MachCpuTypeX8664)
&& MachoRelocationIsPairIntel64 (Relocation->Type)) {
if (MachoRelocationIsPairIntel64 (Relocation->Type)) {
++Index;
++Relocation;
}

View File

@ -92,7 +92,7 @@ MachoSymbolIsDefined (
/**
Returns whether Symbol is defined locally.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Context of the MACH-O.
@param[in] SymbolTable Symbol Table of the MACH-O.
@param[in] DySymtab Dynamic Symbol Table of the MACH-O.
@param[in] Symbol Symbol to evaluate.
@ -100,7 +100,7 @@ MachoSymbolIsDefined (
**/
BOOLEAN
MachoSymbolIsLocalDefined (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN CONST MACH_NLIST_64 *SymbolTable,
IN CONST MACH_DYSYMTAB_COMMAND *DySymtab,
IN CONST MACH_NLIST_64 *Symbol
@ -111,7 +111,7 @@ MachoSymbolIsLocalDefined (
CONST MACH_NLIST_64 *IndirectSymbols;
CONST MACH_NLIST_64 *IndirectSymbolsTop;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (SymbolTable != NULL);
ASSERT (DySymtab != NULL);
ASSERT (Symbol != NULL);
@ -129,7 +129,8 @@ MachoSymbolIsLocalDefined (
}
IndirectSymbols = (CONST MACH_NLIST_64 *)(
(UINTN)MachHeader + DySymtab->IndirectSymbolsOffset
(UINTN)Context->MachHeader
+ DySymtab->IndirectSymbolsOffset
);
IndirectSymbolsTop = &IndirectSymbols[DySymtab->NumberOfIndirectSymbols];
@ -225,7 +226,7 @@ MachoGetLocalDefinedSymbolByName (
/**
Relocate Symbol to be against LinkAddress.
@param[in] MachHeader MACH-O header of the KEXT to relocate.
@param[in] Context Context of the MACH-O.
@param[in] LinkAddress The address to be linked against.
@param[in,out] Symbol The symbol to be relocated.
@ -234,21 +235,21 @@ MachoGetLocalDefinedSymbolByName (
**/
BOOLEAN
MachoRelocateSymbol64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN UINT64 LinkAddress,
IN OUT MACH_NLIST_64 *Symbol
IN CONST OC_MACHO_CONTEXT *Context,
IN UINT64 LinkAddress,
IN OUT MACH_NLIST_64 *Symbol
)
{
CONST MACH_SECTION_64 *Section;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (Symbol != NULL);
ASSERT ((Symbol->Type & MACH_N_TYPE_EXT) == 0);
//
// Symbols are relocated when they describe sections.
//
if (MachoSymbolIsSection (Symbol)) {
Section = MachoGetSectionByAddress64 (MachHeader, Symbol->Value);
Section = MachoGetSectionByAddress64 (Context, Symbol->Value);
if (Section == NULL) {
return FALSE;
}
@ -266,7 +267,7 @@ MachoRelocateSymbol64 (
/**
Retrieves a symbol by the Relocation it is referenced by.
@param[in] MachHeader Header of the MACH-O.
@param[in] Context Header of the MACH-O.
@param[in] NumberOfSymbols Number of symbols in SymbolTable.
@param[in] SymbolTable Symbol Table of the MACH-O.
@param[in] StringTable String Table of the MACH-O.
@ -277,7 +278,7 @@ MachoRelocateSymbol64 (
**/
CONST MACH_NLIST_64 *
MachoGetCxxSymbolByRelocation64 (
IN CONST MACH_HEADER_64 *MachHeader,
IN CONST OC_MACHO_CONTEXT *Context,
IN UINTN NumberOfSymbols,
IN CONST MACH_NLIST_64 *SymbolTable,
IN CONST CHAR8 *StringTable,
@ -290,7 +291,7 @@ MachoGetCxxSymbolByRelocation64 (
CONST MACH_NLIST_64 *Symbol;
CONST CHAR8 *Name;
ASSERT (MachHeader != NULL);
ASSERT (Context != NULL);
ASSERT (SymbolTable != NULL);
ASSERT (StringTable != NULL);
ASSERT (Relocation != NULL);
@ -303,13 +304,14 @@ MachoGetCxxSymbolByRelocation64 (
return &SymbolTable[Relocation->SymbolNumber];
}
Section = MachoGetSectionByIndex64 (MachHeader, Relocation->SymbolNumber);
Section = MachoGetSectionByIndex64 (Context, Relocation->SymbolNumber);
if (Section == NULL) {
return NULL;
}
Value = *(CONST UINT64 *)(
(UINTN)MachHeader + Section->Address + Relocation->Address
(UINTN)Context->MachHeader
+ (Section->Address + Relocation->Address)
);
for (Index = 0; Index < NumberOfSymbols; ++Index) {
Symbol = &SymbolTable[Index];