#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)
extern Boolean PCFM_CompareBytes ( const Byte * left,
const Byte * right,
ByteCount count );
#define PEF_CompareBytes(a,b,c) PCFM_CompareBytes(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 == 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 != -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,
KernelProcessID runningProcessID,
const CFContHashedName * cfragName,
CFContOpenOptions options,
CFContAllocateMem Allocate,
CFContReleaseMem Release,
CFContHandlerRef * containerRef,
CFContHandlerProcsPtr * handlerProcs )
{
#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;
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; 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 ( 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 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 ( (outPosLimit - outputPos) < count1 ) goto FragmentCorruptError;
PEF_BlockClear ( outputPos, count1 );
outputPos += count1;
break;
case kPEFPkDataBlock :
if ( (outPosLimit - outputPos) < count1 ) goto FragmentCorruptError;
PEF_BlockMove ( packedPos, outputPos, count1 );
packedPos += count1;
outputPos += count1;
break;
case kPEFPkDataRepeat :
count2 = GetPackedDataCount ( &packedPos ) + 1;
if ( (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 ( (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 ( (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 ( i >= pefPrivate->sectionCount ) return noErr; ldRelHdr = & pefPrivate->ldrSections [i];
if ( 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