16#include <Library/DebugLib.h>
17#include <Library/MemoryAllocationLib.h>
28#define OC_USER_FULL_PATH_MAX_SIZE 256
36 IN CONST CHAR8 *RootPath
41 RootPathLen = AsciiStrLen (RootPath);
46 DEBUG ((DEBUG_ERROR,
"RootPath is too long!\n"));
62 DEBUG ((DEBUG_ERROR,
"Root Path: %a\n",
mFullPath));
69 IN CONST CHAR8 *FileName,
74 DEBUG ((DEBUG_ERROR,
"Full path: %a\n",
mFullPath));
98 while ((Needle = AsciiStrStr (Needle,
"\\")) != NULL) {
106 IN OC_KERNEL_ADD_ENTRY *Kext,
108 IN OC_GLOBAL_CONFIG *Config,
110 IN OUT UINT32 *ReservedExeSize,
111 IN OUT UINT32 *ReservedInfoSize,
112 IN OUT UINT32 *NumReservedKexts
120 CHAR8 *ExecutablePath;
123 if (!Kext->Enabled) {
131 if ((BundlePath[0] ==
'\0') || (PlistPath[0] ==
'\0')) {
134 "OC: Injected kext %u (%a) has invalid info\n",
138 Kext->Enabled = FALSE;
139 return EFI_INVALID_PARAMETER;
142 if (AsciiStrCmp (Arch, Is32Bit ?
"x86_64" :
"i386") == 0) {
145 "OC: Injected kext %a (%a) at %u skipped due to arch %a != %a\n",
150 Is32Bit ?
"i386" :
"x86_64"
171 if (EFI_ERROR (Status)) {
174 "OC: Failed to fit injected kext path %s%a\\%a",
179 Kext->Enabled = FALSE;
189 if (Kext->PlistData == NULL) {
192 "OC: Plist injected is missing for %s kext %a (%a)\n",
197 Kext->Enabled = FALSE;
198 return EFI_UNSUPPORTED;
204 ExecutablePath =
OC_BLOB_GET (&Kext->ExecutablePath);
205 if (ExecutablePath[0] !=
'\0') {
214 if (EFI_ERROR (Status)) {
217 "OC: Failed to fit injected kext path %s%a\\%a",
222 Kext->Enabled = FALSE;
223 FreePool (Kext->PlistData);
224 Kext->PlistData = NULL;
234 if (Kext->ImageData == NULL) {
237 "OC: Image injected is missing for %a kext %a (%a)\n",
242 Kext->Enabled = FALSE;
243 FreePool (Kext->PlistData);
244 Kext->PlistData = NULL;
245 return EFI_UNSUPPORTED;
257 if (EFI_ERROR (Status)) {
260 "OC: Failed to fit %s kext %a (%a) - %r\n",
261 Is32Bit ? L
"32-bit" : L
"64-bit",
266 if (Kext->ImageData != NULL) {
267 FreePool (Kext->ImageData);
268 Kext->ImageData = NULL;
271 FreePool (Kext->PlistData);
272 Kext->PlistData = NULL;
276 (*NumReservedKexts)++;
283 IN EFI_FILE_PROTOCOL *File,
292 return EFI_INVALID_PARAMETER;
301 IN EFI_FILE_PROTOCOL *File,
317 UINT8 *ConfigFileBuffer;
318 UINT32 ConfigFileSize;
319 OC_GLOBAL_CONFIG Config;
324 EFI_STATUS PrelinkedStatus;
326 CONST CHAR8 *FileName;
329 UINT32 ReservedInfoSize;
330 UINT32 ReservedExeSize;
331 UINT32 NumReservedKexts;
332 UINT32 LinkedExpansion;
334 UINT32 NewPrelinkedSize;
340 OC_KERNEL_ADD_ENTRY *Kext;
343 DEBUG ((DEBUG_ERROR,
"Usage: %a <path/to/OC/folder/> [path/to/kernel]\n\n", argv[0]));
347 FileName = argc > 2 ? argv[2] :
"/System/Library/PrelinkedKernels/prelinkedkernel";
349 DEBUG ((DEBUG_ERROR,
"Read fail %a\n", FileName));
360 CHAR8 AsciiOcConfig[16];
364 if (ConfigFileBuffer == NULL) {
374 if (EFI_ERROR (Status)) {
375 DEBUG ((DEBUG_ERROR,
"Invalid config\n"));
379 if (ErrorCount > 0) {
380 DEBUG ((DEBUG_ERROR,
"Serialisation returns %u %a!\n", ErrorCount, ErrorCount > 1 ?
"errors" :
"error"));
383 PcdGet32 (PcdFixedDebugPrintErrorLevel) |= DEBUG_INFO;
384 PcdGet32 (PcdDebugPrintErrorLevel) |= DEBUG_INFO;
385 PcdGet8 (PcdDebugPropertyMask) |= DEBUG_PROPERTY_DEBUG_CODE_ENABLED;
390 NumReservedKexts = 0;
394 for (Index = 0; Index < Config.Kernel.Add.Count; ++Index) {
395 Kext = Config.Kernel.Add.Values[Index];
406 if (EFI_ERROR (Status)) {
407 DEBUG ((DEBUG_WARN,
"[FAIL] Kernel load and reserve - %r\n", Status));
414 if (LinkedExpansion == 0) {
426 ReservedInfoSize + ReservedExeSize + LinkedExpansion,
429 if (!EFI_ERROR (Status)) {
435 DEBUG ((DEBUG_WARN,
"[FAIL] Kernel unpack failure - %r\n", Status));
442 DEBUG ((DEBUG_WARN,
"[OK] Got version %u\n",
KernelVersion));
444 DEBUG ((DEBUG_WARN,
"[FAIL] Failed to detect version\n"));
448 ZeroMem (&DummyCpuInfo,
sizeof (DummyCpuInfo));
452 Config.Kernel.Quirks.ProvideCurrentCpuInfo = FALSE;
453 ASSERT (Config.Kernel.Quirks.ProvideCurrentCpuInfo == FALSE);
455 ZeroMem (Config.Kernel.Emulate.Cpuid1Data, sizeof (Config.Kernel.Emulate.Cpuid1Data));
456 Config.Kernel.Emulate.Cpuid1Data[0] = 0x000306A9;
457 ZeroMem (Config.Kernel.Emulate.Cpuid1Mask, sizeof (Config.Kernel.Emulate.Cpuid1Mask));
458 Config.Kernel.Emulate.Cpuid1Mask[0] = 0xFFFFFFFF;
460 ASSERT (Config.Kernel.Force.Count == 0);
485 if (EFI_ERROR (PrelinkedStatus)) {
486 DEBUG ((DEBUG_WARN,
"[FAIL] Kernel process - %r\n", PrelinkedStatus));
491 DEBUG ((DEBUG_INFO,
"OC: Prelinked status - %r\n", PrelinkedStatus));
DMG_SIZE_DEVICE_PATH Size
EFI_STATUS ReadAppleKernel(IN EFI_FILE_PROTOCOL *File, IN BOOLEAN Prefer32Bit, OUT BOOLEAN *Is32Bit, OUT UINT8 **Kernel, OUT UINT32 *KernelSize, OUT UINT32 *AllocatedSize, IN UINT32 ReservedSize, OUT UINT8 *Digest OPTIONAL)
#define PRELINK_INFO_RESERVE_SIZE
EFI_STATUS PrelinkedReserveKextSize(IN OUT UINT32 *ReservedInfoSize, IN OUT UINT32 *ReservedExeSize, IN UINT32 InfoPlistSize, IN UINT8 *Executable OPTIONAL, IN UINT32 ExecutableSize OPTIONAL, IN BOOLEAN Is32Bit)
UINT32 OcKernelReadDarwinVersion(IN CONST UINT8 *Kernel, IN UINT32 KernelSize)
UINT32 KcGetSegmentFixupChainsSize(IN UINT32 SegmentSize)
EFI_STATUS OcConfigurationInit(OUT OC_GLOBAL_CONFIG *Config, IN VOID *Buffer, IN UINT32 Size, IN OUT UINT32 *ErrorCount OPTIONAL)
VOID Sha384(UINT8 *Hash, CONST UINT8 *Data, UINTN Len)
VOID OcKernelApplyPatches(IN OC_GLOBAL_CONFIG *Config, IN OC_CPU_INFO *CpuInfo, IN UINT32 DarwinVersion, IN BOOLEAN Is32Bit, IN KERNEL_CACHE_TYPE CacheType, IN VOID *Context, IN OUT UINT8 *Kernel, IN UINT32 Size)
#define OPEN_CORE_CONFIG_PATH
EFI_STATUS OcKernelProcessPrelinked(IN OC_GLOBAL_CONFIG *Config, IN UINT32 DarwinVersion, IN BOOLEAN Is32Bit, IN OUT UINT8 *Kernel, IN UINT32 *KernelSize, IN UINT32 AllocatedSize, IN UINT32 LinkedExpansion, IN UINT32 ReservedExeSize)
#define OPEN_CORE_KEXT_PATH
#define OC_STORAGE_SAFE_PATH_MAX
EFI_STATUS EFIAPI OcAsciiSafeSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
#define L_STR_SIZE(String)
#define OC_BLOB_GET(Blob)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
STATIC BOOLEAN mUse32BitKernel
STATIC VOID AsciiHostSlashes(IN OUT CHAR8 *String)
#define OC_USER_FULL_PATH_MAX_SIZE
STATIC UINTN mRootPathLen
STATIC EFI_STATUS UserOcKernelLoadAndReserveKext(IN OC_KERNEL_ADD_ENTRY *Kext, IN UINT32 Index, IN OC_GLOBAL_CONFIG *Config, IN BOOLEAN Is32Bit, IN OUT UINT32 *ReservedExeSize, IN OUT UINT32 *ReservedInfoSize, IN OUT UINT32 *NumReservedKexts)
EFI_STATUS OcGetFileSize(IN EFI_FILE_PROTOCOL *File, OUT UINT32 *Size)
STATIC CHAR8 mFullPath[OC_USER_FULL_PATH_MAX_SIZE]
STATIC UINT32 KernelVersion
STATIC EFI_FILE_PROTOCOL NilFileProtocol
STATIC UINT32 mPrelinkedSize
int WrapMain(int argc, char *argv[])
STATIC UINT8 * mPrelinked
STATIC UINT8 * UserReadFileFromRoot(IN CONST CHAR8 *FileName, OUT UINT32 *Size)
EFI_STATUS OcGetFileData(IN EFI_FILE_PROTOCOL *File, IN UINT32 Position, IN UINT32 Size, OUT UINT8 *Buffer)
STATIC BOOLEAN UserSetRootPath(IN CONST CHAR8 *RootPath)
STATIC BOOLEAN FailedToProcess
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT8 * UserReadFile(IN CONST CHAR8 *FileName, OUT UINT32 *Size)
VOID UserWriteFile(IN CONST CHAR8 *FileName, IN CONST VOID *Data, IN UINT32 Size)