205 UINT32 NumCxxSymbols;
208 ASSERT (Kext->Context.KxldState != NULL);
209 ASSERT (Kext->Context.KxldStateSize > 0);
211 if (Kext->LinkedSymbolTable != NULL) {
216 Kext->Context.KxldState,
217 Kext->Context.KxldStateSize,
222 if (KxldSymbols == NULL) {
223 return EFI_UNSUPPORTED;
226 SymbolTable = AllocatePool (NumSymbols *
sizeof (*SymbolTable));
227 if (SymbolTable == NULL) {
228 return EFI_OUT_OF_RESOURCES;
231 WalkerBottom = &SymbolTable[0];
232 WalkerTop = &SymbolTable[NumSymbols - 1];
238 "OCAK: Processing %a-bit %a KXLD state with %u symbols\n",
239 Context->Is32Bit ?
"32" :
"64",
244 for (Index = 0; Index < NumSymbols; ++Index) {
246 Kext->Context.KxldState,
247 Kext->Context.KxldStateSize,
248 Context->Is32Bit ? KxldSymbols->Kxld32.NameOffset : KxldSymbols->Kxld64.NameOffset
251 return EFI_INVALID_PARAMETER;
256 KxldAddress = Context->Is32Bit ? KxldSymbols->Kxld32.Address : KxldSymbols->Kxld64.Address;
260 "OCAK: Adding %a-bit symbol %a with %Lx value (flags %u)\n",
261 Context->Is32Bit ?
"32" :
"64",
264 Context->Is32Bit ? KxldSymbols->Kxld32.Flags : KxldSymbols->Kxld64.Flags
268 WalkerBottom->
Value = KxldAddress;
269 WalkerBottom->
Name = Name;
270 WalkerBottom->
Length = (UINT32)AsciiStrLen (WalkerBottom->
Name);
273 WalkerTop->
Value = KxldAddress;
274 WalkerTop->
Name = Name;
275 WalkerTop->
Length = (UINT32)AsciiStrLen (WalkerTop->
Name);
284 Kext->NumberOfSymbols = NumSymbols;
285 Kext->NumberOfCxxSymbols = NumCxxSymbols;
286 Kext->LinkedSymbolTable = SymbolTable;
305 UINT32 ResultingSize;
307 ASSERT (Kext->Context.KxldState != NULL);
308 ASSERT (Kext->Context.KxldStateSize > 0);
310 if (Kext->LinkedVtables != NULL) {
315 Kext->Context.KxldState,
316 Kext->Context.KxldStateSize,
324 if (KxldVtables == NULL) {
325 Kext->LinkedVtables = NULL;
326 Kext->NumberOfVtables = 0;
332 for (Index = 0; Index < NumVtables; ++Index) {
333 if (BaseOverflowAddU32 (NumEntries, KxldVtables[Index].NumEntries, &NumEntries)) {
334 return EFI_OUT_OF_RESOURCES;
338 if ( BaseOverflowMulU32 (NumVtables,
sizeof (*LinkedVtables), &ResultingSize)
339 || BaseOverflowMulAddU32 (NumEntries,
sizeof (*LinkedVtables->
Entries), ResultingSize, &ResultingSize))
341 return EFI_OUT_OF_RESOURCES;
344 LinkedVtables = AllocatePool (ResultingSize);
345 if (LinkedVtables == NULL) {
346 return EFI_OUT_OF_RESOURCES;
349 CurrentVtable = LinkedVtables;
350 for (Index = 0; Index < NumVtables; ++Index) {
352 Kext->Context.KxldState,
353 Kext->Context.KxldStateSize,
354 KxldVtables[Index].NameOffset
356 if (CurrentVtable->
Name == NULL) {
357 FreePool (LinkedVtables);
358 return EFI_INVALID_PARAMETER;
361 KxldSymbols = (
KXLD_SYM_ENTRY_ANY *)((UINT8 *)Kext->Context.KxldState + KxldVtables[Index].EntryOffset);
362 CurrentVtable->
NumEntries = KxldVtables[Index].NumEntries;
366 "OCAK: Adding vtable %a (%u/%u) for %a of %u entries\n",
374 for (Index2 = 0; Index2 < CurrentVtable->
NumEntries; ++Index2) {
375 CurrentVtable->
Entries[Index2].
Address = Context->Is32Bit ? KxldSymbols->Kxld32.Address : KxldSymbols->Kxld64.Address;
377 Kext->Context.KxldState,
378 Kext->Context.KxldStateSize,
379 Context->Is32Bit ? KxldSymbols->Kxld32.NameOffset : KxldSymbols->Kxld64.NameOffset
382 FreePool (LinkedVtables);
383 return EFI_INVALID_PARAMETER;
392 Kext->LinkedVtables = LinkedVtables;
393 Kext->NumberOfVtables = NumVtables;
410 CONST CHAR8 *KextPlistKey;
411 CHAR8 *ScratchWalker;
417 Context->KextScratchBuffer = ScratchWalker = AllocatePool (KextCount *
KEXT_OFFSET_STR_LEN);
418 if (Context->KextScratchBuffer == NULL) {
419 return EFI_OUT_OF_RESOURCES;
422 for (Index = 0; Index < KextCount; ++Index) {
425 if (KextPlist == NULL) {
430 for (FieldIndex = 0; FieldIndex < FieldCount; ++FieldIndex) {
432 if (KextPlistKey == NULL) {
438 return EFI_INVALID_PARAMETER;
441 DEBUG ((DEBUG_VERBOSE,
"OCAK: Shifting 0x%Lx to 0x%Lx\n", KxldState, KxldState + Delta));
446 return EFI_INVALID_PARAMETER;
450 ScratchWalker += AsciiStrSize (ScratchWalker);
475 AlignedSize =
MACHO_ALIGN (Context->PrelinkedStateKernelSize);
476 if ( BaseOverflowAddU32 (Context->PrelinkedSize, AlignedSize, &NewSize)
477 || (NewSize > Context->PrelinkedAllocSize))
479 return EFI_BUFFER_TOO_SMALL;
482 if (Context->Is32Bit) {
483 Context->PrelinkedStateSegment->Segment32.VirtualAddress = (UINT32)Context->PrelinkedLastAddress;
484 Context->PrelinkedStateSegment->Segment32.Size = AlignedSize;
485 Context->PrelinkedStateSegment->Segment32.FileOffset = Context->PrelinkedSize;
486 Context->PrelinkedStateSegment->Segment32.FileSize = AlignedSize;
487 Context->PrelinkedStateSectionKernel->Section32.Address = (UINT32)Context->PrelinkedLastAddress;
488 Context->PrelinkedStateSectionKernel->Section32.Offset = Context->PrelinkedSize;
489 Context->PrelinkedStateSectionKernel->Section32.Size = Context->PrelinkedStateKernelSize;
491 Context->PrelinkedStateSegment->Segment64.VirtualAddress = Context->PrelinkedLastAddress;
492 Context->PrelinkedStateSegment->Segment64.Size = AlignedSize;
493 Context->PrelinkedStateSegment->Segment64.FileOffset = Context->PrelinkedSize;
494 Context->PrelinkedStateSegment->Segment64.FileSize = AlignedSize;
495 Context->PrelinkedStateSectionKernel->Section64.Address = Context->PrelinkedLastAddress;
496 Context->PrelinkedStateSectionKernel->Section64.Offset = Context->PrelinkedSize;
497 Context->PrelinkedStateSectionKernel->Section64.Size = Context->PrelinkedStateKernelSize;
501 &Context->Prelinked[Context->PrelinkedSize],
502 Context->PrelinkedStateKernel,
503 Context->PrelinkedStateKernelSize
506 &Context->Prelinked[Context->PrelinkedSize + Context->PrelinkedStateKernelSize],
507 AlignedSize - Context->PrelinkedStateKernelSize
510 Context->PrelinkedLastAddress += AlignedSize;
511 Context->PrelinkedSize += AlignedSize;
513 AlignedSize =
MACHO_ALIGN (Context->PrelinkedStateKextsSize);
514 if ( BaseOverflowAddU32 (Context->PrelinkedSize, AlignedSize, &NewSize)
515 || (NewSize > Context->PrelinkedAllocSize))
517 return EFI_BUFFER_TOO_SMALL;
520 if (Context->Is32Bit) {
521 Context->PrelinkedStateSegment->Segment32.Size += AlignedSize;
522 Context->PrelinkedStateSegment->Segment32.FileSize += AlignedSize;
523 Context->PrelinkedStateSectionKexts->Section32.Address = (UINT32)Context->PrelinkedLastAddress;
524 Context->PrelinkedStateSectionKexts->Section32.Offset = Context->PrelinkedSize;
525 Context->PrelinkedStateSectionKexts->Section32.Size = Context->PrelinkedStateKextsSize;
527 Context->PrelinkedStateSegment->Segment64.Size += AlignedSize;
528 Context->PrelinkedStateSegment->Segment64.FileSize += AlignedSize;
529 Context->PrelinkedStateSectionKexts->Section64.Address = Context->PrelinkedLastAddress;
530 Context->PrelinkedStateSectionKexts->Section64.Offset = Context->PrelinkedSize;
531 Context->PrelinkedStateSectionKexts->Section64.Size = Context->PrelinkedStateKextsSize;
535 &Context->Prelinked[Context->PrelinkedSize],
536 Context->PrelinkedStateKexts,
537 Context->PrelinkedStateKextsSize
540 &Context->Prelinked[Context->PrelinkedSize + Context->PrelinkedStateKextsSize],
541 AlignedSize - Context->PrelinkedStateKextsSize
544 Context->PrelinkedLastAddress += AlignedSize;
545 Context->PrelinkedSize += AlignedSize;
547 if ((Context->Is32Bit ?
548 Context->PrelinkedStateSectionKexts->Section32.Address : Context->PrelinkedStateSectionKexts->Section64.Address)
549 != Context->PrelinkedStateKextsAddress)
553 (INT64)((Context->Is32Bit ?
554 Context->PrelinkedStateSectionKexts->Section32.Address : Context->PrelinkedStateSectionKexts->Section64.Address)
555 - Context->PrelinkedStateKextsAddress)
557 if (!EFI_ERROR (Status)) {
558 Context->PrelinkedStateKextsAddress = Context->Is32Bit ?
559 Context->PrelinkedStateSectionKexts->Section32.Address : Context->PrelinkedStateSectionKexts->Section64.Address;
564 "OCAK: Rebasing %a-bit KXLD state from %Lx to %Lx - %r\n",
565 Context->Is32Bit ?
"32" :
"64",
566 Context->PrelinkedStateKextsAddress,
568 Context->PrelinkedStateSectionKexts->Section32.Address : Context->PrelinkedStateSectionKexts->Section64.Address,
572 Status = EFI_SUCCESS;