Changeset 219

Show
Ignore:
Timestamp:
07/28/06 20:32:37 (2 years ago)
Author:
pragma
Message:

Mostly working - still needs verification.

Files:

Legend:

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

    r218 r219  
    7575        forces the implementation to return every and all modules it controls, without exception.   
    7676         
    77         In light of that, Relying on the getModules() (and getExports()) methods can have serious  
     77        In light of that, Relying on the getModules() (and getSymbols()) methods can have serious  
    7878        performance implications, depending on the actual implemenation of DynamicLibrary.   
    7979        For example, some implementations may decide to intercept D symbols and map the symbol  
     
    8383        Returns: the module contianing the export, or null if no module in this library contains 
    8484        the export.  The module is not guaranteed to contain the symbol provided, and can simply be  
    85         the library's best guess as to a match.  Call getExport() on the returned module to eliminate 
     85        the library's best guess as to a match.  Call getSymbol() on the returned module to eliminate 
    8686        any such false-positives. 
    8787         
     
    105105    /* 
    106106        Template method that returns a typed export from the library.  The implementation uses 
    107         getExportAddress() internally.  This differs greatly from the use of getExport()  
     107        getSymbolAddress() internally.  This differs greatly from the use of getSymbol()  
    108108        variants in that it allows for a proper D namespace/name instead of a mangled symbol. 
    109109         
     
    125125        static if(T.mangleof[0] == 'P'){ 
    126126            typeof(T) getDExport() { 
    127                 return cast(typeof(T))getExport( "_D" ~  mangleSymbolName!(name) ~ T.mangleof[1..$]).address;  
     127                return cast(typeof(T))getSymbol( "_D" ~  mangleSymbolName!(name) ~ T.mangleof[1..$]).address;  
    128128                } 
    129129        } else { 
    130130            typeof(T) getDExport() { 
    131             return cast(typeof(T))getExport("_D" ~  mangleSymbolName!(name) ~ T.mangleof).address; } 
     131            return cast(typeof(T))getSymbol("_D" ~  mangleSymbolName!(name) ~ T.mangleof).address; } 
    132132        } 
    133133    } 
  • trunk/ddl/Linker.d

    r218 r219  
    118118        if(!m) return; 
    119119        if (m.flags & MIctordone) return; 
    120          
    121         debug debugLog("Module: %s %0.8X\n",m.name,cast(void*)m); 
     120 
     121        debug debugLog("this module: %0.8X",cast(void*)m); 
     122        debug debugLog("(name: %0.8X)",m.name.ptr);      
     123        debug debugLog("(ctor: %0.8X)",cast(void*)(m.ctor)); 
     124        debug debugLog("(dtor: %0.8X)",cast(void*)(m.dtor)); 
     125        debug debugLog("Module: %s\n",m.name); 
     126         
    122127        if (m.ctor || m.dtor) 
    123128        { 
     
    129134             
    130135            m.flags |= MIctorstart; 
     136            debug debugLog("running imported modules (%d)...",m.importedModules.length); 
    131137            foreach(ModuleInfo imported; m.importedModules){ 
    132138                initModule(imported,0); 
     
    142148        { 
    143149            m.flags |= MIctordone; 
     150            debug debugLog("running imported modules (%d)...",m.importedModules.length); 
    144151            foreach(ModuleInfo imported; m.importedModules){ 
    145152                initModule(imported,1); 
     
    147154        }     
    148155    } 
    149      
     156        
    150157    /** 
    151158        Links a module against the linker's internal cross-reference. 
     
    164171        mod.isLinking = true; 
    165172         
    166         foreach(symbol; mod.getSymbols){ 
     173        debug debugLog("Linking module: %s",mod.getName); 
     174         
     175        auto moduleSymbols = mod.getSymbols(); 
     176        for(uint i=0; i<moduleSymbols.length; i++){ 
     177            auto symbol = &(moduleSymbols[i]); 
     178             
    167179            if(symbol.type == SymbolType.Strong) continue; 
    168180            // resolve a dependency from out of the registry 
     
    174186                    } 
    175187                    auto otherSymbol = libMod.getSymbol(symbol.name); 
    176                     assert(otherSymbol.type == SymbolType.Strong); 
    177                      
    178                     symbol.address = otherSymbol.address; 
    179                     symbol.type = SymbolType.Strong; 
    180                     goto nextSymbol; 
     188                    if(otherSymbol.type == SymbolType.Strong){ 
     189                        debug debugLog("[Linker] found %s at %0.8X",otherSymbol.name,otherSymbol.address);       
     190                        symbol.address = otherSymbol.address; 
     191                        symbol.type = SymbolType.Strong; 
     192                        goto nextSymbol; 
     193                    } 
     194                    debug debugLog("symbol is not strong (%s -> %0.8X)",symbol.getTypeName,symbol.address); 
    181195                } 
    182196            } 
     
    200214            throw new LinkModuleException(mod); 
    201215        } 
    202          
     216 
     217        debug debugLog(mod.toString()); 
     218                         
    203219        // dig up the ModuleInfo (if applicable) and initalize it! 
    204220        foreach(sym; mod.getSymbols){ 
     221            if(!sym.address) continue; 
    205222            if(getDemangleType(sym.name) == DemangleType.ModuleInfo){ 
    206223                // found it, now get it and run the constructor 
    207224                ModuleInfo moduleInfo = cast(ModuleInfo)(sym.address); 
    208                 debug debugLog("init! %0.8X",sym.address); 
     225                debug debugLog("init! %s %s %0.8X",sym.name,sym.getTypeName,sym.address); 
    209226                initModule(moduleInfo,0); 
     227                debug debugLog("init done."); 
     228                break; 
    210229            } 
    211230        } 
    212231    } 
    213      
    214     /+ 
    215     public void link(DynamicModule mod){ 
    216         //protect against infinite recursion here by returning early 
    217         //by this, we count on the module being resolved further up the call stack 
    218         if(mod.isLinking) return; 
    219          
    220         mod.isLinking = true; 
    221          
    222         foreach(char[] dep; mod.getDependencies){ 
    223             ExportSymbol sym = ExportSymbol.init; 
    224             //TODO: create a cache for namespace matching requests and search that first 
    225             foreach(DynamicLibrary lib; this.libraries){ 
    226                 DynamicModule libMod = lib.getModuleForExport(dep); 
    227                 if(libMod){ 
    228                     //TODO: add to the cache here 
    229                     sym = libMod.getExport(dep); 
    230                     if(sym != ExportSymbol.init){ 
    231                         if(!libMod.isResolved()){ 
    232                             this.link(libMod); 
    233                         } 
    234                         mod.resolveDependency(sym); 
    235                         goto nextDep; // why keep looping? get the heck out -- we're done! 
    236                     } 
    237                 } 
    238             } 
    239             nextDep: 
    240             debug if(sym == ExportSymbol.init){ 
    241                 debugLog("[Linker.link]: cannot find %s",dep); 
    242             } 
    243         } 
    244         //TODO: possible mod.resolveInternals() call here. 
    245         mod.isLinking = false; 
    246          
    247         if(!mod.isResolved()){ 
    248             throw new LinkModuleException(mod); 
    249         } 
    250          
    251         // dig up the ModuleInfo (if applicable) and initalize it! 
    252         foreach(ExportSymbol sym; mod.getExports){ 
    253             if(getSymbolType(sym.name) == SymbolType.ModuleInfo){ 
    254                 // found it, now get it and run the constructor 
    255                 ModuleInfo moduleInfo = cast(ModuleInfo)(sym.address); 
    256                 debug debugLog("init! %0.8X",sym.address); 
    257                 initModule(moduleInfo,0); 
    258             } 
    259         } 
    260     }+/ 
    261232     
    262233    /** 
  • trunk/ddl/insitu/InSituLibBinary.d

    r181 r219  
    9191                         
    9292            sym.address = cast(void*)address; 
     93            sym.type = SymbolType.Strong; 
    9394                     
    9495            allSymbols[sym.name] = sym; 
  • trunk/ddl/insitu/InSituMapBinary.d

    r161 r219  
    7272        parsePublicsByName(iter);    
    7373        // throw away the publics by address 
     74         
     75        version(Windows){ 
     76            //HACK: add in parts to make DMD/OMF linking work correctly 
     77            //NOTE: blindly pulling in all 'Abs' symbols doesn't work as well as it should 
     78            ExportSymbol sym; 
     79             
     80            // __nullext - placeholder for the start of static init for modules 
     81            sym.address = null; 
     82            sym.name = "__nullext"; 
     83            sym.type = SymbolType.Strong; 
     84            allSymbols[sym.name] = sym; 
     85             
     86            // __except_list - placeholder for the start of the exception handling list in FS 
     87            sym.address = null; 
     88            sym.name = "__except_list"; 
     89            sym.type = SymbolType.Strong; 
     90            allSymbols[sym.name] = sym; 
     91        } 
    7492    } 
    7593     
     
    98116        line = iter.getNext();  // throw away the first line (header) 
    99117        line = iter.getNext();  // throw away the second line (blank) 
    100                 
     118         
    101119        // read until there's a blank line 
    102120        while(true){ 
    103121            line = iter.getNext(); 
    104122            if(line.length == 0) break; 
    105                                      
     123                             
     124            uint rva; 
     125                     
    106126            // throw away the address (first nine chars)  
    107127            if(line[14..21] == "  Imp  ") continue; // throw this away! We want the '__imp__' version instead. 
     
    121141            assert(line.length == 8); 
    122142            pos = 0; 
    123             uint rva; 
    124143            while(pos < 8){ 
    125144                char ch = line[pos]; 
     
    143162            sym.address = cast(void*)rva; 
    144163            sym.name = symbol; 
     164            sym.type = SymbolType.Strong; 
    145165                         
    146166            allSymbols[sym.name] = sym; 
  • trunk/ddl/omf/OMFBinary.d

    r218 r219  
    121121} 
    122122 
    123 void parse(inout EXTDEF[] externs,OMFReader reader){ 
     123void parse(inout EXTDEF[] externs,inout FixupTarget[] targets,OMFReader reader){ 
    124124    while(reader.hasMore()){ 
    125125        EXTDEF extdef;       
    126126        extdef.parse(reader); 
    127127        externs ~= extdef; 
     128         
     129        FixupTarget target; 
     130        target.type = FixupTarget.EXTDEF; 
     131        target.index = externs.length-1; 
     132        targets ~= target;       
    128133    } 
    129134} 
     
    149154} 
    150155 
    151 void parse(inout PUBDEF[] publics,OMFReader reader){ 
     156void parse(inout PUBDEF[] publics,inout FixupTarget[] targets,OMFReader reader){ 
    152157    OMFIndex groupIndex; 
    153158    OMFIndex segmentIndex; 
     
    176181         
    177182        publics ~= pub; 
     183         
     184        FixupTarget target; 
     185        target.type = FixupTarget.PUBDEF; 
     186        target.index = publics.length-1; 
     187        targets ~= target; 
    178188    } 
    179189} 
     
    353363     
    354364    void parse(OMFReader reader){ 
    355     } 
     365        //not used 
     366    } 
     367
     368 
     369 
     370/** 
     371    Defines a mapping between a record and a logical fixup target index. 
     372*/ 
     373struct FixupTarget{ 
     374    enum: ubyte{ 
     375        PUBDEF, 
     376        CEXTDEF, 
     377        COMDAT, 
     378        EXTDEF 
     379    } 
     380    ubyte type; 
     381    uint index; 
    356382} 
    357383 
     
    375401    FixupThread[4] targetThreads;    
    376402} 
     403 
    377404void parse(inout FIXUPP[] fixups,inout FixupData fixupData, OMFReader reader){ 
    378405    ubyte type; 
     
    399426            method = (type & 0b00011100) >> 2; 
    400427             
    401             // frame thread 
     428            // find the frame type 
    402429            if(type & 0b01000000){   
    403430                fixupThread = &(fixupData.frameThreads[threadNumber]);               
    404  
    405                 if(fixupThread.method < 4){  
    406                     reader.get(tmpIndex); 
    407                     fixupThread.index = cast(ushort)tmpIndex; 
    408                 } 
    409                 else{ 
    410                     fixupThread.index = 0; 
    411                 } 
    412             } 
    413             // target thread 
    414             else{  
     431            } 
     432            else{ 
    415433                fixupThread = &(fixupData.targetThreads[threadNumber]); 
     434            } 
     435             
     436            // get the index 
     437            if(method < 4){  
    416438                reader.get(tmpIndex); 
    417439                fixupThread.index = cast(ushort)tmpIndex; 
    418440            } 
    419              
     441            else{ 
     442                fixupThread.index = 0; 
     443            } 
     444            // set the method        
    420445            fixupThread.method = method; 
    421446        }            
     
    676701} 
    677702 
    678 void parse(inout CEXTDEF[] commonExterns,OMFReader reader){ 
     703void parse(inout CEXTDEF[] commonExterns,inout FixupTarget[] targets,OMFReader reader){ 
    679704    while(reader.hasMore()){ 
    680705        CEXTDEF def; 
    681706        def.parse(reader); 
    682707        commonExterns ~= def; 
     708         
     709        FixupTarget target; 
     710        target.type = FixupTarget.CEXTDEF; 
     711        target.index = commonExterns.length-1; 
     712        targets ~= target; 
    683713    } 
    684714} 
     
    735765} 
    736766 
    737 void parse(inout COMDAT[] commonData,inout FixupData fixupData,OMFReader reader){ 
     767void parse(inout COMDAT[] commonData,inout FixupData fixupData,inout FixupTarget[] targets,OMFReader reader){ 
    738768    while(reader.hasMore()){ 
    739769        COMDAT data; 
     
    743773        fixupData.groupIndex = data.groupIndex; 
    744774        fixupData.segmentIndex = data.segmentIndex; 
    745         fixupData.offset = data.enumDataOffset; 
     775        fixupData.offset = data.enumDataOffset;      
     776         
     777        if(!data.isContinuation){        
     778            FixupTarget target; 
     779            target.type = FixupTarget.COMDAT; 
     780            target.index = commonData.length-1; 
     781            targets ~= target; 
     782        } 
    746783    } 
    747784} 
     
    851888    LString libraryName; 
    852889    LString[] names; 
     890    FixupTarget[] targets; 
    853891     
    854892    // comment sub data 
     
    894932        names.length = names.length+1; 
    895933        externs.length = externs.length+1; 
     934        targets.length = targets.length+1; 
    896935         
    897936        while(mainReader.hasMore()){ 
     
    918957             
    919958            case 0x8C: //EXTDEF 
    920                 .parse(externs,reader);  
     959                .parse(externs,targets,reader); 
    921960                break; 
    922961             
    923962            case 0x90: //PUBDEF 
    924                 .parse(publics,reader);  
     963                .parse(publics,targets,reader);  
    925964                break; 
    926965             
     
    958997                 
    959998            case 0xBC: //CEXTDEF 
    960                 .parse(communalExterns,reader);  
     999                .parse(communalExterns,targets,reader);  
    9611000                break; 
    9621001                 
    9631002            case 0xC2: //COMDAT 
    964                 .parse(communalData,fixupData,reader);  
     1003                .parse(communalData,fixupData,targets,reader);  
    9651004                break; 
    9661005                 
     
    10321071        } 
    10331072    } 
    1034      
     1073        
    10351074    public char[] toString(){ 
     1075        char[] getExternName(uint index){ 
     1076            uint workingIndex = index; 
     1077        /*  FixupTarget target = targets[index]; 
     1078             
     1079            switch(target.type){ 
     1080            case FixupTarget.CEXTDEF: 
     1081                return cast(char[])names[communalExterns[target.index].nameIndex]; 
     1082            case FixupTarget.EXTDEF: 
     1083                return cast(char[])externs[target.index].name;               
     1084            case FixupTarget.COMDAT: 
     1085                return cast(char[])communalDefinitions[target.index].communalName;   
     1086            case FixupTarget.PUBDEF: 
     1087                return cast(char[])publics[target.index].name;               
     1088            }*/ 
     1089             
     1090            if(workingIndex < communalExterns.length){ 
     1091                return cast(char[])names[communalExterns[workingIndex].nameIndex]; 
     1092            } 
     1093            workingIndex -= communalExterns.length; 
     1094            if(workingIndex < externs.length){ 
     1095                return cast(char[])externs[workingIndex].name;               
     1096            } 
     1097            workingIndex -= externs.length; 
     1098            if(workingIndex < communalDefinitions.length){ 
     1099                return cast(char[])communalDefinitions[workingIndex].communalName; 
     1100            } 
     1101        }    
     1102         
    10361103        char[] result = ""; 
    10371104        ExtSprintClass sprint = new ExtSprintClass(1024); 
     
    10581125            } 
    10591126        } 
    1060  
     1127         
    10611128        result ~= "WKEXT:\n"; 
    10621129        foreach(idx,weak; weakExterns){ 
    10631130            with(weak){ 
    1064                 char[] weakName = externs[weakIndex].name; 
    1065                 char[] defaultName = externs[resolutionIndex].name; 
    1066                 result ~= sprint("  %d: %s --> %s\n",idx,weakName,defaultName); 
     1131                char[] defaultName = getExternName(resolutionIndex); 
     1132                char[] weakName = getExternName(weakIndex); 
     1133                uint externsLength = externs.length; 
     1134                uint cextedfsLength = communalExterns.length;    
     1135                                     
     1136                result ~= sprint("  %d: (%d) %s --> (%d) %s\n",idx,cast(uint)weakIndex,weakName,cast(uint)resolutionIndex,defaultName); 
    10671137            } 
    10681138        } 
     
    11231193                 
    11241194                if(isExternStyleFixup){ 
    1125                     uint externsLength = externs.length; 
    1126                     uint cextedfsLength = communalExterns.length; 
    1127                     if(fix.targetIndex < externsLength){ 
    1128                         targetName = "extern: " ~ cast(char[])externs[fix.targetIndex].name; 
    1129                     } 
    1130                     else if(fix.targetIndex - externsLength < cextedfsLength){ 
    1131                         targetName = "cextdef: " ~ cast(char[])names[communalExterns[fix.targetIndex-externsLength].nameIndex]; 
    1132                     } 
    1133                     else{ 
    1134                         targetName = "comdat: " ~ cast(char[])communalDefinitions[fix.targetIndex - cextedfsLength - externsLength].communalName; 
    1135                     } 
     1195                    targetName = "extern: " ~ getExternName(targetIndex); 
    11361196                } 
    11371197                else{ 
     
    11391199                } 
    11401200                 
    1141                 result ~= sprint("  %d: %s:%d rel: %s | %s\n",idx,segment,destOffset,rel,targetName); 
     1201                result ~= sprint("  %d: %s:%d rel: %s | %d %s\n",idx,segment,destOffset,rel,targetIndex,targetName); 
    11421202            } 
    11431203        }    
     
    11981258                 
    11991259                result ~= sprint("  %d: Line %d --> %s%s %0.8X\n", 
    1200                     idx,lineNumber,cont,name,baseOffset); 
     1260                    idx,lineNumber,cont,name,cast(uint)baseOffset); 
    12011261            } 
    12021262        } 
     
    12131273            } 
    12141274        } 
    1215              
     1275         
     1276        result ~= "Fixup Targets:\n"; 
     1277        foreach(idx,target; targets) with(target){ 
     1278            char[] targetTypeName; 
     1279            switch(type){ 
     1280            case FixupTarget.COMDAT: targetTypeName = "COMDAT"; break; 
     1281            case FixupTarget.PUBDEF: targetTypeName = "PUBDEF"; break; 
     1282            case FixupTarget.EXTDEF: targetTypeName = "EXTDEF"; break; 
     1283            case FixupTarget.CEXTDEF: targetTypeName = "CEXTDEF"; break; 
     1284            } 
     1285            result ~= sprint("  %d: %s %d\n",idx,targetTypeName,index); 
     1286        }        
     1287                     
    12161288        return result; 
    12171289    }    
  • trunk/ddl/omf/OMFLibrary.d

    r218 r219  
    8181         
    8282    public DynamicModule getModuleForSymbol(char[] name){ 
    83         debug debugLog("looking for " ~ name); 
     83        debug debugLog("[OMF] looking for " ~ name); 
    8484        DynamicModule* mod = name in crossReference; 
    85         debug debugLog("Result: %0.8X",mod); 
     85        debug debugLog("[OMF] Result: %0.8X",mod); 
    8686        if(mod) return *mod; 
    8787        return null; 
     
    9797        for(uint i=0; i<symbols.length; i++){ 
    9898            ExportSymbolPtr exp = &(symbols[i]); 
    99             dictionary[exp.name] = exp; 
    100             crossReference[exp.name] = mod; 
     99            if(exp.name in crossReference){ 
     100                switch(exp.type){ 
     101                case SymbolType.Weak: // replace extern only 
     102                    if(dictionary[exp.name].type == SymbolType.Extern){ 
     103                        crossReference[exp.name] = mod; 
     104                        dictionary[exp.name] = exp; 
     105                    } 
     106                    break; 
     107                case SymbolType.Strong: // always overwrite 
     108                    crossReference[exp.name] = mod; 
     109                    dictionary[exp.name] = exp; 
     110                    break; 
     111                default: 
     112                    // do nothing 
     113                } 
     114            } 
     115            else{ 
     116                crossReference[exp.name] = mod; 
     117                dictionary[exp.name] = exp; 
     118            } 
    101119        } 
    102120    } 
  • trunk/ddl/omf/OMFModule.d

    r218 r219  
    4545    alias SegmentImage* SegmentImagePtr; 
    4646 
    47     OMFBinary binary; 
    48     SegmentImage[] segmentImages;    
     47    debug OMFBinary binary; 
     48    FIXUPP[] fixups; 
     49    SegmentImage[] segmentImages; 
    4950    ExportSymbol[] symbols; 
    5051    ExportSymbolPtr[char[]] symbolXref; 
     
    5455    this(FileBuffer buffer){ 
    5556        resolved = false; 
    56         binary.parse(new DDLReader(buffer)); 
    57         syncronizeSymbols(); 
     57        loadBinary(new DDLReader(buffer)); 
    5858    } 
    5959         
    6060    this(DDLReader reader){ 
    6161        resolved = false; 
    62         binary.parse(reader); 
    63         syncronizeSymbols(); 
     62        loadBinary(reader); 
    6463    } 
    6564     
     
    7877     
    7978    public void resolveFixups(){ 
    80         //do nothing 
     79        FIXUPP[] remainingFixups; 
     80         
     81        foreach(idx,fix; fixups) with(fix){ 
     82            uint fixupValue; 
     83             
     84            // get the fixup value 
     85            if(isExternStyleFixup){ 
     86                debug debugLog("fix target: %d/%d",fix.targetIndex,symbols.length); 
     87                auto sym  = &(symbols[fix.targetIndex-1]); 
     88                if(sym.type != SymbolType.Strong){ 
     89                    remainingFixups ~= fix; 
     90                    continue; 
     91                } 
     92                fixupValue = cast(uint)(sym.address); 
     93                debug debugLog("\tusing symbol: %s %0.8X",sym.name,sym.address); 
     94            } 
     95            else{ 
     96                fixupValue = cast(uint)(segmentImages[fix.targetIndex].data.ptr); 
     97                debug debugLog("using segment pointer: %0.8X",fixupValue); 
     98            } 
     99             
     100            // find the fixup destination 
     101            uint* dest = cast(uint*)(segmentImages[destSegmentIndex].data.ptr + destOffset); 
     102             
     103            // apply the fixup value 
     104            if(fixupValue == 0){ 
     105                //HACK: there exists a very small class of symbols that point to zero at all times 
     106                //NOTE: namely, this includes __except_list and __nullext, which point to the start 
     107                // of their respective segments 
     108                *dest = fixupValue; 
     109            } 
     110            else if(!isSegmentRelative){ 
     111                uint value = fixupValue - cast(uint)dest - 4; // relative fixup, offset by width of field 
     112                debug debugLog("Fixup %d [self relative] %d dest %0.8X (at %0.8X) to %0.8X (using %d)",idx,destSegmentIndex,*dest,dest,value^0xFFFFFFFF,value); 
     113                *dest = value; 
     114            } 
     115            else{ 
     116                debug debugLog("Fixup %d [seg relative] dest %0.8X (at %0.8X) to %0.8X",idx,*dest,dest,*dest+fixupValue); 
     117                *dest += fixupValue;             
     118            } 
     119        } 
     120        this.fixups = remainingFixups; 
    81121    } 
    82122     
    83123    public bool isResolved(){ 
    84         return resolved; 
    85     } 
    86          
    87     protected void syncronizeSymbols(){ 
    88         char[] flag = null; 
    89                  
     124        if(resolved) return true; 
     125         
     126        if(fixups.length > 0) return false; 
     127        foreach(sym; symbols){ 
     128            if(sym.type != SymbolType.Strong) return false; 
     129        } 
     130        resolved = true; 
     131        return true; 
     132    } 
     133         
     134    protected void loadBinary(DDLReader reader){ 
     135        debug{} else{ 
     136            OMFBinary binary; 
     137        } 
     138        binary.parse(reader); 
     139                                 
    90140        //TODO: alter this to zero in on D namespaces and C/asm namespaces 
    91141        this.moduleName = binary.libraryName; 
     
    106156        //NOTE: extern indicies match their OMF counterparts 
    107157        symbols.length =  
    108             binary.externs.length +  
    109             binary.communalExterns.length +  
     158            binary.communalExterns.length +             
     159            (binary.externs.length-1) +  
    110160            binary.communalDefinitions.length + 
    111             binary.publics.length - 1; 
    112              
    113         uint symbolIndex = 0; 
    114          
     161            binary.publics.length; 
     162             
     163        uint symbolIndex = 0; // offset by number of publics (handled later) 
     164         
     165        // communal external symbols 
     166        foreach(ext; binary.communalExterns){ 
     167            ExportSymbolPtr sym = &(symbols[symbolIndex]); 
     168             
     169            sym.type = SymbolType.Weak; 
     170            sym.name = binary.names[ext.nameIndex]; 
     171            symbolXref[sym.name] = sym; 
     172             
     173            symbolIndex++; 
     174        }        
     175                         
    115176        // external symbols 
    116177        foreach(idx,ext; binary.externs){ 
     
    124185            symbolIndex++; 
    125186        } 
    126          
    127         // communal external symbols 
    128         foreach(ext; binary.communalExterns){ 
    129             ExportSymbolPtr sym = &(symbols[symbolIndex]); 
    130              
    131             sym.type = SymbolType.Weak; 
    132             sym.name = binary.names[ext.nameIndex]; 
    133             symbolXref[sym.name] = sym; 
    134              
    135             symbolIndex++; 
    136         } 
    137                  
    138         // get data from iterated records        
    139         foreach(idx,lidata; binary.iteratedData){ 
    140             SegmentImagePtr image = &(segmentImages[lidata.segmentIndex]); 
    141             uint dataLength = lidata.data.length; 
    142             uint offset = lidata.offset; 
    143              
    144         //  debugLog("lidata range: %0.8X .. %0.8X",lidata.data.ptr,lidata.data.ptr+dataLength); 
    145              
    146             // reallocate if needed 
    147             if(image.data.length < offset + dataLength){ 
    148                 image.data.length = offset + dataLength; 
    149             } 
    150             // copy into the buffer 
    151         //  debugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.data.length); 
    152             image.data[offset..offset+dataLength] = lidata.data; 
    153         } 
    154          
    155         // get data from enumerated data 
    156          
    157         foreach(idx,ledata; binary.enumeratedData){ 
    158             SegmentImagePtr image = &(segmentImages[ledata.segmentIndex]); 
    159             uint dataLength = ledata.data.length; 
    160             uint offset = ledata.offset; 
    161         //  debugLog("Img: %0.8X Images: %0.8X",image,segmentImages.ptr); 
    162              
    163             // reallocate if needed 
    164             if(image.data.length < offset + dataLength){ 
    165                 image.data.length = offset + dataLength; 
    166             } 
    167             // copy into the bufferdebugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.ata.dlength); 
    168             image.data[offset..offset+dataLength] = ledata.data; 
    169         } 
    170          
     187                 
    171188        //1st pass for COMDEF records 
    172189        //build up the memory image of the referenced segments  
     
    191208             
    192209            segZeroAddress += comdef.length; 
    193         }        
     210        }            
     211                 
     212        // get data from iterated records    
     213        foreach(idx,lidata; binary.iteratedData){ 
     214            SegmentImagePtr image = &(segmentImages[lidata.segmentIndex]); 
     215            uint dataLength = lidata.data.length; 
     216            uint offset = lidata.offset; 
     217             
     218        //  debugLog("lidata range: %0.8X .. %0.8X",lidata.data.ptr,lidata.data.ptr+dataLength); 
     219             
     220            // reallocate if needed 
     221            if(image.data.length < offset + dataLength){ 
     222                image.data.length = offset + dataLength; 
     223            } 
     224            // copy into the buffer 
     225        //  debugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.data.length); 
     226            image.data[offset..offset+dataLength] = lidata.data; 
     227        } 
     228         
     229        // get data from enumerated data 
     230         
     231        foreach(idx,ledata; binary.enumeratedData){ 
     232            SegmentImagePtr image = &(segmentImages[ledata.segmentIndex]); 
     233            uint dataLength = ledata.data.length; 
     234            uint offset = ledata.offset; 
     235        //  debugLog("Img: %0.8X Images: %0.8X",image,segmentImages.ptr); 
     236             
     237            // reallocate if needed 
     238            if(image.data.length < offset + dataLength){ 
     239                image.data.length = offset + dataLength; 
     240            } 
     241            // copy into the bufferdebugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.ata.dlength); 
     242            image.data[offset..offset+dataLength] = ledata.data; 
     243        } 
     244     
    194245                 
    195246        //1st pass for COMDAT records 
     
    210261            void** addr = &(currentAddress[comdat.segmentIndex]); 
    211262            if(*addr == null){ 
    212                 *addr = image.data.ptr+image.data.length; 
     263                //TODO: change to orignal segment size 
     264                *addr = image.data.ptr + binary.segments[comdat.segmentIndex].dataLength; 
    213265            } 
    214266             
     
    216268            //NOTE: this is done to calculate the offset on this pass 
    217269            if(!comdat.isContinuation){ 
     270                symbolXref[binary.names[comdat.nameIndex]].type = SymbolType.Strong; 
    218271                symbolXref[binary.names[comdat.nameIndex]].address = *addr; 
     272                 
     273                debug debugLog("%d %s first bytes: %0.8X\n",idx,cast(char[])binary.names[comdat.nameIndex],*cast(uint*)comdat.data.ptr); 
    219274            } 
    220275             
     
    223278                         
    224279        // public symbols (done here so address offsets are valid) 
    225         foreach(pub; binary.publics){ 
     280        foreach(idx,pub; binary.publics){ 
    226281            ExportSymbolPtr sym = &(symbols[symbolIndex]); 
    227282             
     
    264319            } 
    265320            done: 
    266              
    267321            symbolIndex++; 
    268322        } 
     
    310364            impSpace += (void*).sizeof; 
    311365        } 
     366         
     367        // process WKEXT records 
     368        foreach(idx,wkext; binary.weakExterns){ 
     369            ExportSymbolPtr sym = &(symbols[wkext.weakIndex-1]); 
     370            //if(sym.address){ 
     371                symbols[wkext.weakIndex-1].type = SymbolType.Weak; 
     372            //} 
     373        } 
     374         
     375        // keep a copy of the fixups (the original FIXUPP record works well enough) 
     376        this.fixups = binary.fixups; 
    312377    } 
    313378     
     
    316381        ExtSprintClass sprint = new ExtSprintClass(1024); 
    317382         
    318         result ~= "\n--OMF Data--\n"; 
    319         result ~= binary.toString(); 
    320         result ~= "\n--OMFBinary Data--\n"; 
     383        debug{ 
     384            result ~= "\n--OMFBinary Data--\n"; 
     385            result ~= binary.toString(); 
     386        } 
     387        result ~= "\n--OMFModule Data--\n"; 
    321388        result ~= "Module: " ~ moduleName ~ "\n\n"; 
    322389         
    323         result ~= "Segment Images:\n";       
    324         foreach(idx,seg; segmentImages){ 
    325             if(idx == 0) continue; 
    326             char[] name = binary.names[binary.segments[idx].nameIndex]; 
    327             result ~= sprint("  %d: %s %d bytes\n",idx,name,seg.data.length); 
     390        debug{ 
     391            result ~= "Segment Images:\n";       
     392            foreach(idx,seg; segmentImages){ 
     393                if(idx == 0) continue; 
     394                char[] name = binary.names[binary.segments[idx].nameIndex]; 
     395                result ~= sprint("  %d: %s %d bytes [%0.8X]\n",idx,name,seg.data.length,seg.data.ptr); 
     396            } 
    328397        } 
    329398         
     
    333402        } 
    334403         
     404        result ~= sprint("Fixups (%d):\n",fixups.length); 
     405        if(fixups.length > 0){ 
     406            foreach(idx,fix; fixups){ 
     407                with(fix){ 
     408                    char[] rel = isSegmentRelative ? "segmentRelative" : "selfRelative"; 
     409                    char[] ext = isExternStyleFixup ? "externStyle" : "segmentStyle"; 
     410                    void* targetAddress = &(segmentImages[destSegmentIndex].data[destOffset]); 
     411                             
     412                    result ~= sprint("  %d: %0.8X %s %s",idx,targetAddress,rel,ext); 
     413     
     414                    if(isExternStyleFixup){ 
     415                        result ~= sprint(" | %s\n",symbols[targetIndex-1].name); 
     416                    } 
     417                    else{ 
     418                        result ~= sprint(" | segment #%d\n",targetIndex); 
     419                    }                
     420                } 
     421            }            
     422        } 
     423         
     424        result ~= "DATA: \n"; 
     425        foreach(idx,segdef; segmentImages){&nbs