mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcMachoLib: Introduce Context concept.
This commit is contained in:
parent
be5fdd2b83
commit
c6bf9d0590
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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))) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user