20#include <Library/BaseLib.h>
21#include <Library/BaseMemoryLib.h>
22#include <Library/BaseOverflowLib.h>
23#include <Library/DebugLib.h>
31#define TEXT_SEG_PROT (MACH_SEGMENT_VM_PROT_READ | MACH_SEGMENT_VM_PROT_EXECUTE)
32#define DATA_SEG_PROT (MACH_SEGMENT_VM_PROT_READ | MACH_SEGMENT_VM_PROT_WRITE)
42 IN CONST CHAR8 *LookupValue,
43 IN UINT32 LookupValueLength,
56 Kext->Processed = TRUE;
58 if (Kext->LinkedSymbolTable != NULL) {
59 NumSymbols = Kext->NumberOfSymbols;
60 Symbols = Kext->LinkedSymbolTable;
63 NumSymbols = Kext->NumberOfCxxSymbols;
64 Symbols = &Kext->LinkedSymbolTable[Kext->NumberOfSymbols - Kext->NumberOfCxxSymbols];
67 SymbolsEnd = &Symbols[NumSymbols];
68 while (Symbols < SymbolsEnd) {
74 if (Symbols->Length == LookupValueLength) {
75 if ( (Symbols->Name[LookupValueLength / 2] == LookupValue[LookupValueLength / 2])
76 && (Symbols->Name[(LookupValueLength / 2) + 1] == LookupValue[(LookupValueLength / 2) + 1]))
78 for (Index = 0; Index < LookupValueLength; ++Index) {
79 if (Symbols->Name[Index] != LookupValue[Index]) {
84 if (Index == LookupValueLength) {
95 for (Index = 0; Index <
ARRAY_SIZE (Kext->Dependencies); ++Index) {
97 if (Dependency == NULL) {
111 if (Symbols != NULL) {
124 IN UINT64 LookupValue,
137 Kext->Processed = TRUE;
139 if (Kext->LinkedSymbolTable != NULL) {
140 NumSymbols = Kext->NumberOfSymbols;
141 Symbols = Kext->LinkedSymbolTable;
144 NumSymbols = Kext->NumberOfCxxSymbols;
145 Symbols = &Kext->LinkedSymbolTable[(Kext->NumberOfSymbols - Kext->NumberOfCxxSymbols) & ~15ULL];
155 SymbolsEnd = &Symbols[NumSymbols & ~15ULL];
156 while (Symbols < SymbolsEnd) {
157 #define MATCH(X) if (Symbols[X].Value == LookupValue) { return &Symbols[X]; }
166 for (Index = 0; Index <
ARRAY_SIZE (Kext->Dependencies); ++Index) {
168 if (Dependency == NULL) {
181 if (Symbols != NULL) {
194 IN CONST CHAR8 *LookupValue,
202 UINT32 LookupValueLength;
205 LookupValueLength = (UINT32)AsciiStrLen (LookupValue);
210 if (LookupValueLength == 0) {
222 for (Index = 0; Index <
ARRAY_SIZE (Kext->Dependencies); ++Index) {
224 if (Dependency == NULL) {
234 if (Symbol != NULL) {
249 IN UINT64 LookupValue,
263 for (Index = 0; Index <
ARRAY_SIZE (Kext->Dependencies); ++Index) {
265 if (Dependency == NULL) {
274 if (Symbol != NULL) {
301 Symbol->Symbol32.Value = (UINT32)Value;
303 Symbol->Symbol32.Section =
NO_SECT;
305 Symbol->Symbol64.Value = Value;
307 Symbol->Symbol64.Section =
NO_SECT;
328 IN CONST CHAR8 *Name,
336 SymbolType = Context->Is32Bit ? Symbol->Symbol32.Type : Symbol->Symbol64.Type;
344 Result = AsciiStrCmp (
360 }
else if ((Context->Is32Bit ? Symbol->Symbol32.Value : Symbol->Symbol64.Value) != 0) {
377 if (ResolveSymbol != NULL) {
407 IN CONST CHAR8 *Name,
409 IN OUT UINT64 *WeakTestValue,
411 IN UINT32 NumUndefinedSymbols
421 ASSERT (UndefinedSymbols != NULL || NumUndefinedSymbols == 0);
425 if (((Context->Is32Bit ? Symbol->Symbol32.Type : Symbol->Symbol64.Type) &
MACH_N_TYPE_STAB) != 0) {
439 if (((Context->Is32Bit ? Symbol->Symbol32.Descriptor : Symbol->Symbol64.Descriptor) &
MACH_N_WEAK_DEF) != 0) {
445 Value = *WeakTestValue;
451 if (NumUndefinedSymbols > 0) {
452 for (Index = 0; Index < NumUndefinedSymbols; ++Index) {
453 if (Context->Is32Bit) {
454 WeakTestSymbol = (
MACH_NLIST_ANY *)&(&UndefinedSymbols->Symbol32)[Index];
456 WeakTestSymbol = (
MACH_NLIST_ANY *)&(&UndefinedSymbols->Symbol64)[Index];
459 Result = AsciiStrCmp (
461 &Kext->Context.MachContext,
467 if (((Context->Is32Bit ?
481 Value = Context->Is32Bit ? WeakTestSymbol->Symbol32.Value : WeakTestSymbol->Symbol64.Value;
482 *WeakTestValue = Value;
486 }
else if (Context->Is32Bit) {
490 if (WeakTestSymbol == NULL) {
494 Result = AsciiStrCmp (
496 &Kext->Context.MachContext,
502 if (((Context->Is32Bit ?
516 Value = Context->Is32Bit ? WeakTestSymbol->Symbol32.Value : WeakTestSymbol->Symbol64.Value;
517 *WeakTestValue = Value;
556 IN UINT64 Adjustment,
557 IN OUT INT32 *Instruction
563 ASSERT (Instruction != NULL);
565 Displacement = ((*Instruction + Target) - Adjustment);
566 Difference = ABS (Displacement);
572 *Instruction = (INT32)Displacement;
599 IN UINT64 LoadAddress,
603 OUT UINT64 *PairTarget,
611 UINT64 TargetAddress;
619 ASSERT (PairTarget != NULL);
621 MachoContext = &Kext->Context.MachContext;
636 if (Relocation->Extern != 0) {
639 Relocation->SymbolNumber
641 if (Symbol == NULL) {
663 if (TargetAddress == 0) {
664 DEBUG ((DEBUG_INFO,
"OCAK: Symbol %a has 0-value\n", Name));
667 if ( (Relocation->SymbolNumber ==
NO_SECT)
668 || (Relocation->SymbolNumber >
MAX_SECT))
675 (Relocation->SymbolNumber - 1)
677 if (Section == NULL) {
681 if (Context->Is32Bit) {
682 TargetAddress = ALIGN_VALUE (
688 TargetAddress = ALIGN_VALUE (
696 if (Context->Is32Bit ?
701 if (NextRelocation == NULL) {
725 *Target = TargetAddress;
726 *PairTarget = PairAddress;
757 if (Index >= Vtable->NumEntries) {
761 Entry = &Vtable->Entries[Index];
762 if (Entry->Name == NULL) {
796 IN UINT64 LoadAddress,
797 IN UINT64 RelocationBase,
806 UINT64 Instruction64;
815 UINT8 *InstructionPtr;
818 BOOLEAN IsNormalLocal;
820 BOOLEAN InvalidPcRel;
824 ASSERT (Relocation != NULL);
828 IsNormalLocal = FALSE;
830 Address = Relocation->Address;
831 Length = Relocation->Size;
832 Type = (UINT8)Relocation->Type;
833 PcRelative = (Relocation->PcRelative != 0);
836 InvalidPcRel = FALSE;
837 ScatteredRelocation = NULL;
842 if (Context->Is32Bit) {
846 Address = ScatteredRelocation->Address;
847 Length = ScatteredRelocation->Size;
848 Type = (UINT8)ScatteredRelocation->Type;
849 PcRelative = (ScatteredRelocation->PcRelative != 0);
850 Target = LoadAddress;
859 &Kext->Context.MachContext,
860 (RelocationBase + Address),
863 if ((InstructionPtr == NULL) || (MaxSize < ((
Length != 3) ? 4U : 8U))) {
867 if (Relocation->Extern == 0) {
868 IsNormalLocal = TRUE;
871 LinkPc = (Address + LoadAddress);
874 if (ScatteredRelocation == NULL) {
894 CopyMem (&Instruction32, InstructionPtr,
sizeof (Instruction32));
896 if ( (Vtable != NULL)
902 if (Context->Is32Bit) {
904 Target = Target + Address - (LinkPc + RelocationBase);
909 Instruction32 += (UINT32)Target;
913 DEBUG ((DEBUG_ERROR,
"OCAK: Non-vanilla 32-bit relocations are unsupported\n"));
983 InvalidPcRel = !PcRelative;
984 Adjustment += LinkPc;
993 InvalidPcRel = !PcRelative;
994 Adjustment += (IsNormalLocal ? LoadAddress : LinkPc);
1001 InvalidPcRel = !PcRelative;
1002 Adjustment += LinkPc;
1003 Target = PairTarget;
1010 InvalidPcRel = PcRelative;
1011 Instruction32 = (INT32)(Target - PairTarget);
1034 CopyMem (InstructionPtr, &Instruction32,
sizeof (Instruction32));
1036 CopyMem (&Instruction64, InstructionPtr,
sizeof (Instruction64));
1038 if ( (Vtable != NULL)
1047 InvalidPcRel = PcRelative;
1048 Instruction64 += Target;
1054 InvalidPcRel = PcRelative;
1055 Instruction64 = (Target - PairTarget);
1066 CopyMem (InstructionPtr, &Instruction64,
sizeof (Instruction64));
1070 DEBUG ((DEBUG_WARN,
"OCAK: Relocation has invalid PC relative flag\n"));
1073 if (Context->Is32Bit) {
1080 ReturnValue |= BIT31;
1109 IN UINT64 LoadAddress,
1110 IN UINT64 RelocationBase,
1112 IN OUT UINT32 *NumRelocations,
1116 UINT32 PreservedRelocations;
1119 UINT32 SectionIndex;
1126 ASSERT (NumRelocations != NULL);
1127 ASSERT (SourceRelocations != NULL || *NumRelocations == 0);
1132 if (Context->Is32Bit && (*NumRelocations == 0)) {
1136 if (Section32 == NULL) {
1143 NextRelocation = &Relocation[Index + 1];
1148 NextRelocation = NULL;
1158 RelocationBase + Section32->
Address,
1162 if (Result == MAX_UINTN) {
1177 ASSERT (TargetRelocations != NULL);
1179 PreservedRelocations = 0;
1181 for (Index = 0; Index < *NumRelocations; ++Index) {
1186 if ( (SourceRelocations[Index].Extern == 0)
1196 NextRelocation = &SourceRelocations[Index + 1];
1200 if (Index == (*NumRelocations - 1)) {
1201 NextRelocation = NULL;
1212 &SourceRelocations[Index],
1215 if (Result == MAX_UINTN) {
1222 if ((Result & ~(UINTN)BIT31) != 0) {
1223 Relocation = &TargetRelocations[PreservedRelocations];
1225 CopyMem (Relocation, &SourceRelocations[Index],
sizeof (*Relocation));
1227 if (Relocation->
Extern != 0) {
1241 ++PreservedRelocations;
1248 if ((Result & BIT31) != 0) {
1253 *NumRelocations = PreservedRelocations;
1266 IN UINT64 LoadAddress,
1268 IN OUT UINT32 *KmodInfoOffset
1272 CONST CHAR8 *SymbolName;
1276 KmodOffset = *KmodInfoOffset;
1278 if ((KmodOffset == 0) && (((MachoContext->Is32Bit ? Symbol->Symbol32.Type : Symbol->Symbol64.Type) &
MACH_N_TYPE_STAB) == 0)) {
1280 ASSERT (SymbolName != NULL);
1282 if (AsciiStrCmp (SymbolName,
"_kmod_info") == 0) {
1291 || ((KmodOffset % 4) != 0)))
1296 *KmodInfoOffset = KmodOffset;
1311 IN UINT64 LoadAddress,
1312 IN UINT32 NumSymbols,
1314 OUT UINT32 *KmodInfoOffset
1322 ASSERT (MachoContext != NULL);
1323 ASSERT (Symbols != NULL || NumSymbols == 0);
1324 ASSERT (KmodInfoOffset != NULL);
1329 if (MachoContext->Is32Bit && (NumSymbols == 0)) {
1333 if (Symbol == NULL) {
1357 for (Index = 0; Index < NumSymbols; ++Index) {
1358 if (MachoContext->Is32Bit) {
1387 IN UINT64 LoadAddress
1390 CONST VOID *FileData;
1397 CONST UINT32 *SymIndices;
1398 VOID *IndirectSymPtr;
1409 if (Section == NULL) {
1413 if (MachoContext->Is32Bit) {
1414 NumSymbols = Section->Section32.Size /
sizeof (UINT32);
1415 FirstSym = Section->Section32.Reserved1;
1417 NumSymbols = (UINT32)(Section->Section64.Size / sizeof (UINT64));
1418 FirstSym = Section->Section64.Reserved1;
1421 Result = BaseOverflowAddU32 (FirstSym, NumSymbols, &OffsetTop);
1422 if (Result || (OffsetTop > DySymtab->NumIndirectSymbols)) {
1427 Result = BaseOverflowMulAddU32 (
1428 DySymtab->NumIndirectSymbols,
1429 MachoContext->Is32Bit ? sizeof (UINT32) :
sizeof (UINT64),
1430 DySymtab->IndirectSymbolsOffset,
1433 if (Result || (OffsetTop > MachSize)) {
1438 ASSERT (FileData != NULL);
1449 Tmp = (VOID *)((UINTN)FileData + DySymtab->IndirectSymbolsOffset);
1450 if (!BASE_TYPE_ALIGNED (UINT32, Tmp)) {
1454 SymIndices = (UINT32 *)Tmp + FirstSym;
1456 IndirectSymPtr = (VOID *)((UINTN)FileData + (MachoContext->Is32Bit ? Section->Section32.Offset : Section->Section64.Offset));
1457 if (MachoContext->Is32Bit ? !BASE_TYPE_ALIGNED (UINT32, IndirectSymPtr) : !BASE_TYPE_ALIGNED (UINT64, IndirectSymPtr)) {
1461 for (Index = 0; Index < NumSymbols; ++Index) {
1467 if (MachoContext->Is32Bit) {
1468 ((UINT32 *)IndirectSymPtr)[Index] += (UINT32)LoadAddress;
1470 ((UINT64 *)IndirectSymPtr)[Index] += LoadAddress;
1474 if (Symbol == NULL) {
1478 if (MachoContext->Is32Bit) {
1479 ((UINT32 *)IndirectSymPtr)[Index] += Symbol->Symbol32.Value;
1481 ((UINT64 *)IndirectSymPtr)[Index] += Symbol->Symbol64.Value;
1506 IN UINT64 LoadAddress,
1507 IN UINT64 FileOffset
1512 UINT64 LinkEditFileOffset;
1513 UINT64 LinkEditFileSize;
1531 CONST CHAR8 *SymbolName;
1533 CONST CHAR8 *StringTable;
1536 UINT32 NumIndirectSymbols;
1538 UINT32 NumLocalSymbols;
1540 UINT32 NumExternalSymbols;
1542 UINT32 NumUndefinedSymbols;
1543 UINT64 WeakTestValue;
1545 UINT32 NumRelocations;
1546 UINT32 NumRelocations2;
1552 UINT32 LinkEditSize;
1553 UINT32 SymbolTableOffset;
1554 UINT32 SymbolTableSize;
1555 UINT32 RelocationsOffset;
1556 UINT32 RelocationsSize;
1557 UINT32 StringTableOffset;
1558 UINT32 StringTableSize;
1560 UINT32 NumSymtabLinkEdit32Symbols;
1562 UINT32 SegmentOffset;
1564 UINT64 LoadAddressOffset;
1566 UINT64 SegmentVmSizes;
1567 UINT32 KmodInfoOffset;
1570 ASSERT (Context != NULL);
1572 ASSERT (LoadAddress != 0);
1580 MachoContext = &Kext->Context.MachContext;
1581 LinkEditSegment = Kext->LinkEditSegment;
1592 FileData = (VOID *)MachHeader;
1605 if ((!IsObject32 && (LinkEditSegment == NULL)) || (Kext->Context.VirtualKmod == 0)) {
1606 return EFI_UNSUPPORTED;
1609 if (BaseOverflowAddU64 (LoadAddress, FileOffset, &LoadAddressOffset)) {
1610 return EFI_INVALID_PARAMETER;
1613 if (Context->Is32Bit) {
1614 ASSERT (LoadAddressOffset < MAX_UINT32);
1627 &NumExternalSymbols,
1629 &NumUndefinedSymbols
1631 if (NumSymbols == 0) {
1632 return EFI_UNSUPPORTED;
1635 Symtab = MachoContext->
Symtab;
1640 ASSERT (DySymtab != NULL);
1675 LinkEdit = Context->LinkBuffer;
1676 LinkEditSize = (SymbolTableSize + RelocationsSize + StringTableSize);
1681 return EFI_UNSUPPORTED;
1686 SymbolTableOffset = 0;
1687 RelocationsOffset = (SymbolTableOffset + SymbolTableSize);
1699 for (Index = 0; Index < NumIndirectSymbols; ++Index) {
1702 if (SymbolName == NULL) {
1703 return EFI_LOAD_ERROR;
1716 return EFI_LOAD_ERROR;
1725 NumSymtabLinkEdit32Symbols = 0;
1727 NumUndefinedSymbols = NumSymbols;
1730 for (Index = 0; Index < NumUndefinedSymbols; ++Index) {
1731 if (Context->Is32Bit) {
1732 Symbol = (
MACH_NLIST_ANY *)(!IsObject32 ? &(&UndefinedSymtab->Symbol32)[Index] : &(&SymbolTable->Symbol32)[Index]);
1753 !IsObject32 ? UndefinedSymtab : NULL,
1754 !IsObject32 ? NumUndefinedSymbols : 0
1759 "OCAK: Symbol %a was unresolved for kext %a\n",
1763 return EFI_LOAD_ERROR;
1767 "OCAK: Symbol %a was resolved for kext %a to %Lx\n",
1780 DEBUG ((DEBUG_INFO,
"OCAK: Vtable patching failed for kext %a\n", Kext->Identifier));
1781 return EFI_LOAD_ERROR;
1798 return EFI_LOAD_ERROR;
1809 if (!Result || (KmodInfoOffset == 0)) {
1810 return EFI_LOAD_ERROR;
1813 KmodInfo = (
KMOD_INFO_ANY *)((UINTN)FileData + (UINTN)KmodInfoOffset);
1816 if (FirstSegment == NULL) {
1817 return EFI_UNSUPPORTED;
1822 return EFI_LOAD_ERROR;
1830 (UINTN)LinkEdit + RelocationsOffset
1845 &TargetRelocation[0]
1848 return EFI_LOAD_ERROR;
1866 &TargetRelocation[NumRelocations]
1869 return EFI_LOAD_ERROR;
1872 NumRelocations += NumRelocations2;
1880 SymtabSize = SymbolTableSize;
1881 if (NumUndefinedSymbols > 0) {
1882 SymtabSize = (UINT32)((UndefinedSymtab - SymbolTable) * (Context->Is32Bit ? sizeof (
MACH_NLIST) :
sizeof (
MACH_NLIST_64)));
1886 (VOID *)((UINTN)LinkEdit + SymbolTableOffset),
1891 if (NumUndefinedSymbols > 0) {
1892 if (Context->Is32Bit) {
1893 SymtabSize2 = (UINT32)(&(&SymbolTable->Symbol32)[NumSymbols] - &(&UndefinedSymtab->Symbol32)[NumUndefinedSymbols]);
1897 (VOID *)((UINTN)LinkEdit + SymbolTableOffset + SymtabSize),
1898 (VOID *)&(&UndefinedSymtab->Symbol32)[NumUndefinedSymbols],
1902 SymtabSize2 = (UINT32)(&(&SymbolTable->Symbol64)[NumSymbols] - &(&UndefinedSymtab->Symbol64)[NumUndefinedSymbols]);
1906 (VOID *)((UINTN)LinkEdit + SymbolTableOffset + SymtabSize),
1907 (VOID *)&(&UndefinedSymtab->Symbol64)[NumUndefinedSymbols],
1912 NumSymbols -= NumUndefinedSymbols;
1919 StringTableOffset = (RelocationsOffset + RelocationsSize);
1921 (VOID *)((UINTN)LinkEdit + StringTableOffset),
1928 if (Context->Is32Bit) {
1936 Symtab->
SymbolsOffset = (UINT32)(LinkEditFileOffset + SymbolTableOffset);
1938 Symtab->
StringsOffset = (UINT32)(LinkEditFileOffset + StringTableOffset);
1943 LinkEditSize = (SymbolTableSize + RelocationsSize + StringTableSize);
1946 (VOID *)((UINTN)FileData + (UINTN)LinkEditFileOffset),
1951 (VOID *)((UINTN)FileData + (UINTN)LinkEditFileOffset + LinkEditSize),
1952 (UINTN)(LinkEditFileSize - LinkEditSize)
1956 if (Context->Is32Bit) {
1981 if (NumUndefinedSymbols > 0) {
1988 NumSymtabLinkEdit32Symbols = 0;
1989 for (Index = 0; Index < NumSymbols; ++Index) {
1999 &SymtabLinkEdit32[NumSymtabLinkEdit32Symbols++],
2005 SymtabSize = (UINT32)(NumSymbols *
sizeof (
MACH_NLIST));
2006 SymtabSize2 = (UINT32)(NumSymtabLinkEdit32Symbols *
sizeof (
MACH_NLIST));
2021 Symtab->
NumSymbols = NumSymtabLinkEdit32Symbols;
2036 if (Context->Is32Bit) {
2049 if (Context->Is32Bit) {
2099 if (Context->Is32Bit) {
2112 KmodInfo->
Kmod32.
HdrSize = IsObject32 ? (UINT32)FileOffset : 0;
2120 MachSize = SegmentOffset + SegmentSize;
2142 MachSize = SegmentOffset + SegmentSize;
2154 return EFI_INVALID_PARAMETER;
#define ARRAY_SIZE(Array)
#define MACH_HEADER_FLAG_DYNAMIC_LINKER_LINK
#define NO_SECT
symbol is not in any section
#define MACH_RELOC_ABSOLUTE
absolute relocation type for Mach-O files
@ MachGenericRelocVanilla
#define MACH_N_TYPE_TYPE
mask for the type bit
#define MACH_HEADER_FLAG_NO_UNDEFINED_REFERENCES
#define MACH_N_TYPE_UNDF
undefined, n_sect == NO_SECT
#define MACH_N_TYPE_INDR
indirect
@ MachX8664RelocUnsigned
for absolute addresses
@ MachX8664RelocGotLoad
a MOVQ load of a GOT entry
@ MachX8664RelocSigned
for signed 32-bit displacement
@ MachX8664RelocSubtractor
@ MachX8664RelocGot
other GOT references
#define MACH_N_TYPE_SECT
defined in section number n_sect
@ MachHeaderFileTypeObject
#define MACH_N_TYPE_ABS
absolute, n_sect == NO_SECT
#define MACH_INDIRECT_SYMBOL_LOCAL
#define MAX_SECT
1 thru 255 inclusive
#define MACH_INDIRECT_SYMBOL_ABS
STATIC BOOLEAN InternalRelocateAndCopyRelocations(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN UINT64 LoadAddress, IN UINT64 RelocationBase, IN CONST MACH_RELOCATION_INFO *SourceRelocations, IN OUT UINT32 *NumRelocations, OUT MACH_RELOCATION_INFO *TargetRelocations)
EFI_STATUS InternalPrelinkKext(IN OUT PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN UINT64 LoadAddress, IN UINT64 FileOffset)
STATIC BOOLEAN InternalCalculateTargets(IN PRELINKED_CONTEXT *Context, IN OUT PRELINKED_KEXT *Kext, IN UINT64 LoadAddress, IN CONST MACH_RELOCATION_INFO *Relocation, IN CONST MACH_RELOCATION_INFO *NextRelocation OPTIONAL, OUT UINT64 *Target, OUT UINT64 *PairTarget, OUT CONST PRELINKED_VTABLE **Vtable OPTIONAL)
CONST PRELINKED_KEXT_SYMBOL * InternalOcGetSymbolName(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN CONST CHAR8 *LookupValue, IN OC_GET_SYMBOL_LEVEL SymbolLevel)
STATIC BOOLEAN InternalRelocateSymbols(IN OC_MACHO_CONTEXT *MachoContext, IN UINT64 LoadAddress, IN UINT32 NumSymbols, IN OUT MACH_NLIST_ANY *Symbols, OUT UINT32 *KmodInfoOffset)
STATIC BOOLEAN InternalSolveSymbol(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN CONST CHAR8 *Name, IN OUT MACH_NLIST_ANY *Symbol, IN OUT UINT64 *WeakTestValue, IN CONST MACH_NLIST_ANY *UndefinedSymbols, IN UINT32 NumUndefinedSymbols)
STATIC BOOLEAN InternalRelocateSymbol(IN OC_MACHO_CONTEXT *MachoContext, IN UINT64 LoadAddress, IN OUT MACH_NLIST_ANY *Symbol, IN OUT UINT32 *KmodInfoOffset)
STATIC CONST PRELINKED_KEXT_SYMBOL * InternalOcGetSymbolWorkerValue(IN PRELINKED_KEXT *Kext, IN UINT64 LookupValue, IN OC_GET_SYMBOL_LEVEL SymbolLevel)
CONST PRELINKED_KEXT_SYMBOL * InternalOcGetSymbolValue(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN UINT64 LookupValue, IN OC_GET_SYMBOL_LEVEL SymbolLevel)
STATIC UINTN InternalRelocateRelocation(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN UINT64 LoadAddress, IN UINT64 RelocationBase, IN CONST MACH_RELOCATION_INFO *Relocation, IN CONST MACH_RELOCATION_INFO *NextRelocation OPTIONAL)
STATIC BOOLEAN InternalProcessSymbolPointers(IN OC_MACHO_CONTEXT *MachoContext, IN CONST MACH_DYSYMTAB_COMMAND *DySymtab, IN UINT64 LoadAddress)
STATIC BOOLEAN InternalIsDirectPureVirtualCall(IN BOOLEAN Is32Bit, IN CONST PRELINKED_VTABLE *Vtable, IN UINT64 Offset)
STATIC CONST PRELINKED_KEXT_SYMBOL * InternalOcGetSymbolWorkerName(IN PRELINKED_KEXT *Kext, IN CONST CHAR8 *LookupValue, IN UINT32 LookupValueLength, IN OC_GET_SYMBOL_LEVEL SymbolLevel)
STATIC BOOLEAN InternalCalculateDisplacementIntel64(IN UINT64 Target, IN UINT64 Adjustment, IN OUT INT32 *Instruction)
VOID InternalSolveSymbolValue(IN BOOLEAN Is32Bit, IN UINT64 Value, OUT MACH_NLIST_ANY *Symbol)
STATIC BOOLEAN InternalSolveSymbolNonWeak(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN CONST CHAR8 *Name, IN OUT MACH_NLIST_ANY *Symbol)
UINT32 MachoGetInnerSize(IN OUT OC_MACHO_CONTEXT *Context)
BOOLEAN MachoRelocateSymbol(IN OUT OC_MACHO_CONTEXT *Context, IN UINT64 LinkAddress, IN OUT MACH_NLIST_ANY *Symbol)
UINT32 MachoGetFileSize(IN OUT OC_MACHO_CONTEXT *Context)
CONST CHAR8 * MachoGetIndirectSymbolName(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_NLIST_ANY *Symbol)
VOID * MachoGetFileData(IN OUT OC_MACHO_CONTEXT *Context)
VOID * MachoGetFilePointerByAddress(IN OUT OC_MACHO_CONTEXT *Context, IN UINT64 Address, OUT UINT32 *MaxSize OPTIONAL)
MACH_SEGMENT_COMMAND_ANY * MachoGetNextSegment(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_SEGMENT_COMMAND_ANY *Segment OPTIONAL)
MACH_HEADER_ANY * MachoGetMachHeader(IN OUT OC_MACHO_CONTEXT *Context)
BOOLEAN MachoInitializeContext(OUT OC_MACHO_CONTEXT *Context, IN VOID *FileData, IN UINT32 FileSize, IN UINT32 HeaderOffset, IN UINT32 InnerSize, IN BOOLEAN Is32Bit)
UINT32 MachoGetSymbolTable(IN OUT OC_MACHO_CONTEXT *Context, OUT CONST MACH_NLIST_ANY **SymbolTable, OUT CONST CHAR8 **StringTable OPTIONAL, OUT CONST MACH_NLIST_ANY **LocalSymbols OPTIONAL, OUT UINT32 *NumLocalSymbols OPTIONAL, OUT CONST MACH_NLIST_ANY **ExternalSymbols OPTIONAL, OUT UINT32 *NumExternalSymbols OPTIONAL, OUT CONST MACH_NLIST_ANY **UndefinedSymbols OPTIONAL, OUT UINT32 *NumUndefinedSymbols OPTIONAL)
BOOLEAN MachoRelocationIsPairIntel64(IN UINT8 Type)
MACH_NLIST_ANY * MachoGetSymbolByIndex(IN OUT OC_MACHO_CONTEXT *Context, IN UINT32 Index)
BOOLEAN MachoPreserveRelocationIntel64(IN UINT8 Type)
BOOLEAN MachoRelocationIsPairIntel32(IN UINT8 Type)
CONST CHAR8 * MachoGetSymbolName(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_NLIST_ANY *Symbol)
MACH_SECTION_ANY * MachoGetNextSection(IN OUT OC_MACHO_CONTEXT *Context, IN MACH_SEGMENT_COMMAND_ANY *Segment, IN MACH_SECTION_ANY *Section OPTIONAL)
UINT32 MachoGetIndirectSymbolTable(IN OUT OC_MACHO_CONTEXT *Context, OUT CONST MACH_NLIST_ANY **SymbolTable)
BOOLEAN MachoSymbolNameIsVtable(IN CONST CHAR8 *SymbolName)
MACH_SECTION * MachoGetSectionByIndex32(IN OUT OC_MACHO_CONTEXT *Context, IN UINT32 Index)
BOOLEAN MachoSymbolNameIsPureVirtual(IN CONST CHAR8 *Name)
MACH_SECTION_ANY * MachoGetSectionByIndex(IN OUT OC_MACHO_CONTEXT *Context, IN UINT32 Index)
MACH_SECTION_ANY * MachoGetSegmentSectionByName(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SegmentName, IN CONST CHAR8 *SectionName)
BOOLEAN MachoSymbolGetFileOffset(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_NLIST_ANY *Symbol, OUT UINT32 *FileOffset, OUT UINT32 *MaxSize OPTIONAL)
CONST PRELINKED_VTABLE * InternalGetOcVtableByName(IN PRELINKED_CONTEXT *Context, IN PRELINKED_KEXT *Kext, IN CONST CHAR8 *Name)
#define X86_64_RIP_RELATIVE_LIMIT
#define VTABLE_ENTRY_SIZE_X(a)
BOOLEAN InternalPatchByVtables(IN PRELINKED_CONTEXT *Context, IN OUT PRELINKED_KEXT *Kext)
#define KXLD_WEAK_TEST_SYMBOL
VOID InternalUnlockContextKexts(IN PRELINKED_CONTEXT *Context)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
#define DivU64x32(x, y, z)
UINT32 NumExternalRelocations
UINT32 NumExternalSymbols
number of externally defined symbols
UINT32 NumIndirectSymbols
UINT32 UndefinedSymbolsIndex
index to undefined symbols
UINT32 NumLocalSymbols
number of local symbols
UINT32 NumOfLocalRelocations
number of local relocation entries
UINT32 IndirectSymbolsOffset
MACH_LOAD_COMMAND_HDR_ UINT32 LocalSymbolsIndex
index to local symbols
UINT32 ExternalRelocationsOffset
UINT32 NumUndefinedSymbols
number of undefined symbols
UINT32 LocalRelocationsOffset
offset to local relocation entries
UINT32 ExternalSymbolsIndex
index to externally defined symbols
MACH_HEADER_FLAGS Flags
flags
MACH_HEADER_FLAGS Flags
flags
MACH_HEADER_FILE_TYPE FileType
type of file
UINT64 Value
value of this symbol (or stab offset)
UINT8 Section
section number or NO_SECT
UINT8 Type
type flag, see below
UINT32 Value
value of this symbol (or stab offset)
UINT32 Extern
does not include value of sym referenced
UINT32 Alignment
section alignment (power of 2)
UINT64 Address
memory address of this section
UINT32 Alignment
section alignment (power of 2)
UINT32 Address
memory address of this section
UINT32 NumRelocations
number of relocation entries
UINT32 RelocationsOffset
file offset of relocation entries
MACH_VM_PROTECTION InitialProtection
initial VM protection
UINT64 FileOffset
file offset of this segment
MACH_LOAD_COMMAND_HDR_ CHAR8 SegmentName[16]
segment Name
UINT64 Size
memory size of this segment
UINT64 FileSize
amount to map from the file
UINT64 VirtualAddress
memory address of this segment
MACH_VM_PROTECTION MaximumProtection
maximum VM protection
UINT32 FileOffset
file offset of this segment
UINT32 Size
memory size of this segment
MACH_VM_PROTECTION InitialProtection
initial VM protection
UINT32 VirtualAddress
memory address of this segment
MACH_VM_PROTECTION MaximumProtection
maximum VM protection
UINT32 FileSize
amount to map from the file
MACH_LOAD_COMMAND_HDR_ CHAR8 SegmentName[16]
segment Name
UINT32 StringsSize
string table size in bytes
MACH_LOAD_COMMAND_HDR_ UINT32 SymbolsOffset
symbol table offset
UINT32 NumSymbols
number of symbol table entries
UINT32 StringsOffset
string table offset
MACH_RELOCATION_INFO * ExternRelocations
MACH_DYSYMTAB_COMMAND * DySymtab
MACH_RELOCATION_INFO * LocalRelocations
MACH_SYMTAB_COMMAND * Symtab
PRELINKED_KEXT * Dependencies[MAX_KEXT_DEPEDENCIES]
MACH_SECTION_64 Section64
MACH_SEGMENT_COMMAND_64 Segment64
MACH_SEGMENT_COMMAND Segment32