Changeset 36
- Timestamp:
- 11/05/05 11:44:51 (3 years ago)
- Files:
-
- trunk/ddl/Demangle.d (modified) (1 diff)
- trunk/ddl/dll/DLLLoader.obj (modified) (previous)
- trunk/ddl/insitu/InSituMapBinary.d (modified) (1 diff)
- trunk/ddl/omf/OMFBinary.d (modified) (9 diffs)
- trunk/ddl/omf/OMFModule.d (modified) (1 diff)
- trunk/test.d (modified) (3 diffs)
- trunk/test/testmodule.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ddl/Demangle.d
r22 r36 178 178 type = SymbolType.PublicSymbol; 179 179 return symbol; 180 } 181 182 public 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; 180 229 } 181 230 trunk/ddl/insitu/InSituMapBinary.d
r34 r36 74 74 // throw away the address (first nine chars) 75 75 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 76 77 77 78 // parse out the symbol trunk/ddl/omf/OMFBinary.d
r21 r36 34 34 uint byteAlignment; 35 35 ubyte[] data; 36 uint nameIndex; 37 uint nextInGroup; 36 38 37 39 // add blocks according to alignment 38 40 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]; 41 59 } 42 60 } … … 155 173 debug writefln("Library Name: %s",name); 156 174 this.libraryName = name; 175 this.libraryName = std.string.replace(this.libraryName,"/","."); 176 this.libraryName = std.string.replace(this.libraryName,"\\","."); 157 177 } 158 178 … … 200 220 } 201 221 222 private import std.stdio; 202 223 /* 203 224 Read in public names … … 255 276 256 277 seg.data.length = cursor.getVWord(); 257 cursor.getIndex(); // throw out name index278 seg.nameIndex = cursor.getIndex(); // get name index 258 279 cursor.getIndex(); // throw out class name index 259 280 cursor.getIndex(); // throw out overlay name index … … 290 311 char[] name = this.names[nameIndex]; 291 312 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. 294 335 //if(name != "FLAT"){ 295 336 // throw new FeatureNotSupportedException( … … 676 717 // create addresses for all of the public symbols 677 718 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]; 682 725 } 683 726 … … 721 764 722 765 fixupValue = cast(uint)target.address; 723 724 766 debug writefln("fixup: %s ",target.name); 725 767 } 726 768 else{ 727 769 Segment* seg = &(this.segments[fix.targetIndex]); 728 729 770 fixupValue = cast(uint)(seg.data.ptr); 730 731 771 debug writefln("fixup segment %d",fix.targetIndex); 732 772 } … … 734 774 if(!fix.isSegmentRelative){ // self relative fixup 735 775 uint* dest = cast(uint*)(this.segments[fix.destSegmentIndex].data.ptr + fix.destOffset); 736 737 776 uint value = fixupValue - cast(uint)dest - 4; // relative fixup, offset by width of field 738 739 777 debug writefln("[self relative] %d dest %0.8X (at %0.8X) to %0.8X",fix.destSegmentIndex,*dest,dest,value^0xFFFFFFFF); 740 741 778 *dest = value; 742 779 } 743 780 else{ 744 781 uint* dest = cast(uint*)(this.segments[fix.destSegmentIndex].data.ptr + fix.destOffset); 745 746 782 debug writefln("[segment] %d dest %0.8X to %0.8X",fix.destSegmentIndex,*dest,fixupValue); 747 748 783 *dest += fixupValue; 749 784 } … … 774 809 public void fixDependency(char[] name,void* address){ 775 810 assert(name in this.dependencies); 776 811 777 812 this.externs[this.dependencies[name]].address = address; 778 813 } trunk/ddl/omf/OMFModule.d
r19 r36 104 104 } 105 105 } 106 107 public char[] toString(){ 108 return binary.toString(); 109 } 106 110 } trunk/test.d
r35 r36 26 26 27 27 private import ddl.all; 28 private import ddl.omf.OMFModule; 28 29 29 30 private import std.stdio; … … 38 39 char[] testmoduleModuleInfo = "__ModuleInfo_10testmodule"; 39 40 40 // first attempt at fully-dynamic linking 41 42 void main(){ 41 void 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 71 DynamicModule[char[]] moduleXRef; 72 DynamicModule[char[]] miscModules; 73 DynamicModule[char[]] specialModules; // std.object and minit go here 74 75 76 // adds library modules to the cross-reference. Modules already present have precedence. 77 void 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 110 bit 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 123 void 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 207 void linkLibrary(DynamicLibrary lib){ 208 foreach(DynamicModule mod; lib.getModules()){ 209 if(!mod.isResolved()){ 210 linkModule(mod); 211 } 212 } 213 } 214 215 void main(){ 43 216 // 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")); 48 221 49 222 // 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 74 228 // 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)); 77 231 78 232 // hello world test … … 81 235 82 236 // run module destructor 237 ModuleInfo moduleInfo = cast(ModuleInfo)(testModule.getExport(testmoduleModuleInfo).address); 83 238 if(moduleInfo.dtor){ 84 239 (*moduleInfo.dtor)(); trunk/test/testmodule.d
r35 r36 25 25 module test.testmodule; 26 26 27 private import std.stdio; 28 27 29 class TestClass{ 28 30 uint a; … … 35 37 36 38 private void test(){ 37 printf("A = %d\n",a);39 writefln("A = %d",a); 38 40 } 39 41 40 42 static this(){ 41 printf("TestClass initalized\n");43 writefln("TestClass initalized"); 42 44 } 43 45 }
