|
|
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, §ionInfo->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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.