Annotation of driverkit/libDriver/ppc/IOPEFLoader.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*
                     25:  * Copyright (c) 1997 Apple Computer, Inc.
                     26:  *
                     27:  *
                     28:  * HISTORY
                     29:  *
                     30:  * Simon Douglas  22 Oct 97
                     31:  * - first checked in.
                     32:  *     From pieces of ProtoCFM, Alan Lillich.
                     33:  */
                     34: 
                     35: 
                     36: #import <stdio.h>
                     37: #import <driverkit/generalFuncs.h>
                     38: 
                     39: #import  <driverkit/ppc/IOMacOSTypes.h>
                     40: #import "IOPEFLibraries.h"
                     41: #import "IOPEFLoader.h"
                     42: #import "IOPEFInternals.h"
                     43: 
                     44: 
                     45: 
                     46: #define LOG    if(1)   kprintf
                     47: #define INFO   if(0)   kprintf
                     48: 
                     49: struct SectionVars {
                     50:     LogicalAddress          address;
                     51:     ByteCount               unpackedLength;
                     52:     Boolean                 isPacked;
                     53: };
                     54: typedef struct SectionVars SectionVars;
                     55: 
                     56: struct InstanceVars {
                     57:     BytePtr                 pef;            // container in memory  
                     58:     CFContHandlerRef        cRef;
                     59:     CFContHandlerProcs *    cProcs;
                     60:     ItemCount               numSections;
                     61:     SectionVars         *   sections;
                     62: };
                     63: typedef struct InstanceVars InstanceVars;
                     64: 
                     65: 
                     66: static OSStatus LocationToAddress( InstanceVars * inst,
                     67:        CFContLogicalLocation * location, LogicalAddress * address );
                     68: static OSStatus SatisfyImports( InstanceVars * inst );
                     69: static OSStatus Instantiate( InstanceVars * inst );
                     70: 
                     71: 
                     72: #define PCFM_BlockCopy(src,dst,len)    memcpy(dst,src,len)
                     73: #define PCFM_BlockClear(dst,len)       memset(dst,0,len)
                     74: #define PCFM_MakeExecutable(addr,len)  flush_cache_v((vm_offset_t)addr, len)
                     75: 
                     76: // �
                     77: // ===========================================================================================
                     78: // CFContHashName ()
                     79: // =================
                     80: 
                     81: 
                     82: CFContStringHash    CFContHashName  ( BytePtr   nameText,
                     83:                                       ByteCount nameLength )
                     84: {
                     85:     BytePtr             currChar    = nameText;
                     86:     SInt32              hashValue   = 0;    // ! Signed to match old published PEF algorithm.
                     87:     ByteCount           length      = 0;
                     88:     ByteCount           limit;
                     89:     CFContStringHash    result;
                     90: 
                     91:     #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> (16) ) )
                     92: 
                     93: 
                     94:     for ( limit = nameLength; limit > 0; limit -= 1 ) {
                     95:         if ( *currChar == NULL ) break;
                     96:         hashValue   = (PseudoRotate ( hashValue )) ^ *currChar;
                     97:         currChar    += 1;
                     98:         length      += 1;
                     99:     }
                    100: 
                    101:     result = (length << 16) | ((UInt16) ((hashValue ^ (hashValue >> 16)) & 0xFFFF));
                    102: 
                    103:     return result;
                    104: 
                    105: 
                    106: }   // CFContHashName ()
                    107: 
                    108: 
                    109: // �
                    110: // ===========================================================================================
                    111: // PCFM_CompareBytes ()
                    112: // ====================
                    113: 
                    114: 
                    115: Boolean PCFM_CompareBytes   ( const Byte *  left,
                    116:                               const Byte *  right,
                    117:                               ByteCount     count )
                    118: {
                    119:     // !!! Blechola!  Switch to a standard routine ASAP!
                    120: 
                    121:     UInt32 *    wLeft;
                    122:     UInt32 *    wRight;
                    123:     UInt8 *     bLeft;
                    124:     UInt8 *     bRight;
                    125: 
                    126:     ByteCount   leftMiss    = (UInt32)left & 0x00000003;
                    127:     ByteCount   rightMiss   = (UInt32)right & 0x00000003;
                    128: 
                    129: 
                    130:     bLeft   = (UInt8 *) left;
                    131:     bRight  = (UInt8 *) right;
                    132: 
                    133:     if ( (leftMiss != 0) && (rightMiss != 0) ) {
                    134:         ByteCount   align   = leftMiss;
                    135:         if ( align > count ) align = count;
                    136:         while ( align > 0 ) {
                    137:             if ( *bLeft++ != *bRight++ ) goto NoMatch;
                    138:             align -= 1;
                    139:             count -= 1;
                    140:         }
                    141:     }
                    142: 
                    143:     wLeft   = (UInt32 *) bLeft;
                    144:     wRight  = (UInt32 *) bRight;
                    145:     while ( count >= 4 ) {
                    146:         if ( *wLeft++ != *wRight++ ) goto NoMatch;
                    147:         count -= 4;
                    148:     }
                    149: 
                    150:     bLeft   = (UInt8 *) wLeft;
                    151:     bRight  = (UInt8 *) wRight;
                    152:     while ( count > 0 ) {
                    153:         if ( *bLeft++ != *bRight++ ) goto NoMatch;
                    154:         count -= 1;
                    155:     }
                    156: 
                    157:     return true;
                    158: 
                    159: 
                    160: NoMatch:
                    161:     return false;
                    162: 
                    163: 
                    164: }   // PCFM_CompareBytes ()
                    165: 
                    166: // ===========================================================================================
                    167: 
                    168: LogicalAddress PCodeAllocateMem( ByteCount size );
                    169: void  PCodeReleaseMem( LogicalAddress address );
                    170: 
                    171: LogicalAddress
                    172: PCodeAllocateMem( ByteCount size )
                    173: {
                    174:     return( IOMalloc( size ));
                    175: }
                    176: 
                    177: void 
                    178: PCodeReleaseMem( LogicalAddress address )
                    179: {
                    180: //    IOFree( address );
                    181: }
                    182: 
                    183: // ===========================================================================================
                    184: 
                    185: OSStatus
                    186: PCodeOpen( LogicalAddress container, ByteCount containerSize, PCodeInstance * instance )
                    187: {
                    188:     OSStatus            err;
                    189:     InstanceVars     *  inst;
                    190: 
                    191:     inst = PCodeAllocateMem( sizeof( InstanceVars));
                    192:     *instance = inst;
                    193: 
                    194:     inst->pef = (BytePtr) container;
                    195:                                             // procID, name, options
                    196:     err = PEF_OpenContainer( container, container, containerSize, 0, 0, 0,
                    197:                            PCodeAllocateMem, PCodeReleaseMem,
                    198:                            &inst->cRef, &inst->cProcs );
                    199:     if( err) LOG( "PEF_OpenContainer = %d\n", err );
                    200: 
                    201:     return( err);
                    202: }
                    203: 
                    204: 
                    205: OSStatus
                    206: PCodeInstantiate( PCodeInstance instance )
                    207: {
                    208:     OSStatus              err;
                    209:     InstanceVars       *  inst = instance;
                    210:     CFContLogicalLocation  initLocation;
                    211:     LogicalAddress        tv;
                    212:     CFragInitBlock        initInfo;
                    213: 
                    214:     do {
                    215:        err = Instantiate( inst );
                    216:        if( err)
                    217:            continue;
                    218: 
                    219:        // call INIT
                    220:        err = PEF_GetAnonymousSymbolLocations( inst->cRef, NULL, &initLocation, NULL );
                    221:        if( err)
                    222:            continue;
                    223:        err = LocationToAddress( inst, &initLocation, &tv );
                    224:        if( err || (tv == NULL) )
                    225:            continue;
                    226:        bzero( &initInfo, sizeof( initInfo));
                    227:        err = CallTVector( &initInfo, 0, 0, 0, 0, 0, tv );
                    228: 
                    229:     } while( false);
                    230: 
                    231:     return( err);
                    232: }
                    233: 
                    234: 
                    235: OSStatus
                    236: PCodeClose( PCodeInstance instance )
                    237: {
                    238:     OSStatus            err;
                    239:     InstanceVars     *  inst = instance;
                    240: 
                    241:     err = PEF_CloseContainer( inst->cRef, 0 );
                    242:     if( err) LOG( "PEF_CloseContainer = %d\n", err );
                    243: 
                    244:     return( err);
                    245: }
                    246: 
                    247: OSStatus
                    248: PCodeFindExport( PCodeInstance instance, const char * symbolName, LogicalAddress * address, CFragSymbolClass * symbolClass )
                    249: {
                    250:     CFContExportedSymbolInfo        symInfo;
                    251:     CFContHashedName                hashName;
                    252:     OSStatus                        err;
                    253:     InstanceVars               *   inst = instance;
                    254: 
                    255:     hashName.nameHash = CFContHashName( (UInt8 *) symbolName, strlen( symbolName) );
                    256:     hashName.nameText = (UInt8 *) symbolName;
                    257: 
                    258:     err = PEF_FindExportedSymbolInfo( inst->cRef, &hashName,
                    259:                                     kCFContExportedSymbolInfoVersion, (void *) 0, &symInfo );
                    260:     if( err) {
                    261:        LOG( "PEF_FindExportedSymbolInfo = %d\n", err );
                    262:        return( err);
                    263:     }
                    264: 
                    265:     if( address);
                    266:        err = LocationToAddress( inst, &symInfo.location, address );
                    267:     if( symbolClass)
                    268:        *symbolClass = symInfo.symbolClass;
                    269: 
                    270:     return( err);
                    271: }
                    272: 
                    273: OSStatus
                    274: PCodeFindMain( PCodeInstance instance, LogicalAddress * mainAddress )
                    275: {
                    276:     InstanceVars               *   inst = instance;
                    277:     CFContLogicalLocation           mainLocation;
                    278:     OSStatus                        err;
                    279: 
                    280:     err = PEF_GetAnonymousSymbolLocations( inst->cRef, &mainLocation, NULL, NULL );
                    281: 
                    282:     if( err == noErr)
                    283:        err = LocationToAddress( inst, &mainLocation, mainAddress );
                    284: 
                    285:     return( err);
                    286: }
                    287: 
                    288: 
                    289: 
                    290: // ===========================================================================================
                    291: 
                    292: static OSStatus
                    293: LocationToAddress( InstanceVars * inst, CFContLogicalLocation * location,
                    294:                LogicalAddress * address )
                    295: {
                    296:     BytePtr                 sectionBase;
                    297:     OSStatus                err = noErr;
                    298: 
                    299:     if ( location->section >= 0 ) {
                    300:         sectionBase = (BytePtr) (inst->sections + location->section)->address;
                    301:         *address = (LogicalAddress) (sectionBase + location->offset);
                    302: 
                    303:     } else if ( location->section == kCFContAbsoluteSectionIndex ) {
                    304:         *address = (LogicalAddress) location->offset;
                    305: 
                    306:     } else if ( location->section == kCFContNoSectionIndex ) {
                    307:         *address = (LogicalAddress) kUnresolvedCFragSymbolAddress;
                    308: 
                    309:     } else
                    310:         err = cfragFragmentFormatErr;
                    311: 
                    312:     return( err);
                    313: }
                    314: 
                    315: 
                    316: static OSStatus
                    317: Instantiate( InstanceVars * inst )
                    318: {
                    319:     CFContHandlerRef        cRef;
                    320:     ItemCount               numSects, sectionIndex;
                    321:     CFContSectionInfo       sectionInfo;
                    322:     CFContSectionInfo   *   section;
                    323:     OSStatus                err;
                    324: 
                    325:     cRef = inst->cRef;
                    326:             
                    327:     err = PEF_GetSectionCount( cRef, &numSects );
                    328:     if( err) LOG( "PEF_GetSectionCount = %d\n", err );
                    329:     INFO( "Num sects = %d\n", numSects );
                    330: 
                    331:     inst->numSections = numSects;
                    332:     inst->sections = PCodeAllocateMem( numSects * sizeof( SectionVars ));
                    333: 
                    334:     for( sectionIndex = 0; sectionIndex < numSects; sectionIndex++ )
                    335:     {
                    336:         Boolean                 isPacked, isMappable;
                    337:         Boolean                 needAlloc, needCopy, needClear;
                    338:         LogicalAddress          sectionAddress;
                    339:         SectionVars         *   sectionVars;
                    340: 
                    341:         sectionVars = inst->sections + sectionIndex;
                    342:         section = &sectionInfo;
                    343: 
                    344:         err = PEF_GetSectionInfo( cRef, sectionIndex, kCFContSectionInfoVersion, section );
                    345:         if( err) LOG( "PEF_GetSectionInfo = %d\n", err );
                    346: 
                    347: #if 0
                    348:         if ( sectionInfo.sharing == kCFContShareSectionInClosure ) goto SectionSharingError;
                    349:         if ( (! (sectionInfo.access & kCFContMemWriteMask)) &&
                    350:              (sectionInfo.options & kRelocatedCFContSectionMask) ) goto SectionOptionsError;
                    351: #endif
                    352: 
                    353:         isPacked            = ((section->options & kPackedCFContSectionMask) != 0);
                    354:         isMappable          = (! isPacked) &&
                    355:                               (! (section->options & kRelocatedCFContSectionMask)) &&
                    356:                               (! (section->access & kCFContMemWriteMask));
                    357: 
                    358:         if ( ! isMappable ) {
                    359:             // ----------------------------------------------------------------------------------
                    360:             // Mappable really means "fully expanded in container", so sections that are not mappable
                    361:             // need to be allocated.  The loader will do the initialization copying.  This is the
                    362:             // standard case for packed PEF data sections.
                    363:             needAlloc   = true;
                    364:             needCopy    = (! isPacked);
                    365:             needClear   = (section->totalLength != section->unpackedLength);
                    366: 
                    367:         } else if ( ! (section->access & kCFContMemWriteMask)  ) {
                    368:             // -----------------------------------------------------------------------------------
                    369:             // A "mappable" read only section.  Make sure it is fully present, i.e. no zero filled
                    370:             // extension.  This is the standard case for code and literal sections.
                    371:             if ( section->totalLength != section->unpackedLength ) {
                    372:                 err = cfragFragmentUsageErr;        // !!! Needs error label & message.
                    373: //              goto ERROR;
                    374:             }
                    375:             needAlloc   = false;
                    376:             needCopy    = false;
                    377:             needClear   = false;
                    378: 
                    379:         } else {
                    380:             // -----------------------------------------------------------------------------------
                    381:             // A "mappable", writeable, don't use in place section.  This is the standard case for
                    382:             // unpacked data sections.
                    383:             needAlloc   = true;
                    384:             needCopy    = true;
                    385:             needClear   = (section->totalLength != section->unpackedLength);
                    386:         }
                    387: 
                    388:         if ( needAlloc ) {
                    389:             // *** Should honor the container's alignment specifications.
                    390:             sectionAddress = PCodeAllocateMem( section->totalLength ); //, 4, allocMode );
                    391:         } else {
                    392:             sectionAddress  = inst->pef + section->containerOffset;
                    393:         }
                    394: 
                    395:         // --------------------------------------------------------------------------------------
                    396:         // !!! The copy/clear code should be moved to the loader as part of the split of the
                    397:         // !!! unpack/relocate operations.  It isn't clear at this point if both the read and
                    398:         // !!! write sides should be touched.  What if the write side pushes out pages brought in
                    399:         // !!! by the read side?  We should also have better advice to say all bytes are changed.
                    400: 
                    401:         if ( needCopy ) {
                    402:             BytePtr     source  = inst->pef + section->containerOffset;
                    403:             BytePtr     dest    = sectionAddress;
                    404:             ByteCount   length  = section->unpackedLength;
                    405: 
                    406:             PCFM_BlockCopy ( source, dest, length );
                    407:         }
                    408: 
                    409:         if ( needClear ) {
                    410:             BytePtr     dest    = (BytePtr) sectionAddress + section->unpackedLength;
                    411:             ByteCount   length  = section->totalLength - section->unpackedLength;
                    412: 
                    413:             PCFM_BlockClear ( dest, length );
                    414:         }
                    415: 
                    416:         // -------------------------------------------------------------------------------------
                    417:         // If CFM was responsible for bringing the container into memory then we have to get the
                    418:         // I&D caches in sync for the (read-only & use-in-place) code sections.
                    419: 
                    420:        if ( (section->access & kCFContMemExecuteMask) && (! (section->access & kCFContMemWriteMask)) && isMappable ) {
                    421:            PCFM_MakeExecutable ( sectionAddress, section->unpackedLength );
                    422:        }
                    423: 
                    424:         err = PEF_SetSectionAddress( cRef, sectionIndex, sectionAddress, sectionAddress );
                    425:         if( err) LOG( "PEF_SetSectionAddress = %d\n", err );
                    426: 
                    427:         sectionVars->address = sectionAddress;
                    428:         sectionVars->unpackedLength = section->unpackedLength;
                    429:         sectionVars->isPacked = isPacked;
                    430:     }
                    431: 
                    432:     // -------------------------------------------------------------------------------------
                    433: 
                    434:     err = SatisfyImports( inst );
                    435:     if( err) LOG( "SatisfyImports = %d\n", err );
                    436: 
                    437:     // -------------------------------------------------------------------------------------
                    438: 
                    439:     for( sectionIndex = 0; sectionIndex < numSects; sectionIndex++ )
                    440:     {
                    441:         SectionVars         *   sectionVars;
                    442: 
                    443:         sectionVars = inst->sections + sectionIndex;
                    444: 
                    445:        INFO("Section[%d] ", sectionIndex );
                    446: 
                    447:         if ( sectionVars->isPacked ) {
                    448:        INFO("unpacking...");
                    449:             err = PEF_UnpackSection(        cRef,
                    450:                                             sectionIndex,
                    451:                                             0,  // Unpack the whole section.
                    452:                                             sectionVars->address,
                    453:                                             sectionVars->unpackedLength );
                    454:             if( err) LOG( "PEF_UnpackSection = %d\n", err );
                    455:         }
                    456: 
                    457:        INFO("reloc...");
                    458:         err = PEF_RelocateSection( cRef, sectionIndex );
                    459: 
                    460:        INFO(" address = 0x%08x\n", sectionVars->address );
                    461:     }
                    462: 
                    463:     if( err) LOG( "Instantiate = %d\n", err );
                    464: 
                    465:     return( err);
                    466: }
                    467: 
                    468: struct StubFunction {
                    469:     LogicalAddress     pc;
                    470:     LogicalAddress     toc;
                    471:     char               name[64];
                    472: };
                    473: typedef struct StubFunction StubFunction;
                    474: 
                    475: OSStatus UnimplementedFunction( UInt32 p1, UInt32 p2, UInt32 p3, UInt32 p4 )
                    476: {
                    477:     char * name = (char *) get_R2();
                    478: 
                    479:     LOG("-*- %s : %x, %x, %x\n", name, p1, p2, p3, p4);
                    480: 
                    481:     set_R2( (UInt32) name);
                    482:     return( -53);
                    483: }
                    484: 
                    485: static OSStatus
                    486: SatisfyImports( InstanceVars * inst )
                    487: {
                    488:     CFContImportedSymbolInfo        symInfo;
                    489: 
                    490:     OSStatus                        err = 0;
                    491:     CFContHandlerRef                cRef;
                    492:     ItemCount                       numLibs, numSyms, index, i;
                    493:     struct CFLibInfo {
                    494:         CFContImportedLibraryInfo   info;
                    495:         LibraryEntry            *   found;
                    496:     };
                    497:     struct CFLibInfo            *   libInfo;
                    498:     struct CFLibInfo            *   curLib;
                    499:     FunctionEntry               *   funcs;
                    500:     TVector                     *   symAddr;
                    501:     StubFunction               *   stub;
                    502: 
                    503:     cRef = inst->cRef;
                    504:     err = PEF_GetImportCounts( cRef, &numLibs, &numSyms );
                    505:     if( err) LOG( "PEF_GetImportCounts = %d\n", err );
                    506: 
                    507:     libInfo = PCodeAllocateMem( numLibs * sizeof( struct CFLibInfo));
                    508:     PCFM_BlockClear( libInfo, numLibs * sizeof( struct CFLibInfo));
                    509: 
                    510:     for( index = 0; index < numLibs; index++ )
                    511:     {
                    512:         curLib = libInfo + index;
                    513:         err = PEF_GetImportedLibraryInfo( cRef, index, kCFContImportedLibraryInfoVersion, &curLib->info);
                    514:         if( err) LOG( "PEF_GetImportCounts = %d\n", err );
                    515: 
                    516:         for( i = 0; i < numLibraries; i++ ) {
                    517:             if( strcmp( (char *) curLib->info.libraryName.nameText, Libraries[ i ].name) == 0) {
                    518:                 curLib->found = &Libraries[ i ];
                    519:                 break;
                    520:             }
                    521:         }
                    522:     }
                    523: 
                    524:     for( index = 0; index < numSyms; index++ )
                    525:     {
                    526:         err = PEF_GetImportedSymbolInfo( cRef, index, kCFContImportedSymbolInfoVersion, &symInfo );
                    527:         if( err) LOG( "PEF_GetImportedSymbolInfo = %d\n", err );
                    528: 
                    529:         curLib = libInfo + symInfo.libraryIndex;
                    530: 
                    531:         symAddr = NULL;
                    532:         if( curLib->found) {
                    533:             for( i = 0; i < curLib->found->numSyms; i++ ) {
                    534: 
                    535:                 funcs = curLib->found->functions + i;
                    536:                 if( strcmp( (char *) symInfo.symbolName.nameText, funcs->name ) == 0) {
                    537:                     symAddr = (TVector *) &funcs->address;
                    538:                     break;
                    539:                 }
                    540:             }
                    541:         }
                    542: 
                    543:        if( symAddr == NULL) {
                    544:            LOG("Undefined %s:%s ", curLib->info.libraryName.nameText, symInfo.symbolName.nameText );
                    545: 
                    546:            stub = IOMalloc( sizeof( StubFunction));
                    547:            symAddr = (TVector *) &stub->pc;
                    548:            stub->pc = UnimplementedFunction;
                    549:            stub->toc = &stub->name[0];
                    550:            strncpy( stub->name, symInfo.symbolName.nameText, 60);
                    551:        }
                    552: 
                    553:         err = PEF_SetImportedSymbolAddress( cRef, index, symAddr );
                    554:         if( err) LOG( "PEF_SetImportedSymbolAddress = %d\n", err );
                    555:     }
                    556: 
                    557:     PCodeReleaseMem( libInfo);
                    558: 
                    559:     return( err);
                    560: }
                    561: 
                    562: 
                    563: 
                    564: 

unix.superglobalmegacorp.com

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