Changeset 218
- Timestamp:
- 07/18/06 23:06:07 (2 years ago)
- Files:
-
- trunk/ddl/DefaultRegistry.d (modified) (2 diffs)
- trunk/ddl/Demangle.d (modified) (3 diffs)
- trunk/ddl/DynamicLibrary.d (modified) (1 diff)
- trunk/ddl/DynamicModule.d (modified) (2 diffs)
- trunk/ddl/ExportSymbol.d (modified) (1 diff)
- trunk/ddl/Linker.d (modified) (3 diffs)
- trunk/ddl/ddl/DDLLibrary.d (modified) (2 diffs)
- trunk/ddl/insitu/InSituLibrary.d (modified) (4 diffs)
- trunk/ddl/insitu/InSituModule.d (modified) (1 diff)
- trunk/ddl/omf/OMFBinary.d (modified) (1 diff)
- trunk/ddl/omf/OMFLibrary.d (modified) (3 diffs)
- trunk/ddl/omf/OMFModule.d (modified) (5 diffs)
- trunk/utils/bless.d (modified) (3 diffs)
- trunk/utils/ddlinfo.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ddl/DefaultRegistry.d
r183 r218 34 34 35 35 private import ddl.LoaderRegistry; 36 private import ddl.ar.ArchiveLoader;36 //private import ddl.ar.ArchiveLoader; 37 37 private import ddl.omf.OMFLoader; 38 38 private import ddl.ddl.DDLLoader; 39 private import ddl.elf.ELFObjLoader;39 //private import ddl.elf.ELFObjLoader; 40 40 private import ddl.insitu.InSituLoader; 41 41 //private import ddl.coff.COFFLoader; … … 49 49 register(new InSituLibLoader()); 50 50 register(new InSituMapLoader()); 51 register(new ArchiveLoader());51 // register(new ArchiveLoader()); 52 52 // register(new COFFObjLoader()); 53 register(new ELFObjLoader());53 // register(new ELFObjLoader()); 54 54 } 55 55 else{ trunk/ddl/Demangle.d
r176 r218 43 43 is merely of type 'PublicSymbol'. 44 44 */ 45 enum SymbolType{45 enum DemangleType{ 46 46 PublicSymbol, 47 47 ClassDefinition, … … 79 79 80 80 /** 81 Parses a mangled D symbol and returns its SymbolType.81 Parses a mangled D symbol and returns its DemangleType. 82 82 83 83 Params: … … 85 85 86 86 Returns: 87 The SymbolType for the symbol.87 The DemangleType for the symbol. 88 88 */ 89 public SymbolType getSymbolType(char[] symbol){89 public DemangleType getDemangleType(char[] symbol){ 90 90 if(symbol.startsWith("_Class")){ 91 return SymbolType.ClassDefinition;91 return DemangleType.ClassDefinition; 92 92 } 93 93 else if(symbol.startsWith("__init_")){ 94 return SymbolType.Initalizer;94 return DemangleType.Initalizer; 95 95 } 96 96 else if(symbol.startsWith("__vtbl_")){ 97 return SymbolType.Vtable;97 return DemangleType.Vtable; 98 98 } 99 99 else if(symbol.startsWith("__arguments_")){ 100 return SymbolType.VarArguments;100 return DemangleType.VarArguments; 101 101 } 102 102 else if(symbol.startsWith("__d")){ 103 return SymbolType.PlatformHook;103 return DemangleType.PlatformHook; 104 104 } 105 105 else if(symbol.startsWith("_assert_")){ 106 return SymbolType.DAssert;106 return DemangleType.DAssert; 107 107 } 108 108 else if(symbol.startsWith("_array_")){ 109 return SymbolType.DArray;109 return DemangleType.DArray; 110 110 } 111 111 else if(symbol.startsWith("__modctor_")){ 112 return SymbolType.ModuleCtor;112 return DemangleType.ModuleCtor; 113 113 } 114 114 else if(symbol.startsWith("__moddtor_")){ 115 return SymbolType.ModuleDtor;115 return DemangleType.ModuleDtor; 116 116 } 117 117 else if(symbol.startsWith("__ModuleInfo_")){ 118 return SymbolType.ModuleInfo;118 return DemangleType.ModuleInfo; 119 119 } 120 120 else if(symbol.startsWith("__nullext")){ 121 return SymbolType.Nullext;121 return DemangleType.Nullext; 122 122 } 123 123 else if(symbol.startsWith("_Dmain")){ 124 return SymbolType.Main;124 return DemangleType.Main; 125 125 } 126 126 else if(symbol.startsWith("_DWinMain")){ 127 return SymbolType.WinMain;127 return DemangleType.WinMain; 128 128 } 129 129 else if(symbol.startsWith("_D")){ 130 return SymbolType.PublicSymbol;130 return DemangleType.PublicSymbol; 131 131 } 132 132 // no particular type, default the symbol to a 'public' 133 return SymbolType.PublicSymbol;133 return DemangleType.PublicSymbol; 134 134 } trunk/ddl/DynamicLibrary.d
r216 r218 45 45 Returns: an export for the requested symbol name. Will throw if the symbol does not exist. 46 46 */ 47 public ExportSymbol getSymbol(char[] name);47 public ExportSymbolPtr getSymbol(char[] name); 48 48 49 49 /** trunk/ddl/DynamicModule.d
r216 r218 103 103 */ 104 104 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){ 107 107 return Attributes.init; 108 108 } … … 118 118 Gets a specific export by name. If the export does not exist, the method returns ExportSymbol.init. 119 119 */ 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(); 121 126 122 127 /** trunk/ddl/ExportSymbol.d
r216 r218 92 92 } 93 93 } 94 95 alias ExportSymbol* ExportSymbolPtr; trunk/ddl/Linker.d
r168 r218 35 35 private import ddl.Demangle; 36 36 private import ddl.LoaderRegistry; 37 private import ddl.DDLException; 37 38 38 39 private import std.moduleinit; // used for ModuleInfo type … … 152 153 This implementation performs a long search of modules, then discrete symbols in the 153 154 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 /+ 155 215 public void link(DynamicModule mod){ 156 216 //protect against infinite recursion here by returning early … … 198 258 } 199 259 } 200 } 260 }+/ 201 261 202 262 /** trunk/ddl/ddl/DDLLibrary.d
r181 r218 66 66 return binary.attributes; 67 67 } 68 69 public ExportSymbol [] getExports(){68 69 public ExportSymbolPtr getSymbol(char[] name){ 70 70 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); 77 72 } 78 73 … … 82 77 } 83 78 84 public DynamicModule getModuleFor Export(char[] name){79 public DynamicModule getModuleForSymbol(char[] name){ 85 80 if(!actualLibrary) loadLibrary(); 86 return actualLibrary.getModuleFor Export(name);81 return actualLibrary.getModuleForSymbol(name); 87 82 } 88 83 trunk/ddl/insitu/InSituLibrary.d
r101 r218 36 36 DynamicModule[] modules; 37 37 DynamicModule[char[]] crossReference; // modules by symbol name 38 ExportSymbol [char[]] dictionary; // symbols by symbol name38 ExportSymbolPtr[char[]] dictionary; // symbols by symbol name 39 39 char[] filename; 40 40 … … 59 59 } 60 60 61 public ExportSymbol[] getExports(){ 62 return dictionary.values; 63 } 64 65 public ExportSymbol getExport(char[] name){ 61 public ExportSymbolPtr getSymbol(char[] name){ 66 62 return dictionary[name]; 67 63 } … … 71 67 } 72 68 73 public DynamicModule getModuleFor Export(char[] name){69 public DynamicModule getModuleForSymbol(char[] name){ 74 70 debug debugLog("[SITU] looking for: %s (xref size: %d)",name,crossReference.length); 75 71 DynamicModule* mod = name in crossReference; … … 85 81 package void addModule(DynamicModule mod){ 86 82 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]); 88 86 dictionary[exp.name] = exp; 89 87 crossReference[exp.name] = mod; trunk/ddl/insitu/InSituModule.d
r92 r218 39 39 return ""; 40 40 } 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(){ 57 43 return exports.values; 58 44 } 59 45 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 63 53 } 64 54 trunk/ddl/omf/OMFBinary.d
r217 r218 1078 1078 result ~= "PUBDEF:\n"; 1079 1079 foreach(idx,pub; publics){ 1080 if(idx == 0) continue;1081 1080 with(pub){ 1082 1081 char[] thisName = name; trunk/ddl/omf/OMFLibrary.d
r217 r218 42 42 DynamicModule[] modules; 43 43 DynamicModule[char[]] crossReference; // modules by symbol name 44 ExportSymbol [char[]] dictionary; // symbols by symbol name44 ExportSymbolPtr[char[]] dictionary; // symbols by symbol name 45 45 Attributes attributes; 46 46 … … 70 70 } 71 71 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; 75 74 if(sym) return *sym; 76 throw new Exception("Symbol " ~ name ~ " not found in library " ~ attributes["omf.filename"] ~ ".");75 else return &ExportSymbol.NONE; 77 76 } 78 77 … … 95 94 package void addModule(OMFModule mod){ 96 95 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]); 98 99 dictionary[exp.name] = exp; 99 100 crossReference[exp.name] = mod; trunk/ddl/omf/OMFModule.d
r217 r218 33 33 private import ddl.omf.OMFBinary; 34 34 private import ddl.omf.DLLProvider; 35 private import ddl.omf.OMFException; 35 36 36 37 private import mango.io.model.IReader; … … 51 52 bool resolved; 52 53 54 this(FileBuffer buffer){ 55 resolved = false; 56 binary.parse(new DDLReader(buffer)); 57 syncronizeSymbols(); 58 } 59 53 60 this(DDLReader reader){ 54 61 resolved = false; … … 65 72 } 66 73 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 70 81 } 71 82 … … 210 221 *addr += comdat.data.length; 211 222 } 212 213 223 214 224 // public symbols (done here so address offsets are valid) 215 225 foreach(pub; binary.publics){ … … 218 228 sym.type = SymbolType.Strong; 219 229 sym.name = pub.name; 220 sym.address = segmentImages[pub.segmentIndex].data.ptr + pub.offset;221 230 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: 222 266 223 267 symbolIndex++; trunk/utils/bless.d
r177 r218 180 180 // get the file 181 181 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); 184 183 185 184 if(outputFileName == ""){ … … 248 247 249 248 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); 253 251 if(verbose) Stdout.println("Created '%s'",outputFileName); 254 252 } … … 275 273 // get the defined namespaces and imported modules 276 274 foreach(DynamicModule mod; lib.getModules()){ 277 SymbolType type;275 DemangleType demangleType; 278 276 char[] result; 279 277 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 } 299 289 } 300 290 } trunk/utils/ddlinfo.d
r177 r218 134 134 Stdout.println("\n%s",mod.getName()); 135 135 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){ 139 138 if(rawOutput){ 140 Stdout.println("%s ",dep);139 Stdout.println("%s %s",symbol.getTypeName,symbol.name); 141 140 } 142 141 else{ 143 Stdout.println("%s ",demangleSymbol(dep));142 Stdout.println("%s %s",symbol.getTypeName,demangleSymbol(symbol.name)); 144 143 } 145 144 } 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 }157 145 } 158 146 }
