Changeset 218

Show
Ignore:
Timestamp:
07/18/06 23:06:07 (2 years ago)
Author:
pragma
Message:

OMF, DDL, and In-Situ modules work correctly, along with utils.

Linking is still pending.

Files:

Legend:

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

    r183 r218  
    3434 
    3535private import ddl.LoaderRegistry; 
    36 private import ddl.ar.ArchiveLoader; 
     36//private import ddl.ar.ArchiveLoader; 
    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; 
     
    4949            register(new InSituLibLoader()); 
    5050            register(new InSituMapLoader()); 
    51           register(new ArchiveLoader());           
     51    //        register(new ArchiveLoader());           
    5252    //      register(new COFFObjLoader());           
    53           register(new ELFObjLoader());            
     53    //        register(new ELFObjLoader());            
    5454        } 
    5555        else{ 
  • trunk/ddl/Demangle.d

    r176 r218  
    4343    is merely of type 'PublicSymbol'. 
    4444*/ 
    45 enum SymbolType{ 
     45enum DemangleType{ 
    4646    PublicSymbol, 
    4747    ClassDefinition, 
     
    7979 
    8080/** 
    81     Parses a mangled D symbol and returns its SymbolType. 
     81    Parses a mangled D symbol and returns its DemangleType. 
    8282     
    8383    Params: 
     
    8585         
    8686    Returns: 
    87         The SymbolType for the symbol. 
     87        The DemangleType for the symbol. 
    8888*/ 
    89 public SymbolType getSymbolType(char[] symbol){ 
     89public DemangleType getDemangleType(char[] symbol){ 
    9090    if(symbol.startsWith("_Class")){ 
    91         return SymbolType.ClassDefinition; 
     91        return DemangleType.ClassDefinition; 
    9292    } 
    9393    else if(symbol.startsWith("__init_")){ 
    94         return SymbolType.Initalizer; 
     94        return DemangleType.Initalizer; 
    9595    } 
    9696    else if(symbol.startsWith("__vtbl_")){ 
    97         return SymbolType.Vtable; 
     97        return DemangleType.Vtable; 
    9898    } 
    9999    else if(symbol.startsWith("__arguments_")){ 
    100         return SymbolType.VarArguments; 
     100        return DemangleType.VarArguments; 
    101101    } 
    102102    else if(symbol.startsWith("__d")){ 
    103         return SymbolType.PlatformHook; 
     103        return DemangleType.PlatformHook; 
    104104    } 
    105105    else if(symbol.startsWith("_assert_")){ 
    106         return SymbolType.DAssert; 
     106        return DemangleType.DAssert; 
    107107    } 
    108108    else if(symbol.startsWith("_array_")){ 
    109         return SymbolType.DArray; 
     109        return DemangleType.DArray; 
    110110    }    
    111111    else if(symbol.startsWith("__modctor_")){ 
    112         return SymbolType.ModuleCtor; 
     112        return DemangleType.ModuleCtor; 
    113113    } 
    114114    else if(symbol.startsWith("__moddtor_")){ 
    115         return SymbolType.ModuleDtor; 
     115        return DemangleType.ModuleDtor; 
    116116    } 
    117117    else if(symbol.startsWith("__ModuleInfo_")){ 
    118         return SymbolType.ModuleInfo; 
     118        return DemangleType.ModuleInfo; 
    119119    } 
    120120    else if(symbol.startsWith("__nullext")){ 
    121         return SymbolType.Nullext; 
     121        return DemangleType.Nullext; 
    122122    } 
    123123    else if(symbol.startsWith("_Dmain")){ 
    124         return SymbolType.Main; 
     124        return DemangleType.Main; 
    125125    }    
    126126    else if(symbol.startsWith("_DWinMain")){ 
    127         return SymbolType.WinMain; 
     127        return DemangleType.WinMain; 
    128128    }        
    129129    else if(symbol.startsWith("_D")){ 
    130         return SymbolType.PublicSymbol; 
     130        return DemangleType.PublicSymbol; 
    131131    } 
    132132    // no particular type, default the symbol to a 'public' 
    133     return SymbolType.PublicSymbol; 
     133    return DemangleType.PublicSymbol; 
    134134} 
  • trunk/ddl/DynamicLibrary.d

    r216 r218  
    4545        Returns: an export for the requested symbol name.  Will throw if the symbol does not exist. 
    4646    */ 
    47     public ExportSymbol getSymbol(char[] name); 
     47    public ExportSymbolPtr getSymbol(char[] name); 
    4848     
    4949    /** 
  • trunk/ddl/DynamicModule.d

    r216 r218  
    103103    */ 
    104104    public Attributes getAttributes(){ 
    105         ExportSymbol symbol = getSymbol("_D" ~ getRawNamespace() ~ "13DDLAttributesHAaAa"); 
    106         if(symbol == ExportSymbol.NONE){ 
     105        ExportSymbol* symbol = getSymbol("_D" ~ getRawNamespace() ~ "13DDLAttributesHAaAa"); 
     106        if(*symbol == ExportSymbol.NONE){ 
    107107            return Attributes.init; 
    108108        } 
     
    118118        Gets a specific export by name.  If the export does not exist, the method returns ExportSymbol.init. 
    119119    */ 
    120     public ExportSymbol getSymbol(char[] name); 
     120    public ExportSymbolPtr getSymbol(char[] name); 
     121     
     122    /** 
     123        Prods the module to resolve any pending fixups.  Used during linking. 
     124    */ 
     125    public void resolveFixups(); 
    121126     
    122127    /** 
  • trunk/ddl/ExportSymbol.d

    r216 r218  
    9292    } 
    9393} 
     94 
     95alias ExportSymbol* ExportSymbolPtr; 
  • trunk/ddl/Linker.d

    r168 r218  
    3535private import ddl.Demangle; 
    3636private import ddl.LoaderRegistry; 
     37private import ddl.DDLException; 
    3738 
    3839private import std.moduleinit; // used for ModuleInfo type 
     
    152153        This implementation performs a long search of modules, then discrete symbols in the 
    153154        cross-reference. 
    154     */ 
     155         
     156        The parameter canSelfResolve is passed as 'true' for registraion variants of link  
     157        routines 
     158    */ 
     159    public void link(DynamicModule mod,bool canSelfResolve=false){ 
     160        //protect against infinite recursion here by returning early 
     161        //by this, we count on the module being resolved further up the call stack 
     162        if(mod.isLinking) return; 
     163         
     164        mod.isLinking = true; 
     165         
     166        foreach(symbol; mod.getSymbols){ 
     167            if(symbol.type == SymbolType.Strong) continue; 
     168            // resolve a dependency from out of the registry 
     169            foreach(lib; this.libraries){ 
     170                auto libMod = lib.getModuleForSymbol(symbol.name); 
     171                if(libMod){ 
     172                    if(!libMod.isResolved()){ 
     173                        this.link(libMod,true); 
     174                    } 
     175                    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; 
     181                } 
     182            } 
     183            // throw if we aboslutely *must* have this symbol resolved on this pass 
     184            if(symbol.type == SymbolType.Extern || !canSelfResolve){ 
     185                throw new DDLException("cannot resolve symbol '%s'",symbol.name); 
     186            } 
     187            nextSymbol: 
     188            {} // satisfy compiler 
     189        } 
     190     
     191        if(canSelfResolve){ 
     192            foreach(sym; mod.getSymbols){ 
     193                if(sym.type == SymbolType.Weak) sym.type = SymbolType.Strong; 
     194            } 
     195        } 
     196        mod.resolveFixups(); 
     197        mod.isLinking = false; 
     198         
     199        if(!mod.isResolved()){ 
     200            throw new LinkModuleException(mod); 
     201        } 
     202         
     203        // dig up the ModuleInfo (if applicable) and initalize it! 
     204        foreach(sym; mod.getSymbols){ 
     205            if(getDemangleType(sym.name) == DemangleType.ModuleInfo){ 
     206                // found it, now get it and run the constructor 
     207                ModuleInfo moduleInfo = cast(ModuleInfo)(sym.address); 
     208                debug debugLog("init! %0.8X",sym.address); 
     209                initModule(moduleInfo,0); 
     210            } 
     211        } 
     212    } 
     213     
     214    /+ 
    155215    public void link(DynamicModule mod){ 
    156216        //protect against infinite recursion here by returning early 
     
    198258            } 
    199259        } 
    200     } 
     260    }+/ 
    201261     
    202262    /** 
  • trunk/ddl/ddl/DDLLibrary.d

    r181 r218  
    6666        return binary.attributes; 
    6767    } 
    68         
    69     public ExportSymbol[] getExports(){ 
     68     
     69    public ExportSymbolPtr getSymbol(char[] name){ 
    7070        if(!actualLibrary) loadLibrary(); 
    71         return actualLibrary.getExports(); 
    72     } 
    73      
    74     public ExportSymbol getExport(char[] name){ 
    75         if(!actualLibrary) loadLibrary(); 
    76         return actualLibrary.getExport(name); 
     71        return actualLibrary.getSymbol(name); 
    7772    } 
    7873     
     
    8277    } 
    8378     
    84     public DynamicModule getModuleForExport(char[] name){ 
     79    public DynamicModule getModuleForSymbol(char[] name){ 
    8580        if(!actualLibrary) loadLibrary(); 
    86         return actualLibrary.getModuleForExport(name); 
     81        return actualLibrary.getModuleForSymbol(name); 
    8782    } 
    8883     
  • trunk/ddl/insitu/InSituLibrary.d

    r101 r218  
    3636    DynamicModule[] modules; 
    3737    DynamicModule[char[]] crossReference; // modules by symbol name 
    38     ExportSymbol[char[]] dictionary; // symbols by symbol name 
     38    ExportSymbolPtr[char[]] dictionary; // symbols by symbol name 
    3939    char[] filename; 
    4040     
     
    5959    }        
    6060     
    61     public ExportSymbol[] getExports(){ 
    62         return dictionary.values; 
    63     } 
    64      
    65     public ExportSymbol getExport(char[] name){ 
     61    public ExportSymbolPtr getSymbol(char[] name){ 
    6662        return dictionary[name]; 
    6763    } 
     
    7167    } 
    7268             
    73     public DynamicModule getModuleForExport(char[] name){ 
     69    public DynamicModule getModuleForSymbol(char[] name){ 
    7470        debug debugLog("[SITU] looking for: %s (xref size: %d)",name,crossReference.length); 
    7571        DynamicModule* mod = name in crossReference; 
     
    8581    package void addModule(DynamicModule mod){ 
    8682        this.modules ~= mod; 
    87         foreach(ExportSymbol exp; mod.getExports()){ 
     83        auto symbols = mod.getSymbols(); 
     84        for(uint i=0; i<symbols.length; i++){ 
     85            ExportSymbolPtr exp = &(symbols[i]); 
    8886            dictionary[exp.name] = exp; 
    8987            crossReference[exp.name] = mod; 
  • trunk/ddl/insitu/InSituModule.d

    r92 r218  
    3939        return ""; 
    4040    } 
    41  
    42     public char[][] getDependencies(){ 
    43         // basically, this does nothing 
    44         static char[][char[]] dependencies; 
    45         return dependencies.values; 
    46     } 
    47      
    48     public void resolveDependencies(ExportSymbol[] exports){ 
    49         //do nothing 
    50     } 
    51      
    52     public void resolveDependency(char[] name,void* address){ 
    53         //do nothing 
    54     } 
    55      
    56     public ExportSymbol[] getExports(){ 
     41         
     42    public ExportSymbol[] getSymbols(){ 
    5743        return exports.values; 
    5844    } 
    5945     
    60     public ExportSymbol getExport(char[] name){ 
    61         if(name in exports) return exports[name]; 
    62         else return ExportSymbol.init; 
     46    public ExportSymbolPtr getSymbol(char[] name){ 
     47        if(name in exports) return &(exports[name]); 
     48        else return &ExportSymbol.NONE; 
     49    } 
     50     
     51    public void resolveFixups(){ 
     52        //do nothing 
    6353    } 
    6454     
  • trunk/ddl/omf/OMFBinary.d

    r217 r218  
    10781078        result ~= "PUBDEF:\n"; 
    10791079        foreach(idx,pub; publics){ 
    1080             if(idx == 0) continue; 
    10811080            with(pub){ 
    10821081                char[] thisName = name; 
  • trunk/ddl/omf/OMFLibrary.d

    r217 r218  
    4242    DynamicModule[] modules; 
    4343    DynamicModule[char[]] crossReference; // modules by symbol name 
    44     ExportSymbol[char[]] dictionary; // symbols by symbol name 
     44    ExportSymbolPtr[char[]] dictionary; // symbols by symbol name 
    4545    Attributes attributes; 
    4646 
     
    7070    } 
    7171     
    72     //TODO: should this throw?! 
    73     public ExportSymbol getSymbol(char[] name){ 
    74         ExportSymbol *sym = name in dictionary; 
     72    public ExportSymbolPtr getSymbol(char[] name){ 
     73        ExportSymbolPtr* sym = name in dictionary; 
    7574        if(sym) return *sym; 
    76         throw new Exception("Symbol " ~ name ~ " not found in library " ~ attributes["omf.filename"] ~ ".")
     75        else return &ExportSymbol.NONE
    7776    } 
    7877     
     
    9594    package void addModule(OMFModule mod){ 
    9695        this.modules ~= mod; 
    97         foreach(ExportSymbol exp; mod.getSymbols()){ 
     96        auto symbols = mod.getSymbols(); 
     97        for(uint i=0; i<symbols.length; i++){ 
     98            ExportSymbolPtr exp = &(symbols[i]); 
    9899            dictionary[exp.name] = exp; 
    99100            crossReference[exp.name] = mod; 
  • trunk/ddl/omf/OMFModule.d

    r217 r218  
    3333private import ddl.omf.OMFBinary; 
    3434private import ddl.omf.DLLProvider; 
     35private import ddl.omf.OMFException; 
    3536 
    3637private import mango.io.model.IReader; 
     
    5152    bool resolved; 
    5253     
     54    this(FileBuffer buffer){ 
     55        resolved = false; 
     56        binary.parse(new DDLReader(buffer)); 
     57        syncronizeSymbols(); 
     58    } 
     59         
    5360    this(DDLReader reader){ 
    5461        resolved = false; 
     
    6572    } 
    6673     
    67     public ExportSymbol getSymbol(char[] name){ 
    68         if(name in symbolXref) return *symbolXref[name]; 
    69         else return ExportSymbol.NONE; 
     74    public ExportSymbol* getSymbol(char[] name){ 
     75        if(name in symbolXref) return symbolXref[name]; 
     76        else return &ExportSymbol.NONE; 
     77    } 
     78     
     79    public void resolveFixups(){ 
     80        //do nothing 
    7081    } 
    7182     
     
    210221            *addr += comdat.data.length; 
    211222        } 
    212          
    213                  
     223                         
    214224        // public symbols (done here so address offsets are valid) 
    215225        foreach(pub; binary.publics){ 
     
    218228            sym.type = SymbolType.Strong; 
    219229            sym.name = pub.name; 
    220             sym.address = segmentImages[pub.segmentIndex].data.ptr + pub.offset; 
    221230            symbolXref[sym.name] = sym; 
     231             
     232            if(segmentImages[pub.segmentIndex].data.length == 0){ 
     233                //NOTE: sometimes, a symbol points into an empty segment, and is really 
     234                // attempting to reference the start of the next populated segment within 
     235                // the same group. 
     236                 
     237                // search for the right group 
     238                foreach(idx,grp; binary.groups){ 
     239                    if(idx == 0) continue; 
     240                    bool tag = false; 
     241                    // search for the next populated segment 
     242                    foreach(segIndex; grp.segments){ 
     243                        if(tag){ 
     244                            if(segmentImages[segIndex].data.length > 0){ 
     245                                sym.address = segmentImages[segIndex].data.ptr + pub.offset; 
     246                                goto done; 
     247                            } 
     248                        } 
     249                        else if(segIndex == pub.segmentIndex){ 
     250                            tag = true; // tag! The next one is it. 
     251                        } 
     252                    } 
     253                } 
     254                //NOTE: you can't win them all.  It turns out that there are a family of 
     255                // runtime libary only cases where symbols of this nature cannot be resolved as 
     256                // they are basically pointers to the beginning of a special-use segment of some kind. 
     257                // Thankfully, these symbols exist at runtime, so naming them as Extern here won't  
     258                // affect runtime linking. 
     259                debug debugLog("Cannot resolve segment address for public '%s'.",cast(char[])pub.name); 
     260                sym.type = SymbolType.Extern; // doesn't exist here 
     261            } 
     262            else{ 
     263                sym.address = segmentImages[pub.segmentIndex].data.ptr + pub.offset; 
     264            } 
     265            done: 
    222266             
    223267            symbolIndex++; 
  • trunk/utils/bless.d

    r177 r218  
    180180    // get the file 
    181181    FileBuffer file = new FileBuffer(filename); 
    182      
    183         char[] originalOutputFile = filePathPart(file.getPath,PathPart.Root | PathPart.Path | PathPart.Name | PathPart.Suffix); 
     182    char[] originalOutputFile = filePathPart(file.getPath,PathPart.Root | PathPart.Path | PathPart.Name | PathPart.Suffix); 
    184183     
    185184    if(outputFileName == ""){ 
     
    248247         
    249248        if(!noCreate){ 
    250             File file = new File(outputFileName); 
    251             file.write(binary.getBinaryData); 
    252              
     249            File destFile = new File(outputFileName); 
     250            destFile.write(binary.getBinaryData); 
    253251            if(verbose) Stdout.println("Created '%s'",outputFileName); 
    254252        } 
     
    275273        // get the defined namespaces and imported modules 
    276274        foreach(DynamicModule mod; lib.getModules()){ 
    277             SymbolType type; 
     275            DemangleType demangleType; 
    278276            char[] result; 
    279277 
    280             // get the exported namespaces 
    281             if(verbose) Stdout.println("Exported Namespaces (%d):",mod.getExports.length); 
    282             foreach(ExportSymbol sym; mod.getExports()){ 
    283                 type = getSymbolType(sym.name); 
    284  
    285                 if(type == SymbolType.ModuleInfo){ 
    286                     binary.definedNamespaces ~= sym.name; 
    287                     if(verbose) Stdout.println("module %s",demangleSymbol(sym.name)); 
    288                 } 
    289             } 
    290  
    291             // get the imported modules  
    292             if(verbose) Stdout.println("Dependencies (%d):",mod.getDependencies.length); 
    293             foreach(char[] name; mod.getDependencies()){ 
    294                 type = getSymbolType(name); 
    295  
    296                 if(type == SymbolType.ModuleInfo){ 
    297                     binary.importedModules ~= name; 
    298                     if(verbose) Stdout.println("module %s",demangleSymbol(name)); 
     278            foreach(sym; mod.getSymbols){ 
     279                demangleType = getDemangleType(sym.name); 
     280                if(demangleType == DemangleType.ModuleInfo){ 
     281                    if(sym.type == SymbolType.Strong || SymbolType.Weak){                    
     282                        binary.definedNamespaces ~= sym.name; 
     283                        if(verbose) Stdout.println("module %s",demangleSymbol(sym.name)); 
     284                    } 
     285                    else{ 
     286                        binary.importedModules ~= sym.name; 
     287                        if(verbose) Stdout.println("module %s",demangleSymbol(sym.name)); 
     288                    } 
    299289                } 
    300290            } 
  • trunk/utils/ddlinfo.d

    r177 r218  
    134134            Stdout.println("\n%s",mod.getName()); 
    135135             
    136             Stdout.println("\nDependencies (%d):",mod.getDependencies.length); 
    137             foreach(char[] dep; mod.getDependencies){ 
    138                 debug Stdout.println("%s",dep); 
     136            Stdout.println("\nSymbols (%d):",mod.getSymbols.length); 
     137            foreach(symbol; mod.getSymbols){ 
    139138                if(rawOutput){ 
    140                     Stdout.println("%s",dep); 
     139                    Stdout.println("%s %s",symbol.getTypeName,symbol.name); 
    141140                } 
    142141                else{ 
    143                     Stdout.println("%s",demangleSymbol(dep)); 
     142                    Stdout.println("%s %s",symbol.getTypeName,demangleSymbol(symbol.name)); 
    144143                } 
    145144            } 
    146              
    147             Stdout.println("\nExports (%d):",mod.getExports.length); 
    148             foreach(ExportSymbol sym; mod.getExports()){ 
    149                 debug Stdout.println("%s",sym.name); 
    150                 if(rawOutput){ 
    151                     Stdout.println("%s",sym.name); 
    152                 } 
    153                 else{ 
    154                     Stdout.println("%s",demangleSymbol(sym.name)); 
    155                 } 
    156             }            
    157145        } 
    158146    }