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