Changeset 292

Show
Ignore:
Timestamp:
04/20/08 19:58:46 (9 months ago)
Author:
h3r3tic
Message:

new linking algorithm

Files:

Legend:

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

    r285 r292  
    3737private import ddl.omf.OMFLoader; 
    3838private import ddl.ddl.DDLLoader; 
    39 private import ddl.elf.ELFObjLoader; 
     39//private import ddl.elf.ELFObjLoader; 
    4040private import ddl.insitu.InSituLoader; 
    4141//private import ddl.coff.COFFLoader; 
     
    6262            register(new ArchiveLoader());           
    6363    //      register(new COFFObjLoader());           
    64             register(new ELFObjLoader());          
     64            //register(new ELFObjLoader());            
    6565        } 
    6666        else{ 
    6767            register(new ArchiveLoader()); 
    68             register(new ELFObjLoader()); 
     68            //register(new ELFObjLoader()); 
    6969            register(new DDLLoader()); 
    7070    //      register(new InSituLibLoader());             
  • trunk/ddl/ExportClass.d

    r279 r292  
    6767      if (ctor) ctor(obj); 
    6868      else { 
    69          auto RegExp ctorMatch = new RegExp
     69         auto Regex ctorMatch = new Regex
    7070               `^_D` ~ name ~ mangleSymbolName!("_ctor") 
    7171               ~ `F` ~ `.*` 
  • trunk/ddl/Linker.d

    r287 r292  
    3636private import ddl.LoaderRegistry; 
    3737private import ddl.DDLException; 
     38import tango.stdc.stdio; 
    3839 
    3940debug private import ddl.Utils; 
     
    99100*/ 
    100101class Linker{ 
     102    public bool autoRunModuleCtors = true; 
     103     
     104     
    101105    protected LoaderRegistry registry; 
    102106    /**  
     
    196200    } 
    197201     
     202     
     203    private void selfResolveAll() { 
     204        foreach (lib; this.libraries) { 
     205            foreach (mod; lib.getModules) { 
     206                if (mod.isResolved) continue; 
     207                 
     208                foreach (ref sym; mod.getSymbols) { 
     209                    if (SymbolType.Weak == sym.type) { 
     210                        sym.type = SymbolType.Strong; 
     211                    } 
     212                } 
     213            } 
     214        } 
     215    } 
     216     
     217     
     218    public void checkResolved(DynamicLibrary lib, void delegate(DynamicModule, ExportSymbolPtr) errHandler = null) { 
     219        foreach (mod; lib.getModules) { 
     220            if (mod.isResolved) continue; 
     221             
     222            foreach (ref sym; mod.getSymbols) { 
     223                if (SymbolType.Strong != sym.type) { 
     224                    if (errHandler !is null) { 
     225                        errHandler(mod, &sym); 
     226                    } else { 
     227                        char[] ext = sym.isExternal ? "external" : "local"; 
     228                        bool isWeak = sym.type == SymbolType.Weak; 
     229                        throw new DDLException("cannot resolve symbol: [{0:8X}] {1} {2} {3}" ~ (isWeak ? " the symbol is weak" : "") ~ \n,cast(uint)sym.address, sym.getTypeName(), ext, sym.name); 
     230                    } 
     231                } 
     232            } 
     233        } 
     234    } 
     235     
     236     
     237    public void runModuleCtors(ModuleSet moduleSet) { 
     238        foreach(mod, moduleInfo; moduleSet) { 
     239            debug debugLog("running {0} init at [{1:8X}]", mod, cast(void*)moduleInfo); 
     240            this.initModule(moduleInfo, 0); 
     241        } 
     242    } 
     243     
     244     
    198245    alias ModuleInfo[char[]] ModuleSet;  
     246     
     247    public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve){ 
     248        if (mod.isLinking) { 
     249            return; 
     250        } 
     251        mod.isLinking = true; 
     252         
     253        //printf("Linking module %.*s"\n, mod.getName); 
     254 
     255        auto modSymbols = mod.getSymbols(); 
     256        symbolIter: foreach (ref sym; modSymbols) { 
     257            if (SymbolType.Strong == sym.type) { 
     258                continue; 
     259            } 
     260 
     261            //printf("Examining %.*s symbol %.*s in %.*s"\n, sym.getTypeName, sym.name, mod.getName); 
     262             
     263            foreach (lib; this.libraries) { 
     264                auto otherMod = lib.getModuleForSymbol(sym.name); 
     265                if (otherMod is null || otherMod is mod) { 
     266                    continue; 
     267                } 
     268                 
     269                if (!otherMod.isResolved) { 
     270                    this.link(otherMod, moduleSet, true); 
     271                } 
     272                 
     273                auto otherSym = otherMod.getSymbol(sym.name); 
     274                if (SymbolType.Unresolved != otherSym.type) { 
     275                /+if ( 
     276                    SymbolType.Strong == otherSym.type 
     277                    || (SymbolType.Weak == otherSym.type && SymbolType.Unresolved == sym.type) 
     278                ) {+/ 
     279                    sym.address = otherSym.address; 
     280                    sym.type = SymbolType.Strong; 
     281                    sym.isExternal = true; 
     282                    continue symbolIter; 
     283                } 
     284            } 
     285 
     286            /+if (sym.type == SymbolType.Weak && canSelfResolve) { 
     287                sym.type = SymbolType.Strong; 
     288            }+/ 
     289        } 
     290 
     291        mod.resolveFixups(); 
     292        //mod.isLinking = false; 
     293         
     294        foreach (ref sym; modSymbols) { 
     295            version (Stacktrace){ 
     296                if (sym.address !is null) { 
     297                    //printf("symbol %.*s line: %d\n", symbol.name, symbol.lineNumber); 
     298                    regist_cb((sym.name ~ \0).ptr, sym.address); 
     299                    addDebugLineInfo__(cast(uint)sym.address, sym.lineNumber, mod.getName); 
     300                } 
     301            } 
     302 
     303 
     304            // symbol must be defined and be local only 
     305            if (sym.address is null || sym.isExternal) { 
     306                continue; 
     307            } 
     308             
     309            char[] suffix = `__ModuleInfoZ`; 
     310            if (sym.name.length > suffix.length && sym.name[$ - suffix.length .. $] == suffix) { 
     311                debug debugLog("Found moduleinfo for {0} at [{1:8X}] {2}", mod.getName, sym.address, sym.name); 
     312                moduleSet[sym.name] = cast(ModuleInfo)(sym.address); 
     313            } 
     314        } 
     315    } 
     316     
     317     
     318    private void finishLinking() { 
     319        foreach (lib; this.libraries) { 
     320            foreach (mod; lib.getModules) { 
     321                mod.isLinking = false; 
     322            } 
     323        } 
     324    } 
     325     
     326     
     327    /* 
     328        This implementation has problems with circular dependencies across modules. I've replaced 
     329        it with one that doesn't do strict checking of SymbolType and isResolved. 
     330        To account for the change, I had to include a function to check the status of the linking. 
     331         
     332        checkResolved(lib) will by default check if every symbol in the lib is Strong and throw an exception. 
     333        It can be given a handler to do more fancy unresolved symbol handling. 
     334         
     335        - h3r3tic, 2008-04-21 
     336    */ 
     337     
    199338         
    200339    /** 
     
    209348        moduleSet a set of modules that need initalization following the link pass. 
    210349    */ 
    211     public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve){ 
     350    /+public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve){ 
    212351        uint i; 
    213352         
     
    218357        mod.isLinking = true; 
    219358         
     359        if (canSelfResolve) printf("(Can self-resolve) "); 
    220360        debug debugLog("Linking module: {0}",mod.getName); 
     361        printf("Linking module %.*s"\n, mod.getName); 
    221362         
    222363        auto moduleSymbols = mod.getSymbols(); 
     364        printf("Number of symbols: %d"\n, moduleSymbols.length); 
     365         
    223366        for(i=0; i<moduleSymbols.length; i++){ 
    224367            auto symbol = &(moduleSymbols[i]); 
     368            printf("Pre-examining %.*s symbol %.*s in %.*s"\n, symbol.getTypeName, symbol.name, mod.getName); 
     369        } 
     370 
     371        for(i=0; i<moduleSymbols.length; i++){ 
     372            auto symbol = &(moduleSymbols[i]); 
     373             
     374            printf("Examining %.*s symbol %.*s in %.*s"\n, symbol.getTypeName, symbol.name, mod.getName); 
    225375             
    226376            // ensure we're only linking weak and unresolved symbols 
     
    231381            foreach(lib; this.libraries){ 
    232382                auto libMod = lib.getModuleForSymbol(symbol.name); 
    233                 if(libMod && libMod != mod){ 
     383                if(libMod && libMod !is mod){ 
    234384                    if(!libMod.isResolved()){ 
    235385                        this.link(libMod,moduleSet,true); 
     
    244394                        goto nextSymbol; 
    245395                    } 
    246                     debug debugLog("symbol is not strong ({0} -> {1:8X})",symbol.getTypeName,symbol.address); 
     396                    debug debugLog("found in {}", libMod.getName); 
     397                    debug debugLog("symbol is not strong ({0} -> {1:X})",symbol.getTypeName,symbol.address); 
     398                } else if (libMod && libMod is mod) { 
     399                    debug debugLog("found in the current module ({})", mod.getName); 
     400                    debug debugLog("symbol is not strong ({0} -> {1:X})",symbol.getTypeName,symbol.address); 
    247401                } 
    248402            } 
     
    254408                char[] ext = symbol.isExternal ? "external" : "local"; 
    255409                char[] self = canSelfResolve ? "can Self Resolve" : "cannot Self Resolve"; 
    256                 throw new DDLException("cannot resolve symbol: ({0}) [{1:8X}] {2} {3} {4}\n",self,cast(uint)symbol.address,symbol.getTypeName(),ext,symbol.name); 
     410                bool isWeak = symbol.type == SymbolType.Weak; 
     411                throw new DDLException("cannot resolve symbol: ({0}) [{1:8X}] {2} {3} {4}" ~ (isWeak ? " the symbol is weak" : "") ~ \n,self,cast(uint)symbol.address,symbol.getTypeName(),ext,symbol.name); 
    257412            } 
    258413             
     
    288443            } 
    289444        } 
    290     } 
     445    }+/ 
    291446     
    292447    /** 
     
    313468        --- 
    314469    */ 
    315     public void link(DynamicLibrary lib){ 
     470    public ModuleSet link(DynamicLibrary lib){ 
    316471        ModuleSet moduleSet; 
    317472         
     
    320475         
    321476        // link 
    322         foreach(DynamicModule mod; lib.getModules){ 
    323             this.link(mod,moduleSet,canSelfResolve); 
    324         } 
    325          
    326         // init - run whatever initalizers are pending 
     477        foreach(DynamicModule mod; lib.getModules) { 
     478            this.link(mod, moduleSet, canSelfResolve); 
     479        } 
     480 
     481        selfResolveAll(); 
     482        finishLinking(); 
     483         
     484        /+// init - run whatever initalizers are pending 
    327485        foreach(mod,moduleInfo; moduleSet){ 
    328486            debug debugLog("running {0} init at [{1:8X}]",mod,cast(void*)moduleInfo); 
     
    330488        } 
    331489    //  _moduleCtor2(moduleSet.values,0); 
     490    +/ 
     491     
     492        if (autoRunModuleCtors) { 
     493            runModuleCtors(moduleSet); 
     494        } 
     495     
     496        return moduleSet; 
    332497    } 
    333498     
  • trunk/ddl/all.d

    r254 r292  
    4141public import ddl.PathLibrary; 
    4242public import ddl.Utils; 
    43  
     43public import ddl.host.HostAppLibrary; 
  • trunk/ddl/host/HostAppModule.d

    r291 r292  
    3636 
    3737private { 
     38    extern(C) extern void* _except_list; 
     39    extern(Windows) extern void _d_throw(void*); 
     40} 
     41 
     42 
     43private { 
    3844    import ddl.host.HostAppLibrary; 
    3945     
     
    4349    import tango.sys.win32.UserGdi; 
    4450    import tango.stdc.stringz; 
     51    import tango.stdc.stdio; 
    4552 
    4653 
     
    8794 
    8895        int add_symbol(LPSTR name, ULONG addr, ULONG size, PVOID){ 
     96            //printf("%s"\n, name); 
    8997            ExportSymbol sym; 
    9098            sym.isExternal = false; 
     
    151159            } 
    152160 
    153             do
    154                 if(GetModuleFileNameA(module_entry.hModule, buffer.ptr, buffer.length)){ 
     161            do
     162                if (GetModuleFileNameA(module_entry.hModule, buffer.ptr, buffer.length)){ 
    155163                    base = sym_load_module(proc, HANDLE.init, buffer.ptr, null, 0, 0); 
    156                     if(base){ 
     164                    if (base){ 
    157165                        sym_enumerate_symbols(proc, base, &add_symbol, null); 
    158166                    } 
    159167                } 
    160             }while(Module32Next(snapshot, &module_entry)); 
     168            } while(Module32Next(snapshot, &module_entry)); 
     169             
     170            addExtraSymbols(); 
     171        } 
     172         
     173         
     174        void addExtraSymbols() { 
     175            HostAppModule.addSymbol(ExportSymbol(false, SymbolType.Strong, &_except_list, "__except_list")); 
     176            HostAppModule.addSymbol(ExportSymbol(false, SymbolType.Strong, &_d_throw, "__d_throw@4")); 
    161177        } 
    162178    } 
  • trunk/ddl/omf/OMFBinary.d

    r285 r292  
    4141private import ddl.omf.OMFException; 
    4242private import ddl.omf.OMFReader; 
     43 
     44import tango.stdc.stdio; 
    4345 
    4446/** 
     
    101103void parse(inout WKEXT[] externs,OMFReader reader){ 
    102104    while(reader.hasMore()){ 
    103         WKEXT ext;       
    104         ext.parse(reader); 
    105         externs ~= ext; 
     105        // HACK: otherwise the parser borks on tango-base-dmd.lib, as of rev 3447 of Tango       
     106        try { 
     107            WKEXT ext;       
     108            ext.parse(reader); 
     109            externs ~= ext; 
     110        } catch (Exception) {} 
    106111    } 
    107112} 
  • trunk/ddl/omf/OMFLibrary.d

    r287 r292  
    8282        debug debugLog("[OMF] looking for {0} in {1}",name,attributes["omf.filename"]); 
    8383        DynamicModule* mod = name in crossReference; 
    84         debug debugLog("[OMF] Result: {0:8X}",mod); 
     84        debug debugLog("[OMF] Result: {0:X}",mod); 
    8585        if(mod) return *mod; 
    8686        return null; 
  • trunk/ddl/omf/OMFModule.d

    r285 r292  
    3636 
    3737private import Text = tango.text.Util; 
     38import tango.stdc.stdio; 
    3839 
    3940version(Windows){ 
     
    9394    protected bool containsAddress(void* addr){ 
    9495        foreach(seg; this.segmentImages){ 
    95             debug debugLog("checking addr: [%0.8X] [%0.8X] [%0.8X]",seg.data.ptr,addr,(seg.data.ptr + seg.data.length)); 
     96            debug debugLog("checking addr: [%0.X] [%0.X] [%0.X]",seg.data.ptr,addr,(seg.data.ptr + seg.data.length)); 
    9697            if(addr >= seg.data.ptr && addr <= (seg.data.ptr + seg.data.length)){ 
    9798                return true; 
     
    106107         
    107108        foreach(idx,fix; fixups) with(fix){ 
     109            /+if (targetSymbol) { 
     110                printf("targetSymbol: %.*s"\n, targetSymbol.name); 
     111            }+/ 
     112             
    108113            uint fixupValue; 
    109114            uint destAddress; 
     
    113118                if(destSymbol.isExternal){ 
    114119                    // discard this fixup - it references a non-local symbol 
    115                     debug debugLog("Discarded Fixup dest {0}:{1} [{2:8X}] rel:{3}",destSymbol.name,destSymbol.getTypeName(),destAddress,cast(uint)isSegmentRelative); 
     120                    debug debugLog("Discarded Fixup dest {0}:{1} [{2:X}] rel:{3}",destSymbol.name,destSymbol.getTypeName(),destAddress,cast(uint)isSegmentRelative); 
    116121                    continue; 
    117122                } 
    118123                else{ 
    119                     debug debugLog("Fixup dest symbol: {0} [{1:8X}] {2}",destSymbol.name,destSymbol.address,destSymbolOffset); 
     124                    debug debugLog("Fixup dest symbol: {0} [{1:X}] {2}",destSymbol.name,destSymbol.address,destSymbolOffset); 
    120125                    destAddress = cast(uint)destSymbol.address + destSymbolOffset; 
    121126                } 
     
    126131             
    127132            if(!containsAddress(cast(void*)destAddress)){ 
    128                 debug debugLog("Module does not contain the destination address for fixup. [{0:8X}]",destAddress); 
     133                debug debugLog("Module does not contain the destination address for fixup. [{0:X}]",destAddress); 
    129134                debug debugLog("dump: {0}",this.toString()); 
    130135                assert(false); 
     
    137142                    // fixup cannot be resolved at this time, so save it for later 
    138143                    remainingFixups ~= fix; 
     144                    //printf("fixup cannot be resolved at this time, so save it for later"\n); 
    139145                    continue; 
    140146                } 
     
    146152             
    147153            debug if(destSymbol){ 
    148                 debugLog("fixup dest {0}:{1} [{2:8X}] ({3:8X}) = fixupValue [{4:8X}] rel:{5}",destSymbol.name,destSymbol.getTypeName(),destAddress,*cast(uint*)destAddress,fixupValue,cast(uint)isSegmentRelative); 
     154                debugLog("fixup dest {0}:{1} [{2:X}] ({3:X}) = fixupValue [{4:X}] rel:{5}",destSymbol.name,destSymbol.getTypeName(),destAddress,*cast(uint*)destAddress,fixupValue,cast(uint)isSegmentRelative); 
    149155            } 
    150156            else{ 
    151                 debugLog("fixup dest (null) [{0:8X}] ({1:8X}) = fixupValue [{2:8X}] rel:{3}",destAddress,*cast(uint*)destAddress,fixupValue,cast(uint)isSegmentRelative); 
     157                debugLog("fixup dest (null) [{0:X}] ({1:X}) = fixupValue [{2:X}] rel:{3}",destAddress,*cast(uint*)destAddress,fixupValue,cast(uint)isSegmentRelative); 
    152158            } 
    153159             
     
    166172            } 
    167173             
    168             debug debugLog("\tfixed to: [{0:8X}]",*cast(uint*)destAddress); 
     174            debug debugLog("\tfixed to: [{0:X}]",*cast(uint*)destAddress); 
    169175        } 
    170176        this.fixups = remainingFixups; 
     
    270276            uint offset = lidata.offset; 
    271277             
    272         //  debugLog("lidata range: %0.8X .. %0.8X",lidata.data.ptr,lidata.data.ptr+dataLength); 
     278        //  debugLog("lidata range: %0.X .. %0.X",lidata.data.ptr,lidata.data.ptr+dataLength); 
    273279             
    274280            // reallocate if needed 
     
    277283            } 
    278284            // copy into the buffer 
    279         //  debugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.data.length); 
     285        //  debugLog("image range: %0.X .. %0.X",image.data.ptr,image.data.ptr+image.data.length); 
    280286            image.data[offset..offset+dataLength] = lidata.data; 
    281287        } 
     
    287293            uint dataLength = ledata.data.length; 
    288294            uint offset = ledata.offset; 
    289         //  debugLog("Img: %0.8X Images: %0.8X",image,segmentImages.ptr); 
     295        //  debugLog("Img: %0.X Images: %0.X",image,segmentImages.ptr); 
    290296             
    291297            // reallocate if needed 
     
    293299                image.data.length = offset + dataLength; 
    294300            } 
    295             // copy into the bufferdebugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.ata.dlength); 
     301            // copy into the bufferdebugLog("image range: %0.X .. %0.X",image.data.ptr,image.data.ptr+image.ata.dlength); 
    296302            image.data[offset..offset+dataLength] = ledata.data; 
    297303        } 
     
    438444            if(fix.isExternStyleFixup){ 
    439445                newFix.targetSymbol = symbolXref[cast(char[])binary.externNames[fix.targetIndex]]; 
     446                //printf("new fix %.*s"\n, newFix.targetSymbol.name); 
    440447            } 
    441448            else{ 
     
    453460            fixups ~= newFix; 
    454461        } 
     462         
     463        //printf("%.*s"\n, toString); 
    455464    } 
    456465     
     
    471480                if(idx == 0) continue; 
    472481                char[] name = binary.names[binary.segments[idx].nameIndex]; 
    473                 result ~= sprint("  {0}: {1} {2} bytes [{3:8X}]\n",idx,name,seg.data.length,seg.data.ptr); 
     482                result ~= sprint("  {0}: {1} {2} bytes [{3:X}]\n",idx,name,seg.data.length,seg.data.ptr); 
    474483            } 
    475484        } 
     
    478487        foreach(idx,sym; symbols){ 
    479488            char[] ext = sym.isExternal ? "external" : "local"; 
    480             result ~= sprint("  {0}: [{1:8X}] {2} {3} {4}\n",idx,cast(uint)sym.address,sym.getTypeName(),ext,sym.name); 
     489            result ~= sprint("  {0}: [{1:X}] {2} {3} {4}\n",idx,cast(uint)sym.address,sym.getTypeName(),ext,sym.name); 
    481490        } 
    482491         
     
    491500 
    492501                    if(destSymbol){ 
    493                         result ~= sprint(" | {0} [{1:8X}]",destSymbol.name,cast(uint)destSymbol.address+destSymbolOffset); 
     502                        result ~= sprint(" | {0} [{1:X}]",destSymbol.name,cast(uint)destSymbol.address+destSymbolOffset); 
    494503                    } 
    495504                    else{ 
    496                         result ~= sprint(" | [{0:8X}]",cast(uint)destSegmentAddress); 
     505                        result ~= sprint(" | [{0:X}]",cast(uint)destSegmentAddress); 
    497506                    }                    
    498507                         
    499508                    if(isExternStyleFixup){ 
    500                         result ~= sprint(" | {0} [{1:8X}]",targetSymbol.name,targetSymbol.address); 
     509                        result ~= sprint(" | {0} [{1:X}]",targetSymbol.name,targetSymbol.address); 
    501510                    } 
    502511                    else{ 
    503                         result ~= sprint(" | segment #{0} [{1:8X}]",targetSegmentIndex,segmentImages[targetSegmentIndex].data.ptr); 
     512                        result ~= sprint(" | segment #{0} [{1:X}]",targetSegmentIndex,segmentImages[targetSegmentIndex].data.ptr); 
    504513                    } 
    505514                    result ~= "\n"; 
     
    514523            foreach(byteidx,b; cast(ubyte[])(segdef.data)){ 
    515524                if(byteidx % 16 == 0){ 
    516                      result ~= sprint(" |  {0}\n  [{1:8X}] ",buf2,segdef.data.ptr+byteidx); 
     525                     result ~= sprint(" |  {0}\n  [{1:X}] ",buf2,segdef.data.ptr+byteidx); 
    517526                     buf2 = ""; 
    518527                } 
  • trunk/utils/bless_bn.d

    r291 r292  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 767
     4long auto_build_number = 769
  • trunk/utils/ddlinfo_bn.d

    r291 r292  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 847
     4long auto_build_number = 849
  • trunk/utils/insitu_bn.d

    r291 r292  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 764
     4long auto_build_number = 766