Changeset 36

Show
Ignore:
Timestamp:
11/05/05 11:44:51 (3 years ago)
Author:
pragma
Message:

Dirty commit - playing catch-up and backing up source remotely.

Files:

Legend:

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

    r22 r36  
    178178    type = SymbolType.PublicSymbol; 
    179179    return symbol; 
     180} 
     181 
     182public SymbolType getSymbolType(in char[] symbol){ 
     183    SymbolType type; 
     184    DemangleCursor cursor; 
     185    cursor.data = symbol; 
     186    cursor.position = 0; 
     187     
     188    if(cursor.parseToken("_Class")){ 
     189        type = SymbolType.ClassDefinition; 
     190    } 
     191    else if(cursor.parseToken("__init_")){ 
     192        type = SymbolType.Initalizer; 
     193    } 
     194    else if(cursor.parseToken("__vtbl_")){ 
     195        type = SymbolType.Vtable; 
     196    } 
     197    else if(cursor.parseToken("__arguments_")){ 
     198        type = SymbolType.VarArguments; 
     199    } 
     200    else if(cursor.parseToken("__d")){ 
     201        type = SymbolType.PlatformHook; 
     202    } 
     203    else if(cursor.parseToken("_assert_")){ 
     204        type = SymbolType.DAssert; 
     205    } 
     206    else if(cursor.parseToken("_array_")){ 
     207        type = SymbolType.DArray; 
     208    }    
     209    else if(cursor.parseToken("__modctor_")){ 
     210        type = SymbolType.ModuleCtor; 
     211    } 
     212    else if(cursor.parseToken("__moddtor_")){ 
     213        type = SymbolType.ModuleDtor; 
     214    } 
     215    else if(cursor.parseToken("__ModuleInfo_")){ 
     216        type = SymbolType.ModuleInfo; 
     217    } 
     218    else if(cursor.parseToken("__nullext")){ 
     219        type = SymbolType.Nullext; 
     220    }    
     221    else if(cursor.parseToken("_D")){ 
     222        type = SymbolType.PublicSymbol; 
     223    } 
     224    else{ 
     225        // no particular type, default the symbol to a 'public' 
     226        type = SymbolType.PublicSymbol; 
     227    } 
     228    return type; 
    180229} 
    181230 
  • trunk/ddl/insitu/InSituMapBinary.d

    r34 r36  
    7474            // throw away the address (first nine chars)  
    7575            if(line[14..21] == "  Imp  ") continue; // throw this away! We want the '__imp__' version instead. 
     76            if(line[14..21] == "  Abs  ") continue; // this isn't needed either 
    7677                     
    7778            // parse out the symbol 
  • trunk/ddl/omf/OMFBinary.d

    r21 r36  
    3434    uint byteAlignment; 
    3535    ubyte[] data; 
     36    uint nameIndex; 
     37    uint nextInGroup; 
    3638     
    3739    // add blocks according to alignment 
    3840    public void addData(ubyte[] newBlock){ 
    39         data.length = data.length + (data.length % byteAlignment); 
    40         data ~= newBlock; 
     41        if(data.length == 0){ 
     42             data = newBlock; 
     43        } 
     44        else{ 
     45            data.length = data.length + (data.length % byteAlignment); 
     46            data ~= newBlock; 
     47        } 
     48    } 
     49     
     50    // getData - allows for grouped segments to represent neighboring places in memory, in order 
     51    public void* getData(Segment[] allSegments,uint offset){ 
     52        if(offset >= data.length){ 
     53            if(nextInGroup == 0){ 
     54                throw new Exception("cannot get offset " ~ std.string.toString(offset) ~" in this segment"); 
     55            } 
     56            return allSegments[nextInGroup].getData(allSegments,offset - data.length); 
     57        } 
     58        return &data[offset]; 
    4159    } 
    4260} 
     
    155173        debug writefln("Library Name: %s",name); 
    156174        this.libraryName = name; 
     175        this.libraryName = std.string.replace(this.libraryName,"/","."); 
     176        this.libraryName = std.string.replace(this.libraryName,"\\","."); 
    157177    } 
    158178     
     
    200220    } 
    201221 
     222    private import std.stdio; 
    202223    /* 
    203224        Read in public names 
     
    255276         
    256277        seg.data.length = cursor.getVWord();  
    257         cursor.getIndex(); // throw out name index 
     278        seg.nameIndex = cursor.getIndex(); // get name index 
    258279        cursor.getIndex(); // throw out class name index 
    259280        cursor.getIndex(); // throw out overlay name index 
     
    290311        char[] name = this.names[nameIndex]; 
    291312         
    292         //TODO: test and re-evaluate.  "internal\minit.asm" has an odd group assignment for module init (probably not needed) 
    293          
     313        if(name == "DGROUP"){ 
     314            debug printf("[segment group] \n"); 
     315             
     316            bit firstTime = true; 
     317            ushort lastIndex; 
     318            while(cursor.hasMore()){ 
     319                cursor.getByte(); // throw out the type index 
     320                ushort segmentIndex = cursor.getIndex(); 
     321                             
     322                if(firstTime){ 
     323                    firstTime = false; 
     324                } 
     325                else{ 
     326                    segments[lastIndex].nextInGroup = segmentIndex; 
     327                } 
     328                 
     329                debug printf("GRP Segment[%d]: %.*s (%d) prev: %d\n",segmentIndex,this.names[this.segments[segmentIndex].nameIndex],this.segments[segmentIndex].data.length,lastIndex); 
     330                lastIndex = segmentIndex; 
     331            } 
     332        } 
     333         
     334        //TODO: test and re-evaluate.   
    294335        //if(name != "FLAT"){ 
    295336        //  throw new FeatureNotSupportedException( 
     
    676717        // create addresses for all of the public symbols        
    677718        foreach(inout PublicSymbol pub; this.publics){ 
    678             //printf("name: %.*s segindex: %d offset: %d\n",pub.name,pub.segmentIndex,pub.offset); 
    679             if(pub.segmentIndex == 0) continue; // workaround for __nullext being located at 0:0 
    680              
    681             pub.address = &this.segments[pub.segmentIndex].data[pub.offset]; 
     719            printf("name: %.*s segindex: %d offset: %d\n",pub.name,pub.segmentIndex,pub.offset); 
     720            //if(pub.segmentIndex == 0) continue; //HACK: workaround for __nullext being located at 0:0 
     721                         
     722            //TODO: refactor using .getData(uint ofs) to provide a point for group-based addressing 
     723            pub.address = this.segments[pub.segmentIndex].getData(this.segments,pub.offset); 
     724            //pub.address = &this.segments[pub.segmentIndex].data[pub.offset]; 
    682725        } 
    683726     
     
    721764                 
    722765                fixupValue = cast(uint)target.address; 
    723                  
    724766                debug writefln("fixup: %s ",target.name); 
    725767            } 
    726768            else{ 
    727769                Segment* seg = &(this.segments[fix.targetIndex]); 
    728                          
    729770                fixupValue = cast(uint)(seg.data.ptr); 
    730                  
    731771                debug writefln("fixup segment %d",fix.targetIndex); 
    732772            } 
     
    734774            if(!fix.isSegmentRelative){ // self relative fixup 
    735775                uint* dest = cast(uint*)(this.segments[fix.destSegmentIndex].data.ptr + fix.destOffset); 
    736                  
    737776                uint value = fixupValue - cast(uint)dest - 4; // relative fixup, offset by width of field 
    738                  
    739777                debug writefln("[self relative] %d dest %0.8X (at %0.8X) to %0.8X",fix.destSegmentIndex,*dest,dest,value^0xFFFFFFFF); 
    740                  
    741778                *dest = value; 
    742779            } 
    743780            else{ 
    744781                uint* dest = cast(uint*)(this.segments[fix.destSegmentIndex].data.ptr + fix.destOffset); 
    745                  
    746782                debug writefln("[segment] %d dest %0.8X to %0.8X",fix.destSegmentIndex,*dest,fixupValue); 
    747                  
    748783                *dest += fixupValue; 
    749784            } 
     
    774809    public void fixDependency(char[] name,void* address){ 
    775810        assert(name in this.dependencies); 
    776          
     811 
    777812        this.externs[this.dependencies[name]].address = address; 
    778813    } 
  • trunk/ddl/omf/OMFModule.d

    r19 r36  
    104104        } 
    105105    } 
     106     
     107    public char[] toString(){ 
     108        return binary.toString(); 
     109    } 
    106110} 
  • trunk/test.d

    r35 r36  
    2626 
    2727private import ddl.all; 
     28private import ddl.omf.OMFModule; 
    2829 
    2930private import std.stdio; 
     
    3839char[] testmoduleModuleInfo = "__ModuleInfo_10testmodule"; 
    3940 
    40 // first attempt at fully-dynamic linking 
    41  
    42 void main(){ 
     41void initModule(ModuleInfo m, int skip){ 
     42    if (m.ctor || m.dtor) 
     43    { 
     44        if (m.flags & MIctorstart) 
     45        {   if (skip) 
     46            return; 
     47        throw new ModuleCtorError(m); 
     48        } 
     49 
     50        m.flags |= MIctorstart; 
     51        foreach(ModuleInfo imported; m.importedModules){ 
     52            initModule(imported,0); 
     53        } 
     54        if (m.ctor) 
     55        (*m.ctor)(); 
     56        m.flags &= ~MIctorstart; 
     57        m.flags |= MIctordone; 
     58 
     59        //TODO: Now that construction is done, register the destructor 
     60    } 
     61    else 
     62    { 
     63        m.flags |= MIctordone; 
     64        foreach(ModuleInfo imported; m.importedModules){ 
     65            initModule(imported,1); 
     66        } 
     67    }     
     68
     69 
     70// module cross-reference - provides a lookup for modules by namespace 
     71DynamicModule[char[]] moduleXRef; 
     72DynamicModule[char[]] miscModules; 
     73DynamicModule[char[]] specialModules; // std.object and minit go here 
     74 
     75 
     76// adds library modules to the cross-reference.  Modules already present have precedence. 
     77void addLibraryToXRef(DynamicLibrary lib){ 
     78    foreach(DynamicModule mod; lib.getModules){ 
     79        char[] name = mod.getName; 
     80        printf("xref: %.*s",name); 
     81        if(name == "internal.minit.asm"){ 
     82            printf("Minit: %.*s\n",(cast(OMFModule)mod).toString());     
     83        } 
     84         
     85        // special modules go here 
     86        if(name == "" || name == "std.object" || name == "internal.minit.asm" || (name.length >= 12 && name[0..12] == "std.typeinfo")){ 
     87            if(!(name in moduleXRef)){       
     88                specialModules[name] = mod; 
     89                printf(" (special)"); 
     90            } 
     91        } 
     92        // d language modules go to the xref 
     93        else if(name[($-2)..$] == ".d"){ 
     94            if(!(name in moduleXRef)){               
     95                moduleXRef[name] = mod; 
     96                printf(" (Xref)"); 
     97            } 
     98        } 
     99        // everything else goes to the misc category 
     100        else{ 
     101            if(!(name in miscModules)){  
     102                miscModules[name] = mod; 
     103                printf(" (misc)"); 
     104            } 
     105        } 
     106        printf("\n"); 
     107    }    
     108
     109 
     110bit supportsDependency(DynamicModule src,DynamicModule external){ 
     111    foreach(char[] dep; src.getDependencies){ 
     112        foreach(ExportSymbol sym; external.getExports){ 
     113            if(dep == sym.name){ 
     114                printf("\nmodule '%.*s' supports '%.*s' ('%.*s')\n",external.getName,src.getName,dep); 
     115                 return true; 
     116            } 
     117        } 
     118    } 
     119    return false; 
     120
     121 
     122// links a new module into the xref 
     123void linkModule(DynamicModule mod){ 
     124    //Q&D recursion stopper: log which modules are presently being worked 
     125    //TODO: refactor to use a flag like ModuleInfo 
     126//  static DynamicModule[] inProgress; 
     127//  if(mod in inProgress) throw new Exception("circular initalization loop!"); 
     128//  inProgress ~= mod; 
     129     
     130    printf("resolving: %.*s\n",mod.getName); 
     131     
     132    // always attempt the special modules first 
     133    printf("resolving specials..."); 
     134    foreach(DynamicModule externalModule; specialModules.values){ 
     135        if(supportsDependency(mod,externalModule)){ 
     136            if(!externalModule.isResolved){ 
     137                linkModule(externalModule); 
     138            } 
     139            mod.resolveDependencies(externalModule.getExports); 
     140            if(mod.isResolved) break; 
     141        } 
     142    } 
     143    printf("done\n"); 
     144         
     145    // is there still more?  Try the D module imports 
     146    if(!mod.isResolved()){ 
     147        printf("resolving d modules..."); 
     148        foreach(char[] dep; mod.getDependencies){ 
     149            if(getSymbolType(dep) == SymbolType.ModuleInfo){ 
     150                // get a module namespace to work with 
     151                SymbolType dummy; 
     152                char[] name = demangleSymbol(dep,dummy); 
     153                 
     154                // dig up the referenced external module 
     155                DynamicModule externalModule = moduleXRef[name~".d"]; 
     156                if(!externalModule) throw new Exception("cannot find module '" ~ name ~ "'"); 
     157                 
     158                // recursive linking - only link modules if they are fully resolved 
     159                if(!externalModule.isResolved){ 
     160                    linkModule(externalModule); 
     161                } 
     162                 
     163                // link in this module 
     164                mod.resolveDependencies(externalModule.getExports); 
     165            } 
     166        } 
     167        printf("done\n"); 
     168    } 
     169     
     170    // more? Try everything else 
     171    if(!mod.isResolved()){ 
     172        printf("resolving misc modules..."); 
     173        foreach(DynamicModule externalModule; miscModules.values){ 
     174            if(supportsDependency(mod,externalModule)){ 
     175                if(!externalModule.isResolved) linkModule(externalModule); 
     176                mod.resolveDependencies(externalModule.getExports); 
     177                if(mod.isResolved) break; 
     178            } 
     179        } 
     180        printf("done.\n"); 
     181    } 
     182     
     183    // did it work? Throw an exception since there's nothing more to be done 
     184    if(!mod.isResolved()){ 
     185        char[] dump; 
     186        foreach(char[] dep; mod.getDependencies){ 
     187            dump ~= "\n" ~ dep; 
     188        } 
     189        throw new Exception("module: " ~ mod.getName ~ " cannot be fully resolved." ~ dump); 
     190    } 
     191     
     192    // brute-force search for the module ctor (if it exists) 
     193    printf("ctor search..."); 
     194    foreach(ExportSymbol sym; mod.getExports){ 
     195        if(getSymbolType(sym.name) == SymbolType.ModuleInfo){ 
     196            // found it, now get it and run the constructor 
     197            ModuleInfo moduleInfo = cast(ModuleInfo)(sym.address); 
     198            initModule(moduleInfo,0); 
     199        } 
     200    } 
     201    printf("done\n"); 
     202
     203 
     204 
     205 
     206// dynamically link in an entire library 
     207void linkLibrary(DynamicLibrary lib){ 
     208    foreach(DynamicModule mod; lib.getModules()){ 
     209        if(!mod.isResolved()){ 
     210            linkModule(mod); 
     211        } 
     212    } 
     213
     214 
     215void main(){     
    43216    // pull in the in situ module (all the currently compiled-in support) 
    44     DynamicLibrary insitu = loadDDL("this.ddl"); 
    45      
    46     // pull in the phobos runtime 
    47     //DynamicLibrary phobos = loadDDL("phobos.ddl"); 
     217    addLibraryToXRef(loadDDL("test.map")); 
     218        
     219    // pull in the phobos runtime (for modules we don't have included in situ) 
     220    addLibraryToXRef(loadDDL("phobos.lib")); 
    48221         
    49222    // load in the test module 
    50     DynamicLibrary testModule = loadDDL("testmodule.ddl"); 
    51      
    52     // resolve outstanding dependencies 
    53     foreach(DynamicModule mod; testModule.getModules){ 
    54         //brain-dead approach to resolution 
    55         mod.resolveDependencies(insitu.getExports()); 
    56     } 
    57          
    58     // ensure everything is resolved 
    59     foreach(DynamicModule mod; testModule.getModules){ 
    60         if(!mod.isResolved()){ 
    61             char[] dump; 
    62             foreach(char[] dep; mod.getDependencies){ 
    63                 dump ~= "\n" ~ dep; 
    64             } 
    65             throw new Exception("module: " ~ mod.getName ~ " cannot be fully resolved." ~ dump); 
    66         } 
    67         mod.resolveDependencies(insitu.getExports()); 
    68     } 
    69          
    70     // run module constructor 
    71     ModuleInfo moduleInfo = cast(ModuleInfo)(testModule.getExport(testmoduleModuleInfo).address); 
    72     (*moduleInfo.ctor)(); 
    73      
     223    DynamicLibrary testModule = loadDDL("testmodule.obj"); 
     224 
     225    // perform a dynamic link for this module 
     226    linkLibrary(testModule); 
     227         
    74228    // add test 
    75     AddFunction addFunc = cast(AddFunction)(testModule.getExport(addFunctionSignature).address); 
    76     writefln("add: 42+69 = %d",addFunc(42,69)); 
     229    //AddFunction addFunc = cast(AddFunction)(testModule.getExport(addFunctionSignature).address); 
     230    //writefln("add: 42+69 = %d",addFunc(42,69)); 
    77231     
    78232    // hello world test 
     
    81235     
    82236    // run module destructor 
     237    ModuleInfo moduleInfo = cast(ModuleInfo)(testModule.getExport(testmoduleModuleInfo).address); 
    83238    if(moduleInfo.dtor){ 
    84239        (*moduleInfo.dtor)(); 
  • trunk/test/testmodule.d

    r35 r36  
    2525module test.testmodule; 
    2626 
     27private import std.stdio; 
     28 
    2729class TestClass{ 
    2830    uint a; 
     
    3537     
    3638    private void test(){ 
    37         printf("A = %d\n",a); 
     39        writefln("A = %d",a); 
    3840    } 
    3941     
    4042    static this(){ 
    41         printf("TestClass initalized\n"); 
     43        writefln("TestClass initalized"); 
    4244    } 
    4345}