mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcAppleKernelLib: Fix patching KC vtables with imports from kexts
This commit is contained in:
parent
9e166de9ac
commit
d8ace47606
@ -1805,7 +1805,7 @@ typedef struct {
|
||||
Key : 2,
|
||||
Next : 12, ///< 1 or 4-byte stide
|
||||
IsAuth : 1; ///< 0 -> not authenticated. 1 -> authenticated
|
||||
} MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE;
|
||||
} MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE;
|
||||
|
||||
// header of the LC_DYLD_CHAINED_FIXUPS payload
|
||||
typedef struct {
|
||||
|
||||
@ -444,11 +444,11 @@ InternalKcConvertRelocToFixup (
|
||||
|
||||
UINT16 NewFixupPage;
|
||||
UINT16 NewFixupPageOffset;
|
||||
MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE NewFixup;
|
||||
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE NewFixup;
|
||||
|
||||
UINT16 IterFixupPageOffset;
|
||||
VOID *IterFixupData;
|
||||
MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE IterFixup;
|
||||
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE IterFixup;
|
||||
UINT16 NextIterFixupPageOffset;
|
||||
|
||||
UINT16 FixupDelta;
|
||||
@ -488,7 +488,7 @@ InternalKcConvertRelocToFixup (
|
||||
// This 1MB here is a bit of a hack. I think it is just the same thing
|
||||
// as KERNEL_BASE_PADDR in OcAfterBootCompatLib.
|
||||
//
|
||||
NewFixup.Target = ReadUnaligned64 (RelocDest) - BASE_1MB;
|
||||
NewFixup.Target = ReadUnaligned64 (RelocDest) - KERNEL_FIXUP_OFFSET;
|
||||
|
||||
NewFixupPage = (UINT16) (RelocOffsetInSeg / MACHO_PAGE_SIZE);
|
||||
NewFixupPageOffset = (UINT16) (RelocOffsetInSeg % MACHO_PAGE_SIZE);
|
||||
|
||||
@ -1405,10 +1405,11 @@ InternalPrelinkKext64 (
|
||||
//
|
||||
// Undefined symbols are solved via their name.
|
||||
//
|
||||
SymbolName = MachoGetSymbolName64 (MachoContext, Symbol);
|
||||
Result = InternalSolveSymbol64 (
|
||||
Context,
|
||||
Kext,
|
||||
MachoGetSymbolName64 (MachoContext, Symbol),
|
||||
SymbolName,
|
||||
Symbol,
|
||||
&WeakTestValue,
|
||||
UndefinedSymtab,
|
||||
|
||||
@ -257,6 +257,10 @@ InternalConnectExternalSymtab (
|
||||
#define VTABLE_HEADER_LEN_64 2U
|
||||
#define VTABLE_HEADER_SIZE_64 (VTABLE_HEADER_LEN_64 * VTABLE_ENTRY_SIZE_64)
|
||||
|
||||
#define KERNEL_ADDRESS_MASK 0xFFFFFFFF00000000ULL
|
||||
#define KERNEL_ADDRESS_BASE 0xFFFFFF8000000000ULL
|
||||
#define KERNEL_FIXUP_OFFSET BASE_1MB
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Major : 14;
|
||||
|
||||
@ -96,10 +96,11 @@ InternalConstructVtablePrelinked64 (
|
||||
OUT PRELINKED_VTABLE *Vtable
|
||||
)
|
||||
{
|
||||
CONST UINT64 *VtableData;
|
||||
UINT64 Value;
|
||||
UINT32 Index;
|
||||
CONST PRELINKED_KEXT_SYMBOL *Symbol;
|
||||
CONST UINT64 *VtableData;
|
||||
UINT64 Value;
|
||||
UINT32 Index;
|
||||
CONST PRELINKED_KEXT_SYMBOL *Symbol;
|
||||
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE *Rebase;
|
||||
|
||||
ASSERT (Kext != NULL);
|
||||
ASSERT (VtableLookup != NULL);
|
||||
@ -123,6 +124,32 @@ InternalConstructVtablePrelinked64 (
|
||||
(Value = VtableData[Index + VTABLE_HEADER_LEN_64]) != 0;
|
||||
++Index
|
||||
) {
|
||||
|
||||
//
|
||||
// For all non-kernel (which uses own relocation) virtual tables
|
||||
// all virtual tables will contain fixups exclusively.
|
||||
// For now we will just detect them by the kernel address
|
||||
// as it is faster than compare Kext->Identifier and Context->IsKernelCollection.
|
||||
//
|
||||
if ((Value & KERNEL_ADDRESS_MASK) != KERNEL_ADDRESS_BASE) {
|
||||
//
|
||||
// FIXME: This needs a bit more love with aliasing and alignment.
|
||||
// Some day, when Intel rewrites EDK II.
|
||||
//
|
||||
Rebase = (MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE *)(UINTN) &Value;
|
||||
DEBUG_CODE_BEGIN ();
|
||||
if (Rebase->CacheLevel != 0
|
||||
|| Rebase->Diversity != 0
|
||||
|| Rebase->AddrDiv != 0
|
||||
|| Rebase->Key != 0
|
||||
|| Rebase->IsAuth != 0) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Invalid fixup %Lx in %a for %a\n", Value, Vtable->Name, Kext->Identifier));
|
||||
}
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
Value = Rebase->Target + KERNEL_FIXUP_OFFSET + KERNEL_ADDRESS_BASE;
|
||||
}
|
||||
|
||||
//
|
||||
// If we can't find the symbol, it means that the virtual function was
|
||||
// defined inline. There's not much I can do about this; it just means
|
||||
@ -205,6 +232,7 @@ InternalPrepareCreateVtablesPrelinked64 (
|
||||
// __ZTV20IOACPIPlatformDevice
|
||||
//
|
||||
if (Symbol->Value == 0) {
|
||||
DEBUG ((DEBUG_VERBOSE, "OCAK: Skipping %a with NULL value\n", Symbol->Name));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -446,6 +446,10 @@ GetFileSize (
|
||||
}
|
||||
|
||||
int wrap_main(int argc, char** argv) {
|
||||
PcdGet32 (PcdFixedDebugPrintErrorLevel) |= DEBUG_INFO;
|
||||
PcdGet32 (PcdDebugPrintErrorLevel) |= DEBUG_INFO;
|
||||
|
||||
|
||||
UINT32 AllocSize;
|
||||
PRELINKED_CONTEXT Context;
|
||||
const char *name = argc > 1 ? argv[1] : "/System/Library/PrelinkedKernels/prelinkedkernel";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user