#include <IOKit/ndrvsupport/IONDRVLibraries.h>
#if __ppc__
#include "IOPEFInternals.h"
#define PEF_Assert(a) if( !(a)) kprintf("PEF_Assert:")
#define PEF_BlockMove(src,dst,len) memcpy(dst,src,len)
#define PEF_BlockClear(dst,len) memset(dst,0,len)
#define PEF_CompareBytes(a,b,c) (0 == bcmp(a,b,c))
#define EnableCFMDebugging 0
enum {
kPEFHandlerProcCount = 18
};
static CFContHandlerProcs PEFHandlerProcs = {
kPEFHandlerProcCount,
kCFContHandlerABIVersion,
PEF_OpenContainer, PEF_CloseContainer, PEF_GetContainerInfo,
PEF_GetSectionCount, PEF_GetSectionInfo, PEF_FindSectionInfo, PEF_SetSectionAddress,
PEF_GetAnonymousSymbolLocations,
PEF_GetExportedSymbolCount, PEF_GetExportedSymbolInfo, PEF_FindExportedSymbolInfo,
PEF_GetImportCounts, PEF_GetImportedLibraryInfo, PEF_GetImportedSymbolInfo, PEF_SetImportedSymbolAddress,
PEF_UnpackSection, PEF_RelocateSection, PEF_RelocateImportsOnly, };
#if EnableCFMDebugging
static char gDebugMessage [256];
#endif
const unsigned char opcode [128] = {
krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
krCODE,krDATA,krDESC,krDSC2, krVTBL,krSYMR,krXXXX,krXXXX,
krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
krSYMB,krCDIS,krDTIS,krSECN, krXXXX,krXXXX,krXXXX,krXXXX,
krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
krDELT,krDELT,krDELT,krDELT, krDELT,krDELT,krDELT,krDELT,
krRPT ,krRPT ,krRPT ,krRPT , krRPT ,krRPT ,krRPT ,krRPT ,
krLABS,krLABS,krLSYM,krLSYM, krXXXX,krXXXX,krXXXX,krXXXX,
krLRPT,krLRPT,krLSEC,krLSEC, krXXXX,krXXXX,krXXXX,krXXXX,
krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
};
static ByteCount GetNameLength ( BytePtr nameStart )
{
BytePtr nameEnd = nameStart;
if (nameStart != NULL)
{
while (*nameEnd != 0)
nameEnd += 1;
}
return (nameEnd - nameStart);
}
static LoaderRelExpHeader * FindRelocationInfo ( PEFPrivateInfo * pefPrivate,
ItemCount sectionIndex )
{
LoaderRelExpHeader * relocInfo = NULL;
const ItemCount loopLimit = pefPrivate->ldrHeader->numSections;
ItemCount relocIndex;
for (relocIndex = 0; relocIndex < loopLimit; relocIndex += 1)
{
relocInfo = &pefPrivate->ldrSections[relocIndex];
if (sectionIndex == (ItemCount) relocInfo->sectionNumber)
return relocInfo;
}
return NULL;
}
static void GetSectionName ( PEFPrivateInfo * pefPrivate,
SectionHeader * sectionHeader,
CFContHashedName * sectionName )
{
CFContStringHash nameHash = 0;
BytePtr nameText = NULL;
ByteCount nameLength;
if (sectionHeader->sectionName != ((ByteCount) -1))
{
nameText = pefPrivate->stringTable + sectionHeader->sectionName;
nameLength = GetNameLength ( nameText );
nameHash = CFContHashName ( nameText, nameLength );
}
sectionName->nameHash = nameHash;
sectionName->nameText = nameText;
}
OSStatus PEF_OpenContainer ( LogicalAddress mappedAddress,
LogicalAddress runningAddress,
ByteCount containerLength,
CFContOpenOptions options,
CFContAllocateMem Allocate,
CFContReleaseMem Release,
CFContHandlerRef * containerRef,
CFContHandlerProcsPtr * handlerProcs,
UInt32 * createDate )
{
#pragma unused ( containerLength )
#pragma unused ( runningProcessID )
#pragma unused ( cfragName )
OSStatus err = -1; FileHeader * fileHeader = (FileHeader *) mappedAddress;
PEFPrivateInfo * pefPrivate = NULL;
SectionHeader * loaderSection = NULL;
SInt32 sectionIndex;
if ((sizeof (PEF_SBits32) != 4) | (sizeof (PEF_UBits32) != 4))
goto InternalError;
if ((Allocate == NULL) ||
(Release == NULL) ||
(containerRef == NULL) ||
(handlerProcs == NULL))
goto ParameterError;
*containerRef = NULL; *handlerProcs = NULL;
if (mappedAddress == NULL)
goto OK;
if ((fileHeader->magic1 != kPEFMagic1) ||
(fileHeader->magic2 != kPEFMagic2) ||
(fileHeader->fileTypeID != kPEFTypeID) ||
(fileHeader->versionNumber != kPEFVersion))
goto FragmentFormatError;
if (createDate)
*createDate = fileHeader->dateTimeStamp;
pefPrivate = (PEFPrivateInfo *) ((*Allocate) ( sizeof ( PEFPrivateInfo ) ));
if (pefPrivate == NULL)
goto PrivateMemoryError;
PEF_BlockClear ( pefPrivate, sizeof ( *pefPrivate ) );
pefPrivate->Allocate = Allocate;
pefPrivate->Release = Release;
pefPrivate->mappedContainer = (BytePtr) mappedAddress;
pefPrivate->runningContainer = (BytePtr) runningAddress;
pefPrivate->sectionCount = fileHeader->loadableSections;
pefPrivate->sections = (SectionHeader *) (fileHeader + 1);
pefPrivate->stringTable = (BytePtr) (&pefPrivate->sections[fileHeader->numberSections]);
pefPrivate->loadInPlace = ((options & kCFContPrepareInPlaceMask) != 0);
for (sectionIndex = 0; sectionIndex < fileHeader->numberSections; sectionIndex += 1)
{
loaderSection = & pefPrivate->sections[sectionIndex];
if (loaderSection->regionKind == kPEFLoaderSection)
break;
}
if (sectionIndex == fileHeader->numberSections)
goto FragmentCorruptError;
pefPrivate->ldrSectionNo = sectionIndex;
pefPrivate->ldrHeader = (LoaderHeader *) ((BytePtr)mappedAddress + loaderSection->containerOffset);
pefPrivate->ldrStringTable = (BytePtr)pefPrivate->ldrHeader + pefPrivate->ldrHeader->stringsOffset;
pefPrivate->ldrImportFiles = (LoaderImportFileID *) (pefPrivate->ldrHeader + 1);
pefPrivate->ldrImportSymbols = (LoaderImport *) (pefPrivate->ldrImportFiles + pefPrivate->ldrHeader->numImportFiles);
pefPrivate->ldrSections = (LoaderRelExpHeader *) (pefPrivate->ldrImportSymbols + pefPrivate->ldrHeader->numImportSyms);
pefPrivate->ldrRelocations = (BytePtr)pefPrivate->ldrHeader + pefPrivate->ldrHeader->relocationsOffset;
pefPrivate->ldrHashSlot = (HashSlotEntry *) ((BytePtr)pefPrivate->ldrHeader + pefPrivate->ldrHeader->hashSlotTable);
pefPrivate->ldrHashChain = (HashChainEntry *) (pefPrivate->ldrHashSlot + (1 << pefPrivate->ldrHeader->hashSlotTabSize));
pefPrivate->ldrExportSymbols = (LoaderExport *) (pefPrivate->ldrHashChain + pefPrivate->ldrHeader->numExportSyms);
if (pefPrivate->ldrHeader->numImportSyms > 0)
{
pefPrivate->imports = (BytePtr *) ((*Allocate) ( pefPrivate->ldrHeader->numImportSyms * sizeof ( BytePtr ) ));
if (pefPrivate->imports == NULL)
goto PrivateMemoryError;
}
if (pefPrivate->sectionCount <= kBuiltinSectionArraySize)
{
pefPrivate->mappedOrigins = & pefPrivate->originArray[0];
pefPrivate->runningOffsets = & pefPrivate->offsetArray[0];
}
else
{
pefPrivate->mappedOrigins = (BytePtr *) ((*Allocate) ( pefPrivate->sectionCount * sizeof ( BytePtr ) ));
if (pefPrivate->mappedOrigins == NULL)
goto PrivateMemoryError;
pefPrivate->runningOffsets = (ByteCount *) ((*Allocate) ( pefPrivate->sectionCount * sizeof ( ByteCount ) ));
if (pefPrivate->runningOffsets == NULL)
goto PrivateMemoryError;
}
for (sectionIndex = 0; ((ItemCount) sectionIndex) < pefPrivate->sectionCount; sectionIndex += 1)
{
SectionHeader * section = & pefPrivate->sections[sectionIndex];
pefPrivate->mappedOrigins[sectionIndex] = (BytePtr) -1; pefPrivate->runningOffsets[sectionIndex] = - ((ByteCount) section->sectionAddress);
if (pefPrivate->loadInPlace)
{
if ((section->regionKind == kPEFPIDataSection) || (section->execSize != section->rawSize))
goto FragmentUsageError;
section->sectionAddress = pefPrivate->runningContainer + section->containerOffset;
pefPrivate->mappedOrigins[sectionIndex] = pefPrivate->mappedContainer + section->containerOffset;
pefPrivate->runningOffsets[sectionIndex] += (ByteCount) section->sectionAddress; }
}
if (options & kCFContPrepareInPlaceMask)
fileHeader->memoryAddress = runningAddress;
OK:
err = noErr;
*handlerProcs = &PEFHandlerProcs;
*containerRef = (CFContHandlerRef) pefPrivate;
EXIT:
return err;
ERROR:
(void) PEF_CloseContainer ( (CFContHandlerRef) pefPrivate, kNilOptions );
goto EXIT;
InternalError:
err = cfragCFMInternalErr;
goto ERROR;
ParameterError:
err = paramErr;
goto ERROR;
FragmentFormatError:
err = cfragFragmentFormatErr;
goto ERROR;
PrivateMemoryError:
err = cfragNoPrivateMemErr;
goto ERROR;
FragmentCorruptError:
err = cfragFragmentCorruptErr;
goto ERROR;
FragmentUsageError:
err = cfragFragmentUsageErr;
goto ERROR;
}
OSStatus PEF_CloseContainer ( CFContHandlerRef containerRef,
CFContCloseOptions options )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
CFContReleaseMem Release = NULL;
if (pefPrivate == NULL)
goto OK;
Release = pefPrivate->Release;
if (pefPrivate->sectionCount > kBuiltinSectionArraySize)
{
if (pefPrivate->mappedOrigins != NULL)
{
(*Release) ( pefPrivate->mappedOrigins );
pefPrivate->mappedOrigins = NULL;
}
if (pefPrivate->runningOffsets != NULL)
{
(*Release) ( pefPrivate->runningOffsets );
pefPrivate->runningOffsets = NULL;
}
}
if (pefPrivate->imports != NULL)
{
(*Release) ( pefPrivate->imports );
pefPrivate->imports = NULL;
}
pefPrivate->resolved = 0;
if (! (options & kCFContPartialCloseMask))
(*Release) ( pefPrivate );
OK:
err = noErr;
return err;
}
OSStatus PEF_GetContainerInfo ( CFContHandlerRef containerRef,
PBVersion infoVersion,
CFContContainerInfo * containerInfo )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
FileHeader * fileHeader = NULL;
if ((pefPrivate == NULL) || (containerInfo == NULL))
goto ParameterError;
if (infoVersion != kCFContContainerInfoVersion)
goto ParameterError;
fileHeader = (FileHeader *) pefPrivate->mappedContainer;
containerInfo->cfragName.nameHash = 0; containerInfo->cfragName.nameText = NULL;
containerInfo->modDate = fileHeader->dateTimeStamp;
containerInfo->architecture = fileHeader->architectureID;
containerInfo->currentVersion = fileHeader->currentVersion;
containerInfo->oldImpVersion = fileHeader->oldImpVersion;
containerInfo->oldDefVersion = fileHeader->oldDefVersion;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_GetSectionCount ( CFContHandlerRef containerRef,
ItemCount * sectionCount )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
if ((pefPrivate == NULL) || (sectionCount == NULL))
goto ParameterError;
*sectionCount = pefPrivate->sectionCount;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_GetSectionInfo ( CFContHandlerRef containerRef,
ItemCount sectionIndex,
PBVersion infoVersion,
CFContSectionInfo * sectionInfo )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
SectionHeader * sectionHeader = NULL;
if ((pefPrivate == NULL) || (sectionInfo == NULL))
goto ParameterError;
if (infoVersion != kCFContSectionInfoVersion)
goto ParameterError;
if (sectionIndex >= pefPrivate->sectionCount)
goto ParameterError;
sectionHeader = &pefPrivate->sections[sectionIndex];
GetSectionName ( pefPrivate, sectionHeader, §ionInfo->sectionName );
sectionInfo->sharing = sectionHeader->shareKind;
sectionInfo->alignment = sectionHeader->alignment;
sectionInfo->reservedA = 0;
sectionInfo->containerOffset = sectionHeader->containerOffset;
sectionInfo->containerLength = sectionHeader->rawSize;
sectionInfo->unpackedLength = sectionHeader->initSize;
sectionInfo->totalLength = sectionHeader->execSize;
sectionInfo->defaultAddress = sectionHeader->sectionAddress;
sectionInfo->options = kNilOptions;
if (FindRelocationInfo (pefPrivate, sectionIndex) != NULL)
sectionInfo->options |= kRelocatedCFContSectionMask;
switch (pefPrivate->sections[sectionIndex].regionKind)
{
case kPEFCodeSection :
sectionInfo->access = kCFContNormalCode;
break;
case kPEFDataSection :
sectionInfo->access = kCFContWriteableData;
break;
case kPEFPIDataSection :
sectionInfo->access = kCFContWriteableData;
sectionInfo->options |= kPackedCFContSectionMask;
break;
case kPEFConstantSection :
sectionInfo->access = kCFContReadOnlyData;
break;
case kPEFExecDataSection :
sectionInfo->access = kCFContWriteableData | kCFContMemExecuteMask;
break;
default :
sectionInfo->access = kCFContReadOnlyData; break;
}
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_FindSectionInfo ( CFContHandlerRef containerRef,
const CFContHashedName * sectionName,
PBVersion infoVersion,
ItemCount * sectionIndex, CFContSectionInfo * sectionInfo ) {
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
SectionHeader * sectionHeader = NULL;
CFContHashedName hashedName;
ItemCount tempIndex;
CFContSectionInfo tempInfo;
if (pefPrivate == NULL)
goto ParameterError;
if ((sectionInfo != NULL) && (infoVersion != kCFContSectionInfoVersion))
goto ParameterError;
if (sectionIndex == NULL)
sectionIndex = &tempIndex;
if (sectionInfo == NULL)
sectionInfo = &tempInfo;
for (tempIndex = 0; tempIndex < pefPrivate->sectionCount; tempIndex += 1)
{
sectionHeader = &pefPrivate->sections[tempIndex];
GetSectionName ( pefPrivate, sectionHeader, &hashedName );
if ((hashedName.nameHash == sectionName->nameHash) &&
(PEF_CompareBytes (hashedName.nameText, sectionName->nameText, CFContStringHashLength (hashedName.nameHash))))
break;
}
if (tempIndex == pefPrivate->sectionCount)
goto NoSectionError;
*sectionIndex = tempIndex;
err = PEF_GetSectionInfo ( containerRef, tempIndex, infoVersion, sectionInfo );
if (err != noErr)
goto ERROR;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
NoSectionError:
err = cfragNoSectionErr;
goto ERROR;
}
OSStatus PEF_SetSectionAddress ( CFContHandlerRef containerRef,
ItemCount sectionIndex,
LogicalAddress mappedAddress,
LogicalAddress runningAddress )
{
OSErr err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
SectionHeader * section = NULL;
if ((pefPrivate == NULL) || (sectionIndex >= pefPrivate->sectionCount))
goto ParameterError;
section = & pefPrivate->sections[sectionIndex];
if (! pefPrivate->loadInPlace)
{
pefPrivate->mappedOrigins[sectionIndex] = (BytePtr) mappedAddress;
pefPrivate->runningOffsets[sectionIndex] += (ByteCount) runningAddress;
}
else
{
if ((runningAddress != section->sectionAddress) ||
(mappedAddress != pefPrivate->mappedOrigins[sectionIndex]))
goto UsageError;
}
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
UsageError:
err = cfragFragmentUsageErr;
goto ERROR;
}
extern OSStatus PEF_GetAnonymousSymbolLocations ( CFContHandlerRef containerRef,
CFContLogicalLocation * mainLocation, CFContLogicalLocation * initLocation, CFContLogicalLocation * termLocation ) {
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
LoaderHeader * ldrHeader = NULL;
CFContLogicalLocation tempLocation;
if ((pefPrivate == NULL))
goto ParameterError;
if (mainLocation == NULL)
mainLocation = &tempLocation;
if (initLocation == NULL)
initLocation = &tempLocation;
if (termLocation == NULL)
termLocation = &tempLocation;
ldrHeader = pefPrivate->ldrHeader;
mainLocation->section = ldrHeader->entryPointSection;
mainLocation->offset = ldrHeader->entryPointOffset;
initLocation->section = ldrHeader->initPointSection;
initLocation->offset = ldrHeader->initPointOffset;
termLocation->section = ldrHeader->termPointSection;
termLocation->offset = ldrHeader->termPointOffset;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
extern OSStatus PEF_GetExportedSymbolCount ( CFContHandlerRef containerRef,
ItemCount * exportCount )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
if ((pefPrivate == NULL) || (exportCount == NULL))
goto ParameterError;
*exportCount = pefPrivate->ldrHeader->numExportSyms;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_GetExportedSymbolInfo ( CFContHandlerRef containerRef,
CFContSignedIndex exportIndex,
PBVersion infoVersion,
CFContExportedSymbolInfo * exportInfo )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
LoaderExport * exportedSymbol = NULL;
if ((pefPrivate == NULL) || (exportInfo == NULL))
goto ParameterError;
if ((ItemCount) exportIndex >= pefPrivate->ldrHeader->numExportSyms)
goto ParameterError;
if (infoVersion != kCFContExportedSymbolInfoVersion)
goto ParameterError;
if (exportIndex >= 0)
{
exportedSymbol = &pefPrivate->ldrExportSymbols[exportIndex];
exportInfo->symbolName.nameHash = pefPrivate->ldrHashChain[exportIndex].hashword;
exportInfo->symbolName.nameText = &pefPrivate->ldrStringTable[exportedSymbol->nameOffset];
exportInfo->symbolClass = exportedSymbol->symClass;
exportInfo->reservedA = 0;
exportInfo->reservedB = 0;
exportInfo->options = kNilOptions;
exportInfo->location.section = exportedSymbol->sectionNumber;
#if 1 // *** Disable the reexported import optimization.
exportInfo->location.offset = exportedSymbol->offset;
#else
if ((! pefPrivate->resolved) || (exportedSymbol->sectionNumber != kReExportImport))
{
exportInfo->location.offset = exportedSymbol->address;
}
else
{
exportInfo->location.section = kPhysicalExport;
exportInfo->location.offset = pefPrivate->imports[exportedSymbol->address];
}
#endif
}
else
{
CFContLogicalLocation mainLocation;
CFContLogicalLocation initLocation;
CFContLogicalLocation termLocation;
err = PEF_GetAnonymousSymbolLocations ( containerRef, &mainLocation, &initLocation, &termLocation );
if (err != noErr)
goto ERROR;
switch (exportIndex)
{
case kMainCFragSymbolIndex :
exportInfo->location = mainLocation;
exportInfo->symbolClass = 0xFF; break;
case kInitCFragSymbolIndex :
exportInfo->location = initLocation;
exportInfo->symbolClass = kTVectorCFragSymbol; break;
case kTermCFragSymbolIndex :
exportInfo->location = termLocation;
exportInfo->symbolClass = kTVectorCFragSymbol; break;
default :
goto ParameterError;
}
exportInfo->symbolName.nameHash = 0;
exportInfo->symbolName.nameText = NULL;
exportInfo->reservedA = 0;
exportInfo->reservedB = 0;
exportInfo->options = kNilOptions;
}
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_FindExportedSymbolInfo ( CFContHandlerRef containerRef,
const CFContHashedName * exportName,
PBVersion infoVersion,
ItemCount * exportIndex_o, CFContExportedSymbolInfo * exportInfo ) {
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
LoaderExport * exportedSymbol = NULL;
CFContStringHash * hashwordList = NULL;
CFContStringHash * nextHashword = NULL;
HashSlotEntry * hashSlot = NULL;
ByteCount nameLength = CFContStringHashLength ( exportName->nameHash );
ItemCount exportIndex;
ItemCount slotIndex;
ItemCount chainLimit;
Boolean nameMatch;
if (pefPrivate == NULL)
goto ParameterError;
if (infoVersion != kCFContExportedSymbolInfoVersion)
goto ParameterError;
hashwordList = &pefPrivate->ldrHashChain[0].hashword;
slotIndex = GetPEFHashSlot ( exportName->nameHash, pefPrivate->ldrHeader->hashSlotTabSize );
hashSlot = &pefPrivate->ldrHashSlot[slotIndex];
exportIndex = hashSlot->chainIndex;
chainLimit = exportIndex + hashSlot->chainCount;
nextHashword = &hashwordList[exportIndex];
while (exportIndex < chainLimit)
{
if (*nextHashword == exportName->nameHash)
{
exportedSymbol = &pefPrivate->ldrExportSymbols[exportIndex];
nameMatch = PEF_CompareBytes ( exportName->nameText,
&pefPrivate->ldrStringTable[exportedSymbol->nameOffset],
nameLength );
if (nameMatch)
goto Found;
}
exportIndex += 1;
nextHashword += 1; }
goto NotFoundError;
Found:
if (exportIndex_o != NULL)
*exportIndex_o = exportIndex;
if (exportInfo != NULL)
{
err = PEF_GetExportedSymbolInfo ( containerRef, exportIndex, infoVersion, exportInfo );
if (err != noErr)
goto ERROR;
}
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
NotFoundError:
err = cfragNoSymbolErr;
goto ERROR;
}
OSStatus PEF_GetImportCounts ( CFContHandlerRef containerRef,
ItemCount * libraryCount, ItemCount * symbolCount ) {
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
if (pefPrivate == NULL)
goto ParameterError;
if (libraryCount != NULL)
*libraryCount = pefPrivate->ldrHeader->numImportFiles;
if (symbolCount != NULL)
*symbolCount = pefPrivate->ldrHeader->numImportSyms;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_GetImportedLibraryInfo ( CFContHandlerRef containerRef,
ItemCount libraryIndex,
PBVersion infoVersion,
CFContImportedLibraryInfo * libraryInfo )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
LoaderImportFileID * importedLibrary = NULL;
BytePtr nameText = NULL;
ByteCount nameLength;
if ((pefPrivate == NULL) || (libraryInfo == NULL))
goto ParameterError;
if (infoVersion != kCFContImportedLibraryInfoVersion)
goto ParameterError;
if (libraryIndex >= pefPrivate->ldrHeader->numImportFiles)
goto ParameterError;
importedLibrary = &pefPrivate->ldrImportFiles[libraryIndex];
nameText = &pefPrivate->ldrStringTable[importedLibrary->fileNameOffset];
nameLength = GetNameLength ( nameText );
libraryInfo->libraryName.nameHash = CFContHashName ( nameText, nameLength );
libraryInfo->libraryName.nameText = nameText;
libraryInfo->linkedVersion = importedLibrary->linkedVersion;
libraryInfo->oldImpVersion = importedLibrary->oldImpVersion;
libraryInfo->options = kNilOptions;
if (importedLibrary->options & kPEFInitBeforeMask)
libraryInfo->options |= kCFContInitBeforeMask;
if (importedLibrary->options & kPEFWeakLibraryMask)
libraryInfo->options |= kCFContWeakLibraryMask;
if (importedLibrary->options & kPEFDeferredBindMask)
libraryInfo->options |= kCFContDeferredBindMask;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_GetImportedSymbolInfo ( CFContHandlerRef containerRef,
ItemCount symbolIndex,
PBVersion infoVersion,
CFContImportedSymbolInfo * symbolInfo )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
LoaderImport * importedSymbol = NULL;
LoaderImportFileID * importedLibrary = NULL;
BytePtr nameText = NULL;
ByteCount nameLength;
ItemCount libraryCount;
ItemCount libraryIndex;
if ((pefPrivate == NULL) || (symbolInfo == NULL))
goto ParameterError;
if (infoVersion != kCFContImportedSymbolInfoVersion)
goto ParameterError;
if (symbolIndex >= pefPrivate->ldrHeader->numImportSyms)
goto ParameterError;
importedSymbol = &pefPrivate->ldrImportSymbols[symbolIndex];
libraryCount = pefPrivate->ldrHeader->numImportFiles;
nameText = &pefPrivate->ldrStringTable[importedSymbol->nameOffset];
nameLength = GetNameLength ( nameText );
symbolInfo->symbolName.nameHash = CFContHashName ( nameText, nameLength );
symbolInfo->symbolName.nameText = nameText;
symbolInfo->symbolClass = importedSymbol->symClass & 0x0F;
symbolInfo->reservedA = 0;
symbolInfo->reservedB = 0;
symbolInfo->options = 0;
if (importedSymbol->symClass & kPEFWeakSymbolMask)
symbolInfo->options |= kCFContWeakSymbolMask;
for (libraryIndex = 0; libraryIndex < libraryCount; libraryIndex += 1)
{
importedLibrary = &pefPrivate->ldrImportFiles[libraryIndex];
if ((importedLibrary->impFirst <= symbolIndex) &&
(symbolIndex < (importedLibrary->impFirst + importedLibrary->numImports)))
{
break;
}
}
if (libraryIndex == libraryCount)
goto FragmentCorruptError;
symbolInfo->libraryIndex = libraryIndex;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
FragmentCorruptError:
err = cfragFragmentCorruptErr;
goto ERROR;
}
OSStatus PEF_SetImportedSymbolAddress ( CFContHandlerRef containerRef,
ItemCount symbolIndex,
LogicalAddress symbolAddress )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
if (pefPrivate == NULL)
goto ParameterError;
if (symbolIndex >= pefPrivate->ldrHeader->numImportSyms)
goto ParameterError;
pefPrivate->imports[symbolIndex] = symbolAddress;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
static UInt32 GetPackedDataCount ( UInt8 * * byteHandle )
{
UInt32 count = 0;
UInt8 * bytePtr = *byteHandle;
UInt8 currByte;
do
{
currByte = *bytePtr++;
count = (count << kPEFPkDataVCountShift) | (currByte & kPEFPkDataVCountMask);
}
while ((currByte & kPEFPkDataVCountEndMask) != 0);
*byteHandle = bytePtr;
return count;
}
static OSStatus UnpackFullSection ( BytePtr packedBase,
BytePtr packedEnd,
BytePtr outputBase,
BytePtr outputEnd )
{
OSStatus err = cfragCFMInternalErr;
BytePtr packedPos = packedBase;
BytePtr outputPos = outputBase;
BytePtr outPosLimit = outputEnd + 1;
UInt8 currByte;
UInt8 opcode;
UInt32 count1;
UInt32 count2;
UInt32 count3;
if ((packedEnd + 1) == 0)
goto FragmentUsageError;
while (packedPos <= packedEnd)
{
currByte = *packedPos++;
opcode = currByte >> kPEFPkDataOpcodeShift;
count1 = currByte & kPEFPkDataCount5Mask;
if (count1 == 0)
count1 = GetPackedDataCount ( &packedPos );
switch (opcode)
{
case kPEFPkDataZero :
if (((UInt32) (outPosLimit - outputPos)) < count1)
goto FragmentCorruptError;
PEF_BlockClear ( outputPos, count1 );
outputPos += count1;
break;
case kPEFPkDataBlock :
if (((UInt32)(outPosLimit - outputPos)) < count1)
goto FragmentCorruptError;
PEF_BlockMove ( packedPos, outputPos, count1 );
packedPos += count1;
outputPos += count1;
break;
case kPEFPkDataRepeat :
count2 = GetPackedDataCount ( &packedPos ) + 1;
if (((UInt32)(outPosLimit - outputPos)) < (count1 * count2))
goto FragmentCorruptError;
if (count1 == 1)
{
currByte = *packedPos++;
for (; count2 != 0; count2 -= 1)
*outputPos++ = currByte;
}
else
{
for (; count2 != 0; count2 -= 1)
{
PEF_BlockMove ( packedPos, outputPos, count1 );
outputPos += count1;
}
packedPos += count1;
}
break;
case kPEFPkDataRepeatBlock :
count2 = GetPackedDataCount ( &packedPos );
count3 = GetPackedDataCount ( &packedPos );
if (((UInt32)(outPosLimit - outputPos)) < (((count1 + count2) * count3) + count1))
goto FragmentCorruptError;
{
BytePtr commonPos = packedPos;
packedPos += count1;
for (; count3 != 0; count3 -= 1)
{
PEF_BlockMove ( commonPos, outputPos, count1 );
outputPos += count1;
PEF_BlockMove ( packedPos, outputPos, count2 );
packedPos += count2;
outputPos += count2;
}
PEF_BlockMove ( commonPos, outputPos, count1 );
outputPos += count1;
}
break;
case kPEFPkDataRepeatZero :
count2 = GetPackedDataCount ( &packedPos );
count3 = GetPackedDataCount ( &packedPos );
if (((UInt32)(outPosLimit - outputPos)) < (((count1 + count2) * count3) + count1))
goto FragmentCorruptError;
PEF_BlockClear ( outputPos, count1 );
outputPos += count1;
for (; count3 != 0; count3 -= 1)
{
PEF_BlockMove ( packedPos, outputPos, count2 );
packedPos += count2;
outputPos += count2;
PEF_BlockClear ( outputPos, count1 );
outputPos += count1;
}
break;
default :
goto FragmentCorruptError;
}
}
if ((packedPos != (packedEnd + 1)) || (outputPos != outPosLimit))
goto FragmentCorruptError;
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
FragmentUsageError:
err = cfragFragmentUsageErr;
goto ERROR;
FragmentCorruptError:
err = cfragFragmentCorruptErr;
goto ERROR;
}
static void PartialBlockClear ( BytePtr outputBase,
ByteCount outputStartOffset,
ByteCount outputEndOffset,
ByteCount outputOffset,
ByteCount count )
{
if (((outputOffset + count) <= outputStartOffset) || (outputOffset > outputEndOffset))
return ;
if (outputOffset < outputStartOffset)
{
count -= (outputStartOffset - outputOffset);
outputOffset = outputStartOffset;
}
if (count > (outputEndOffset - outputOffset + 1))
count = outputEndOffset - outputOffset + 1;
PEF_BlockClear ( outputBase + (outputOffset - outputStartOffset), count );
}
static void PartialBlockMove ( BytePtr source,
BytePtr outputBase,
ByteCount outputStartOffset,
ByteCount outputEndOffset,
ByteCount outputOffset,
ByteCount count )
{
if (((outputOffset + count) <= outputStartOffset) || (outputOffset > outputEndOffset))
return ;
if (outputOffset < outputStartOffset)
{
const ByteCount skipCount = outputStartOffset - outputOffset;
source += skipCount;
count -= skipCount;
outputOffset = outputStartOffset;
}
if (count > (outputEndOffset - outputOffset + 1))
count = outputEndOffset - outputOffset + 1;
PEF_BlockMove ( source, outputBase + (outputOffset - outputStartOffset), count );
}
static OSStatus UnpackPartialSection ( BytePtr packedBase,
BytePtr packedEnd,
BytePtr outputBase,
BytePtr outputEnd,
ByteCount outputStartOffset )
{
OSStatus err = cfragCFMInternalErr;
const ByteCount outputEndOffset = outputStartOffset + (outputEnd - outputBase);
BytePtr packedPos = NULL;
BytePtr packedBoundary = NULL;
ByteCount outputOffset;
ByteCount outputBoundary;
UInt8 currByte;
UInt8 opcode;
UInt32 count1;
UInt32 count2;
UInt32 count3;
if (((packedEnd + 1) == 0) || ((outputEnd + 1) == 0))
goto FragmentUsageError;
outputOffset = 0;
packedPos = packedBase;
do
{
packedBoundary = packedPos; outputBoundary = outputOffset;
currByte = *packedPos++;
opcode = currByte >> kPEFPkDataOpcodeShift;
count1 = currByte & kPEFPkDataCount5Mask;
if (count1 == 0)
count1 = GetPackedDataCount ( &packedPos );
switch (opcode)
{
case kPEFPkDataZero :
outputOffset += count1;
break;
case kPEFPkDataBlock :
packedPos += count1;
outputOffset += count1;
break;
case kPEFPkDataRepeat :
count2 = GetPackedDataCount ( &packedPos ) + 1; packedPos += count1;
outputOffset += count1 * count2;
break;
case kPEFPkDataRepeatBlock :
count2 = GetPackedDataCount ( &packedPos );
count3 = GetPackedDataCount ( &packedPos );
packedPos += count1 + (count2 * count3);
outputOffset += count1 + ((count1 + count2) * count3);
break;
case kPEFPkDataRepeatZero :
count2 = GetPackedDataCount ( &packedPos );
count3 = GetPackedDataCount ( &packedPos );
packedPos += count2 * count3;
outputOffset += count1 + ((count1 + count2) * count3);
break;
default :
goto FragmentCorruptError;
}
}
while (outputOffset <= outputStartOffset);
packedPos = packedBoundary; outputOffset = outputBoundary;
do
{
currByte = *packedPos++;
opcode = currByte >> kPEFPkDataOpcodeShift;
count1 = currByte & kPEFPkDataCount5Mask;
if (count1 == 0)
count1 = GetPackedDataCount ( &packedPos );
switch (opcode)
{
case kPEFPkDataZero :
PartialBlockClear ( outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
outputOffset += count1;
break;
case kPEFPkDataBlock :
PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
packedPos += count1;
outputOffset += count1;
break;
case kPEFPkDataRepeat : count2 = GetPackedDataCount ( &packedPos ) + 1; for (; count2 != 0; count2 -= 1)
{
PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
outputOffset += count1;
}
packedPos += count1;
break;
case kPEFPkDataRepeatBlock :
count2 = GetPackedDataCount ( &packedPos );
count3 = GetPackedDataCount ( &packedPos );
{
BytePtr commonPos = packedPos;
packedPos += count1;
for (; count3 != 0; count3 -= 1)
{
PartialBlockMove ( commonPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
outputOffset += count1;
PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count2 );
packedPos += count2;
outputOffset += count2;
}
PartialBlockMove ( commonPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
outputOffset += count1;
}
break;
case kPEFPkDataRepeatZero :
count2 = GetPackedDataCount ( &packedPos );
count3 = GetPackedDataCount ( &packedPos );
PartialBlockClear ( outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
outputOffset += count1;
for (; count3 != 0; count3 -= 1)
{
PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count2 );
packedPos += count2;
outputOffset += count2;
PartialBlockClear ( outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
outputOffset += count1;
}
break;
default :
goto FragmentCorruptError;
}
}
while ((outputOffset <= outputEndOffset) && (packedPos <= packedEnd));
if (outputOffset <= outputEndOffset)
{
PEF_BlockClear ( outputBase + (outputOffset - outputStartOffset), outputEndOffset - outputOffset + 1 );
}
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
FragmentUsageError:
err = cfragFragmentUsageErr;
goto ERROR;
FragmentCorruptError:
err = cfragFragmentCorruptErr;
goto ERROR;
}
OSStatus PEF_UnpackSection ( CFContHandlerRef containerRef,
ItemCount sectionIndex,
ByteCount sectionOffset,
LogicalAddress bufferAddress,
ByteCount bufferLength )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
SectionHeader * section = NULL;
BytePtr packedBase = NULL;
BytePtr packedEnd = NULL;
BytePtr outputBase = bufferAddress;
BytePtr outputEnd = outputBase + bufferLength - 1;
if (pefPrivate == NULL)
goto ParameterError;
if (sectionIndex >= pefPrivate->sectionCount)
goto ParameterError;
if ((bufferAddress == NULL) && (bufferLength != 0))
goto ParameterError;
section = &pefPrivate->sections[sectionIndex];
if ((sectionOffset + bufferLength) > section->execSize)
goto ParameterError;
packedBase = pefPrivate->mappedContainer + section->containerOffset;
packedEnd = packedBase + section->rawSize - 1;
if ((sectionOffset == 0) && (bufferLength == section->initSize))
{
err = UnpackFullSection ( packedBase, packedEnd, outputBase, outputEnd );
if (err != noErr)
goto ERROR;
#if EnableCFMDebugging
if (false && EnableCFMDebugging && (section->execSize > 8))
{
UInt32 word;
BytePtr partContents = (*pefPrivate->Allocate) ( section->execSize - 2 );
PEF_Assert ( partContents != NULL );
err = PEF_UnpackSection ( containerRef, sectionIndex, 1, &word, 4 );
PEF_Assert ( err == noErr );
err = PEF_UnpackSection ( containerRef, sectionIndex, section->execSize / 2, &word, 4 );
PEF_Assert ( err == noErr );
err = PEF_UnpackSection ( containerRef, sectionIndex, section->execSize - 5, &word, 4 );
PEF_Assert ( err == noErr );
err = PEF_UnpackSection ( containerRef, sectionIndex, 1, partContents, section->execSize - 2 );
PEF_Assert ( err == noErr );
(*pefPrivate->Release) ( partContents );
}
#endif
}
else
{
if (section->initSize < sectionOffset)
{
PEF_BlockClear ( bufferAddress, bufferLength );
}
else
{
err = UnpackPartialSection ( packedBase, packedEnd, outputBase, outputEnd, sectionOffset );
if (err != noErr)
goto ERROR;
}
#if EnableCFMDebugging
if (EnableCFMDebugging)
{
BytePtr fullContents = (*pefPrivate->Allocate) ( section->execSize );
PEF_Assert ( fullContents != NULL );
PEF_BlockClear ( fullContents, section->execSize );
err = UnpackFullSection ( packedBase, packedEnd, fullContents, fullContents + section->initSize - 1 );
PEF_Assert ( err == noErr );
PEF_Assert ( PEF_CompareBytes ( fullContents + sectionOffset, bufferAddress, bufferLength ) );
(*pefPrivate->Release) ( fullContents );
}
#endif
}
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
OSStatus PEF_RelocateSection ( CFContHandlerRef containerRef,
ItemCount sectionIndex )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
BytePtr * raddr;
ByteCount dataA;
int cnt; ByteCount codeA;
LoaderRelExpHeader * ldRelHdr;
Relocation *reloc, *rlend;
Relocation r;
long rpt; long secn;
long rsymi;
BytePtr *imports;
ByteCount *regions;
long i;
long relNum;
BytePtr regStart;
SectionHeader * section;
if (pefPrivate == NULL)
goto ParameterError;
if (sectionIndex >= pefPrivate->sectionCount)
goto ParameterError;
regStart = pefPrivate->mappedOrigins[sectionIndex];
section = & pefPrivate->sections [sectionIndex];
pefPrivate->resolved = 1;
for (i = 0; ; i++)
{
if (((ItemCount) i) >= pefPrivate->sectionCount)
return noErr; ldRelHdr = & pefPrivate->ldrSections [i];
if (((ItemCount) ldRelHdr->sectionNumber) == sectionIndex)
break;
}
regions = pefPrivate->runningOffsets;
imports = pefPrivate->imports;
reloc = (Relocation *) (pefPrivate->ldrRelocations + ldRelHdr->relocationsOffset);
rlend = (Relocation *) ((RelocInstr *) reloc + ldRelHdr->numRelocations);
raddr = (BytePtr *) regStart; rsymi = 0;
codeA = regions [0];
dataA = regions [1];
rpt = 0;
#if 0
sprintf ( gDebugMessage, "PLPrepareRegion: start @ %.8X\n", raddr );
PutSerialMesssage ( gDebugMessage );
#endif
relNum = 0;
while (reloc < rlend)
{
r = *reloc;
reloc = (Relocation *) ((RelocInstr *) reloc + 1);
switch (opcode [r.opcode.op])
{
case krDDAT :
raddr = (BytePtr *) ((BytePtr)raddr + (r.deltadata.delta_d4 * 4)); cnt = r.deltadata.cnt;
while (--cnt >= 0)
{
*raddr++ += dataA;
}
break;
case krCODE :
cnt = r.run.cnt_m1 + 1;
while (--cnt >= 0)
{
*raddr++ += codeA;
}
break;
case krDATA :
cnt = r.run.cnt_m1 + 1;
while (--cnt >= 0)
{
*raddr++ += dataA;
}
break;
case krDESC :
cnt = r.run.cnt_m1 + 1;
while (--cnt >= 0)
{
*raddr++ += codeA;
*raddr++ += dataA;
raddr++;
}
break;
case krDSC2 :
cnt = r.run.cnt_m1 + 1;
while (--cnt >= 0)
{
*raddr++ += codeA;
*raddr++ += dataA;
}
break;
case krVTBL :
cnt = r.run.cnt_m1 + 1;
while (--cnt >= 0)
{
*raddr++ += dataA;
raddr++;
}
break;
case krSYMR :
cnt = r.run.cnt_m1 + 1;
while (--cnt >= 0)
{
*raddr++ += (ByteCount) imports [rsymi++];
}
break;
case krSYMB :
rsymi = r.glp.idx;
*raddr++ += (ByteCount) imports [rsymi++];
break;
case krCDIS :
codeA = regions [r.glp.idx];
break;
case krDTIS :
dataA = regions [r.glp.idx];
break;
case krSECN :
*raddr++ += regions [r.glp.idx];
break;
case krDELT :
raddr = (BytePtr *) ((BytePtr) raddr + r.delta.delta_m1 + 1); #if 0
sprintf ( gDebugMessage, "PLPrepareRegion: delta to %.8X\n", raddr );
PutSerialMesssage ( gDebugMessage );
#endif
break;
case krRPT :
if (--rpt == 0)
break; if (rpt < 0) rpt = r.rpt.rcnt_m1 + 1; cnt = r.rpt.icnt_m1 + 2; reloc = (Relocation *) ((RelocInstr *) reloc - cnt);
break;
case krLABS :
raddr = (BytePtr *) ((r.large1.idx_top << 16) + reloc->bot + regStart);
reloc = (Relocation *) ((RelocInstr *) reloc + 1);
#if 0
sprintf ( gDebugMessage, "PLPrepareRegion: abs to %.8X\n", raddr );
PutSerialMesssage ( gDebugMessage );
#endif
break;
case krLSYM :
rsymi = (r.large1.idx_top << 16) + reloc->bot;
reloc = (Relocation *) ((RelocInstr *) reloc + 1);
*raddr++ += (ByteCount) imports [rsymi++];
break;
case krLRPT :
if (--rpt == 0)
{
reloc = (Relocation *) ((RelocInstr *) reloc + 1);
break;
}
if (rpt < 0)
rpt = (r.large2.idx_top << 16) + reloc->bot;
cnt = r.large2.cnt_m1 + 2;
reloc = (Relocation *) ((RelocInstr *) reloc - cnt);
break;
case krLSEC :
secn = (r.large2.idx_top << 16) + reloc->bot;
switch (r.large2.cnt_m1)
{
case 0 :
*raddr++ += regions [secn];
break;
case 1 :
codeA = regions [secn];
break;
case 2 :
dataA = regions [secn];
break;
}
reloc = (Relocation *) ((RelocInstr *) reloc + 1);
break;
default :
goto FragmentCorruptError;
}
}
#if 0
sprintf ( gDebugMessage, "PLPrepareRegion: end @ %.8X\n", raddr );
PutSerialMesssage ( gDebugMessage );
#endif
err = noErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
FragmentCorruptError:
err = cfragFragmentCorruptErr;
goto ERROR;
}
OSStatus PEF_RelocateImportsOnly ( CFContHandlerRef containerRef,
ItemCount sectionIndex,
ItemCount libraryIndex )
{
OSStatus err = cfragCFMInternalErr;
PEFPrivateInfo * pefPrivate = (PEFPrivateInfo *) containerRef;
if (pefPrivate == NULL)
goto ParameterError;
if (sectionIndex >= pefPrivate->sectionCount)
goto ParameterError;
if (libraryIndex >= pefPrivate->ldrHeader->numImportFiles)
goto ParameterError;
if (pefPrivate == NULL)
goto ParameterError;
return unimpErr;
EXIT:
return err;
ERROR:
goto EXIT;
ParameterError:
err = paramErr;
goto ERROR;
}
#endif