Annotation of XNU/iokit/Families/IONDRVSupport/IOPEFInternals.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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