Annotation of driverkit/libDriver/ppc/IOPEFInternals.c, revision 1.1.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.