Annotation of driverkit/libDriver/ppc/IOPEFInternals.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*
        !            25:  * Copyright (c) 1997 Apple Computer, Inc.
        !            26:  *
        !            27:  *
        !            28:  * HISTORY
        !            29:  *
        !            30:  * Simon Douglas  22 Oct 97
        !            31:  * - first checked in.
        !            32:  */
        !            33: 
        !            34: 
        !            35: 
        !            36: /*
        !            37:     File:       PEFLoader.c
        !            38: 
        !            39:     Contains:   PEF loader implementation.
        !            40: 
        !            41:     Version:    Maxwell
        !            42: 
        !            43:     Copyright:  � 1994-1996 by Apple Computer, Inc., all rights reserved.
        !            44: 
        !            45:     File Ownership:
        !            46: 
        !            47:         DRI:                Alan Lillich
        !            48: 
        !            49:         Other Contact:      <<unknown>>
        !            50: 
        !            51:         Technology:         Core Runtime
        !            52: 
        !            53:     Writers:
        !            54: 
        !            55:         (AWL)   Alan Lillich
        !            56:         (ELE)   Erik Eidt
        !            57: 
        !            58:      Change History (most recent first):
        !            59: 
        !            60:         <26>     10/4/96    AWL     Disable partial unpacking tests.
        !            61:         <25>     9/26/96    AWL     Fix assertions to have the right polarity.
        !            62:         <24>     9/18/96    AWL     Simplify UnpackPartialSection.
        !            63:         <23>     8/27/96    AWL     Support partial unpacking in PEF_UnpackSection.
        !            64:         <22>     8/23/96    AWL     (1379028) Propagate changes from CodeFragmentContainerPriv.
        !            65:         <21>     8/16/96    AWL     Isolate memory utilities to work with both CFM and ProtoCFM.
        !            66:         <20>     4/18/96    AWL     (1342167) Fix problems with relocations for in-place sections.
        !            67:         <19>      4/2/96    AWL     (1336962) Fix checks for missing optional parameters.
        !            68:         <18>      3/7/96    AWL     Remove unused variable in PEF_UnpackSection.
        !            69:         <17>     2/28/96    AWL     Adapt for new container handler model.
        !            70:         <16>     1/19/96    AWL     Changes for D11.
        !            71:         <15>    10/10/95    AWL     Minor cleanup for CodeWarrior's strict checking.
        !            72:         <14>     6/14/95    AWL     Pick up flags from CFMWhere ASAP.
        !            73:         <13>     5/23/95    AWL     Introduce temporary hack to workaround build problem for 68K
        !            74:                                     ModernOS booting code. *** THIS BREAKS REAL 68K BUILDS! ***
        !            75:         <12>      2/8/95    AWL     Update debug output calls.
        !            76:         <11>    12/14/94    AWL     Changes for Maxwell D4 build.
        !            77:         <10>     12/2/94    AWL     Disable reexported import optimization because of problems with
        !            78:                                     missing weak libraries. It could be put back later with the
        !            79:                                     addition of a "resolvedImports" bit vector.
        !            80:          <9>      9/9/94    AWL     Switch to the "real" API and SPI headers.
        !            81:          <8>      9/2/94    AWL     Error codes are now in Errors.h.
        !            82:          <7>     7/28/94    AWL     Return cfragSymbolNotFound instead of paramErr from
        !            83:                                     PLFindExportInfo. (#1177313)
        !            84:          <6>     7/12/94    AWL     Fix load-in-place processing in SetRegionAddress.
        !            85:          <5>     6/20/94    AWL     Allow the CFL info pointer to be NULL for a "get procs" call to
        !            86:                                     OpenContainer.
        !            87:          <4>      5/9/94    AWL     Change PLGetSpecialSectionInfo to handle some of the wierdness
        !            88:                                     in nonloaded sections.
        !            89:          <3>     4/28/94    AWL     Simplify cross address space use for booting. Fix problem with
        !            90:                                     load in place, should not require SetRegionAddress.
        !            91:          <2>     2/25/94    AWL     Update for Q&D solution to loading across address spaces.
        !            92:                                     Fix problem in PLGetSpecialSectionInfo switch statement.
        !            93:          <1>     2/15/94    AWL     Initial checkin for kernel based CFM.
        !            94: 
        !            95:           ------------------------------------------------------------------------------------
        !            96: 
        !            97:         <31>    09/15/93    AWL     (&ELE) Add CFL prefix to hash functions.
        !            98:         <30>    09/08/93    ELE     (&AWL) Fix sneaky little typo that causes load failure.
        !            99:         <29>    08/30/93    AWL     Add declaration so that 68K native CFM compiles.
        !           100:         <28>    08/26/93    AWL     Move CFTypes.h and CFLoader.h up with other Apple private
        !           101:                                     headers.
        !           102:         <26>    07/08/93    AWL     (&ELE) Fixed version field names in import file IDs.
        !           103:                                     Remove version < 0 checks as versions are unsigned.
        !           104:         <25>    06/16/93    ELE     ELE & AWL Change to New Pool allocation.
        !           105:         <24>    06/09/93    ELE     ELE & AWL Fix bug in GetSpecialSection for debugger.
        !           106:         <23>    06/09/93    JRG     ELE & AWL Changes:
        !           107:         <22>    06/08/93    ELE     (&AWL) Shift to allocation bottleneck.  Added support for
        !           108:                                     packed data sections.  Switched to new CFLoader section
        !           109:                                     attribute bits.
        !           110:         <21>    02/15/93    ELE     Changed NewPtr->NewPtrSys
        !           111:         <20>    02/03/93    ELE     Added architecture pass thru to GetVersion per CFL Spec.
        !           112:         <19>    12/23/92    ELE     Fixed bug where init routine was being returned for the
        !           113:                                     term routine.
        !           114:         <17>    10/29/92    ELE     GetVersion - added dateStamp.
        !           115:         <16>    10/01/92    ELE     fix bug in use in place, update of header!
        !           116:         <15>    10/01/92    ELE     fix bug in use in place!
        !           117:         <14>    09/28/92    ELE     needed to update field expIndex from Find/GetExportInfo.
        !           118:         <13>    09/23/92    ELE     updated to new PEF format, updated to new CF Loader SPI.
        !           119:         <12>    09/23/92    ELE     Latest version.
        !           120: 
        !           121: */
        !           122: 
        !           123: 
        !           124: #import "IOPEFInternals.h"
        !           125: 
        !           126: // ===========================================================================================
        !           127: 
        !           128: #define PEF_Assert(a)          if( !(a)) kprintf("PEF_Assert:")
        !           129: #define PEF_BlockMove(src,dst,len) memcpy(dst,src,len)
        !           130: #define PEF_BlockClear(dst,len)    memset(dst,0,len)
        !           131: extern Boolean  PCFM_CompareBytes   ( const Byte *  left,
        !           132:                               const Byte *  right,
        !           133:                               ByteCount     count );
        !           134: #define PEF_CompareBytes(a,b,c) PCFM_CompareBytes(a,b,c)
        !           135: 
        !           136: #define EnableCFMDebugging     0
        !           137: 
        !           138: // ===========================================================================================
        !           139: 
        !           140: 
        !           141: enum {
        !           142:     kPEFHandlerProcCount    = 18
        !           143: };
        !           144: 
        !           145: static CFContHandlerProcs   PEFHandlerProcs = {
        !           146:     kPEFHandlerProcCount,
        !           147:     kCFContHandlerABIVersion,
        !           148: 
        !           149:     PEF_OpenContainer,                  //  1
        !           150:     PEF_CloseContainer,                 //  2
        !           151:     PEF_GetContainerInfo,               //  3
        !           152: 
        !           153:     PEF_GetSectionCount,                //  4
        !           154:     PEF_GetSectionInfo,                 //  5
        !           155:     PEF_FindSectionInfo,                //  6
        !           156:     PEF_SetSectionAddress,              //  7
        !           157: 
        !           158:     PEF_GetAnonymousSymbolLocations,    //  8
        !           159: 
        !           160:     PEF_GetExportedSymbolCount,         //  9
        !           161:     PEF_GetExportedSymbolInfo,          // 10
        !           162:     PEF_FindExportedSymbolInfo,         // 11
        !           163: 
        !           164:     PEF_GetImportCounts,                // 12
        !           165:     PEF_GetImportedLibraryInfo,         // 13
        !           166:     PEF_GetImportedSymbolInfo,          // 14
        !           167:     PEF_SetImportedSymbolAddress,       // 15
        !           168: 
        !           169:     PEF_UnpackSection,                  // 16
        !           170:     PEF_RelocateSection,                // 17
        !           171:     PEF_RelocateImportsOnly,            // 18
        !           172: };
        !           173: 
        !           174: 
        !           175: #if EnableCFMDebugging
        !           176:     static char gDebugMessage [256];
        !           177: #endif
        !           178: 
        !           179: // ===========================================================================================
        !           180: 
        !           181: const unsigned char opcode [128] = {
        !           182:          krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
        !           183:          krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
        !           184:          krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
        !           185:          krDDAT,krDDAT,krDDAT,krDDAT, krDDAT,krDDAT,krDDAT,krDDAT,
        !           186: 
        !           187:          krCODE,krDATA,krDESC,krDSC2, krVTBL,krSYMR,krXXXX,krXXXX,
        !           188:          krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
        !           189:          krSYMB,krCDIS,krDTIS,krSECN, krXXXX,krXXXX,krXXXX,krXXXX,
        !           190:          krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
        !           191: 
        !           192:          krDELT,krDELT,krDELT,krDELT, krDELT,krDELT,krDELT,krDELT,
        !           193:          krRPT ,krRPT ,krRPT ,krRPT , krRPT ,krRPT ,krRPT ,krRPT ,
        !           194:          krLABS,krLABS,krLSYM,krLSYM, krXXXX,krXXXX,krXXXX,krXXXX,
        !           195:          krLRPT,krLRPT,krLSEC,krLSEC, krXXXX,krXXXX,krXXXX,krXXXX,
        !           196: 
        !           197:          krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
        !           198:          krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
        !           199:          krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
        !           200:          krXXXX,krXXXX,krXXXX,krXXXX, krXXXX,krXXXX,krXXXX,krXXXX,
        !           201: };
        !           202: 
        !           203: // �
        !           204: // ===========================================================================================
        !           205: // GetNameLength ()
        !           206: // ================
        !           207: 
        !           208: 
        !           209: static ByteCount    GetNameLength   ( BytePtr nameStart )
        !           210: {
        !           211:     BytePtr nameEnd = nameStart;
        !           212: 
        !           213: 
        !           214:     if ( nameStart != NULL ) {
        !           215:         while ( *nameEnd != 0 ) nameEnd += 1;
        !           216:     }
        !           217: 
        !           218:     return (nameEnd - nameStart);
        !           219: 
        !           220: 
        !           221: }   // GetNameLength ()
        !           222: 
        !           223: 
        !           224: // �
        !           225: // ===========================================================================================
        !           226: // FindRelocationInfo ()
        !           227: // =====================
        !           228: 
        !           229: 
        !           230: static LoaderRelExpHeader * FindRelocationInfo  ( PEFPrivateInfo *  pefPrivate,
        !           231:                                                   ItemCount         sectionIndex )
        !           232: {
        !           233:     LoaderRelExpHeader *    relocInfo   = NULL;
        !           234:     const ItemCount         loopLimit   = pefPrivate->ldrHeader->numSections;
        !           235:     ItemCount               relocIndex;
        !           236: 
        !           237: 
        !           238:     for ( relocIndex = 0; relocIndex < loopLimit; relocIndex += 1 ) {
        !           239:         relocInfo = &pefPrivate->ldrSections[relocIndex];
        !           240:         if ( sectionIndex == relocInfo->sectionNumber ) return relocInfo;
        !           241:     }
        !           242:     return NULL;
        !           243: 
        !           244: 
        !           245: }   // FindRelocationInfo ()
        !           246: 
        !           247: 
        !           248: // �
        !           249: // ===========================================================================================
        !           250: // GetSectionName ()
        !           251: // =================
        !           252: 
        !           253: 
        !           254: static void GetSectionName  ( PEFPrivateInfo *      pefPrivate,
        !           255:                               SectionHeader *       sectionHeader,
        !           256:                               CFContHashedName *    sectionName )
        !           257: {
        !           258:     CFContStringHash    nameHash    = 0;
        !           259:     BytePtr             nameText    = NULL;
        !           260:     ByteCount           nameLength;
        !           261: 
        !           262: 
        !           263:     if ( sectionHeader->sectionName != -1 ) {
        !           264:         nameText    = pefPrivate->stringTable + sectionHeader->sectionName;
        !           265:         nameLength  = GetNameLength ( nameText );
        !           266:         nameHash    = CFContHashName ( nameText, nameLength );
        !           267:     }
        !           268: 
        !           269:     sectionName->nameHash   = nameHash;
        !           270:     sectionName->nameText   = nameText;
        !           271: 
        !           272: 
        !           273: }   // GetSectionName ()
        !           274: 
        !           275: 
        !           276: // �
        !           277: // ===========================================================================================
        !           278: // PEF_OpenContainer ()
        !           279: // ====================
        !           280: 
        !           281: 
        !           282: OSStatus    PEF_OpenContainer   ( LogicalAddress            mappedAddress,
        !           283:                                   LogicalAddress            runningAddress,
        !           284:                                   ByteCount                 containerLength,
        !           285:                                   KernelProcessID           runningProcessID,
        !           286:                                   const CFContHashedName *  cfragName,
        !           287:                                   CFContOpenOptions         options,
        !           288:                                   CFContAllocateMem         Allocate,
        !           289:                                   CFContReleaseMem          Release,
        !           290:                                   CFContHandlerRef *        containerRef,
        !           291:                                   CFContHandlerProcsPtr *   handlerProcs )
        !           292: {
        !           293:     #pragma unused ( containerLength )
        !           294:     #pragma unused ( runningProcessID )
        !           295:     #pragma unused ( cfragName )
        !           296: 
        !           297:     OSStatus                err             = -1;//cfragCFMInternalErr;
        !           298:     FileHeader *            fileHeader      = (FileHeader *) mappedAddress;
        !           299:     PEFPrivateInfo *        pefPrivate      = NULL;
        !           300:     SectionHeader *         loaderSection   = NULL;
        !           301:     SInt32                  sectionIndex;
        !           302: 
        !           303: 
        !           304:     if ( (sizeof ( PEF_SBits32 ) != 4) | (sizeof ( PEF_UBits32 ) != 4) ) goto InternalError;    // ! Is "int" 32 bits?
        !           305: 
        !           306:     if ( (Allocate == NULL)     ||
        !           307:          (Release == NULL)      ||
        !           308:          (containerRef == NULL) ||
        !           309:          (handlerProcs == NULL) ) goto ParameterError;
        !           310: 
        !           311:     *containerRef   = NULL;     // Clear for errors, only set on OK path.
        !           312:     *handlerProcs   = NULL;
        !           313: 
        !           314: 
        !           315:     // ---------------------------------------------------------------------------------
        !           316:     // Allow the container address to be null as a special case to get the loader procs.
        !           317:     // Otherwise validate the header as acceptable PEF.
        !           318: 
        !           319:     if ( mappedAddress == NULL ) goto OK;
        !           320: 
        !           321:     if ( (fileHeader->magic1 != kPEFMagic1)     ||
        !           322:          (fileHeader->magic2 != kPEFMagic2)     ||
        !           323:          (fileHeader->fileTypeID != kPEFTypeID) ||
        !           324:          (fileHeader->versionNumber != kPEFVersion) )   goto FragmentFormatError;
        !           325: 
        !           326: 
        !           327:     // -----------------------------------------------
        !           328:     // Allocate and initialize the private info block.
        !           329: 
        !           330:     pefPrivate = (PEFPrivateInfo *) ((*Allocate) ( sizeof ( PEFPrivateInfo ) ));
        !           331:     if ( pefPrivate == NULL ) goto PrivateMemoryError;
        !           332: 
        !           333:     PEF_BlockClear ( pefPrivate, sizeof ( *pefPrivate ) );
        !           334: 
        !           335:     pefPrivate->Allocate            = Allocate;
        !           336:     pefPrivate->Release             = Release;
        !           337:     pefPrivate->mappedContainer     = (BytePtr) mappedAddress;
        !           338:     pefPrivate->runningContainer    = (BytePtr) runningAddress;
        !           339:     pefPrivate->sectionCount        = fileHeader->loadableSections;
        !           340:     pefPrivate->sections            = (SectionHeader *) (fileHeader + 1);
        !           341:     pefPrivate->stringTable         = (BytePtr) (&pefPrivate->sections[fileHeader->numberSections]);
        !           342:     pefPrivate->loadInPlace         = ((options & kCFContPrepareInPlaceMask) != 0);
        !           343: 
        !           344:     // -----------------------------------------------------
        !           345:     // Find the loader section and extract important fields.
        !           346: 
        !           347:     for ( sectionIndex = 0; sectionIndex < fileHeader->numberSections; sectionIndex += 1 ) {
        !           348:         loaderSection = & pefPrivate->sections[sectionIndex];
        !           349:         if ( loaderSection->regionKind == kPEFLoaderSection ) break;
        !           350:     }
        !           351:     if ( sectionIndex == fileHeader->numberSections ) goto FragmentCorruptError;
        !           352: 
        !           353:     pefPrivate->ldrSectionNo        = sectionIndex;
        !           354:     pefPrivate->ldrHeader           = (LoaderHeader *) ((BytePtr)mappedAddress + loaderSection->containerOffset);
        !           355:     pefPrivate->ldrStringTable      = (BytePtr)pefPrivate->ldrHeader + pefPrivate->ldrHeader->stringsOffset;
        !           356: 
        !           357:     pefPrivate->ldrImportFiles      = (LoaderImportFileID *) (pefPrivate->ldrHeader + 1);
        !           358:     pefPrivate->ldrImportSymbols    = (LoaderImport *) (pefPrivate->ldrImportFiles + pefPrivate->ldrHeader->numImportFiles);
        !           359:     pefPrivate->ldrSections         = (LoaderRelExpHeader *) (pefPrivate->ldrImportSymbols + pefPrivate->ldrHeader->numImportSyms);
        !           360:     pefPrivate->ldrRelocations      = (BytePtr)pefPrivate->ldrHeader + pefPrivate->ldrHeader->relocationsOffset;
        !           361: 
        !           362:     pefPrivate->ldrHashSlot         = (HashSlotEntry *) ((BytePtr)pefPrivate->ldrHeader + pefPrivate->ldrHeader->hashSlotTable);
        !           363:     pefPrivate->ldrHashChain        = (HashChainEntry *) (pefPrivate->ldrHashSlot + (1 << pefPrivate->ldrHeader->hashSlotTabSize));
        !           364:     pefPrivate->ldrExportSymbols    = (LoaderExport *) (pefPrivate->ldrHashChain + pefPrivate->ldrHeader->numExportSyms);
        !           365: 
        !           366:     // ----------------------------------------------------
        !           367:     // Set up the array to store resolved import addresses.
        !           368: 
        !           369:     if ( pefPrivate->ldrHeader->numImportSyms > 0 ) {
        !           370:         pefPrivate->imports = (BytePtr *) ((*Allocate) ( pefPrivate->ldrHeader->numImportSyms * sizeof ( BytePtr ) ));
        !           371:         if ( pefPrivate->imports == NULL ) goto PrivateMemoryError;
        !           372:     }
        !           373: 
        !           374:     // -----------------------------------------------------------------
        !           375:     // Set up the pointers to the arrays of section origins and offsets.
        !           376: 
        !           377:     if (pefPrivate->sectionCount <= kBuiltinSectionArraySize) {
        !           378:         pefPrivate->mappedOrigins   = & pefPrivate->originArray[0];
        !           379:         pefPrivate->runningOffsets  = & pefPrivate->offsetArray[0];
        !           380:     } else {
        !           381:         pefPrivate->mappedOrigins   = (BytePtr *) ((*Allocate) ( pefPrivate->sectionCount * sizeof ( BytePtr ) ));
        !           382:         if ( pefPrivate->mappedOrigins == NULL ) goto PrivateMemoryError;
        !           383:         pefPrivate->runningOffsets = (ByteCount *) ((*Allocate) ( pefPrivate->sectionCount * sizeof ( ByteCount ) ));
        !           384:         if ( pefPrivate->runningOffsets == NULL ) goto PrivateMemoryError;
        !           385:     }
        !           386: 
        !           387:     // ---------------------------------------------------------------------------------------
        !           388:     // Fill in the origin and offset arrays.  The origin array gives the base address of the
        !           389:     // section instance as visible in the loader's address space.  I.e. it tells the loader
        !           390:     // where it can access the loaded section contents.  The offset array tells what to add
        !           391:     // for relocations refering to that section.  So it must be based on running addresses and
        !           392:     // must "remove" the presumed running address.  If the section will be used in place we
        !           393:     // must compute the final values here.  Otherwise SetRegionAddress will be called later to
        !           394:     // provide the mapped and running addresses.  Validate load in place restrictions too.
        !           395: 
        !           396:     // ??? We really ought to consider getting rid of the preset for in-place usage and make
        !           397:     // ??? that case as close as possible to the normal case.
        !           398: 
        !           399:     // ! Note that although the ByteCount type used in the offset arrays is unsigned, ignoring
        !           400:     // ! overflow lets things work right for a full -4GB to +4GB offset range.
        !           401: 
        !           402:     for ( sectionIndex = 0; sectionIndex < pefPrivate->sectionCount; sectionIndex += 1 ) {
        !           403: 
        !           404:         SectionHeader * section = & pefPrivate->sections[sectionIndex];
        !           405: 
        !           406:         pefPrivate->mappedOrigins[sectionIndex]     = (BytePtr) -1; // ! Just a diagnostic tag.
        !           407:         pefPrivate->runningOffsets[sectionIndex]    = - ((ByteCount) section->sectionAddress);  // Subtract the presumed address.
        !           408: 
        !           409:         if ( pefPrivate->loadInPlace ) {
        !           410:             if ( (section->regionKind == kPEFPIDataSection) || (section->execSize != section->rawSize) ) goto FragmentUsageError;
        !           411:             section->sectionAddress                     = pefPrivate->runningContainer + section->containerOffset;
        !           412:             pefPrivate->mappedOrigins[sectionIndex]     = pefPrivate->mappedContainer + section->containerOffset;
        !           413:             pefPrivate->runningOffsets[sectionIndex]    += (ByteCount) section->sectionAddress;     // Add in the new address.
        !           414:         }
        !           415: 
        !           416:     }
        !           417: 
        !           418:     if ( options & kCFContPrepareInPlaceMask ) fileHeader->memoryAddress = runningAddress;
        !           419: 
        !           420: 
        !           421: OK:
        !           422:     err = noErr;
        !           423:     *handlerProcs = &PEFHandlerProcs;
        !           424:     *containerRef = (CFContHandlerRef) pefPrivate;
        !           425: 
        !           426: EXIT:
        !           427:     return err;
        !           428: 
        !           429: ERROR:
        !           430:     (void) PEF_CloseContainer ( (CFContHandlerRef) pefPrivate, kNilOptions );
        !           431:     goto EXIT;
        !           432: 
        !           433: InternalError:
        !           434:     err = cfragCFMInternalErr;
        !           435:     goto ERROR;
        !           436: 
        !           437: ParameterError:
        !           438:     err = paramErr;
        !           439:     goto ERROR;
        !           440: 
        !           441: FragmentFormatError:
        !           442:     err = cfragFragmentFormatErr;
        !           443:     goto ERROR;
        !           444: 
        !           445: PrivateMemoryError:
        !           446:     err = cfragNoPrivateMemErr;
        !           447:     goto ERROR;
        !           448: 
        !           449: FragmentCorruptError:
        !           450:     err = cfragFragmentCorruptErr;
        !           451:     goto ERROR;
        !           452: 
        !           453: FragmentUsageError:
        !           454:     err = cfragFragmentUsageErr;
        !           455:     goto ERROR;
        !           456: 
        !           457: 
        !           458: }   // PEF_OpenContainer ()
        !           459: 
        !           460: 
        !           461: // �
        !           462: // ===========================================================================================
        !           463: // PEF_CloseContainer ()
        !           464: // =====================
        !           465: 
        !           466: 
        !           467: OSStatus    PEF_CloseContainer  ( CFContHandlerRef      containerRef,
        !           468:                                   CFContCloseOptions    options )
        !           469: {
        !           470:     OSStatus            err         = cfragCFMInternalErr;
        !           471:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !           472:     CFContReleaseMem    Release     = NULL;
        !           473: 
        !           474: 
        !           475:     if ( pefPrivate == NULL ) goto OK;  // Simplifies error cleanup from PEF_OpenContainer.
        !           476: 
        !           477: 
        !           478:     Release = pefPrivate->Release;
        !           479: 
        !           480:     if ( pefPrivate->sectionCount > kBuiltinSectionArraySize ) {
        !           481:         if ( pefPrivate->mappedOrigins != NULL ) {
        !           482:             (*Release) ( pefPrivate->mappedOrigins );
        !           483:             pefPrivate->mappedOrigins = NULL;
        !           484:         }
        !           485:         if ( pefPrivate->runningOffsets != NULL ) {
        !           486:             (*Release) ( pefPrivate->runningOffsets );
        !           487:             pefPrivate->runningOffsets = NULL;
        !           488:         }
        !           489:     }
        !           490: 
        !           491:     if ( pefPrivate->imports != NULL ) {
        !           492:         (*Release) ( pefPrivate->imports );
        !           493:         pefPrivate->imports = NULL;
        !           494:     }
        !           495: 
        !           496:     pefPrivate->resolved = 0;   // ! Disables reexported import optimization.
        !           497: 
        !           498:     if ( ! (options & kCFContPartialCloseMask) ) (*Release) ( pefPrivate );
        !           499: 
        !           500: 
        !           501: OK:
        !           502:     err = noErr;
        !           503: 
        !           504: EXIT:
        !           505:     return err;
        !           506: 
        !           507: ERROR:
        !           508:     goto EXIT;
        !           509: 
        !           510: 
        !           511: }   // PEF_CloseContainer ()
        !           512: 
        !           513: 
        !           514: // �
        !           515: // ===========================================================================================
        !           516: // PEF_GetContainerInfo ()
        !           517: // =======================
        !           518: 
        !           519: 
        !           520: OSStatus    PEF_GetContainerInfo    ( CFContHandlerRef      containerRef,
        !           521:                                       PBVersion             infoVersion,
        !           522:                                       CFContContainerInfo * containerInfo )
        !           523: {
        !           524:     OSStatus            err         = cfragCFMInternalErr;
        !           525:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !           526:     FileHeader *        fileHeader  = NULL;
        !           527: 
        !           528: 
        !           529:     if ( (pefPrivate == NULL) || (containerInfo == NULL) ) goto ParameterError;
        !           530:     if ( infoVersion != kCFContContainerInfoVersion ) goto ParameterError;
        !           531: 
        !           532: 
        !           533:     fileHeader  = (FileHeader *) pefPrivate->mappedContainer;
        !           534: 
        !           535:     containerInfo->cfragName.nameHash   = 0;    // PEF does not have an embedded name.
        !           536:     containerInfo->cfragName.nameText   = NULL;
        !           537: 
        !           538:     containerInfo->modDate          = fileHeader->dateTimeStamp;
        !           539:     containerInfo->architecture     = fileHeader->architectureID;
        !           540:     containerInfo->currentVersion   = fileHeader->currentVersion;
        !           541:     containerInfo->oldImpVersion    = fileHeader->oldImpVersion;
        !           542:     containerInfo->oldDefVersion    = fileHeader->oldDefVersion;
        !           543: 
        !           544: 
        !           545: OK:
        !           546:     err = noErr;
        !           547: 
        !           548: EXIT:
        !           549:     return err;
        !           550: 
        !           551: ERROR:
        !           552:     goto EXIT;
        !           553: 
        !           554: ParameterError:
        !           555:     err = paramErr;
        !           556:     goto ERROR;
        !           557: 
        !           558: 
        !           559: }   // PEF_GetContainerInfo ()
        !           560: 
        !           561: 
        !           562: // �
        !           563: // ===========================================================================================
        !           564: // PEF_GetSectionCount ()
        !           565: // ======================
        !           566: 
        !           567: 
        !           568: OSStatus    PEF_GetSectionCount ( CFContHandlerRef  containerRef,
        !           569:                                   ItemCount *       sectionCount )
        !           570: {
        !           571:     OSStatus            err         = cfragCFMInternalErr;
        !           572:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !           573: 
        !           574: 
        !           575:     if ( (pefPrivate == NULL) || (sectionCount == NULL) ) goto ParameterError;
        !           576: 
        !           577:     *sectionCount = pefPrivate->sectionCount;
        !           578: 
        !           579: 
        !           580: OK:
        !           581:     err = noErr;
        !           582: 
        !           583: EXIT:
        !           584:     return err;
        !           585: 
        !           586: ERROR:
        !           587:     goto EXIT;
        !           588: 
        !           589: ParameterError:
        !           590:     err = paramErr;
        !           591:     goto ERROR;
        !           592: 
        !           593: 
        !           594: }   // PEF_GetSectionCount ()
        !           595: 
        !           596: 
        !           597: // �
        !           598: // ===========================================================================================
        !           599: // PEF_GetSectionInfo ()
        !           600: // =====================
        !           601: 
        !           602: 
        !           603: OSStatus    PEF_GetSectionInfo  ( CFContHandlerRef      containerRef,
        !           604:                                   ItemCount             sectionIndex,
        !           605:                                   PBVersion             infoVersion,
        !           606:                                   CFContSectionInfo *   sectionInfo )
        !           607: {
        !           608:     OSStatus            err             = cfragCFMInternalErr;
        !           609:     PEFPrivateInfo *    pefPrivate      = (PEFPrivateInfo *) containerRef;
        !           610:     SectionHeader *     sectionHeader   = NULL;
        !           611: 
        !           612: 
        !           613:     if ( (pefPrivate == NULL) || (sectionInfo == NULL) ) goto ParameterError;
        !           614:     if ( infoVersion != kCFContSectionInfoVersion ) goto ParameterError;
        !           615:     if ( sectionIndex >= pefPrivate->sectionCount ) goto ParameterError;
        !           616: 
        !           617: 
        !           618:     sectionHeader = &pefPrivate->sections[sectionIndex];
        !           619: 
        !           620:     GetSectionName ( pefPrivate, sectionHeader, &sectionInfo->sectionName );
        !           621: 
        !           622:     sectionInfo->sharing            = sectionHeader->shareKind;
        !           623:     sectionInfo->alignment          = sectionHeader->alignment;
        !           624:     sectionInfo->reservedA          = 0;
        !           625:     sectionInfo->containerOffset    = sectionHeader->containerOffset;
        !           626:     sectionInfo->containerLength    = sectionHeader->rawSize;
        !           627:     sectionInfo->unpackedLength     = sectionHeader->initSize;
        !           628:     sectionInfo->totalLength        = sectionHeader->execSize;
        !           629:     sectionInfo->defaultAddress     = sectionHeader->sectionAddress;
        !           630: 
        !           631:     sectionInfo->options = kNilOptions;
        !           632:     if ( FindRelocationInfo ( pefPrivate, sectionIndex ) != NULL ) sectionInfo->options |= kRelocatedCFContSectionMask;
        !           633: 
        !           634:     switch ( pefPrivate->sections[sectionIndex].regionKind ) {
        !           635:         case kPEFCodeSection :
        !           636:             sectionInfo->access = kCFContNormalCode;
        !           637:             break;
        !           638:         case kPEFDataSection :
        !           639:             sectionInfo->access = kCFContWriteableData;
        !           640:             break;
        !           641:         case kPEFPIDataSection :
        !           642:             sectionInfo->access = kCFContWriteableData;
        !           643:             sectionInfo->options |= kPackedCFContSectionMask;
        !           644:             break;
        !           645:         case kPEFConstantSection :
        !           646:             sectionInfo->access = kCFContReadOnlyData;
        !           647:             break;
        !           648:         case kPEFExecDataSection :
        !           649:             sectionInfo->access = kCFContWriteableData | kCFContMemExecuteMask;
        !           650:             break;
        !           651:         default :
        !           652:             sectionInfo->access = kCFContReadOnlyData;  // ! Not necessarily right, but safe.
        !           653:             break;
        !           654:     }
        !           655: 
        !           656: 
        !           657: OK:
        !           658:     err = noErr;
        !           659: 
        !           660: EXIT:
        !           661:     return err;
        !           662: 
        !           663: ERROR:
        !           664:     goto EXIT;
        !           665: 
        !           666: ParameterError:
        !           667:     err = paramErr;
        !           668:     goto ERROR;
        !           669: 
        !           670: 
        !           671: }   // PEF_GetSectionInfo ()
        !           672: 
        !           673: 
        !           674: // �
        !           675: // ===========================================================================================
        !           676: // PEF_FindSectionInfo ()
        !           677: // ======================
        !           678: 
        !           679: 
        !           680: OSStatus    PEF_FindSectionInfo ( CFContHandlerRef          containerRef,
        !           681:                                   const CFContHashedName *  sectionName,
        !           682:                                   PBVersion                 infoVersion,
        !           683:                                   ItemCount *               sectionIndex,   // May be null.
        !           684:                                   CFContSectionInfo *       sectionInfo )   // May be null.
        !           685: {
        !           686:     OSStatus            err             = cfragCFMInternalErr;
        !           687:     PEFPrivateInfo *    pefPrivate      = (PEFPrivateInfo *) containerRef;
        !           688:     SectionHeader *     sectionHeader   = NULL;
        !           689:     CFContHashedName    hashedName;
        !           690: 
        !           691:     ItemCount           tempIndex;
        !           692:     CFContSectionInfo   tempInfo;
        !           693: 
        !           694: 
        !           695:     if ( pefPrivate == NULL ) goto ParameterError;
        !           696:     if ( (sectionInfo != NULL) && (infoVersion != kCFContSectionInfoVersion) ) goto ParameterError;
        !           697: 
        !           698:     if ( sectionIndex == NULL ) sectionIndex = &tempIndex;
        !           699:     if ( sectionInfo == NULL ) sectionInfo = &tempInfo;
        !           700: 
        !           701: 
        !           702:     for ( tempIndex = 0; tempIndex < pefPrivate->sectionCount; tempIndex += 1 ) {
        !           703:         sectionHeader = &pefPrivate->sections[tempIndex];
        !           704:         GetSectionName ( pefPrivate, sectionHeader, &hashedName );
        !           705:         if ( (hashedName.nameHash == sectionName->nameHash) &&
        !           706:              (PEF_CompareBytes ( hashedName.nameText, sectionName->nameText, CFContStringHashLength ( hashedName.nameHash ) )) ) break;
        !           707:     }
        !           708:     if ( tempIndex == pefPrivate->sectionCount ) goto NoSectionError;
        !           709:     *sectionIndex = tempIndex;
        !           710: 
        !           711:     err = PEF_GetSectionInfo ( containerRef, tempIndex, infoVersion, sectionInfo );
        !           712:     if ( err != noErr ) goto ERROR;
        !           713: 
        !           714: 
        !           715: OK:
        !           716:     err = noErr;
        !           717: 
        !           718: EXIT:
        !           719:     return err;
        !           720: 
        !           721: ERROR:
        !           722:     goto EXIT;
        !           723: 
        !           724: ParameterError:
        !           725:     err = paramErr;
        !           726:     goto ERROR;
        !           727: 
        !           728: NoSectionError:
        !           729:     err = cfragNoSectionErr;
        !           730:     goto ERROR;
        !           731: 
        !           732: 
        !           733: }   // PEF_FindSectionInfo ()
        !           734: 
        !           735: 
        !           736: // �
        !           737: // ===========================================================================================
        !           738: // PEF_SetSectionAddress ()
        !           739: // ========================
        !           740: 
        !           741: 
        !           742: OSStatus    PEF_SetSectionAddress   ( CFContHandlerRef  containerRef,
        !           743:                                       ItemCount         sectionIndex,
        !           744:                                       LogicalAddress    mappedAddress,
        !           745:                                       LogicalAddress    runningAddress )
        !           746: {
        !           747:     OSErr               err         = cfragCFMInternalErr;
        !           748:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !           749:     SectionHeader *     section     = NULL;
        !           750: 
        !           751: 
        !           752:     if ( (pefPrivate == NULL)   || (sectionIndex >= pefPrivate->sectionCount) ) goto ParameterError;
        !           753: 
        !           754: 
        !           755:     // --------------------------------------------------------------------------------------
        !           756:     // For a load in place usage we've already set the addresses, make sure these match.
        !           757:     // Otherwise set both addresses.  Note that the "presumed" address is already subtracted.
        !           758: 
        !           759:     section = & pefPrivate->sections[sectionIndex];
        !           760: 
        !           761:     if ( ! pefPrivate->loadInPlace ) {
        !           762: 
        !           763:         pefPrivate->mappedOrigins[sectionIndex]     = (BytePtr) mappedAddress;
        !           764:         pefPrivate->runningOffsets[sectionIndex]    += (ByteCount) runningAddress;
        !           765: 
        !           766:     } else {
        !           767: 
        !           768:         if ( (runningAddress != section->sectionAddress) ||
        !           769:              (mappedAddress != pefPrivate->mappedOrigins[sectionIndex]) ) goto UsageError;
        !           770: 
        !           771:     }
        !           772: 
        !           773: 
        !           774: OK:
        !           775:     err = noErr;
        !           776: 
        !           777: EXIT:
        !           778:     return err;
        !           779: 
        !           780: ERROR:
        !           781:     goto EXIT;
        !           782: 
        !           783: ParameterError:
        !           784:     err = paramErr;
        !           785:     goto ERROR;
        !           786: 
        !           787: UsageError:
        !           788:     err = cfragFragmentUsageErr;
        !           789:     goto ERROR;
        !           790: 
        !           791: 
        !           792: }   // PEF_SetSectionAddress ()
        !           793: 
        !           794: 
        !           795: // �
        !           796: // ===========================================================================================
        !           797: // PEF_GetAnonymousSymbolLocations ()
        !           798: // ==================================
        !           799: 
        !           800: 
        !           801: extern OSStatus PEF_GetAnonymousSymbolLocations ( CFContHandlerRef          containerRef,
        !           802:                                                   CFContLogicalLocation *   mainLocation,   // May be null.
        !           803:                                                   CFContLogicalLocation *   initLocation,   // May be null.
        !           804:                                                   CFContLogicalLocation *   termLocation )  // May be null.
        !           805: {
        !           806:     OSStatus            err         = cfragCFMInternalErr;
        !           807:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !           808:     LoaderHeader *      ldrHeader   = NULL;
        !           809: 
        !           810:     CFContLogicalLocation   tempLocation;
        !           811: 
        !           812: 
        !           813:     if ( (pefPrivate == NULL) ) goto ParameterError;
        !           814: 
        !           815:     if ( mainLocation == NULL ) mainLocation    = &tempLocation;
        !           816:     if ( initLocation == NULL ) initLocation    = &tempLocation;
        !           817:     if ( termLocation == NULL ) termLocation    = &tempLocation;
        !           818: 
        !           819: 
        !           820:     ldrHeader = pefPrivate->ldrHeader;
        !           821: 
        !           822:     mainLocation->section   = ldrHeader->entryPointSection;
        !           823:     mainLocation->offset    = ldrHeader->entryPointOffset;
        !           824: 
        !           825:     initLocation->section   = ldrHeader->initPointSection;
        !           826:     initLocation->offset    = ldrHeader->initPointOffset;
        !           827: 
        !           828:     termLocation->section   = ldrHeader->termPointSection;
        !           829:     termLocation->offset    = ldrHeader->termPointOffset;
        !           830: 
        !           831: 
        !           832: OK:
        !           833:     err = noErr;
        !           834: 
        !           835: EXIT:
        !           836:     return err;
        !           837: 
        !           838: ERROR:
        !           839:     goto EXIT;
        !           840: 
        !           841: ParameterError:
        !           842:     err = paramErr;
        !           843:     goto ERROR;
        !           844: 
        !           845: 
        !           846: }   // PEF_GetAnonymousSymbolLocations ()
        !           847: 
        !           848: 
        !           849: // �
        !           850: // ===========================================================================================
        !           851: // PEF_GetExportedSymbolCount ()
        !           852: // =============================
        !           853: 
        !           854: 
        !           855: extern OSStatus PEF_GetExportedSymbolCount  ( CFContHandlerRef  containerRef,
        !           856:                                               ItemCount *       exportCount )
        !           857: {
        !           858:     OSStatus            err         = cfragCFMInternalErr;
        !           859:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !           860: 
        !           861: 
        !           862:     if ( (pefPrivate == NULL) || (exportCount == NULL) ) goto ParameterError;
        !           863: 
        !           864:     *exportCount = pefPrivate->ldrHeader->numExportSyms;
        !           865: 
        !           866: 
        !           867: OK:
        !           868:     err = noErr;
        !           869: 
        !           870: EXIT:
        !           871:     return err;
        !           872: 
        !           873: ERROR:
        !           874:     goto EXIT;
        !           875: 
        !           876: ParameterError:
        !           877:     err = paramErr;
        !           878:     goto ERROR;
        !           879: 
        !           880: 
        !           881: }   // PEF_GetExportedSymbolCount ()
        !           882: 
        !           883: 
        !           884: // �
        !           885: // ===========================================================================================
        !           886: // PEF_GetExportedSymbolInfo ()
        !           887: // ============================
        !           888: 
        !           889: 
        !           890: OSStatus    PEF_GetExportedSymbolInfo   ( CFContHandlerRef              containerRef,
        !           891:                                           CFContSignedIndex             exportIndex,
        !           892:                                           PBVersion                     infoVersion,
        !           893:                                           CFContExportedSymbolInfo *    exportInfo )
        !           894: {
        !           895:     OSStatus            err             = cfragCFMInternalErr;
        !           896:     PEFPrivateInfo *    pefPrivate      = (PEFPrivateInfo *) containerRef;
        !           897:     LoaderExport *      exportedSymbol  = NULL;
        !           898: 
        !           899: 
        !           900:     if ( (pefPrivate == NULL) || (exportInfo == NULL) ) goto ParameterError;
        !           901:     if ( exportIndex >= pefPrivate->ldrHeader->numExportSyms ) goto ParameterError;
        !           902:     if ( infoVersion != kCFContExportedSymbolInfoVersion ) goto ParameterError;
        !           903: 
        !           904: 
        !           905:     if ( exportIndex >= 0 ) {
        !           906: 
        !           907:         exportedSymbol = &pefPrivate->ldrExportSymbols[exportIndex];
        !           908: 
        !           909:         exportInfo->symbolName.nameHash = pefPrivate->ldrHashChain[exportIndex].hashword;
        !           910:         exportInfo->symbolName.nameText = &pefPrivate->ldrStringTable[exportedSymbol->nameOffset];
        !           911: 
        !           912:         exportInfo->symbolClass = exportedSymbol->symClass;
        !           913:         exportInfo->reservedA   = 0;
        !           914:         exportInfo->reservedB   = 0;
        !           915:         exportInfo->options     = kNilOptions;
        !           916: 
        !           917:         exportInfo->location.section = exportedSymbol->sectionNumber;
        !           918: 
        !           919:         #if 1   // *** Disable the reexported import optimization.
        !           920:             exportInfo->location.offset = exportedSymbol->offset;
        !           921:         #else
        !           922:             // This is the buggy optimization.  It has problems with missing weak libraries.
        !           923:             // Addition of a "resolvedImports" bit vector is probably the way to fix it, but it
        !           924:             // may not be much of an optimization then.
        !           925:             if ( (! pefPrivate->resolved) || (exportedSymbol->sectionNumber != kReExportImport) ) {
        !           926:                 exportInfo->location.offset = exportedSymbol->address;
        !           927:             } else {
        !           928:                 exportInfo->location.section    = kPhysicalExport;
        !           929:                 exportInfo->location.offset     = pefPrivate->imports[exportedSymbol->address];
        !           930:             }
        !           931:         #endif
        !           932: 
        !           933:     } else {
        !           934: 
        !           935:         CFContLogicalLocation   mainLocation;
        !           936:         CFContLogicalLocation   initLocation;
        !           937:         CFContLogicalLocation   termLocation;
        !           938: 
        !           939:         err = PEF_GetAnonymousSymbolLocations ( containerRef, &mainLocation, &initLocation, &termLocation );
        !           940:         if ( err != noErr ) goto ERROR;
        !           941: 
        !           942:         switch ( exportIndex ) {
        !           943:             case kMainCFragSymbolIndex  :
        !           944:                 exportInfo->location = mainLocation;
        !           945:                 exportInfo->symbolClass = 0xFF;     // !!! Ought to have a kUnknownCFragSymbol constant.
        !           946:                 break;
        !           947:             case kInitCFragSymbolIndex  :
        !           948:                 exportInfo->location = initLocation;
        !           949:                 exportInfo->symbolClass = kTVectorCFragSymbol;  // ! Damn well better be!
        !           950:                 break;
        !           951:             case kTermCFragSymbolIndex  :
        !           952:                 exportInfo->location = termLocation;
        !           953:                 exportInfo->symbolClass = kTVectorCFragSymbol;  // ! Damn well better be!
        !           954:                 break;
        !           955:             default :
        !           956:                 goto ParameterError;
        !           957:         }
        !           958: 
        !           959:         exportInfo->symbolName.nameHash = 0;
        !           960:         exportInfo->symbolName.nameText = NULL;
        !           961: 
        !           962:         exportInfo->reservedA   = 0;
        !           963:         exportInfo->reservedB   = 0;
        !           964:         exportInfo->options     = kNilOptions;
        !           965: 
        !           966:     }
        !           967: 
        !           968: 
        !           969: OK:
        !           970:     err = noErr;
        !           971: 
        !           972: EXIT:
        !           973:     return err;
        !           974: 
        !           975: ERROR:
        !           976:     goto EXIT;
        !           977: 
        !           978: ParameterError:
        !           979:     err = paramErr;
        !           980:     goto ERROR;
        !           981: 
        !           982: 
        !           983: }   // PEF_GetExportedSymbolInfo ()
        !           984: 
        !           985: 
        !           986: // �
        !           987: // ===========================================================================================
        !           988: // PEF_FindExportedSymbolInfo ()
        !           989: // =============================
        !           990: 
        !           991: 
        !           992: OSStatus    PEF_FindExportedSymbolInfo  ( CFContHandlerRef              containerRef,
        !           993:                                           const CFContHashedName *      exportName,
        !           994:                                           PBVersion                     infoVersion,
        !           995:                                           ItemCount *                   exportIndex_o,  // May be null.
        !           996:                                           CFContExportedSymbolInfo *    exportInfo )    // May be null.
        !           997: {
        !           998:     OSStatus            err             = cfragCFMInternalErr;
        !           999:     PEFPrivateInfo *    pefPrivate      = (PEFPrivateInfo *) containerRef;
        !          1000:     LoaderExport *      exportedSymbol  = NULL;
        !          1001:     CFContStringHash *  hashwordList    = NULL;
        !          1002:     CFContStringHash *  nextHashword    = NULL;
        !          1003:     HashSlotEntry *     hashSlot        = NULL;
        !          1004:     ByteCount           nameLength      = CFContStringHashLength ( exportName->nameHash );
        !          1005:     ItemCount           exportIndex;
        !          1006:     ItemCount           slotIndex;
        !          1007:     ItemCount           chainLimit;
        !          1008:     Boolean             nameMatch;
        !          1009: 
        !          1010: 
        !          1011:     if ( pefPrivate == NULL ) goto ParameterError;
        !          1012:     if ( infoVersion != kCFContExportedSymbolInfoVersion ) goto ParameterError;
        !          1013: 
        !          1014: 
        !          1015:     hashwordList    = &pefPrivate->ldrHashChain[0].hashword;
        !          1016: 
        !          1017:     slotIndex       = GetPEFHashSlot ( exportName->nameHash, pefPrivate->ldrHeader->hashSlotTabSize );
        !          1018:     hashSlot        = &pefPrivate->ldrHashSlot[slotIndex];
        !          1019: 
        !          1020:     exportIndex     = hashSlot->chainIndex;
        !          1021:     chainLimit      = exportIndex + hashSlot->chainCount;
        !          1022:     nextHashword    = &hashwordList[exportIndex];
        !          1023: 
        !          1024:     while ( exportIndex < chainLimit ) {
        !          1025: 
        !          1026:         if ( *nextHashword == exportName->nameHash ) {
        !          1027:             exportedSymbol = &pefPrivate->ldrExportSymbols[exportIndex];
        !          1028:             nameMatch = PEF_CompareBytes ( exportName->nameText,
        !          1029:                                            &pefPrivate->ldrStringTable[exportedSymbol->nameOffset],
        !          1030:                                            nameLength );
        !          1031:             if ( nameMatch ) goto Found;
        !          1032:         }
        !          1033: 
        !          1034:         exportIndex     += 1;
        !          1035:         nextHashword    += 1;   // ! Pointer arithmetic.
        !          1036:     }
        !          1037:     goto NotFoundError;
        !          1038: 
        !          1039: Found:
        !          1040:     if ( exportIndex_o != NULL ) *exportIndex_o = exportIndex;
        !          1041:     if ( exportInfo != NULL ) {
        !          1042:         err = PEF_GetExportedSymbolInfo ( containerRef, exportIndex, infoVersion, exportInfo );
        !          1043:         if ( err != noErr ) goto ERROR;
        !          1044:     }
        !          1045: 
        !          1046: 
        !          1047: OK:
        !          1048:     err = noErr;
        !          1049: 
        !          1050: EXIT:
        !          1051:     return err;
        !          1052: 
        !          1053: ERROR:
        !          1054:     goto EXIT;
        !          1055: 
        !          1056: ParameterError:
        !          1057:     err = paramErr;
        !          1058:     goto ERROR;
        !          1059: 
        !          1060: NotFoundError:
        !          1061:     err = cfragNoSymbolErr;
        !          1062:     goto ERROR;
        !          1063: 
        !          1064: 
        !          1065: }   // PEF_FindExportedSymbolInfo ()
        !          1066: 
        !          1067: 
        !          1068: // �
        !          1069: // ===========================================================================================
        !          1070: // PEF_GetImportCounts ()
        !          1071: // ======================
        !          1072: 
        !          1073: 
        !          1074: OSStatus    PEF_GetImportCounts ( CFContHandlerRef  containerRef,
        !          1075:                                   ItemCount *       libraryCount,   // May be null.
        !          1076:                                   ItemCount *       symbolCount )   // May be null.
        !          1077: {
        !          1078:     OSStatus            err         = cfragCFMInternalErr;
        !          1079:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !          1080: 
        !          1081: 
        !          1082:     if ( pefPrivate == NULL ) goto ParameterError;
        !          1083: 
        !          1084:     if ( libraryCount != NULL ) *libraryCount = pefPrivate->ldrHeader->numImportFiles;
        !          1085:     if ( symbolCount != NULL ) *symbolCount = pefPrivate->ldrHeader->numImportSyms;
        !          1086: 
        !          1087: 
        !          1088: OK:
        !          1089:     err = noErr;
        !          1090: 
        !          1091: EXIT:
        !          1092:     return err;
        !          1093: 
        !          1094: ERROR:
        !          1095:     goto EXIT;
        !          1096: 
        !          1097: ParameterError:
        !          1098:     err = paramErr;
        !          1099:     goto ERROR;
        !          1100: 
        !          1101: 
        !          1102: }   // PEF_GetImportCounts ()
        !          1103: 
        !          1104: 
        !          1105: // �
        !          1106: // ===========================================================================================
        !          1107: // PEF_GetImportedLibraryInfo ()
        !          1108: // =============================
        !          1109: 
        !          1110: 
        !          1111: OSStatus    PEF_GetImportedLibraryInfo  ( CFContHandlerRef              containerRef,
        !          1112:                                           ItemCount                     libraryIndex,
        !          1113:                                           PBVersion                     infoVersion,
        !          1114:                                           CFContImportedLibraryInfo *   libraryInfo )
        !          1115: {
        !          1116:     OSStatus                err             = cfragCFMInternalErr;
        !          1117:     PEFPrivateInfo *        pefPrivate      = (PEFPrivateInfo *) containerRef;
        !          1118:     LoaderImportFileID *    importedLibrary = NULL;
        !          1119:     BytePtr                 nameText        = NULL;
        !          1120:     ByteCount               nameLength;
        !          1121: 
        !          1122: 
        !          1123:     if ( (pefPrivate == NULL) || (libraryInfo == NULL) ) goto ParameterError;
        !          1124:     if ( infoVersion != kCFContImportedLibraryInfoVersion ) goto ParameterError;
        !          1125:     if ( libraryIndex >= pefPrivate->ldrHeader->numImportFiles ) goto ParameterError;
        !          1126: 
        !          1127: 
        !          1128:     importedLibrary = &pefPrivate->ldrImportFiles[libraryIndex];
        !          1129: 
        !          1130:     nameText    = &pefPrivate->ldrStringTable[importedLibrary->fileNameOffset];
        !          1131:     nameLength  = GetNameLength ( nameText );
        !          1132: 
        !          1133:     libraryInfo->libraryName.nameHash   = CFContHashName ( nameText, nameLength );
        !          1134:     libraryInfo->libraryName.nameText   = nameText;
        !          1135: 
        !          1136:     libraryInfo->linkedVersion  = importedLibrary->linkedVersion;
        !          1137:     libraryInfo->oldImpVersion  = importedLibrary->oldImpVersion;
        !          1138:     libraryInfo->options        = kNilOptions;
        !          1139: 
        !          1140:     if ( importedLibrary->options & kPEFInitBeforeMask ) libraryInfo->options |= kCFContInitBeforeMask;
        !          1141:     if ( importedLibrary->options & kPEFWeakLibraryMask ) libraryInfo->options |= kCFContWeakLibraryMask;
        !          1142:     if ( importedLibrary->options & kPEFDeferredBindMask ) libraryInfo->options |= kCFContDeferredBindMask;
        !          1143: 
        !          1144: 
        !          1145: OK:
        !          1146:     err = noErr;
        !          1147: 
        !          1148: EXIT:
        !          1149:     return err;
        !          1150: 
        !          1151: ERROR:
        !          1152:     goto EXIT;
        !          1153: 
        !          1154: ParameterError:
        !          1155:     err = paramErr;
        !          1156:     goto ERROR;
        !          1157: 
        !          1158: 
        !          1159: }   // PEF_GetImportedLibraryInfo ()
        !          1160: 
        !          1161: 
        !          1162: // �
        !          1163: // ===========================================================================================
        !          1164: // PEF_GetImportedSymbolInfo ()
        !          1165: // ============================
        !          1166: 
        !          1167: 
        !          1168: OSStatus    PEF_GetImportedSymbolInfo   ( CFContHandlerRef              containerRef,
        !          1169:                                           ItemCount                     symbolIndex,
        !          1170:                                           PBVersion                     infoVersion,
        !          1171:                                           CFContImportedSymbolInfo *    symbolInfo )
        !          1172: {
        !          1173:     OSStatus                err             = cfragCFMInternalErr;
        !          1174:     PEFPrivateInfo *        pefPrivate      = (PEFPrivateInfo *) containerRef;
        !          1175:     LoaderImport *          importedSymbol  = NULL;
        !          1176:     LoaderImportFileID *    importedLibrary = NULL;
        !          1177:     BytePtr                 nameText        = NULL;
        !          1178:     ByteCount               nameLength;
        !          1179:     ItemCount               libraryCount;
        !          1180:     ItemCount               libraryIndex;
        !          1181: 
        !          1182: 
        !          1183:     if ( (pefPrivate == NULL) || (symbolInfo == NULL) ) goto ParameterError;
        !          1184:     if ( infoVersion != kCFContImportedSymbolInfoVersion ) goto ParameterError;
        !          1185:     if ( symbolIndex >= pefPrivate->ldrHeader->numImportSyms ) goto ParameterError;
        !          1186: 
        !          1187: 
        !          1188:     importedSymbol  = &pefPrivate->ldrImportSymbols[symbolIndex];
        !          1189:     libraryCount    = pefPrivate->ldrHeader->numImportFiles;
        !          1190: 
        !          1191:     nameText    = &pefPrivate->ldrStringTable[importedSymbol->nameOffset];
        !          1192:     nameLength  = GetNameLength ( nameText );
        !          1193: 
        !          1194:     symbolInfo->symbolName.nameHash = CFContHashName ( nameText, nameLength );
        !          1195:     symbolInfo->symbolName.nameText = nameText;
        !          1196: 
        !          1197:     symbolInfo->symbolClass     = importedSymbol->symClass & 0x0F;
        !          1198:     symbolInfo->reservedA       = 0;
        !          1199:     symbolInfo->reservedB       = 0;
        !          1200:     symbolInfo->options         = 0;
        !          1201: 
        !          1202:     if ( importedSymbol->symClass & kPEFWeakSymbolMask ) symbolInfo->options |= kCFContWeakSymbolMask;
        !          1203: 
        !          1204:     for ( libraryIndex = 0; libraryIndex < libraryCount; libraryIndex += 1 ) {
        !          1205:         importedLibrary = &pefPrivate->ldrImportFiles[libraryIndex];
        !          1206:         if ( (importedLibrary->impFirst <= symbolIndex) &&
        !          1207:              (symbolIndex < (importedLibrary->impFirst + importedLibrary->numImports)) ) {
        !          1208:             break;
        !          1209:         }
        !          1210:     }
        !          1211:     if ( libraryIndex == libraryCount ) goto FragmentCorruptError;
        !          1212: 
        !          1213:     symbolInfo->libraryIndex = libraryIndex;
        !          1214: 
        !          1215: 
        !          1216: OK:
        !          1217:     err = noErr;
        !          1218: 
        !          1219: EXIT:
        !          1220:     return err;
        !          1221: 
        !          1222: ERROR:
        !          1223:     goto EXIT;
        !          1224: 
        !          1225: ParameterError:
        !          1226:     err = paramErr;
        !          1227:     goto ERROR;
        !          1228: 
        !          1229: FragmentCorruptError:
        !          1230:     err = cfragFragmentCorruptErr;
        !          1231:     goto ERROR;
        !          1232: 
        !          1233: 
        !          1234: }   // PEF_GetImportedSymbolInfo ()
        !          1235: 
        !          1236: 
        !          1237: // �
        !          1238: // ===========================================================================================
        !          1239: // PEF_SetImportedSymbolAddress ()
        !          1240: // ===============================
        !          1241: 
        !          1242: 
        !          1243: OSStatus    PEF_SetImportedSymbolAddress    ( CFContHandlerRef              containerRef,
        !          1244:                                               ItemCount                     symbolIndex,
        !          1245:                                               LogicalAddress                symbolAddress )
        !          1246: {
        !          1247:     OSStatus            err         = cfragCFMInternalErr;
        !          1248:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !          1249: 
        !          1250: 
        !          1251:     if ( pefPrivate == NULL ) goto ParameterError;
        !          1252:     if ( symbolIndex >= pefPrivate->ldrHeader->numImportSyms ) goto ParameterError;
        !          1253: 
        !          1254: 
        !          1255:     pefPrivate->imports[symbolIndex] = symbolAddress;
        !          1256: 
        !          1257: 
        !          1258: OK:
        !          1259:     err = noErr;
        !          1260: 
        !          1261: EXIT:
        !          1262:     return err;
        !          1263: 
        !          1264: ERROR:
        !          1265:     goto EXIT;
        !          1266: 
        !          1267: ParameterError:
        !          1268:     err = paramErr;
        !          1269:     goto ERROR;
        !          1270: 
        !          1271: 
        !          1272: }   // PEF_SetImportedSymbolAddress ()
        !          1273: 
        !          1274: 
        !          1275: // �
        !          1276: // ===========================================================================================
        !          1277: // GetPackedDataCount ()
        !          1278: // =====================
        !          1279: 
        !          1280: 
        !          1281: static UInt32   GetPackedDataCount ( UInt8 * *  byteHandle )
        !          1282: {
        !          1283:     UInt32  count   = 0;
        !          1284:     UInt8 * bytePtr = *byteHandle;
        !          1285:     UInt8   currByte;
        !          1286: 
        !          1287: 
        !          1288:     do {
        !          1289:         currByte = *bytePtr++;
        !          1290:         count = (count << kPEFPkDataVCountShift) | (currByte & kPEFPkDataVCountMask);
        !          1291:     } while ( (currByte & kPEFPkDataVCountEndMask) != 0 );
        !          1292: 
        !          1293:     *byteHandle = bytePtr;
        !          1294: 
        !          1295:     return count;
        !          1296: 
        !          1297: 
        !          1298: }   // GetPackedDataCount ()
        !          1299: 
        !          1300: 
        !          1301: // �
        !          1302: // ===========================================================================================
        !          1303: // UnpackFullSection ()
        !          1304: // ====================
        !          1305: 
        !          1306: 
        !          1307: // ------------------------------------------------------------------------------------------
        !          1308: // This is the "normal" case from CFM, unpacking all of the packed portion.  Along the way we
        !          1309: // make sure we're not writing beyond the end of the unpacked data.  At the end we make sure
        !          1310: // that all we didn't read past the end of the packed data, and that all of the output was
        !          1311: // written.
        !          1312: 
        !          1313: // ! Note that the xyzEnd pointers are the actual end of the range, not one byte beyond.  This
        !          1314: // ! routine will work if the output end address is 0xFFFFFFFF, but not if the packed end is.
        !          1315: 
        !          1316: // ! Don't do range comparisons as "(lowAddr + length) > highAddr", because this might wrap
        !          1317: // ! the end high end of the address space.  Always do "(highAddr - lowAddr) > length".
        !          1318: 
        !          1319: // ??? We should gather some statistics on actual usage to see whether it is worthwhile to
        !          1320: // ??? have local customized code for common cases.  E.g. block fill of 1, 2, or 4 bytes, or
        !          1321: // ??? of interleaved repeats with 1/2/4 byte common or custom portions.
        !          1322: 
        !          1323: 
        !          1324: static OSStatus UnpackFullSection   ( BytePtr   packedBase,
        !          1325:                                       BytePtr   packedEnd,
        !          1326:                                       BytePtr   outputBase,
        !          1327:                                       BytePtr   outputEnd )
        !          1328: {
        !          1329:     OSStatus    err         = cfragCFMInternalErr;
        !          1330:     BytePtr     packedPos   = packedBase;
        !          1331:     BytePtr     outputPos   = outputBase;
        !          1332:     BytePtr     outPosLimit = outputEnd + 1;    // ! Might be zero if outputEnd is 0xFFFFFFFF.
        !          1333: 
        !          1334:     UInt8       currByte;
        !          1335:     UInt8       opcode;
        !          1336:     UInt32      count1;
        !          1337:     UInt32      count2;
        !          1338:     UInt32      count3;
        !          1339: 
        !          1340: 
        !          1341:     if ( (packedEnd + 1) == 0 ) goto FragmentUsageError;
        !          1342: 
        !          1343: 
        !          1344:     while ( packedPos <= packedEnd ) {
        !          1345: 
        !          1346: 
        !          1347:         currByte    = *packedPos++;
        !          1348:         opcode      = currByte >> kPEFPkDataOpcodeShift;
        !          1349:         count1      = currByte & kPEFPkDataCount5Mask;
        !          1350: 
        !          1351:         if ( count1 == 0 ) count1 = GetPackedDataCount ( &packedPos );
        !          1352: 
        !          1353: 
        !          1354:         switch ( opcode ) {
        !          1355: 
        !          1356: 
        !          1357:             case kPEFPkDataZero :
        !          1358: 
        !          1359:                 if ( (outPosLimit - outputPos) < count1 ) goto FragmentCorruptError;
        !          1360: 
        !          1361:                 PEF_BlockClear ( outputPos, count1 );
        !          1362:                 outputPos += count1;
        !          1363: 
        !          1364:                 break;
        !          1365: 
        !          1366: 
        !          1367:             case kPEFPkDataBlock :
        !          1368: 
        !          1369:                 if ( (outPosLimit - outputPos) < count1 ) goto FragmentCorruptError;
        !          1370: 
        !          1371:                 PEF_BlockMove ( packedPos, outputPos, count1 );
        !          1372:                 packedPos   += count1;
        !          1373:                 outputPos   += count1;
        !          1374: 
        !          1375:                 break;
        !          1376: 
        !          1377: 
        !          1378:             case kPEFPkDataRepeat :     // ??? Need a BlockFill routine?
        !          1379: 
        !          1380:                 count2 = GetPackedDataCount ( &packedPos ) + 1;     // ! Stored count is 1 less.
        !          1381: 
        !          1382:                 if ( (outPosLimit - outputPos) < (count1 * count2) ) goto FragmentCorruptError;
        !          1383: 
        !          1384:                 if ( count1 == 1 ) {    // ??? Is this worth the bother?  Other sizes?
        !          1385: 
        !          1386:                     currByte = *packedPos++;
        !          1387:                     for ( ; count2 != 0; count2 -= 1 ) *outputPos++ = currByte;
        !          1388: 
        !          1389:                 } else {
        !          1390: 
        !          1391:                     for ( ; count2 != 0; count2 -= 1 ) {
        !          1392:                         PEF_BlockMove ( packedPos, outputPos, count1 );
        !          1393:                         outputPos += count1;
        !          1394:                     }
        !          1395:                     packedPos += count1;
        !          1396: 
        !          1397:                 }
        !          1398: 
        !          1399:                 break;
        !          1400: 
        !          1401: 
        !          1402:             case kPEFPkDataRepeatBlock :
        !          1403: 
        !          1404:                 count2  = GetPackedDataCount ( &packedPos );
        !          1405:                 count3  = GetPackedDataCount ( &packedPos );
        !          1406: 
        !          1407:                 if ( (outPosLimit - outputPos) < (((count1 + count2) * count3) + count1) ) goto FragmentCorruptError;
        !          1408: 
        !          1409:                 {
        !          1410:                     BytePtr commonPos   = packedPos;
        !          1411: 
        !          1412:                     packedPos += count1;    // Skip the common part.
        !          1413: 
        !          1414:                     for ( ; count3 != 0; count3 -= 1 ) {
        !          1415: 
        !          1416:                         PEF_BlockMove ( commonPos, outputPos, count1 );
        !          1417:                         outputPos += count1;
        !          1418: 
        !          1419:                         PEF_BlockMove ( packedPos, outputPos, count2 );
        !          1420:                         packedPos   += count2;
        !          1421:                         outputPos   += count2;
        !          1422: 
        !          1423:                     }
        !          1424: 
        !          1425:                     PEF_BlockMove ( commonPos, outputPos, count1 );
        !          1426:                     outputPos += count1;
        !          1427: 
        !          1428:                 }
        !          1429: 
        !          1430:                 break;
        !          1431: 
        !          1432: 
        !          1433:             case kPEFPkDataRepeatZero :
        !          1434: 
        !          1435:                 count2 = GetPackedDataCount ( &packedPos );
        !          1436:                 count3 = GetPackedDataCount ( &packedPos );
        !          1437: 
        !          1438:                 if ( (outPosLimit - outputPos) < (((count1 + count2) * count3) + count1) ) goto FragmentCorruptError;
        !          1439: 
        !          1440:                 PEF_BlockClear ( outputPos, count1 );
        !          1441:                 outputPos += count1;
        !          1442: 
        !          1443:                 for ( ; count3 != 0; count3 -= 1 ) {
        !          1444: 
        !          1445:                     PEF_BlockMove ( packedPos, outputPos, count2 );
        !          1446:                     packedPos   += count2;
        !          1447:                     outputPos   += count2;
        !          1448: 
        !          1449:                     PEF_BlockClear ( outputPos, count1 );
        !          1450:                     outputPos += count1;
        !          1451: 
        !          1452:                 }
        !          1453: 
        !          1454:                 break;
        !          1455: 
        !          1456: 
        !          1457:             default :
        !          1458:                 goto FragmentCorruptError;
        !          1459: 
        !          1460:         }
        !          1461: 
        !          1462:     }
        !          1463: 
        !          1464: 
        !          1465:     if ( (packedPos != (packedEnd + 1)) || (outputPos != outPosLimit) ) goto FragmentCorruptError;
        !          1466: 
        !          1467: 
        !          1468: OK:
        !          1469:     err = noErr;
        !          1470: 
        !          1471: EXIT:
        !          1472:     return err;
        !          1473: 
        !          1474: ERROR:
        !          1475:     goto EXIT;
        !          1476: 
        !          1477: 
        !          1478: FragmentUsageError:
        !          1479:     err = cfragFragmentUsageErr;
        !          1480:     goto ERROR;
        !          1481: 
        !          1482: FragmentCorruptError:
        !          1483:     err = cfragFragmentCorruptErr;
        !          1484:     goto ERROR;
        !          1485: 
        !          1486: 
        !          1487: }   // UnpackFullSection ()
        !          1488: 
        !          1489: 
        !          1490: // �
        !          1491: // ===========================================================================================
        !          1492: // UnpackPartialSection ()
        !          1493: // =======================
        !          1494: 
        !          1495: 
        !          1496: // -------------------------------------------------------------------------------------------
        !          1497: // This is the case where we want to extract some arbitrary portion of a section as it would
        !          1498: // be when instantiated but not relocated.  We have to interpret the packed part up to the
        !          1499: // desired output start, then continue begin unpacking for real.  If we run out of packed data
        !          1500: // before filling the output, we fill the rest of the output with zeroes.
        !          1501: 
        !          1502: // ! We have to be very careful in the skip logic because the current operation probably spans
        !          1503: // ! the skip/output boundary.  We have to be similarly careful at the output end because the
        !          1504: // ! current operation probably spans the tail of the output.  Don't forget that the partial
        !          1505: // ! output at the start could also fill the output and overflow the tail!
        !          1506: 
        !          1507: // ! Note that the xyzEnd pointers are the actual end of the range, not one byte beyond.  This
        !          1508: // ! routine might not work if outputEnd is 0xFFFFFFFF.  This is because outputPos points to
        !          1509: // ! the next byte to be written.  The loops that are controlled by "outputPos < outputBase"
        !          1510: // ! or "outputPos <= outputEnd" would fail in this case if outputPos were "outputEnd + 1",
        !          1511: // ! i.e. outputPos would be zero.
        !          1512: 
        !          1513: // ! Don't do range comparisons as "(lowAddr + length) > highAddr", because this might wrap
        !          1514: // ! the end high end of the address space.  Always do "(highAddr - lowAddr) > length".
        !          1515: 
        !          1516: 
        !          1517: // -------------------------------------------------------------------------------------------
        !          1518: 
        !          1519: 
        !          1520: static void PartialBlockClear   ( BytePtr   outputBase,
        !          1521:                                   ByteCount outputStartOffset,
        !          1522:                                   ByteCount outputEndOffset,
        !          1523:                                   ByteCount outputOffset,
        !          1524:                                   ByteCount count )
        !          1525: {
        !          1526: 
        !          1527:     if ( ((outputOffset + count) <= outputStartOffset) || (outputOffset > outputEndOffset) ) return;    // Nothing to output.
        !          1528: 
        !          1529:     if ( outputOffset < outputStartOffset ) {
        !          1530:         count -= (outputStartOffset - outputOffset);
        !          1531:         outputOffset = outputStartOffset;
        !          1532:     }
        !          1533: 
        !          1534:     if ( count > (outputEndOffset - outputOffset + 1) ) count = outputEndOffset - outputOffset + 1;
        !          1535: 
        !          1536:     PEF_BlockClear ( outputBase + (outputOffset - outputStartOffset), count );
        !          1537: 
        !          1538: }   // PartialBlockClear ();
        !          1539: 
        !          1540: 
        !          1541: // -------------------------------------------------------------------------------------------
        !          1542: 
        !          1543: 
        !          1544: static void PartialBlockMove    ( BytePtr   source,
        !          1545:                                   BytePtr   outputBase,
        !          1546:                                   ByteCount outputStartOffset,
        !          1547:                                   ByteCount outputEndOffset,
        !          1548:                                   ByteCount outputOffset,
        !          1549:                                   ByteCount count )
        !          1550: {
        !          1551: 
        !          1552:     if ( ((outputOffset + count) <= outputStartOffset) || (outputOffset > outputEndOffset) ) return;    // Nothing to output.
        !          1553: 
        !          1554:     if ( outputOffset < outputStartOffset ) {
        !          1555:         const ByteCount skipCount   = outputStartOffset - outputOffset;
        !          1556:         source  += skipCount;
        !          1557:         count   -= skipCount;
        !          1558:         outputOffset = outputStartOffset;
        !          1559:     }
        !          1560: 
        !          1561:     if ( count > (outputEndOffset - outputOffset + 1) ) count = outputEndOffset - outputOffset + 1;
        !          1562: 
        !          1563:     PEF_BlockMove ( source, outputBase + (outputOffset - outputStartOffset), count );
        !          1564: 
        !          1565: }   // PartialBlockClear ();
        !          1566: 
        !          1567: 
        !          1568: // -------------------------------------------------------------------------------------------
        !          1569: 
        !          1570: 
        !          1571: static OSStatus UnpackPartialSection    ( BytePtr   packedBase,
        !          1572:                                           BytePtr   packedEnd,
        !          1573:                                           BytePtr   outputBase,
        !          1574:                                           BytePtr   outputEnd,
        !          1575:                                           ByteCount outputStartOffset )
        !          1576: {
        !          1577:     OSStatus        err             = cfragCFMInternalErr;
        !          1578:     const ByteCount outputEndOffset = outputStartOffset + (outputEnd - outputBase);
        !          1579:     BytePtr         packedPos       = NULL;
        !          1580:     BytePtr         packedBoundary  = NULL;
        !          1581:     ByteCount       outputOffset;
        !          1582:     ByteCount       outputBoundary;
        !          1583: 
        !          1584:     UInt8           currByte;
        !          1585:     UInt8           opcode;
        !          1586:     UInt32          count1;
        !          1587:     UInt32          count2;
        !          1588:     UInt32          count3;
        !          1589: 
        !          1590: 
        !          1591:     if ( ((packedEnd + 1) == 0) || ((outputEnd + 1) == 0) ) goto FragmentUsageError;
        !          1592: 
        !          1593: 
        !          1594:     // --------------------------------------------------------------------------------------
        !          1595:     // Skip the packed data until we get within the output range.  We know there is something
        !          1596:     // to unpack, otherwise the zero fill of the output would be done by the caller.  This
        !          1597:     // loop sets outputOffset to the end of what would be unpacked, until the outputOffset is
        !          1598:     // beyond the outputStartOffset.  I.e. until we hit the first operation that would create
        !          1599:     // actual output.
        !          1600: 
        !          1601:     outputOffset    = 0;
        !          1602:     packedPos       = packedBase;
        !          1603: 
        !          1604:     do {
        !          1605: 
        !          1606:         packedBoundary  = packedPos;    // The start of the current operation.
        !          1607:         outputBoundary  = outputOffset;
        !          1608: 
        !          1609:         currByte        = *packedPos++;
        !          1610:         opcode          = currByte >> kPEFPkDataOpcodeShift;
        !          1611:         count1          = currByte & kPEFPkDataCount5Mask;
        !          1612: 
        !          1613:         if ( count1 == 0 ) count1 = GetPackedDataCount ( &packedPos );
        !          1614: 
        !          1615:         switch ( opcode ) {
        !          1616: 
        !          1617:             case kPEFPkDataZero :
        !          1618:                 outputOffset += count1;
        !          1619:                 break;
        !          1620: 
        !          1621:             case kPEFPkDataBlock :
        !          1622:                 packedPos       += count1;
        !          1623:                 outputOffset    += count1;
        !          1624:                 break;
        !          1625: 
        !          1626:             case kPEFPkDataRepeat :
        !          1627:                 count2 = GetPackedDataCount ( &packedPos ) + 1;     // ! Stored count is 1 less.
        !          1628:                 packedPos       += count1;
        !          1629:                 outputOffset    += count1 * count2;
        !          1630:                 break;
        !          1631: 
        !          1632: 
        !          1633:             case kPEFPkDataRepeatBlock :
        !          1634:                 count2  = GetPackedDataCount ( &packedPos );
        !          1635:                 count3  = GetPackedDataCount ( &packedPos );
        !          1636:                 packedPos       += count1 + (count2 * count3);
        !          1637:                 outputOffset    += count1 + ((count1 + count2) * count3);
        !          1638:                 break;
        !          1639: 
        !          1640: 
        !          1641:             case kPEFPkDataRepeatZero :
        !          1642:                 count2 = GetPackedDataCount ( &packedPos );
        !          1643:                 count3 = GetPackedDataCount ( &packedPos );
        !          1644:                 packedPos       += count2 * count3;
        !          1645:                 outputOffset    += count1 + ((count1 + count2) * count3);
        !          1646:                 break;
        !          1647: 
        !          1648: 
        !          1649:             default :
        !          1650:                 goto FragmentCorruptError;
        !          1651: 
        !          1652:         }
        !          1653: 
        !          1654:     } while ( outputOffset <= outputStartOffset );
        !          1655: 
        !          1656: 
        !          1657:     //----------------------------------------------------------------------------------------
        !          1658:     // Now do the actual unpacking.  This uses a copy of the full unpack logic with special
        !          1659:     // block copy/clear routines.  These special routines do the bounds checking, only writing
        !          1660:     // output where actually allowed.  This involves "unnecessary" checks for the "middle"
        !          1661:     // operations that are fully within the range, but vastly simplifies the boundary cases.
        !          1662: 
        !          1663:     packedPos       = packedBoundary;       // Reset to the operation that spans the output start.
        !          1664:     outputOffset    = outputBoundary;
        !          1665: 
        !          1666:     do {
        !          1667: 
        !          1668:         currByte    = *packedPos++;
        !          1669:         opcode      = currByte >> kPEFPkDataOpcodeShift;
        !          1670:         count1      = currByte & kPEFPkDataCount5Mask;
        !          1671: 
        !          1672:         if ( count1 == 0 ) count1 = GetPackedDataCount ( &packedPos );
        !          1673: 
        !          1674:         switch ( opcode ) {
        !          1675: 
        !          1676:             case kPEFPkDataZero :
        !          1677:                 PartialBlockClear ( outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1678:                 outputOffset += count1;
        !          1679:                 break;
        !          1680: 
        !          1681:             case kPEFPkDataBlock :
        !          1682:                 PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1683:                 packedPos       += count1;
        !          1684:                 outputOffset    += count1;
        !          1685:                 break;
        !          1686: 
        !          1687:             case kPEFPkDataRepeat :     // ??? Need a BlockFill routine?
        !          1688:                 count2 = GetPackedDataCount ( &packedPos ) + 1;     // ! Stored count is 1 less.
        !          1689:                 for ( ; count2 != 0; count2 -= 1 ) {
        !          1690:                     PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1691:                     outputOffset += count1;
        !          1692:                 }
        !          1693:                 packedPos += count1;
        !          1694:                 break;
        !          1695: 
        !          1696:             case kPEFPkDataRepeatBlock :
        !          1697: 
        !          1698:                 count2  = GetPackedDataCount ( &packedPos );
        !          1699:                 count3  = GetPackedDataCount ( &packedPos );
        !          1700: 
        !          1701:                 {
        !          1702:                     BytePtr commonPos   = packedPos;
        !          1703: 
        !          1704:                     packedPos += count1;    // Skip the common part.
        !          1705: 
        !          1706:                     for ( ; count3 != 0; count3 -= 1 ) {
        !          1707: 
        !          1708:                         PartialBlockMove ( commonPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1709:                         outputOffset += count1;
        !          1710: 
        !          1711:                         PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count2 );
        !          1712:                         packedPos       += count2;
        !          1713:                         outputOffset    += count2;
        !          1714: 
        !          1715:                     }
        !          1716: 
        !          1717:                     PartialBlockMove ( commonPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1718:                     outputOffset += count1;
        !          1719: 
        !          1720:                 }
        !          1721: 
        !          1722:                 break;
        !          1723: 
        !          1724:             case kPEFPkDataRepeatZero :
        !          1725: 
        !          1726:                 count2 = GetPackedDataCount ( &packedPos );
        !          1727:                 count3 = GetPackedDataCount ( &packedPos );
        !          1728: 
        !          1729:                 PartialBlockClear ( outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1730:                 outputOffset += count1;
        !          1731: 
        !          1732:                 for ( ; count3 != 0; count3 -= 1 ) {
        !          1733: 
        !          1734:                     PartialBlockMove ( packedPos, outputBase, outputStartOffset, outputEndOffset, outputOffset, count2 );
        !          1735:                     packedPos       += count2;
        !          1736:                     outputOffset    += count2;
        !          1737: 
        !          1738:                     PartialBlockClear ( outputBase, outputStartOffset, outputEndOffset, outputOffset, count1 );
        !          1739:                     outputOffset += count1;
        !          1740: 
        !          1741:                 }
        !          1742: 
        !          1743:                 break;
        !          1744: 
        !          1745:             default :
        !          1746:                 goto FragmentCorruptError;
        !          1747: 
        !          1748:         }
        !          1749: 
        !          1750:     } while ( (outputOffset <= outputEndOffset) && (packedPos <= packedEnd) );
        !          1751: 
        !          1752: 
        !          1753:     // ------------------------------------------
        !          1754:     // Finally block clear anything that is left.
        !          1755: 
        !          1756:     if ( outputOffset <= outputEndOffset ) {
        !          1757:         PEF_BlockClear ( outputBase + (outputOffset - outputStartOffset), outputEndOffset - outputOffset + 1 );
        !          1758:     }
        !          1759: 
        !          1760: 
        !          1761: OK:
        !          1762:     err = noErr;
        !          1763: 
        !          1764: EXIT:
        !          1765:     return err;
        !          1766: 
        !          1767: ERROR:
        !          1768:     goto EXIT;
        !          1769: 
        !          1770: 
        !          1771: FragmentUsageError:
        !          1772:     err = cfragFragmentUsageErr;
        !          1773:     goto ERROR;
        !          1774: 
        !          1775: FragmentCorruptError:
        !          1776:     err = cfragFragmentCorruptErr;
        !          1777:     goto ERROR;
        !          1778: 
        !          1779: 
        !          1780: }   // UnpackPartialSection ()
        !          1781: 
        !          1782: 
        !          1783: // �
        !          1784: // ===========================================================================================
        !          1785: // PEF_UnpackSection ()
        !          1786: // ====================
        !          1787: 
        !          1788: 
        !          1789: OSStatus    PEF_UnpackSection   ( CFContHandlerRef  containerRef,
        !          1790:                                   ItemCount         sectionIndex,
        !          1791:                                   ByteCount         sectionOffset,
        !          1792:                                   LogicalAddress    bufferAddress,
        !          1793:                                   ByteCount         bufferLength )
        !          1794: {
        !          1795:     OSStatus            err         = cfragCFMInternalErr;
        !          1796:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !          1797:     SectionHeader *     section     = NULL;
        !          1798:     BytePtr             packedBase  = NULL;
        !          1799:     BytePtr             packedEnd   = NULL;
        !          1800:     BytePtr             outputBase  = bufferAddress;
        !          1801:     BytePtr             outputEnd   = outputBase + bufferLength - 1;
        !          1802: 
        !          1803: 
        !          1804:     if ( pefPrivate == NULL ) goto ParameterError;
        !          1805:     if ( sectionIndex >= pefPrivate->sectionCount ) goto ParameterError;
        !          1806:     if ( (bufferAddress == NULL) && (bufferLength != 0) ) goto ParameterError;
        !          1807: 
        !          1808:     section = &pefPrivate->sections[sectionIndex];
        !          1809:     if ( (sectionOffset + bufferLength) > section->execSize ) goto ParameterError;
        !          1810: 
        !          1811:     packedBase  = pefPrivate->mappedContainer + section->containerOffset;
        !          1812:     packedEnd   = packedBase + section->rawSize - 1;
        !          1813: 
        !          1814: 
        !          1815:     if ( (sectionOffset == 0) && (bufferLength == section->initSize) ) {
        !          1816: 
        !          1817:         err = UnpackFullSection ( packedBase, packedEnd, outputBase, outputEnd );
        !          1818:         if ( err != noErr ) goto ERROR;
        !          1819: 
        !          1820:         if ( false && EnableCFMDebugging && (section->execSize > 8) ) { // Force some tests of partial unpacking.
        !          1821: 
        !          1822:             UInt32  word;
        !          1823:             BytePtr  partContents   = (*pefPrivate->Allocate) ( section->execSize - 2 );
        !          1824: 
        !          1825:             PEF_Assert ( partContents != NULL );
        !          1826: 
        !          1827:             err = PEF_UnpackSection ( containerRef, sectionIndex, 1, &word, 4 );
        !          1828:             PEF_Assert ( err == noErr );
        !          1829: 
        !          1830:             err = PEF_UnpackSection ( containerRef, sectionIndex, section->execSize / 2, &word, 4 );
        !          1831:             PEF_Assert ( err == noErr );
        !          1832: 
        !          1833:             err = PEF_UnpackSection ( containerRef, sectionIndex, section->execSize - 5, &word, 4 );
        !          1834:             PEF_Assert ( err == noErr );
        !          1835: 
        !          1836:             err = PEF_UnpackSection ( containerRef, sectionIndex, 1, partContents, section->execSize - 2 );
        !          1837:             PEF_Assert ( err == noErr );
        !          1838: 
        !          1839:             (*pefPrivate->Release) ( partContents );
        !          1840:         }
        !          1841: 
        !          1842:     } else {
        !          1843: 
        !          1844:         if ( section->initSize < sectionOffset ) {
        !          1845:             PEF_BlockClear ( bufferAddress, bufferLength );
        !          1846:         } else {
        !          1847:             err = UnpackPartialSection ( packedBase, packedEnd, outputBase, outputEnd, sectionOffset );
        !          1848:             if ( err != noErr ) goto ERROR;
        !          1849:         }
        !          1850: 
        !          1851:         if ( EnableCFMDebugging ) {     // See if the partial output agrees with full output.
        !          1852: 
        !          1853:             BytePtr  fullContents   = (*pefPrivate->Allocate) ( section->execSize );
        !          1854: 
        !          1855:             PEF_Assert ( fullContents != NULL );
        !          1856:             PEF_BlockClear ( fullContents, section->execSize );
        !          1857: 
        !          1858:             err = UnpackFullSection ( packedBase, packedEnd, fullContents, fullContents + section->initSize - 1 );
        !          1859:             PEF_Assert ( err == noErr );
        !          1860: 
        !          1861:             PEF_Assert ( PEF_CompareBytes ( fullContents + sectionOffset, bufferAddress, bufferLength ) );
        !          1862: 
        !          1863:             (*pefPrivate->Release) ( fullContents );
        !          1864: 
        !          1865:         }
        !          1866: 
        !          1867:     }
        !          1868: 
        !          1869: 
        !          1870: OK:
        !          1871:     err = noErr;
        !          1872: 
        !          1873: EXIT:
        !          1874:     return err;
        !          1875: 
        !          1876: ERROR:
        !          1877:     goto EXIT;
        !          1878: 
        !          1879: 
        !          1880: ParameterError:
        !          1881:     err = paramErr;
        !          1882:     goto ERROR;
        !          1883: 
        !          1884: 
        !          1885: }   // PEF_UnpackSection ()
        !          1886: 
        !          1887: 
        !          1888: // �
        !          1889: // ===========================================================================================
        !          1890: // PEF_RelocateSection ()
        !          1891: // ======================
        !          1892: 
        !          1893: 
        !          1894: // *** This needs cleaning up.
        !          1895: 
        !          1896: 
        !          1897: OSStatus    PEF_RelocateSection ( CFContHandlerRef  containerRef,
        !          1898:                                   ItemCount         sectionIndex )
        !          1899: {
        !          1900:     OSStatus            err         = cfragCFMInternalErr;
        !          1901:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !          1902: 
        !          1903:     BytePtr *   raddr;
        !          1904:     ByteCount dataA;
        !          1905:     int cnt;    // ! Must be signed.
        !          1906:     ByteCount codeA;
        !          1907:     LoaderRelExpHeader * ldRelHdr;
        !          1908:     Relocation *reloc, *rlend;
        !          1909:     Relocation r;
        !          1910:     long rpt;   // ! Must be signed.
        !          1911:     long secn;
        !          1912:     long rsymi;
        !          1913:     BytePtr *imports;
        !          1914:     ByteCount *regions;
        !          1915:     long i;
        !          1916:     long relNum;
        !          1917:     BytePtr regStart;
        !          1918:     SectionHeader * section;
        !          1919: 
        !          1920: 
        !          1921:     if ( pefPrivate == NULL ) goto ParameterError;
        !          1922:     if ( sectionIndex >= pefPrivate->sectionCount ) goto ParameterError;
        !          1923: 
        !          1924:     regStart = pefPrivate->mappedOrigins[sectionIndex];
        !          1925:     section = & pefPrivate->sections [sectionIndex];
        !          1926: 
        !          1927:     pefPrivate->resolved = 1;       // !!! Really means relocated, and should be set on exit.
        !          1928: 
        !          1929:     for (i = 0; ; i++) {
        !          1930:         if ( i >= pefPrivate->sectionCount ) return noErr;  // No relocations for this section.
        !          1931:         ldRelHdr = & pefPrivate->ldrSections [i];
        !          1932:         if ( ldRelHdr->sectionNumber == sectionIndex ) break;
        !          1933:     }
        !          1934: 
        !          1935:     regions = pefPrivate->runningOffsets;
        !          1936:     imports = pefPrivate->imports;
        !          1937: 
        !          1938:     reloc = (Relocation *) (pefPrivate->ldrRelocations + ldRelHdr->relocationsOffset);
        !          1939:     rlend = (Relocation *) ((RelocInstr *) reloc + ldRelHdr->numRelocations);
        !          1940:     raddr = (BytePtr *) regStart;   // ! Change the stride from 1 to 4.
        !          1941:     rsymi = 0;
        !          1942:     codeA = regions [0];
        !          1943:     dataA = regions [1];
        !          1944:     rpt = 0;
        !          1945: 
        !          1946:     #if 0
        !          1947:         sprintf ( gDebugMessage, "PLPrepareRegion: start @ %.8X\n", raddr );
        !          1948:         PutSerialMesssage ( gDebugMessage );
        !          1949:     #endif
        !          1950: 
        !          1951:     relNum = 0;
        !          1952:     while (reloc < rlend) {
        !          1953: 
        !          1954:         r = *reloc;
        !          1955:         reloc = (Relocation *) ((RelocInstr *) reloc + 1);
        !          1956: 
        !          1957:         switch ( opcode [r.opcode.op] ) {
        !          1958:             case krDDAT :
        !          1959:                 raddr = (BytePtr *) ((BytePtr)raddr + (r.deltadata.delta_d4 * 4));  // ! Reduce stride to 1.
        !          1960:                 cnt = r.deltadata.cnt;
        !          1961:                 while (--cnt >= 0) {
        !          1962:                     *raddr++ += dataA;
        !          1963:                 }
        !          1964:                 break;
        !          1965: 
        !          1966:             case krCODE :
        !          1967:                 cnt = r.run.cnt_m1 + 1;
        !          1968:                 while (--cnt >= 0) {
        !          1969:                     *raddr++ += codeA;
        !          1970:                 }
        !          1971:                 break;
        !          1972: 
        !          1973:             case krDATA :
        !          1974:                 cnt = r.run.cnt_m1 + 1;
        !          1975:                 while (--cnt >= 0) {
        !          1976:                     *raddr++ += dataA;
        !          1977:                 }
        !          1978:                 break;
        !          1979: 
        !          1980:             case krDESC :
        !          1981:                 cnt = r.run.cnt_m1 + 1;
        !          1982:                 while (--cnt >= 0) {
        !          1983:                     *raddr++ += codeA;
        !          1984:                     *raddr++ += dataA;
        !          1985:                     raddr++;
        !          1986:                 }
        !          1987:                 break;
        !          1988: 
        !          1989:             case krDSC2 :
        !          1990:                 cnt = r.run.cnt_m1 + 1;
        !          1991:                 while (--cnt >= 0) {
        !          1992:                     *raddr++ += codeA;
        !          1993:                     *raddr++ += dataA;
        !          1994:                 }
        !          1995:                 break;
        !          1996: 
        !          1997:             case krVTBL :
        !          1998:                 cnt = r.run.cnt_m1 + 1;
        !          1999:                 while (--cnt >= 0) {
        !          2000:                     *raddr++ += dataA;
        !          2001:                     raddr++;
        !          2002:                 }
        !          2003:                 break;
        !          2004: 
        !          2005:             case krSYMR :
        !          2006:                 cnt = r.run.cnt_m1 + 1;
        !          2007:                 while (--cnt >= 0) {
        !          2008:                     *raddr++ += (ByteCount) imports [rsymi++];
        !          2009:                 }
        !          2010:                 break;
        !          2011: 
        !          2012:             case krSYMB :
        !          2013:                 rsymi = r.glp.idx;
        !          2014:                 *raddr++ += (ByteCount) imports [rsymi++];
        !          2015:                 break;
        !          2016: 
        !          2017:             case krCDIS :
        !          2018:                 codeA = regions [r.glp.idx];
        !          2019:                 break;
        !          2020: 
        !          2021:             case krDTIS :
        !          2022:                 dataA = regions [r.glp.idx];
        !          2023:                 break;
        !          2024: 
        !          2025:             case krSECN :
        !          2026:                 *raddr++ += regions [r.glp.idx];
        !          2027:                 break;
        !          2028: 
        !          2029:             case krDELT :
        !          2030:                 raddr = (BytePtr *) ((BytePtr) raddr + r.delta.delta_m1 + 1);   // ! Reduce stride to 1.
        !          2031:                 #if 0
        !          2032:                     sprintf ( gDebugMessage, "PLPrepareRegion: delta to %.8X\n", raddr );
        !          2033:                     PutSerialMesssage ( gDebugMessage );
        !          2034:                 #endif
        !          2035:                 break;
        !          2036: 
        !          2037:             case krRPT :
        !          2038:                 if (--rpt == 0) break;  // count was 1 --> rpt done
        !          2039:                 if (rpt < 0)                    // first time rpt encountered?
        !          2040:                     rpt = r.rpt.rcnt_m1 + 1; // yes- initialize rpt count
        !          2041:                 cnt = r.rpt.icnt_m1 + 2;    // yes or no - back up cnt instrs
        !          2042:                 reloc = (Relocation *) ((RelocInstr *) reloc - cnt);
        !          2043:                 break;
        !          2044: 
        !          2045:             case krLABS :
        !          2046:                 raddr = (BytePtr *) ((r.large1.idx_top << 16) + reloc->bot + regStart);
        !          2047:                 reloc = (Relocation *) ((RelocInstr *) reloc + 1);
        !          2048:                 #if 0
        !          2049:                     sprintf ( gDebugMessage, "PLPrepareRegion: abs to %.8X\n", raddr );
        !          2050:                     PutSerialMesssage ( gDebugMessage );
        !          2051:                 #endif
        !          2052:                 break;
        !          2053: 
        !          2054:             case krLSYM :
        !          2055:                 rsymi = (r.large1.idx_top << 16) + reloc->bot;
        !          2056:                 reloc = (Relocation *) ((RelocInstr *) reloc + 1);
        !          2057:                 *raddr++ += (ByteCount) imports [rsymi++];
        !          2058:                 break;
        !          2059: 
        !          2060:             case krLRPT :
        !          2061:                 if (--rpt == 0) {
        !          2062:                     reloc = (Relocation *) ((RelocInstr *) reloc + 1);
        !          2063:                     break;
        !          2064:                 }
        !          2065:                 if (rpt < 0)
        !          2066:                     rpt = (r.large2.idx_top << 16) + reloc->bot;
        !          2067:                 cnt = r.large2.cnt_m1 + 2;
        !          2068:                 reloc = (Relocation *) ((RelocInstr *) reloc - cnt);
        !          2069:                 break;
        !          2070: 
        !          2071:             case krLSEC :
        !          2072:                 secn = (r.large2.idx_top << 16) + reloc->bot;
        !          2073:                 switch (r.large2.cnt_m1) {
        !          2074:                     case 0 : *raddr++ += regions [secn]; break;
        !          2075:                     case 1 : codeA  = regions [secn]; break;
        !          2076:                     case 2 : dataA  = regions [secn]; break;
        !          2077:                 }
        !          2078:                 reloc = (Relocation *) ((RelocInstr *) reloc + 1);
        !          2079:                 break;
        !          2080: 
        !          2081:             default :
        !          2082:                 goto FragmentCorruptError;
        !          2083:         }
        !          2084:     }
        !          2085: 
        !          2086: 
        !          2087:     #if 0
        !          2088:         sprintf ( gDebugMessage, "PLPrepareRegion: end @ %.8X\n", raddr );
        !          2089:         PutSerialMesssage ( gDebugMessage );
        !          2090:     #endif
        !          2091: 
        !          2092: 
        !          2093: OK:
        !          2094:     err = noErr;
        !          2095: 
        !          2096: EXIT:
        !          2097:     return err;
        !          2098: 
        !          2099: ERROR:
        !          2100:     goto EXIT;
        !          2101: 
        !          2102: ParameterError:
        !          2103:     err = paramErr;
        !          2104:     goto ERROR;
        !          2105: 
        !          2106: FragmentCorruptError:
        !          2107:     err = cfragFragmentCorruptErr;
        !          2108:     goto ERROR;
        !          2109: 
        !          2110: 
        !          2111: }   // PEF_RelocateSection ()
        !          2112: 
        !          2113: 
        !          2114: // �
        !          2115: // ===========================================================================================
        !          2116: // PEF_RelocateImportsOnly ()
        !          2117: // ==========================
        !          2118: 
        !          2119: 
        !          2120: OSStatus    PEF_RelocateImportsOnly ( CFContHandlerRef  containerRef,
        !          2121:                                       ItemCount         sectionIndex,
        !          2122:                                       ItemCount         libraryIndex )
        !          2123: {
        !          2124:     OSStatus            err         = cfragCFMInternalErr;
        !          2125:     PEFPrivateInfo *    pefPrivate  = (PEFPrivateInfo *) containerRef;
        !          2126: 
        !          2127: 
        !          2128:     if ( pefPrivate == NULL ) goto ParameterError;
        !          2129:     if ( sectionIndex >= pefPrivate->sectionCount ) goto ParameterError;
        !          2130:     if ( libraryIndex >= pefPrivate->ldrHeader->numImportFiles ) goto ParameterError;
        !          2131: 
        !          2132: 
        !          2133:     if ( pefPrivate == NULL ) goto ParameterError;
        !          2134: 
        !          2135: 
        !          2136:     return unimpErr;    // !!! Fix this!
        !          2137: 
        !          2138: 
        !          2139: OK:
        !          2140:     err = noErr;
        !          2141: 
        !          2142: EXIT:
        !          2143:     return err;
        !          2144: 
        !          2145: ERROR:
        !          2146:     goto EXIT;
        !          2147: 
        !          2148: ParameterError:
        !          2149:     err = paramErr;
        !          2150:     goto ERROR;
        !          2151: 
        !          2152: 
        !          2153: }   // PEF_RelocateImportsOnly ()
        !          2154: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.