Changeset 219
- Timestamp:
- 07/28/06 20:32:37 (2 years ago)
- Files:
-
- trunk/ddl/DynamicLibrary.d (modified) (4 diffs)
- trunk/ddl/Linker.d (modified) (7 diffs)
- trunk/ddl/insitu/InSituLibBinary.d (modified) (1 diff)
- trunk/ddl/insitu/InSituMapBinary.d (modified) (4 diffs)
- trunk/ddl/omf/OMFBinary.d (modified) (19 diffs)
- trunk/ddl/omf/OMFLibrary.d (modified) (2 diffs)
- trunk/ddl/omf/OMFModule.d (modified) (13 diffs)
- trunk/test/linktest1.d (modified) (2 diffs)
- trunk/test/testmodule.d (modified) (1 diff)
- trunk/utils/ddlinfo.d (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ddl/DynamicLibrary.d
r218 r219 75 75 forces the implementation to return every and all modules it controls, without exception. 76 76 77 In light of that, Relying on the getModules() (and get Exports()) methods can have serious77 In light of that, Relying on the getModules() (and getSymbols()) methods can have serious 78 78 performance implications, depending on the actual implemenation of DynamicLibrary. 79 79 For example, some implementations may decide to intercept D symbols and map the symbol … … 83 83 Returns: the module contianing the export, or null if no module in this library contains 84 84 the export. The module is not guaranteed to contain the symbol provided, and can simply be 85 the library's best guess as to a match. Call get Export() on the returned module to eliminate85 the library's best guess as to a match. Call getSymbol() on the returned module to eliminate 86 86 any such false-positives. 87 87 … … 105 105 /* 106 106 Template method that returns a typed export from the library. The implementation uses 107 get ExportAddress() internally. This differs greatly from the use of getExport()107 getSymbolAddress() internally. This differs greatly from the use of getSymbol() 108 108 variants in that it allows for a proper D namespace/name instead of a mangled symbol. 109 109 … … 125 125 static if(T.mangleof[0] == 'P'){ 126 126 typeof(T) getDExport() { 127 return cast(typeof(T))get Export( "_D" ~ mangleSymbolName!(name) ~ T.mangleof[1..$]).address;127 return cast(typeof(T))getSymbol( "_D" ~ mangleSymbolName!(name) ~ T.mangleof[1..$]).address; 128 128 } 129 129 } else { 130 130 typeof(T) getDExport() { 131 return cast(typeof(T))get Export("_D" ~ mangleSymbolName!(name) ~ T.mangleof).address; }131 return cast(typeof(T))getSymbol("_D" ~ mangleSymbolName!(name) ~ T.mangleof).address; } 132 132 } 133 133 } trunk/ddl/Linker.d
r218 r219 118 118 if(!m) return; 119 119 if (m.flags & MIctordone) return; 120 121 debug debugLog("Module: %s %0.8X\n",m.name,cast(void*)m); 120 121 debug debugLog("this module: %0.8X",cast(void*)m); 122 debug debugLog("(name: %0.8X)",m.name.ptr); 123 debug debugLog("(ctor: %0.8X)",cast(void*)(m.ctor)); 124 debug debugLog("(dtor: %0.8X)",cast(void*)(m.dtor)); 125 debug debugLog("Module: %s\n",m.name); 126 122 127 if (m.ctor || m.dtor) 123 128 { … … 129 134 130 135 m.flags |= MIctorstart; 136 debug debugLog("running imported modules (%d)...",m.importedModules.length); 131 137 foreach(ModuleInfo imported; m.importedModules){ 132 138 initModule(imported,0); … … 142 148 { 143 149 m.flags |= MIctordone; 150 debug debugLog("running imported modules (%d)...",m.importedModules.length); 144 151 foreach(ModuleInfo imported; m.importedModules){ 145 152 initModule(imported,1); … … 147 154 } 148 155 } 149 156 150 157 /** 151 158 Links a module against the linker's internal cross-reference. … … 164 171 mod.isLinking = true; 165 172 166 foreach(symbol; mod.getSymbols){ 173 debug debugLog("Linking module: %s",mod.getName); 174 175 auto moduleSymbols = mod.getSymbols(); 176 for(uint i=0; i<moduleSymbols.length; i++){ 177 auto symbol = &(moduleSymbols[i]); 178 167 179 if(symbol.type == SymbolType.Strong) continue; 168 180 // resolve a dependency from out of the registry … … 174 186 } 175 187 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; 188 if(otherSymbol.type == SymbolType.Strong){ 189 debug debugLog("[Linker] found %s at %0.8X",otherSymbol.name,otherSymbol.address); 190 symbol.address = otherSymbol.address; 191 symbol.type = SymbolType.Strong; 192 goto nextSymbol; 193 } 194 debug debugLog("symbol is not strong (%s -> %0.8X)",symbol.getTypeName,symbol.address); 181 195 } 182 196 } … … 200 214 throw new LinkModuleException(mod); 201 215 } 202 216 217 debug debugLog(mod.toString()); 218 203 219 // dig up the ModuleInfo (if applicable) and initalize it! 204 220 foreach(sym; mod.getSymbols){ 221 if(!sym.address) continue; 205 222 if(getDemangleType(sym.name) == DemangleType.ModuleInfo){ 206 223 // found it, now get it and run the constructor 207 224 ModuleInfo moduleInfo = cast(ModuleInfo)(sym.address); 208 debug debugLog("init! % 0.8X",sym.address);225 debug debugLog("init! %s %s %0.8X",sym.name,sym.getTypeName,sym.address); 209 226 initModule(moduleInfo,0); 227 debug debugLog("init done."); 228 break; 210 229 } 211 230 } 212 231 } 213 214 /+215 public void link(DynamicModule mod){216 //protect against infinite recursion here by returning early217 //by this, we count on the module being resolved further up the call stack218 if(mod.isLinking) return;219 220 mod.isLinking = true;221 222 foreach(char[] dep; mod.getDependencies){223 ExportSymbol sym = ExportSymbol.init;224 //TODO: create a cache for namespace matching requests and search that first225 foreach(DynamicLibrary lib; this.libraries){226 DynamicModule libMod = lib.getModuleForExport(dep);227 if(libMod){228 //TODO: add to the cache here229 sym = libMod.getExport(dep);230 if(sym != ExportSymbol.init){231 if(!libMod.isResolved()){232 this.link(libMod);233 }234 mod.resolveDependency(sym);235 goto nextDep; // why keep looping? get the heck out -- we're done!236 }237 }238 }239 nextDep:240 debug if(sym == ExportSymbol.init){241 debugLog("[Linker.link]: cannot find %s",dep);242 }243 }244 //TODO: possible mod.resolveInternals() call here.245 mod.isLinking = false;246 247 if(!mod.isResolved()){248 throw new LinkModuleException(mod);249 }250 251 // dig up the ModuleInfo (if applicable) and initalize it!252 foreach(ExportSymbol sym; mod.getExports){253 if(getSymbolType(sym.name) == SymbolType.ModuleInfo){254 // found it, now get it and run the constructor255 ModuleInfo moduleInfo = cast(ModuleInfo)(sym.address);256 debug debugLog("init! %0.8X",sym.address);257 initModule(moduleInfo,0);258 }259 }260 }+/261 232 262 233 /** trunk/ddl/insitu/InSituLibBinary.d
r181 r219 91 91 92 92 sym.address = cast(void*)address; 93 sym.type = SymbolType.Strong; 93 94 94 95 allSymbols[sym.name] = sym; trunk/ddl/insitu/InSituMapBinary.d
r161 r219 72 72 parsePublicsByName(iter); 73 73 // throw away the publics by address 74 75 version(Windows){ 76 //HACK: add in parts to make DMD/OMF linking work correctly 77 //NOTE: blindly pulling in all 'Abs' symbols doesn't work as well as it should 78 ExportSymbol sym; 79 80 // __nullext - placeholder for the start of static init for modules 81 sym.address = null; 82 sym.name = "__nullext"; 83 sym.type = SymbolType.Strong; 84 allSymbols[sym.name] = sym; 85 86 // __except_list - placeholder for the start of the exception handling list in FS 87 sym.address = null; 88 sym.name = "__except_list"; 89 sym.type = SymbolType.Strong; 90 allSymbols[sym.name] = sym; 91 } 74 92 } 75 93 … … 98 116 line = iter.getNext(); // throw away the first line (header) 99 117 line = iter.getNext(); // throw away the second line (blank) 100 118 101 119 // read until there's a blank line 102 120 while(true){ 103 121 line = iter.getNext(); 104 122 if(line.length == 0) break; 105 123 124 uint rva; 125 106 126 // throw away the address (first nine chars) 107 127 if(line[14..21] == " Imp ") continue; // throw this away! We want the '__imp__' version instead. … … 121 141 assert(line.length == 8); 122 142 pos = 0; 123 uint rva;124 143 while(pos < 8){ 125 144 char ch = line[pos]; … … 143 162 sym.address = cast(void*)rva; 144 163 sym.name = symbol; 164 sym.type = SymbolType.Strong; 145 165 146 166 allSymbols[sym.name] = sym; trunk/ddl/omf/OMFBinary.d
r218 r219 121 121 } 122 122 123 void parse(inout EXTDEF[] externs, OMFReader reader){123 void parse(inout EXTDEF[] externs,inout FixupTarget[] targets,OMFReader reader){ 124 124 while(reader.hasMore()){ 125 125 EXTDEF extdef; 126 126 extdef.parse(reader); 127 127 externs ~= extdef; 128 129 FixupTarget target; 130 target.type = FixupTarget.EXTDEF; 131 target.index = externs.length-1; 132 targets ~= target; 128 133 } 129 134 } … … 149 154 } 150 155 151 void parse(inout PUBDEF[] publics, OMFReader reader){156 void parse(inout PUBDEF[] publics,inout FixupTarget[] targets,OMFReader reader){ 152 157 OMFIndex groupIndex; 153 158 OMFIndex segmentIndex; … … 176 181 177 182 publics ~= pub; 183 184 FixupTarget target; 185 target.type = FixupTarget.PUBDEF; 186 target.index = publics.length-1; 187 targets ~= target; 178 188 } 179 189 } … … 353 363 354 364 void parse(OMFReader reader){ 355 } 365 //not used 366 } 367 } 368 369 370 /** 371 Defines a mapping between a record and a logical fixup target index. 372 */ 373 struct FixupTarget{ 374 enum: ubyte{ 375 PUBDEF, 376 CEXTDEF, 377 COMDAT, 378 EXTDEF 379 } 380 ubyte type; 381 uint index; 356 382 } 357 383 … … 375 401 FixupThread[4] targetThreads; 376 402 } 403 377 404 void parse(inout FIXUPP[] fixups,inout FixupData fixupData, OMFReader reader){ 378 405 ubyte type; … … 399 426 method = (type & 0b00011100) >> 2; 400 427 401 // f rame thread428 // find the frame type 402 429 if(type & 0b01000000){ 403 430 fixupThread = &(fixupData.frameThreads[threadNumber]); 404 405 if(fixupThread.method < 4){ 406 reader.get(tmpIndex); 407 fixupThread.index = cast(ushort)tmpIndex; 408 } 409 else{ 410 fixupThread.index = 0; 411 } 412 } 413 // target thread 414 else{ 431 } 432 else{ 415 433 fixupThread = &(fixupData.targetThreads[threadNumber]); 434 } 435 436 // get the index 437 if(method < 4){ 416 438 reader.get(tmpIndex); 417 439 fixupThread.index = cast(ushort)tmpIndex; 418 440 } 419 441 else{ 442 fixupThread.index = 0; 443 } 444 // set the method 420 445 fixupThread.method = method; 421 446 } … … 676 701 } 677 702 678 void parse(inout CEXTDEF[] commonExterns, OMFReader reader){703 void parse(inout CEXTDEF[] commonExterns,inout FixupTarget[] targets,OMFReader reader){ 679 704 while(reader.hasMore()){ 680 705 CEXTDEF def; 681 706 def.parse(reader); 682 707 commonExterns ~= def; 708 709 FixupTarget target; 710 target.type = FixupTarget.CEXTDEF; 711 target.index = commonExterns.length-1; 712 targets ~= target; 683 713 } 684 714 } … … 735 765 } 736 766 737 void parse(inout COMDAT[] commonData,inout FixupData fixupData, OMFReader reader){767 void parse(inout COMDAT[] commonData,inout FixupData fixupData,inout FixupTarget[] targets,OMFReader reader){ 738 768 while(reader.hasMore()){ 739 769 COMDAT data; … … 743 773 fixupData.groupIndex = data.groupIndex; 744 774 fixupData.segmentIndex = data.segmentIndex; 745 fixupData.offset = data.enumDataOffset; 775 fixupData.offset = data.enumDataOffset; 776 777 if(!data.isContinuation){ 778 FixupTarget target; 779 target.type = FixupTarget.COMDAT; 780 target.index = commonData.length-1; 781 targets ~= target; 782 } 746 783 } 747 784 } … … 851 888 LString libraryName; 852 889 LString[] names; 890 FixupTarget[] targets; 853 891 854 892 // comment sub data … … 894 932 names.length = names.length+1; 895 933 externs.length = externs.length+1; 934 targets.length = targets.length+1; 896 935 897 936 while(mainReader.hasMore()){ … … 918 957 919 958 case 0x8C: //EXTDEF 920 .parse(externs, reader);959 .parse(externs,targets,reader); 921 960 break; 922 961 923 962 case 0x90: //PUBDEF 924 .parse(publics, reader);963 .parse(publics,targets,reader); 925 964 break; 926 965 … … 958 997 959 998 case 0xBC: //CEXTDEF 960 .parse(communalExterns, reader);999 .parse(communalExterns,targets,reader); 961 1000 break; 962 1001 963 1002 case 0xC2: //COMDAT 964 .parse(communalData,fixupData, reader);1003 .parse(communalData,fixupData,targets,reader); 965 1004 break; 966 1005 … … 1032 1071 } 1033 1072 } 1034 1073 1035 1074 public char[] toString(){ 1075 char[] getExternName(uint index){ 1076 uint workingIndex = index; 1077 /* FixupTarget target = targets[index]; 1078 1079 switch(target.type){ 1080 case FixupTarget.CEXTDEF: 1081 return cast(char[])names[communalExterns[target.index].nameIndex]; 1082 case FixupTarget.EXTDEF: 1083 return cast(char[])externs[target.index].name; 1084 case FixupTarget.COMDAT: 1085 return cast(char[])communalDefinitions[target.index].communalName; 1086 case FixupTarget.PUBDEF: 1087 return cast(char[])publics[target.index].name; 1088 }*/ 1089 1090 if(workingIndex < communalExterns.length){ 1091 return cast(char[])names[communalExterns[workingIndex].nameIndex]; 1092 } 1093 workingIndex -= communalExterns.length; 1094 if(workingIndex < externs.length){ 1095 return cast(char[])externs[workingIndex].name; 1096 } 1097 workingIndex -= externs.length; 1098 if(workingIndex < communalDefinitions.length){ 1099 return cast(char[])communalDefinitions[workingIndex].communalName; 1100 } 1101 } 1102 1036 1103 char[] result = ""; 1037 1104 ExtSprintClass sprint = new ExtSprintClass(1024); … … 1058 1125 } 1059 1126 } 1060 1127 1061 1128 result ~= "WKEXT:\n"; 1062 1129 foreach(idx,weak; weakExterns){ 1063 1130 with(weak){ 1064 char[] weakName = externs[weakIndex].name; 1065 char[] defaultName = externs[resolutionIndex].name; 1066 result ~= sprint(" %d: %s --> %s\n",idx,weakName,defaultName); 1131 char[] defaultName = getExternName(resolutionIndex); 1132 char[] weakName = getExternName(weakIndex); 1133 uint externsLength = externs.length; 1134 uint cextedfsLength = communalExterns.length; 1135 1136 result ~= sprint(" %d: (%d) %s --> (%d) %s\n",idx,cast(uint)weakIndex,weakName,cast(uint)resolutionIndex,defaultName); 1067 1137 } 1068 1138 } … … 1123 1193 1124 1194 if(isExternStyleFixup){ 1125 uint externsLength = externs.length; 1126 uint cextedfsLength = communalExterns.length; 1127 if(fix.targetIndex < externsLength){ 1128 targetName = "extern: " ~ cast(char[])externs[fix.targetIndex].name; 1129 } 1130 else if(fix.targetIndex - externsLength < cextedfsLength){ 1131 targetName = "cextdef: " ~ cast(char[])names[communalExterns[fix.targetIndex-externsLength].nameIndex]; 1132 } 1133 else{ 1134 targetName = "comdat: " ~ cast(char[])communalDefinitions[fix.targetIndex - cextedfsLength - externsLength].communalName; 1135 } 1195 targetName = "extern: " ~ getExternName(targetIndex); 1136 1196 } 1137 1197 else{ … … 1139 1199 } 1140 1200 1141 result ~= sprint(" %d: %s:%d rel: %s | % s\n",idx,segment,destOffset,rel,targetName);1201 result ~= sprint(" %d: %s:%d rel: %s | %d %s\n",idx,segment,destOffset,rel,targetIndex,targetName); 1142 1202 } 1143 1203 } … … 1198 1258 1199 1259 result ~= sprint(" %d: Line %d --> %s%s %0.8X\n", 1200 idx,lineNumber,cont,name, baseOffset);1260 idx,lineNumber,cont,name,cast(uint)baseOffset); 1201 1261 } 1202 1262 } … … 1213 1273 } 1214 1274 } 1215 1275 1276 result ~= "Fixup Targets:\n"; 1277 foreach(idx,target; targets) with(target){ 1278 char[] targetTypeName; 1279 switch(type){ 1280 case FixupTarget.COMDAT: targetTypeName = "COMDAT"; break; 1281 case FixupTarget.PUBDEF: targetTypeName = "PUBDEF"; break; 1282 case FixupTarget.EXTDEF: targetTypeName = "EXTDEF"; break; 1283 case FixupTarget.CEXTDEF: targetTypeName = "CEXTDEF"; break; 1284 } 1285 result ~= sprint(" %d: %s %d\n",idx,targetTypeName,index); 1286 } 1287 1216 1288 return result; 1217 1289 } trunk/ddl/omf/OMFLibrary.d
r218 r219 81 81 82 82 public DynamicModule getModuleForSymbol(char[] name){ 83 debug debugLog(" looking for " ~ name);83 debug debugLog("[OMF] looking for " ~ name); 84 84 DynamicModule* mod = name in crossReference; 85 debug debugLog(" Result: %0.8X",mod);85 debug debugLog("[OMF] Result: %0.8X",mod); 86 86 if(mod) return *mod; 87 87 return null; … … 97 97 for(uint i=0; i<symbols.length; i++){ 98 98 ExportSymbolPtr exp = &(symbols[i]); 99 dictionary[exp.name] = exp; 100 crossReference[exp.name] = mod; 99 if(exp.name in crossReference){ 100 switch(exp.type){ 101 case SymbolType.Weak: // replace extern only 102 if(dictionary[exp.name].type == SymbolType.Extern){ 103 crossReference[exp.name] = mod; 104 dictionary[exp.name] = exp; 105 } 106 break; 107 case SymbolType.Strong: // always overwrite 108 crossReference[exp.name] = mod; 109 dictionary[exp.name] = exp; 110 break; 111 default: 112 // do nothing 113 } 114 } 115 else{ 116 crossReference[exp.name] = mod; 117 dictionary[exp.name] = exp; 118 } 101 119 } 102 120 } trunk/ddl/omf/OMFModule.d
r218 r219 45 45 alias SegmentImage* SegmentImagePtr; 46 46 47 OMFBinary binary; 48 SegmentImage[] segmentImages; 47 debug OMFBinary binary; 48 FIXUPP[] fixups; 49 SegmentImage[] segmentImages; 49 50 ExportSymbol[] symbols; 50 51 ExportSymbolPtr[char[]] symbolXref; … … 54 55 this(FileBuffer buffer){ 55 56 resolved = false; 56 binary.parse(new DDLReader(buffer)); 57 syncronizeSymbols(); 57 loadBinary(new DDLReader(buffer)); 58 58 } 59 59 60 60 this(DDLReader reader){ 61 61 resolved = false; 62 binary.parse(reader); 63 syncronizeSymbols(); 62 loadBinary(reader); 64 63 } 65 64 … … 78 77 79 78 public void resolveFixups(){ 80 //do nothing 79 FIXUPP[] remainingFixups; 80 81 foreach(idx,fix; fixups) with(fix){ 82 uint fixupValue; 83 84 // get the fixup value 85 if(isExternStyleFixup){ 86 debug debugLog("fix target: %d/%d",fix.targetIndex,symbols.length); 87 auto sym = &(symbols[fix.targetIndex-1]); 88 if(sym.type != SymbolType.Strong){ 89 remainingFixups ~= fix; 90 continue; 91 } 92 fixupValue = cast(uint)(sym.address); 93 debug debugLog("\tusing symbol: %s %0.8X",sym.name,sym.address); 94 } 95 else{ 96 fixupValue = cast(uint)(segmentImages[fix.targetIndex].data.ptr); 97 debug debugLog("using segment pointer: %0.8X",fixupValue); 98 } 99 100 // find the fixup destination 101 uint* dest = cast(uint*)(segmentImages[destSegmentIndex].data.ptr + destOffset); 102 103 // apply the fixup value 104 if(fixupValue == 0){ 105 //HACK: there exists a very small class of symbols that point to zero at all times 106 //NOTE: namely, this includes __except_list and __nullext, which point to the start 107 // of their respective segments 108 *dest = fixupValue; 109 } 110 else if(!isSegmentRelative){ 111 uint value = fixupValue - cast(uint)dest - 4; // relative fixup, offset by width of field 112 debug debugLog("Fixup %d [self relative] %d dest %0.8X (at %0.8X) to %0.8X (using %d)",idx,destSegmentIndex,*dest,dest,value^0xFFFFFFFF,value); 113 *dest = value; 114 } 115 else{ 116 debug debugLog("Fixup %d [seg relative] dest %0.8X (at %0.8X) to %0.8X",idx,*dest,dest,*dest+fixupValue); 117 *dest += fixupValue; 118 } 119 } 120 this.fixups = remainingFixups; 81 121 } 82 122 83 123 public bool isResolved(){ 84 return resolved; 85 } 86 87 protected void syncronizeSymbols(){ 88 char[] flag = null; 89 124 if(resolved) return true; 125 126 if(fixups.length > 0) return false; 127 foreach(sym; symbols){ 128 if(sym.type != SymbolType.Strong) return false; 129 } 130 resolved = true; 131 return true; 132 } 133 134 protected void loadBinary(DDLReader reader){ 135 debug{} else{ 136 OMFBinary binary; 137 } 138 binary.parse(reader); 139 90 140 //TODO: alter this to zero in on D namespaces and C/asm namespaces 91 141 this.moduleName = binary.libraryName; … … 106 156 //NOTE: extern indicies match their OMF counterparts 107 157 symbols.length = 108 binary. externs.length +109 binary.communalExterns.length+158 binary.communalExterns.length + 159 (binary.externs.length-1) + 110 160 binary.communalDefinitions.length + 111 binary.publics.length - 1; 112 113 uint symbolIndex = 0; 114 161 binary.publics.length; 162 163 uint symbolIndex = 0; // offset by number of publics (handled later) 164 165 // communal external symbols 166 foreach(ext; binary.communalExterns){ 167 ExportSymbolPtr sym = &(symbols[symbolIndex]); 168 169 sym.type = SymbolType.Weak; 170 sym.name = binary.names[ext.nameIndex]; 171 symbolXref[sym.name] = sym; 172 173 symbolIndex++; 174 } 175 115 176 // external symbols 116 177 foreach(idx,ext; binary.externs){ … … 124 185 symbolIndex++; 125 186 } 126 127 // communal external symbols 128 foreach(ext; binary.communalExterns){ 129 ExportSymbolPtr sym = &(symbols[symbolIndex]); 130 131 sym.type = SymbolType.Weak; 132 sym.name = binary.names[ext.nameIndex]; 133 symbolXref[sym.name] = sym; 134 135 symbolIndex++; 136 } 137 138 // get data from iterated records 139 foreach(idx,lidata; binary.iteratedData){ 140 SegmentImagePtr image = &(segmentImages[lidata.segmentIndex]); 141 uint dataLength = lidata.data.length; 142 uint offset = lidata.offset; 143 144 // debugLog("lidata range: %0.8X .. %0.8X",lidata.data.ptr,lidata.data.ptr+dataLength); 145 146 // reallocate if needed 147 if(image.data.length < offset + dataLength){ 148 image.data.length = offset + dataLength; 149 } 150 // copy into the buffer 151 // debugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.data.length); 152 image.data[offset..offset+dataLength] = lidata.data; 153 } 154 155 // get data from enumerated data 156 157 foreach(idx,ledata; binary.enumeratedData){ 158 SegmentImagePtr image = &(segmentImages[ledata.segmentIndex]); 159 uint dataLength = ledata.data.length; 160 uint offset = ledata.offset; 161 // debugLog("Img: %0.8X Images: %0.8X",image,segmentImages.ptr); 162 163 // reallocate if needed 164 if(image.data.length < offset + dataLength){ 165 image.data.length = offset + dataLength; 166 } 167 // copy into the bufferdebugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.ata.dlength); 168 image.data[offset..offset+dataLength] = ledata.data; 169 } 170 187 171 188 //1st pass for COMDEF records 172 189 //build up the memory image of the referenced segments … … 191 208 192 209 segZeroAddress += comdef.length; 193 } 210 } 211 212 // get data from iterated records 213 foreach(idx,lidata; binary.iteratedData){ 214 SegmentImagePtr image = &(segmentImages[lidata.segmentIndex]); 215 uint dataLength = lidata.data.length; 216 uint offset = lidata.offset; 217 218 // debugLog("lidata range: %0.8X .. %0.8X",lidata.data.ptr,lidata.data.ptr+dataLength); 219 220 // reallocate if needed 221 if(image.data.length < offset + dataLength){ 222 image.data.length = offset + dataLength; 223 } 224 // copy into the buffer 225 // debugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.data.length); 226 image.data[offset..offset+dataLength] = lidata.data; 227 } 228 229 // get data from enumerated data 230 231 foreach(idx,ledata; binary.enumeratedData){ 232 SegmentImagePtr image = &(segmentImages[ledata.segmentIndex]); 233 uint dataLength = ledata.data.length; 234 uint offset = ledata.offset; 235 // debugLog("Img: %0.8X Images: %0.8X",image,segmentImages.ptr); 236 237 // reallocate if needed 238 if(image.data.length < offset + dataLength){ 239 image.data.length = offset + dataLength; 240 } 241 // copy into the bufferdebugLog("image range: %0.8X .. %0.8X",image.data.ptr,image.data.ptr+image.ata.dlength); 242 image.data[offset..offset+dataLength] = ledata.data; 243 } 244 194 245 195 246 //1st pass for COMDAT records … … 210 261 void** addr = &(currentAddress[comdat.segmentIndex]); 211 262 if(*addr == null){ 212 *addr = image.data.ptr+image.data.length; 263 //TODO: change to orignal segment size 264 *addr = image.data.ptr + binary.segments[comdat.segmentIndex].dataLength; 213 265 } 214 266 … … 216 268 //NOTE: this is done to calculate the offset on this pass 217 269 if(!comdat.isContinuation){ 270 symbolXref[binary.names[comdat.nameIndex]].type = SymbolType.Strong; 218 271 symbolXref[binary.names[comdat.nameIndex]].address = *addr; 272 273 debug debugLog("%d %s first bytes: %0.8X\n",idx,cast(char[])binary.names[comdat.nameIndex],*cast(uint*)comdat.data.ptr); 219 274 } 220 275 … … 223 278 224 279 // public symbols (done here so address offsets are valid) 225 foreach( pub; binary.publics){280 foreach(idx,pub; binary.publics){ 226 281 ExportSymbolPtr sym = &(symbols[symbolIndex]); 227 282 … … 264 319 } 265 320 done: 266 267 321 symbolIndex++; 268 322 } … … 310 364 impSpace += (void*).sizeof; 311 365 } 366 367 // process WKEXT records 368 foreach(idx,wkext; binary.weakExterns){ 369 ExportSymbolPtr sym = &(symbols[wkext.weakIndex-1]); 370 //if(sym.address){ 371 symbols[wkext.weakIndex-1].type = SymbolType.Weak; 372 //} 373 } 374 375 // keep a copy of the fixups (the original FIXUPP record works well enough) 376 this.fixups = binary.fixups; 312 377 } 313 378 … … 316 381 ExtSprintClass sprint = new ExtSprintClass(1024); 317 382 318 result ~= "\n--OMF Data--\n"; 319 result ~= binary.toString(); 320 result ~= "\n--OMFBinary Data--\n"; 383 debug{ 384 result ~= "\n--OMFBinary Data--\n"; 385 result ~= binary.toString(); 386 } 387 result ~= "\n--OMFModule Data--\n"; 321 388 result ~= "Module: " ~ moduleName ~ "\n\n"; 322 389 323 result ~= "Segment Images:\n"; 324 foreach(idx,seg; segmentImages){ 325 if(idx == 0) continue; 326 char[] name = binary.names[binary.segments[idx].nameIndex]; 327 result ~= sprint(" %d: %s %d bytes\n",idx,name,seg.data.length); 390 debug{ 391 result ~= "Segment Images:\n"; 392 foreach(idx,seg; segmentImages){ 393 if(idx == 0) continue; 394 char[] name = binary.names[binary.segments[idx].nameIndex]; 395 result ~= sprint(" %d: %s %d bytes [%0.8X]\n",idx,name,seg.data.length,seg.data.ptr); 396 } 328 397 } 329 398 … … 333 402 } 334 403 404 result ~= sprint("Fixups (%d):\n",fixups.length); 405 if(fixups.length > 0){ 406 foreach(idx,fix; fixups){ 407 with(fix){ 408 char[] rel = isSegmentRelative ? "segmentRelative" : "selfRelative"; 409 char[] ext = isExternStyleFixup ? "externStyle" : "segmentStyle"; 410 void* targetAddress = &(segmentImages[destSegmentIndex].data[destOffset]); 411 412 result ~= sprint(" %d: %0.8X %s %s",idx,targetAddress,rel,ext); 413 414 if(isExternStyleFixup){ 415 result ~= sprint(" | %s\n",symbols[targetIndex-1].name); 416 } 417 else{ 418 result ~= sprint(" | segment #%d\n",targetIndex); 419 } 420 } 421 } 422 } 423 424 result ~= "DATA: \n"; 425 foreach(idx,segdef; segmentImages){&nbs
