275 IN BOOLEAN CalculateSizeOnly,
276 OUT UINT8 *Destination,
277 IN UINT32 DestinationSize,
279 OUT UINT64 *FileOffset OPTIONAL
284 UINT32 HeaderSizeAligned;
291 UINT32 SectionOffset;
292 UINT32 SymbolsOffset;
293 UINT32 StringsOffset;
294 UINT32 AlignedOffset;
295 UINT32 RelocationsSize;
298 UINT32 OriginalDelta;
307 BOOLEAN FoundLinkedit;
310 ASSERT (Context->FileSize > 0);
313 if (!CalculateSizeOnly) {
314 ASSERT (Destination != NULL);
315 ASSERT (DestinationSize > 0);
331 HeaderSize =
sizeof (*Header) +
Header->CommandsSize;
332 if (!CalculateSizeOnly) {
333 if (HeaderSize > DestinationSize) {
344 HeaderSizeAligned = 0;
347 if (!CalculateSizeOnly) {
348 if (HeaderSizeAligned > DestinationSize) {
352 ZeroMem (&Destination[HeaderSize], HeaderSizeAligned - HeaderSize);
356 if (FileOffset != NULL) {
363 FoundLinkedit = FALSE;
370 if (Segment->FileSize > Segment->Size) {
376 "OCMCO: Src segment offset 0x%X size 0x%X delta 0x%X\n",
385 OriginalDelta = CurrentDelta;
392 CopyFileOffset = Segment->FileOffset;
393 CopyFileSize = Segment->FileSize;
394 CopyVmSize = Segment->Size;
396 if (IsObject && (CopyFileOffset <= HeaderSizeAligned)) {
397 CurrentDelta = HeaderSizeAligned - HeaderSize;
401 if (CopyFileOffset > HeaderSize) {
402 CurrentDelta -= (UINT32)(CopyFileOffset - HeaderSize);
405 if (FileOffset != NULL) {
406 *FileOffset = HeaderSizeAligned;
408 }
else if (!IsObject && (CopyFileOffset <= HeaderSize)) {
409 CopyFileOffset = HeaderSize;
410 CopyFileSize = Segment->FileSize - CopyFileOffset;
411 CopyVmSize = Segment->Size - CopyFileOffset;
412 if ((CopyFileSize > Segment->FileSize) || (CopyVmSize > Segment->Size)) {
423 if (FirstSegment == NULL) {
424 FirstSegment = Segment;
431 if (
MACH_X (BaseOverflowTriAddU)(CopyFileOffset, CurrentDelta, CopyVmSize, &CurrentSize)
432 || (!CalculateSizeOnly && (CurrentSize > DestinationSize)))
441 ASSERT (CopyFileSize <= MAX_UINTN && CopyVmSize <= MAX_UINTN);
443 if (!CalculateSizeOnly) {
444 ZeroMem (&Destination[CopyFileOffset + OriginalDelta], CurrentDelta - OriginalDelta);
445 CopyMem (&Destination[CopyFileOffset + CurrentDelta], &Source[CopyFileOffset], (UINTN)CopyFileSize);
446 ZeroMem (&Destination[CopyFileOffset + CurrentDelta + CopyFileSize], (UINTN)(CopyVmSize - CopyFileSize));
454 if (!CalculateSizeOnly) {
457 DstSegment = Segment;
460 SegmentOffset = DstSegment->FileOffset + CurrentDelta;
464 "OCMCO: Dst segment offset 0x%X size 0x%X delta 0x%X\n",
470 if (!IsObject && (DstSegment->VirtualAddress - SegmentOffset != FirstSegment->VirtualAddress)) {
474 if (!CalculateSizeOnly) {
475 DstSegment->FileOffset = SegmentOffset;
476 DstSegment->FileSize = DstSegment->Size;
484 if (AsciiStrnCmp (DstSegment->SegmentName,
"__LINKEDIT",
ARRAY_SIZE (DstSegment->SegmentName)) == 0) {
485 FoundLinkedit = TRUE;
487 if (!CalculateSizeOnly) {
496 if (Symtab != NULL) {
515 if (DySymtab != NULL) {
550 OriginalDelta = CurrentDelta;
551 CopyFileOffset = DstSegment->FileOffset;
552 for (Index = 0; Index < DstSegment->NumSections; ++Index) {
553 SectionOffset = DstSegment->Sections[Index].Offset;
557 "OCMCO: Src section %u offset 0x%X size 0x%X delta 0x%X\n",
560 DstSegment->Sections[Index].Size,
568 if (DstSegment->Sections[Index].Offset == 0) {
573 SectionOffset += CurrentDelta;
574 CopyFileOffset = SectionOffset + DstSegment->Sections[Index].Size;
579 "OCMCO: Dst section %u offset 0x%X size 0x%X delta 0x%X\n",
582 DstSegment->Sections[Index].Size,
586 if (!CalculateSizeOnly) {
587 DstSegment->Sections[Index].Offset = SectionOffset;
591 CurrentDelta = OriginalDelta +
MACH_X_TO_UINT32 (Segment->Size - Segment->FileSize);
598 if (!FoundLinkedit) {
599 DEBUG ((DEBUG_VERBOSE,
"OCMCO: __LINKEDIT not found\n"));
610 if (!CalculateSizeOnly) {
613 DstSegment = Segment;
616 for (Index = 0; Index < DstSegment->NumSections; ++Index) {
617 SectionOffset = DstSegment->Sections[Index].RelocationsOffset;
619 if (SectionOffset != 0) {
622 "OCMCO: Src section %u relocs offset 0x%X count %u delta 0x%X\n",
625 DstSegment->Sections[Index].NumRelocations,
629 CopyFileOffset = SectionOffset;
632 CurrentDelta = AlignedOffset - SectionOffset;
634 if (
MACH_X (BaseOverflowTriAddU)(CopyFileOffset, CurrentDelta, RelocationsSize, &CurrentSize)
635 || (!CalculateSizeOnly && (CurrentSize > DestinationSize)))
640 SectionOffset += CurrentDelta;
644 "OCMCO: Dst section %u relocs offset 0x%X count %u delta 0x%X\n",
647 DstSegment->Sections[Index].NumRelocations,
651 if (!CalculateSizeOnly) {
652 DstSegment->Sections[Index].RelocationsOffset = SectionOffset;
653 CopyMem (&Destination[CopyFileOffset + CurrentDelta], &Source[CopyFileOffset], RelocationsSize);
669 if (Symtab != NULL) {
675 "OCMCO: Src symtab 0x%X (%u symbols), strings 0x%X (size 0x%X) delta 0x%X\n",
683 if (!CalculateSizeOnly) {
690 if (SymbolsOffset != 0) {
691 CopyFileOffset = SymbolsOffset;
693 AlignedOffset = ALIGN_VALUE (SymbolsOffset + CurrentDelta,
sizeof (
MACH_NLIST_X));
694 CurrentDelta = AlignedOffset - SymbolsOffset;
696 if (
MACH_X (BaseOverflowTriAddU)(CopyFileOffset, CurrentDelta, SymtabSize, &CurrentSize)
697 || (!CalculateSizeOnly && (CurrentSize > DestinationSize)))
702 SymbolsOffset += CurrentDelta;
704 if (!CalculateSizeOnly) {
706 CopyMem (&Destination[CopyFileOffset + CurrentDelta], &Source[CopyFileOffset], SymtabSize);
713 if (StringsOffset != 0) {
714 CopyFileOffset = StringsOffset;
715 if (
MACH_X (BaseOverflowTriAddU)(CopyFileOffset, CurrentDelta, Symtab->
StringsSize, &CurrentSize)
716 || (!CalculateSizeOnly && (CurrentSize > DestinationSize)))
721 StringsOffset += CurrentDelta;
723 if (!CalculateSizeOnly) {
725 CopyMem (&Destination[CopyFileOffset + CurrentDelta], &Source[CopyFileOffset], Symtab->
StringsSize);
731 "OCMCO: Dst symtab 0x%X (%u symbols), strings 0x%X (size 0x%X) delta 0x%X\n",
745 if (CurrentSize == 0) {
751 ASSERT (FileSize >= HeaderSize);
753 if ((!CalculateSizeOnly && (FileSize > DestinationSize))) {
757 if (!CalculateSizeOnly) {
759 Destination + HeaderSize,
760 (UINT8 *)
Header + HeaderSize,
761 FileSize - HeaderSize
765 CurrentSize = FileSize;
768 if (!CalculateSizeOnly && Strip) {
783 IN CONST CHAR8 *Prefix
795 ASSERT (Context->FileSize != 0);
800 PrefixLength = AsciiStrLen (Prefix);
805 LoadCommand = &
Header->Commands[0];
807 for (LcIndex = 0; LcIndex <
Header->NumCommands; ++LcIndex) {
814 || (AsciiStrnCmp (Segment->SegmentName, Prefix, PrefixLength) != 0))
816 if (FirstSegment != NULL) {
831 if (Segment->Size != Segment->FileSize) {
838 if (FirstSegment == NULL) {
839 FirstSegment = Segment;
847 FirstSegment->Size = Segment->VirtualAddress - FirstSegment->VirtualAddress + Segment->Size;
848 FirstSegment->FileSize = Segment->FileOffset - FirstSegment->FileOffset + Segment->FileSize;
853 FirstSegment->InitialProtection |= Segment->InitialProtection;
854 FirstSegment->MaximumProtection |= Segment->MaximumProtection;
863 if (FirstSegment == NULL) {
870 if (SkipCount == 0) {
877 RemainingArea =
Header->CommandsSize - ((UINTN)LoadCommand - (UINTN)&
Header->Commands[0]);
879 (UINT8 *)FirstSegment + FirstSegment->CommandSize,
883 ZeroMem (LoadCommand, RemainingArea);
888 Header->NumCommands -= SkipCount;
901 IN UINT32 HeaderOffset,
915 ASSERT (FileData != NULL);
917 ASSERT (FileSize >= HeaderOffset);
920 if (HeaderOffset == 0) {
921 ASSERT (InnerSize == FileSize);
924 ASSERT (FileSize >= InnerSize && FileSize - InnerSize >= HeaderOffset);
926 TopOfFile = ((UINTN)FileData + FileSize);
927 ASSERT (TopOfFile > (UINTN)FileData);
929 MachData = (UINT8 *)FileData + HeaderOffset;
934 if (HeaderOffset == 0) {
940 if (EFI_ERROR (Status)) {
945 InnerSize = FileSize;
948 if ( (FileSize <
sizeof (*MachHeader))
963 Result = BaseOverflowAddUN (
964 (UINTN)MachHeader->Commands,
965 MachHeader->CommandsSize,
968 if (Result || (TopOfCommands > TopOfFile)) {
975 Index = 0,
Command = MachHeader->Commands;
976 Index < MachHeader->NumCommands;
980 Result = BaseOverflowAddUN (
986 || (TopOfCommand > TopOfCommands)
994 Result = BaseOverflowAddU32 (
1004 if (MachHeader->CommandsSize != CommandsSize) {
1029 ZeroMem (Context,
sizeof (*Context));
1033 Context->FileData = FileData;
1034 Context->FileSize = FileSize;
1035 Context->InnerSize = InnerSize;
1383 OUT CONST CHAR8 **StringTable OPTIONAL,
1385 OUT UINT32 *NumLocalSymbols OPTIONAL,
1387 OUT UINT32 *NumExternalSymbols OPTIONAL,
1389 OUT UINT32 *NumUndefinedSymbols OPTIONAL
1393 UINT32 NoLocalSymbols;
1394 UINT32 NoExternalSymbols;
1395 UINT32 NoUndefinedSymbols;
1397 ASSERT (Context != NULL);
1398 ASSERT (SymbolTable != NULL);
1405 if (Context->Symtab->NumSymbols == 0) {
1409 SymTab =
MACH_X (&Context->SymbolTable->Symbol);
1411 for (Index = 0; Index < Context->Symtab->NumSymbols; ++Index) {
1417 *SymbolTable =
MACH_X (&Context->SymbolTable->Symbol);
1419 if (StringTable != NULL) {
1420 *StringTable = Context->StringTable;
1424 NoExternalSymbols = 0;
1425 NoUndefinedSymbols = 0;
1427 if (Context->DySymtab != NULL) {
1428 NoLocalSymbols = Context->DySymtab->NumLocalSymbols;
1429 NoExternalSymbols = Context->DySymtab->NumExternalSymbols;
1430 NoUndefinedSymbols = Context->DySymtab->NumUndefinedSymbols;
1433 if (NumLocalSymbols != NULL) {
1434 ASSERT (LocalSymbols != NULL);
1435 *NumLocalSymbols = NoLocalSymbols;
1436 if (NoLocalSymbols != 0) {
1437 *LocalSymbols = &SymTab[Context->DySymtab->LocalSymbolsIndex];
1441 if (NumExternalSymbols != NULL) {
1442 ASSERT (ExternalSymbols != NULL);
1443 *NumExternalSymbols = NoExternalSymbols;
1444 if (NoExternalSymbols != 0) {
1445 *ExternalSymbols = &SymTab[Context->DySymtab->ExternalSymbolsIndex];
1449 if (NumUndefinedSymbols != NULL) {
1450 ASSERT (UndefinedSymbols != NULL);
1451 *NumUndefinedSymbols = NoUndefinedSymbols;
1452 if (NoUndefinedSymbols != 0) {
1453 *UndefinedSymbols = &SymTab[Context->DySymtab->UndefinedSymbolsIndex];
1457 return Context->Symtab->NumSymbols;