|
|
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.