Changeset 14

Show
Ignore:
Timestamp:
09/05/05 15:02:10 (3 years ago)
Author:
pragma
Message:

dirty incremental - fixes numerous OMF parsing bugs with phobos.lib

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ddl/all.d

    r10 r14  
    3131 
    3232interface DynamicModule{ 
     33    public char[] getName(); 
    3334    public char[][] getDependencies(); 
    3435    public void resolveDependency(char[] name,void* address); 
  • trunk/ddl/omf/OMFBinary.d

    r13 r14  
    9898    } 
    9999     
     100    public char[] getName(){ 
     101        return libraryName; 
     102    } 
     103     
    100104    public char[] toString(){ 
    101105        char[] output; 
     
    148152        return output; 
    149153    } 
    150  
    151     protected void parseTHeader(RecordCursor cursor){ 
     154    protected void parseTHEADR(RecordCursor cursor){ 
    152155        char[] name = cursor.getLString(); 
    153         debug writefln("Header: %s",name); 
     156        debug writefln("Library Name: %s",name); 
    154157        this.libraryName = name; 
    155158    } 
    156159     
    157     protected void parseComment(RecordCursor cursor){ 
     160    protected void parseCOMENT(RecordCursor cursor){ 
    158161        ubyte commentType = cursor.getByte(); 
    159162        ubyte commentClass = cursor.getByte(); 
     
    180183    } 
    181184     
    182     protected void parseModuleEnd(RecordCursor cursor){ 
    183         // completely and totally ignored as it is only useful for finding a module start address 
    184     } 
    185      
    186     protected void parseExternNames(RecordCursor cursor){ 
     185    protected void parseMODEND(RecordCursor cursor){ 
     186        //NOTE: this is completely and totally ignored.  The main loop exits after this call. 
     187    } 
     188     
     189    protected void parseEXTDEF(RecordCursor cursor){ 
    187190        while(cursor.hasMore()){ 
    188191            ExternalSymbol ext; 
     
    228231        Get names for the names list  
    229232    */ 
    230     protected void parseListOfNames(RecordCursor cursor){ 
     233    protected void parseLNAMES(RecordCursor cursor){ 
    231234        while(cursor.hasMore()){ 
    232235            char[] name = cursor.getLString(); 
    233             debug writefln("name: %s",name); 
     236            debug writefln("LNAME: %s",name); 
    234237             
    235238            this.names ~= name; 
     
    241244        - really doesn't do all that much aside from marking the length, alignment and reserve an array index 
    242245    */ 
    243     protected void parseSegmentDefinition(RecordCursor cursor){        
     246    protected void parseSEGDEF(RecordCursor cursor){       
    244247        // record segment information 
    245248        Segment seg; 
     
    279282        Parse the group definition - verifies that the group specified is indeed named 'FLAT'. 
    280283    */ 
    281     protected void parseGroupDefinition(RecordCursor cursor){ 
     284    protected void parseGRPDEF(RecordCursor cursor){ 
    282285        uint nameIndex = cursor.getIndex(); 
    283286        char[] name = this.names[nameIndex]; 
     
    295298        Gather fixup data    
    296299    */       
    297     protected void parseFixupData(RecordCursor cursor){ 
     300    protected void parseFIXUPP(RecordCursor cursor){ 
    298301        while(cursor.hasMore()){ 
    299302            ushort type = cursor.getByte();              
     
    398401     
    399402     
    400     protected void parseLogicalEnumeratedData(RecordCursor cursor){ 
     403    protected void parseLEDATA(RecordCursor cursor){ 
    401404        uint segmentIndex = cursor.getIndex(); 
    402405        uint offsetAddress = cursor.getVWord(); 
     
    408411        this.enumData.offset = offsetAddress; 
    409412         
    410         debug writefln("enum data: segmentIndex %d | offset %d | length %d",segmentIndex,offsetAddress,rawData.length);        
     413        debug writefln("LEDATA: segmentIndex %d | offset %d | length %d",segmentIndex,offsetAddress,rawData.length);       
    411414    }    
    412415 
    413416    // add raw data to a segment     
    414     protected void parseLogicalIteratedData(RecordCursor cursor){  
     417    protected void parseLIDATA(RecordCursor cursor){   
    415418        uint segmentIndex = cursor.getIndex(); 
    416419        uint offsetAddress = cursor.getVWord(); 
     
    471474 
    472475     
    473     protected void parseExternalNames(RecordCursor cursor){ 
     476    protected void parseCEXTDEF(RecordCursor cursor){ 
    474477        while(cursor.hasMore()){ 
    475478            // get the name index for this external reference 
     
    485488    } 
    486489     
     490    protected void parseCOMDEF(RecordCursor cursor){ 
     491        //TODO: make sure that the COMDEF is actually defined somewhere after linking 
     492        //TODO: may have to create it here on the fly, flagged as 'common' so that duplicates can be eliminated 
     493        while(cursor.hasMore()){ 
     494            char[] communalName = cursor.getLString(); 
     495            cursor.getVByte(); // throw out type index 
     496            ubyte dataType = cursor.getByte(); 
     497             
     498            uint getNumericValue(){ 
     499                ubyte indicator = cursor.getByte(); 
     500                if(indicator <= 128){ 
     501                    return indicator; 
     502                } 
     503                else if(indicator == 0x81){ 
     504                    return cursor.getWord(); 
     505                } 
     506                else if(indicator == 0x84){ 
     507                    return (cursor.getByte() << 16) | cursor.getWord(); 
     508                } 
     509                else if(indicator == 0x88){ 
     510                    return cursor.getDWord(); 
     511                } 
     512                else throw new FeatureNotSupportedException( 
     513                    std.string.format("COMDEF numeric type %0.2X is not supported",indicator) 
     514                ); 
     515            } 
     516                         
     517            if(dataType < 0x51){ 
     518                debug writefln("COMDEF %s: segment #%d",communalName,dataType);  
     519            } 
     520            else if(dataType == 0x61){ 
     521                uint elements = getNumericValue(); 
     522                uint size = getNumericValue(); 
     523                debug writefln("COMDEF %s: FAR data - %d elements, %d bytes each",communalName,elements,size); 
     524            } 
     525            else if(dataType == 0x62){ 
     526                uint bytes = getNumericValue(); 
     527                debug writefln("COMDEF %s: NEAR data - %d bytes",communalName,bytes); 
     528            } 
     529            else{ 
     530                throw new FeatureNotSupportedException( 
     531                    std.string.format("COMDEF type %0.2X is not supported",dataType) 
     532                ); 
     533            } 
     534             
     535            ExternalSymbol ext; 
     536            ext.name = communalName; 
     537            debug writefln("COMDEF extern: %s",ext.name);            
     538            this.externs ~= ext;     
     539        } 
     540    } 
     541     
    487542    //discrete bits of data for code 
    488     protected void parseCommonData(RecordCursor cursor){ 
     543    protected void parseCOMDAT(RecordCursor cursor){ 
    489544        ubyte flags = cursor.getByte(); 
    490545             
     
    581636            //NOTE: the specification is organized by the type number, simply search it on xxH. 
    582637            switch(type){ 
    583             case 0x80: parseTHeader(cursor); break; 
    584             case 0x88: parseComment(cursor); break; 
    585             case 0x8A: parseModuleEnd(cursor); return; // last record 
    586             case 0x8C: parseExternNames(cursor); break; 
     638            case 0x80: parseTHEADR(cursor); break; 
     639            case 0x88: parseCOMENT(cursor); break; 
     640            case 0x8A: parseMODEND(cursor); return; // last record 
     641            case 0x8C: parseEXTDEF(cursor); break; 
    587642            case 0x90: parsePUBDEF(cursor); break; 
    588             case 0x96: parseListOfNames(cursor); break; 
    589             case 0x98: parseSegmentDefinition(cursor); break; 
    590             case 0x9A: parseGroupDefinition(cursor); break; 
    591             case 0x9C: parseFixupData(cursor); break; 
    592             case 0xA0: parseLogicalEnumeratedData(cursor); break; 
    593             case 0xA2: parseLogicalIteratedData(cursor); break; 
    594             case 0xBC: parseExternalNames(cursor); break; 
    595             case 0xC2: parseCommonData(cursor); break; 
     643            case 0x96: parseLNAMES(cursor); break; 
     644            case 0x98: parseSEGDEF(cursor); break; 
     645            case 0x9A: parseGRPDEF(cursor); break; 
     646            case 0x9C: parseFIXUPP(cursor); break; 
     647            case 0xA0: parseLEDATA(cursor); break; 
     648            case 0xA2: parseLIDATA(cursor); break; 
     649            case 0xB0: parseCOMDEF(cursor); break; 
     650            case 0xBC: parseCEXTDEF(cursor); break; 
     651            case 0xC2: parseCOMDAT(cursor); break; 
    596652            default: 
    597653                throw new FeatureNotSupportedException( 
     
    633689             
    634690            if(fix.isExternStyleFixup){ 
     691                debug writefln("extern %d of %d",fix.targetIndex,externs.length); 
    635692                ExternalSymbol* target = &(this.externs[fix.targetIndex]); 
    636693                 
  • trunk/ddl/omf/OMFLibrary.d

    r13 r14  
    4949     
    5050    package void addModule(OMFModule mod){ 
     51    printf("adding module %d to library\n",this.modules.length); 
     52        this.modules ~= mod; 
    5153        foreach(ExportSymbol exp; mod.getExports()){ 
    5254            dictionary[exp.name] = exp; 
     
    7274        libFile.read(flags); 
    7375         
    74         printf("Dictionary: %0.8X\n",dictionaryOffset); 
     76        debug writefln("Dictionary: %0.8X\n",dictionaryOffset); 
    7577         
    7678        assert(type == 0xF0);  // assert OMF library 
     
    8688        OMFModule mod; 
    8789        while(!libFile.eof()){ 
    88             printf("offset: %0.8X\n",libFile.position); 
     90            debug writefln("offset: %0.8X\n",libFile.position); 
    8991         
    9092            mod = new OMFModule(); 
     
    9799                libFile.seek(delta,SeekPos.Current);  
    98100            } 
    99              
     101 
     102            // determine if we're at the end of the module list          
    100103            ubyte next; 
    101104            libFile.read(next); 
    102             printf("next: %0.2X\n",next); 
    103             assert(next != 0xF1); 
     105            debug writefln("next: %0.2X\n",next); 
    104106            libFile.seek(-1,SeekPos.Current);        
    105              
     107            if(next == 0xF1) break;  
    106108        } 
    107          
    108109        //skip the dictionary (redundant) 
    109110        libFile.close(); 
  • trunk/ddl/omf/OMFLoader.d

    r10 r14  
    4747            OMFModule mod = new OMFModule(); 
    4848            mod.loadFromFile(filename); 
    49             lib.addModule(mod);          
     49            printf("%.*s ==> %d exports\n",mod.getName(),mod.getExports.length); 
     50            lib.addModule(mod); 
     51            printf("%.*s ==> %d exports\n",lib.getModules[0].getName(),mod.getExports.length); 
    5052        } 
    5153        return lib; 
  • trunk/ddl/omf/OMFModule.d

    r10 r14  
    3232 
    3333class OMFModule : DynamicModule{ 
     34    char[] moduleName; 
    3435    char[][] dependencies; 
    3536    ExportSymbol[char[]] exports; 
     
    3839    package this(){ 
    3940        /* module-only constructor */ 
     41    } 
     42     
     43    char[] getName(){ 
     44        return this.moduleName; 
    4045    } 
    4146 
     
    5661        return exports[name]; 
    5762    } 
    58          
     63 
    5964    package void loadFromFile(char[] filename){ 
    6065        binary = new OMFBinary(); 
    6166        binary.loadFromFile(filename); 
    62          
    63         debug writefln("Binary: %s",binary.toString()); 
    6467        syncronizeSymbols(); 
    6568    } 
    6669     
    67     public void loadFromFile(char[] filename,File fileStream){ 
     70    package void loadFromFile(char[] filename,File fileStream){ 
    6871        binary = new OMFBinary(); 
    6972        binary.loadFromFile(filename,fileStream); 
    70          
    71         debug writefln("Binary: %s",binary.toString()); 
    7273        syncronizeSymbols(); 
    7374    } 
    7475     
    7576    protected void syncronizeSymbols(){ 
     77        this.dependencies.length = 0; 
     78        this.moduleName = binary.getName(); 
     79         
    7680        foreach(ExternalSymbol ext; binary.getExterns()){ 
    7781            if(ext.isResolved()){ 
  • trunk/ddl/omf/RecordCursor.d

    r9 r14  
    8080    } 
    8181     
     82    public ushort getDWord(){ 
     83        ushort result = *cast(uint*)cast(void*)data[position..position+4].ptr; 
     84        position+=4; 
     85        return result; 
     86    }    
     87     
    8288    public char[] getLString(){ 
    8389        char[] result; 
    8490        uint len = getByte(); 
    85          
     91                
    8692        if(len == 0) return result; 
    87         // debug writefln("getLString() pos: %s length: %s len: %s",position,data.length,len); 
     93 
     94        //NOTE: this is an undocumented extension to OMF for supporting names greater than 254 chars in length!!! 
     95        if(len == 255){ 
     96            getByte(); // throw away next byte (possibly high-order bytes in little-endian format - usually zero) 
     97            len = getWord(); // get the actual 16-bit length 
     98        } 
    8899         
    89100        result = cast(char[])data[position..position+len]; 
  • trunk/ddltest.d

    r13 r14  
    2828 
    2929void main(){ 
    30     test1(); 
     30    test2(); 
    3131} 
  • trunk/test/all.d

    r13 r14  
    2626 
    2727import test.test1; 
     28import test.test2; 
  • trunk/test/test1.d

    r13 r14  
    2626 
    2727private import ddl.all; 
     28private import std.stdio; 
    2829 
    2930void test1(){ 
    30     loadDDL(r"c:\dev\dm\lib\phobos.lib"); 
     31    DynamicLibrary lib = loadDDL(r"c:\dev\dm\lib\phobos.lib"); 
     32     
     33    writefln("Phobos modules (%d):",lib.getModules().length); 
     34    foreach(DynamicModule mod; lib.getModules()){ 
     35        writefln("%s",mod.getName()); 
     36    } 
    3137}