Changeset 271
- Timestamp:
- 11/05/06 10:14:56 (2 years ago)
- Files:
-
- trunk/ddl/Attributes.d (modified) (1 diff)
- trunk/ddl/DDLException.d (modified) (3 diffs)
- trunk/ddl/DDLReader.d (modified) (7 diffs)
- trunk/ddl/DDLWriter.d (modified) (2 diffs)
- trunk/ddl/DefaultRegistry.d (modified) (2 diffs)
- trunk/ddl/Demangle.d (modified) (2 diffs)
- trunk/ddl/DynamicLibrary.d (modified) (3 diffs)
- trunk/ddl/ExportClass.d (modified) (1 diff)
- trunk/ddl/ExportSymbol.d (modified) (4 diffs)
- trunk/ddl/FileBuffer.d (modified) (1 diff)
- trunk/ddl/Linker.d (modified) (14 diffs)
- trunk/ddl/ar/ArchiveLibrary.d (modified) (2 diffs)
- trunk/ddl/elf/ELFBinary.d (modified) (9 diffs)
- trunk/ddl/elf/ELFHeaders.d (modified) (4 diffs)
- trunk/ddl/elf/ELFLibrary.d (modified) (4 diffs)
- trunk/ddl/elf/ELFModule.d (modified) (1 diff)
- trunk/ddl/elf/ELFObjLoader.d (modified) (1 diff)
- trunk/ddl/elf/ELFPrinter.d (modified) (1 diff)
- trunk/ddl/insitu/InSituMapBinary.d (modified) (2 diffs)
- trunk/ddl/omf/OMFLibrary.d (modified) (1 diff)
- trunk/ddl/omf/OMFModule.d (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ddl/Attributes.d
r175 r271 32 32 module ddl.Attributes; 33 33 34 /** 35 Map designed to hold DynamicModule attributes. The keys and values stored 36 in the map are ASCII/UTF-8 data. 37 */ 34 38 alias char[][char[]] Attributes; 35 39 36 Attributes copyInto(Attributes from,Attributes to){ 40 /** 41 Attribute helper method. 42 43 Params: 44 from = source set of attributes to copy from 45 to = destination set of attributes to copy to (will be modified) 46 */ 47 Attributes copyInto(Attributes from,inout Attributes to){ 37 48 if(from == Attributes.init) return from; 38 49 foreach(char[] key,char[] value; from){ trunk/ddl/DDLException.d
r158 r271 39 39 */ 40 40 class DDLException : Exception{ 41 /** 42 Explicit constructor, suitable to be used within nested vararg calls. 43 44 Params; 45 fmt = format string for the exception message 46 arguments = type info array 47 argptr = start of vararg data 48 */ 41 49 public this(char[] fmt,TypeInfo[] arguments,void* argptr){ 42 50 ExtSprintClass sprint = new ExtSprintClass(fmt.length + 1024); … … 44 52 } 45 53 54 /** 55 Typical constructor, flexible enough to be used in most cases. 56 57 The syntax of this constructor signature is identical to that used 58 for printf-style formatting. 59 60 Params; 61 fmt = format string for the exception message 62 */ 46 63 public this(char[] fmt,...){ 47 64 ExtSprintClass sprint = new ExtSprintClass(fmt.length + 1024); … … 49 66 } 50 67 68 /** 69 Default constructor. 70 71 This calls DDLException.boilerplate() internally to generate the complete 72 exception message. 73 */ 74 //public this(char[] msg){ 75 // super(DDLException.boilerplate(msg)); 76 // } 77 78 /** 79 Boilerplate message generator. 80 81 This is used to emit a boilerplate error message, and is used internally by the 82 default constructor. 83 */ 51 84 public static char[] boilerplate(char[] message){ 52 85 return( 53 86 "[Exception] You have run into a condition not handled, or possibly incorrectly handled, by DDL.\n" ~ 54 87 message ~ 55 "\nPlease create a ticket (or look for similar ones) at http:// trac.dsource.org/projects/ddl/newticket, explain the circumstances and paste this message into it. Also, if possible, please attach a minimal, reproducible testcase.\n - Thank You. -"88 "\nPlease create a ticket (or look for similar ones) at http://www.dsource.org/projects/ddl/newticket, explain the circumstances and paste this message into it. Also, if possible, please attach a minimal, reproducible testcase.\n - Thank You. -" 56 89 ); 57 90 } trunk/ddl/DDLReader.d
r261 r271 41 41 debug private import mango.io.Stdout; 42 42 43 /** 44 Mango IO Reader subclass. 45 46 DDLReader provides a few key pieces of functionality that are used heavily within 47 DDL's input operations. In short, it provides a way to seek, peek and get an 48 entire buffer from a buffer or condiut. This makes it possible to implement a 49 wider array of parser types (e.g. unlimited read-ahead, and recursive descent) than 50 is possible with the standard Mango Reader. 51 52 The reader class itself is useful as-is, but implementors are strongly encouraged 53 to subclass the reader, as to create a richer and more task-oriented feature set. 54 */ 43 55 public class DDLReader : Reader{ 56 /** 57 Simple constructor. Requires no IBuffer or IConduit instances. 58 59 Params: 60 data = data to use for this reader. 61 */ 44 62 public this(void[] data){ 45 63 super(new Buffer(data,data.length)); 46 64 } 47 65 66 /** 67 IBuffer style constructor. 68 69 Params: 70 buffer = buffer to read 71 */ 48 72 public this (IBuffer buffer){ 49 73 super(buffer); 50 74 } 51 75 76 /** 77 IConduit style constructor. 78 79 Params: 80 conduit = conduit to read 81 */ 52 82 public this (IConduit conduit){ 53 83 super(conduit); 54 84 } 55 85 86 /** 87 Look ahead one byte into the input buffer, without advancing the current 88 read position. 89 90 Params: 91 x = (inout) will contain the value of the byte just after the current read position. 92 */ 56 93 public DDLReader peek(inout ubyte x){ 57 94 x = (cast(ubyte[])buffer.get(1,false))[0]; … … 59 96 } 60 97 98 /** 99 Look ahead <i>n</i> bytes into the input buffer, without advancing the current 100 read position. 101 102 Params: 103 x = (inout) will contain the value(s) of the byte(s) just after the current read position. 104 elements = (default: uint.max) the number of bytes to peek. 105 */ 61 106 public DDLReader peek(inout ubyte[] x,uint elements = uint.max){ 62 107 if(elements == uint.max) … … 69 114 } 70 115 71 //props to Kris for suggesting this method of getting 100% of the remaining data in a conduit 116 /** 117 Reads everything the underlying conduit has. 118 119 The current position will be at EOF after this operation. 120 121 Params: 122 x = (inout) will contain everything from the current read position to the end of the file. 123 */ 72 124 DDLReader getAll(inout void[] x) 73 125 { 126 //props to Kris for suggesting this method of getting 100% of the remaining data in a conduit 74 127 IConduit conduit = getBuffer.getConduit(); 75 128 … … 97 150 } 98 151 152 /** 153 Returns: (true/false) If the conduit has any more data to be read. 154 */ 99 155 bool hasMore(){ 100 156 … … 109 165 } 110 166 111 // perform a seek relative to the current buffer position and status using the conduit 112 // NOTE: this will clear out the current buffer 167 /** 168 Perform a seek relative to the current buffer position and status using the conduit. 169 170 Some Mango conduits are seekable directly. For all others, this method seeks by 171 manipulating the buffer and the current read position instead. 172 173 <b>NOTE:</b> this will clear out the current buffer, which may have some performance 174 implications. 175 176 Params: 177 offset = the number of bytes to seek from the specified anchor 178 anchor = (default: Begin) specifies the point in the conduit from where seeks are 179 calculated (see: ISeekable.SeekAnchor for more info). 180 */ 113 181 void seek(ulong offset, ISeekable.SeekAnchor anchor=ISeekable.SeekAnchor.Begin){ 114 182 IConduit conduit = getBuffer.getConduit(); … … 145 213 } 146 214 147 // get the position relative to the current buffer position and status 215 /** 216 Returns: The position relative to the current buffer position. 217 */ 148 218 ulong getPosition(){ 149 219 IConduit conduit = getBuffer.getConduit(); … … 159 229 160 230 // override to provide debug support 161 debug (REMOVE) override protected IReader decodeArray (void[]* x, uint bytes, uint width, uint type){162 try{163 return super.decodeArray(x,bytes,width,type);164 }165 catch(Exception e){166 Stdout.println("Exception thrown while decoding array (%0.8X) %d bytes, width %d, type %d",x,bytes,width,type);167 throw e;168 }169 return this;170 }171 172 // override to provide debug support173 231 debug override protected uint read (void *dst, uint bytes, uint type){ 174 232 try{ trunk/ddl/DDLWriter.d
r179 r271 36 36 private import mango.io.model.IConduit; 37 37 38 /** 39 Mango IO Writer subclass. 40 41 DDLWriter, apart from adding symmetry to DDLReader, provides seeking capability for 42 random-access <i>output</i>. 43 */ 38 44 public class DDLWriter : Writer{ 45 /** 46 IBuffer style constructor. 47 48 Params: 49 buffer = buffer to read 50 */ 39 51 public this (IBuffer buffer){ 40 52 super(buffer); 41 53 } 42 54 55 /** 56 IConduit style constructor. 57 58 Params: 59 conduit = conduit to read 60 */ 43 61 public this (IConduit conduit){ 44 62 super(conduit); 45 63 } 46 64 47 // perform a seek relative to the current buffer position and status using the conduit 48 // NOTE: this will flush the current buffer's contents 65 66 /** 67 Perform a seek relative to the current buffer position and status using the conduit. 68 69 Some Mango conduits are seekable directly. For all others, this method seeks by 70 manipulating the buffer and the current read position instead. 71 72 <b>NOTE:</b> this will clear out the current buffer, which may have some performance 73 implications. 74 75 Params: 76 offset = the number of bytes to seek from the specified anchor 77 anchor = (default: Begin) specifies the point in the conduit from where seeks are 78 calculated (see: ISeekable.SeekAnchor for more info). 79 */ 49 80 void seek(ulong offset, ISeekable.SeekAnchor anchor=ISeekable.SeekAnchor.Begin){ 50 81 IConduit conduit = getBuffer.getConduit(); … … 83 114 } 84 115 85 // get the position relative to the current buffer position and status 116 /** 117 Returns: The position relative to the current buffer position. 118 */ 86 119 ulong getPosition(){ 87 120 IConduit conduit = getBuffer.getConduit(); trunk/ddl/DefaultRegistry.d
r254 r271 41 41 //private import ddl.coff.COFFLoader; 42 42 43 /** 44 Default Loader Registry implementation. 45 46 Pulls in support for all standard loader types. The order of loader registration 47 is different for each platform, to help make things more efficent for typical cases. 48 49 See ddl.LoaderRegistry for more details. 50 */ 43 51 class DefaultRegistry : LoaderRegistry{ 52 /** 53 Default constructor. 54 */ 44 55 public this(){ 45 56 version(Windows){ // order optimized per OS … … 51 62 register(new ArchiveLoader()); 52 63 // register(new COFFObjLoader()); 53 //register(new ELFObjLoader());64 register(new ELFObjLoader()); 54 65 } 55 66 else{ trunk/ddl/Demangle.d
r218 r271 45 45 enum DemangleType{ 46 46 PublicSymbol, 47 PublicDSymbol, 47 48 ClassDefinition, 48 49 Initalizer, … … 128 129 } 129 130 else if(symbol.startsWith("_D")){ 130 return DemangleType.Public Symbol;131 return DemangleType.PublicDSymbol; 131 132 } 132 133 // no particular type, default the symbol to a 'public' 133 134 return DemangleType.PublicSymbol; 134 135 } 136 137 /** 138 Decomposes mangled D namespaces into an array of names. 139 140 The array of namespaces is called a "namespace chain". 141 142 Params: 143 mangled: (inout) a mangled D namespace. 144 145 Return: Returns a namespace chain that is equivalent to the mangled input. 146 */ 147 public char[][] parseNamespaceChain(inout char[] mangled){ 148 char[][] chain; 149 uint ate; 150 uint len; 151 152 while(mangled.length > 0){ 153 ate = 0; 154 len = 0; 155 while(mangled[ate] >= '0' && mangled[ate] <= '9'){ 156 len = (len*10) + (mangled[ate] - '0'); 157 ate++; 158 } 159 if(ate == 0) break; 160 chain ~= mangled[ate..ate+len]; 161 mangled = mangled[ate+len..$]; 162 } 163 return chain; 164 } 165 166 /** 167 Combines a namespace chain into a dot ('.') separated namespace. 168 169 Params: 170 chain: A namespace chain to convert. 171 172 Return: A dot-sepearated version of the original chain. 173 */ 174 public char[] toNamespace(char[][] chain){ 175 char[] result = chain[0]; 176 for(uint i=1; i<chain.length; i++){ 177 result ~= "." ~ chain[i]; 178 } 179 return result; 180 } trunk/ddl/DynamicLibrary.d
r260 r271 186 186 } 187 187 } 188 188 189 189 template getCtor(TInterface, char [] classname, P1) { 190 190 TInterface function(P1) getCtor() { … … 224 224 } 225 225 } 226 226 /** 227 Gets all classes from this library, that are subclasses of a common base class. 228 229 This method exhaustively searches all symbols within the library for defined 230 classes, and then returns them as ExportClass instances. 231 232 Params: 233 T = The base interface or class for all the returned classes. 234 235 Returns: An array of ExportClass instances for this library. 236 */ 227 237 ExportClass!(T)[] getSubclasses(T)() { 228 238 ExportClass!(T)[] res; … … 247 257 } 248 258 249 259 /** 260 Get a ExportClass instance from the library that matches a given class name. 261 262 Params: 263 TInterface = Interface used to build an ExportClass instance. 264 classname = Name of the class to fetch. 265 266 Returns: A ExportClass instance composed from the supplied interface type, that 267 references 'classname' within this library. 268 269 Examples: 270 --- 271 // get class Foobar, which is a subclass of IFoo 272 ExportClass!(IFoo) klass = library.getClass!(IFoo,"Foobar"); 273 --- 274 */ 250 275 ExportClass!(Tinterface) getClass(Tinterface, char[] classname)() { 251 276 return new ExportClass!(Tinterface)( trunk/ddl/ExportClass.d
r260 r271 32 32 import std.regexp : RegExp; 33 33 34 /** 35 Dynamic class loading utility. 36 37 ExportClass provided dynamic class-loading support, as a blended compile-time, run-time 38 solution. 39 */ 34 40 class ExportClass(T) { 35 41 alias T baseType; trunk/ddl/ExportSymbol.d
r218 r271 30 30 module ddl.ExportSymbol; 31 31 32 /* 33 Determines the resolution status of the symbol 34 **/ 32 35 enum SymbolType: ubyte{ 33 Weak, // may or may not be defined, and cannot be not relied upon for linking34 Strong, // defined, can be linked against35 Extern // undefined, needs a strong reference36 Unresolved, // undefined 37 Weak, // defined but can be overriden by another defintion during a linker pass 38 Strong, // defined and can be linked against 36 39 } 37 40 … … 41 44 struct ExportSymbol{ 42 45 /** 46 Determines if the symbol is external to it's containing module. 47 48 Local symbols are defined within the memory space controlled by the symbol's module. If 49 a symbol is not local, it considered to be External, meaning that this symbol is merely 50 a reference to another symbol. 51 */ 52 public bool isExternal; 53 54 /** 43 55 The type of the symbol. 44 */ 45 56 */ 46 57 public SymbolType type; 47 58 /** … … 71 82 **/ 72 83 bool isResolved(){ 73 return type == SymbolType. Weak || SymbolType.Extern;84 return type == SymbolType.Strong; 74 85 } 75 86 … … 87 98 case SymbolType.Strong: return "strong"; 88 99 case SymbolType.Weak: return "weak"; 89 case SymbolType. Extern: return "extern";100 case SymbolType.Unresolved: return "unresolved"; 90 101 default: 91 102 } trunk/ddl/FileBuffer.d
r181 r271 75 75 return IBuffer.Mixed; 76 76 } 77 78 public void close(){ 79 this.flush(); 80 this.getConduit().close(); 81 } 77 82 } trunk/ddl/Linker.d
r261 r271 1 1 /+ 2 Copyright (c) 2005-2006 Eric Anderton 2 Copyright (c) 2005-2006 Eric Anderton, Tomasz Stachowiak 3 3 4 4 Permission is hereby granted, free of charge, to any person … … 26 26 Authors: Eric Anderton 27 27 License: BSD Derivative (see source for details) 28 Copyright: 2005 Eric Anderton28 Copyright: 2005,2006 Eric Anderton 29 29 */ 30 30 module ddl.Linker; … … 90 90 down the list. 91 91 */ 92 protected DynamicLibrary[ ] libraries;92 protected DynamicLibrary[DynamicLibrary] libraries; 93 93 94 94 /** … … 140 140 debug debugLog("-done."); 141 141 } 142 debug debugLog("running ctor [%0.8X]",cast(void*)m.ctor); 142 143 if (m.ctor) 143 144 (*m.ctor)(); 145 debug debugLog("done running ctor"); 144 146 m.flags &= ~MIctorstart; 145 147 m.flags |= MIctordone; … … 159 161 } 160 162 161 alias ModuleInfo[ DynamicModule] ModuleSet;163 alias ModuleInfo[char[]] ModuleSet; 162 164 163 165 /** … … 172 174 moduleSet a set of modules that need initalization following the link pass. 173 175 */ 174 public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve =false){176 public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve){ 175 177 uint i; 176 178 … … 187 189 auto symbol = &(moduleSymbols[i]); 188 190 191 // ensure we're only linking weak and unresolved symbols 189 192 if(symbol.type == SymbolType.Strong) continue; 193 190 194 // resolve a dependency from out of the registry 191 195 debug debugLog("searching %d registered libs",this.libraries.length); … … 198 202 auto otherSymbol = libMod.getSymbol(symbol.name); 199 203 if(otherSymbol.type == SymbolType.Strong){ 200 debug debugLog("[Linker] found %s at %0.8X",otherSymbol.name,otherSymbol.address); 204 debug debugLog("[Linker] found %s at %0.8X",otherSymbol.name,otherSymbol.address); 201 205 symbol.address = otherSymbol.address; 202 206 symbol.type = SymbolType.Strong; 207 symbol.isExternal = true; // set extern status for externally resolved weak symbols 203 208 goto nextSymbol; 204 209 } … … 206 211 } 207 212 } 208 // throw if we aboslutely *must* have this symbol resolved on this pass209 if(symbol.type == SymbolType. Extern || !canSelfResolve){210 throw new DDLException("cannot resolve symbol '%s'",symbol.name);213 // attempt to self-resolve where needed 214 if(symbol.type == SymbolType.Weak && canSelfResolve){ 215 symbol.type = SymbolType.Strong; 211 216 } 217 else if(symbol.type != SymbolType.Strong){ 218 char[] ext = symbol.isExternal ? "external" : "local"; 219 char[] self = canSelfResolve ? "can Self Resolve" : "cannot Self Resolve"; 220 throw new DDLException("cannot resolve symbol: (%s) [%0.8X] %s %s %s\n",self,cast(uint)symbol.address,symbol.getTypeName(),ext,symbol.name); 221 } 222 212 223 nextSymbol: 213 224 {} // satisfy compiler 214 }215 216 if(canSelfResolve){217 for(i=0; i<moduleSymbols.length; i++){218 auto symbol = &(moduleSymbols[i]);219 if(symbol.type == SymbolType.Weak) symbol.type = SymbolType.Strong;220 }221 225 } 222 226 … … 229 233 230 234 debug debugLog("mod is resolved: %s",mod.toString()); 231 232 // dig up the ModuleInfo (if applicable) and store it for later use.233 if(!(mod in moduleSet)){234 debug debugLog("looking for: %s","__ModuleInfo_" ~ mod.getRawNamespace);235 auto sym = mod.getSymbol("__ModuleInfo_" ~ mod.getRawNamespace);236 if (sym.address != null){237 debug debugLog("Found moduleinfo for %s at [%0.8X] %s",mod.getName space,sym.address,sym.name);238 moduleSet[ mod] = cast(ModuleInfo)(sym.address);235 236 auto allSymbols = mod.getSymbols(); 237 foreach (symbol; allSymbols) { 238 // symbol must be defined and be local only 239 if (symbol.address is null || symbol.isExternal) continue; 240 if (symbol.name.length > `__ModuleInfo_`.length && symbol.name[0 .. `__ModuleInfo_`.length] == `__ModuleInfo_`) { 241 debug debugLog("Found moduleinfo for %s at [%0.8X] %s",mod.getName,symbol.address,symbol.name); 242 moduleSet[symbol.name] = cast(ModuleInfo)(symbol.address); 239 243 } 240 244 } … … 250 254 proceeding with the actual link. 251 255 256 Weak symbol resolution, mostly D templates, will not ocurr for the library passed 257 in, unless it is already registered. The reason behind this restriction is to 258 ensure that all libraries that are linked by a given linker, reference the same 259 set of common weak symbols. 260 252 261 Examples: 253 262 --- … … 261 270 public void link(DynamicLibrary lib){ 262 271 ModuleSet moduleSet; 263 Exception exception = null; 272 273 // determine registration status 274 bool canSelfResolve = this.isRegistered(lib); 264 275 265 276 // link 266 try{ 267 foreach(DynamicModule mod; lib.getModules){ 268 this.link(mod,moduleSet); 269 } 270 } 271 catch(Exception e){ 272 exception = e; // re-throw in a minute... 273 } 274 275 // init (run whatever initalizers are pending, regardless of failure) 276 foreach(mod,moduleInfo; moduleSet){ 277 debug debugLog("running %s init at [%0.8X]",mod.getName,cast(void*)moduleInfo); 278 this.initModule(moduleInfo,0); 279 } 280 281 //re-throw if need be 282 if(exception) throw exception; 277 foreach(DynamicModule mod; lib.getModules){ 278 this.link(mod,moduleSet,canSelfResolve); 279 } 280 281 // init - run whatever initalizers are pending 282 // foreach(mod,moduleInfo; moduleSet){ 283 //debug debugLog("running %s init at [%0.8X]",mod,cast(void*)moduleInfo); 284 // this.initModule(moduleInfo,0); 285 // } 286 _moduleCtor2(moduleSet.values,0); 283 287 } 284 288 … … 308 312 debugLog("[Linker.register]: %s",mod.getName); 309 313 } 310 libraries ~= lib;314 libraries[lib] = lib; 311 315 } 312 316 … … 350 354 register(result); 351 355 return result; 352 } 356 } 357 358 /** 359 Returns true if the library provided is registered with this linker. 360 */ 361 public bool isRegistered(DynamicLibrary lib){ 362 return !!(lib in this.libraries); 363 } 353 364 } trunk/ddl/ar/ArchiveLibrary.d
r220 r271 223 223 if(exp.name in crossReference){ 224 224 switch(exp.type){ 225 case SymbolType.Weak: // replace externonly226 if(dictionary[exp.name].type == SymbolType. Extern){225 case SymbolType.Weak: // replace unresolved only 226 if(dictionary[exp.name].type == SymbolType.Unresolved){ 227 227 crossReference[exp.name] = mod; 228 228 dictionary[exp.name] = exp; … … 243 243 } 244 244 } 245 246 public char[] toString(){ 247 char[] result; 248 249 foreach(mod; modules){ 250 result ~= mod.toString(); 251 } 252 return result; 253 } 245 254 246 255 /** trunk/ddl/elf/ELFBinary.d
r220 r271 50 50 class ELFBinary{ 51 51 public: 52 Elf32_Ehdr elfhdr;52 Elf32_Ehdr* elfhdr; 53 53 Elf32_Shdr[] sechdrs; 54 54 Elf32_Phdr[] proghdrs; 55 Elf32_Sym[] globalSymbols; 56 Elf32_Sym[] localSymbols; 57 Elf32_Sym[] weakSymbols; 58 59 Elf32_Sym[] symbols; 60 61 ExportSymbol[char[]] exports; 62 ExportSymbol[] unresolvedSymbols; 63 55 Elf32_Sym[char[]] globalSymbols; 56 Elf32_Sym[char[]] localSymbols; 57 Elf32_Sym[char[]] weakSymbols; 58 64 59 char[] shnames; 65 60 char[] dynsymnames; 66 61 char[] symtabnames; 67 62 68 bit dynamic; 69 70 Attributes attributes; 63 bool dynamic; 64 65 void* bitslab; 66 uint slabsize; 71 67 72 68 /** … … 75 71 this(){ 76 72 } 77 73 74 75 // shim to help with array generation 76 private T[] ptrArray(T)(uint offset,uint len){ 77 return (cast(T*)(this.bitslab + offset))[0..len]; 78 } 79 78 80 /** 79 81 Loads an ELF object file from the provided reader. … … 83 85 */ 84 86 void parse(ELFReader reader){ 87 void[] data; 88 reader.getAll(data); 89 this.slabsize = data.length; 90 this.bitslab = data.ptr; 91 85 92 // Read ELF Header 86 reader.get(elfhdr);93 elfhdr = cast(Elf32_Ehdr*)bitslab; 87 94 88 95 // Checking sanity of ELF magic string … … 132 139 } 133 140 134 if ((proghdrs.length = elfhdr.e_phnum) > 0) {135 // Move ahead to program header table136 reader.setPosition(elfhdr.e_phoff);137 138 debug debugLog("program headers: %d",proghdrs.length);139 140 // Read program headers141 for (int i = 0; i < proghdrs.length; i++) {142 Elf32_Phdr ephdr;143 reader.get(ephdr);144 proghdrs[i] = ephdr;145 }146 }147 148 //TODO: should this ignore the e_shentsize when reading sections?149 if ((sechdrs.length = elfhdr.e_shnum) > 0) {150 // Move ahead to section header table151 reader.setPosition(elfhdr.e_shoff);152 153 debug debugLog("section headers: %d",sechdrs.length);154 155 // Read section headers156 for (int i = 0; i < sechdrs.length; i++) {157 Elf32_Shdr eshdr;158 reader.get(eshdr);159 sechdrs[i] = eshdr;160 }161 }162 141 142 this.proghdrs = ptrArray!(Elf32_Phdr)(elfhdr.e_phoff,elfhdr.e_phnum); 143 this.sechdrs = ptrArray!(Elf32_Shdr)(elfhdr.e_shoff,elfhdr.e_shnum); 144 /* 163 145 debug{ 164 146 debugLog("type: %d",elfhdr.e_type); … … 167 149 debugLog("section header size: %d",elfhdr.e_shentsize); 168 150 } 151 */ 169 152 170 153 // section header index for symbol table … … 172 155 173 156 // Load section names 174 reader.setPosition(sechdrs[elfhdr.e_shstrndx].sh_offset); 175 reader.get(shnames,sechdrs[elfhdr.e_shstrndx].sh_size); 157 this.shnames = ptrArray!(char)(sechdrs[elfhdr.e_shstrndx].sh_offset,sechdrs[elfhdr.e_shstrndx].sh_size); 176 158 177 // parse sections 178 for(int i = 0; i < sechdrs.length; i++) { 179 Elf32_Shdr thisSection = sechdrs[i]; 180 159 foreach(thisSection; this.sechdrs){ 181 160 switch(thisSection.sh_type){ 182 161 case SHT_NULL: 183 162 /*This value marks the section header as inactive; it does not have an associated section. 184 163 Other members of the section header have undefined values */ 164 debug debugLog("SHT_NULL"); 185 165 break; 186 166 … … 188 168 /*The section holds information defined by the program, whose format and meaning are 189 169 determined solely by the program.*/ 190 break; 170 debug debugLog("SHT_PROGBITS"); 171 break; 172 173 case SHT_DYNSYM: 174 /* symbol table - dynamic linking only */ 175 debug debugLog("SHT_DYNSYM"); 176 // fallthrough 191 177 192 178 case SHT_SYMTAB: 193 /* symbol table */ 179 /* symbol table - static symbols */ 180 debug debugLog("SHT_SYMTAB"); 194 181 // get associated string table 195 182 Elf32_Shdr stringSection = sechdrs[thisSection.sh_link]; 196 char[] stringTable; 197 198 reader.setPosition(stringSection.sh_offset); 199 reader.get(stringTable,stringSection.sh_size); 200 201 char[][uint] symbolNames = crackStringTable(stringTable); 202 203 // read in the symbols 204 reader.setPosition(thisSection.sh_offset); 205 parseSYMTAB(thisSection.sh_info, symbolNames, reader); 183 char* stringTable = cast(char*)(bitslab + stringSection.sh_offset); 184 185 Elf32_Sym[] symbols = ptrArray!(Elf32_Sym)(thisSection.sh_offset,thisSection.sh_info); 186 187 debug{ 188 foreach(sym; symbols){ 189 debugLog("sym: %d %s %s %s",sym.st_name,toDString(&stringTable[sym.st_name]),sym.getTypeName,sym.getBindName); 190 } 191 } 206 192 break; 207 193 208 194 case SHT_STRTAB: 209 195 /*The section holds a string table. An object file may have multiple string table sections. */ 196 debug debugLog("SHT_STRTAB"); 210 197 break; 211 198 … … 213 200 /*The section holds relocation entries with explicit addends, such as type Elf32_Rela 214 201 for the 32-bit class of object files. An object file may have multiple relocation sections.*/ 215 break; 216 217 case SHT_HASH: break; 218 case SHT_DYNAMIC: break; 202 debug debugLog("SHT_RELA"); 203 204 Elf32_Rela[] relaSet = ptrArray!(Elf32_Rela)(thisSection.sh_offset,thisSection.sh_info); 205 206 debug{ 207 foreach(rela; relaSet){ 208 } 209 } 210 211 break; 212 213 case SHT_HASH: 214 /*The section holds a symbol hash table. All objects participating in dynamic linking 215 must contain a symbol hash table. Currently, an object file may have only one hash 216 table, but this restriction may be relaxed in the future. See 'Hash Table' in Part 2 for 217 details.*/ 218 debug debugLog("SHT_HASH"); 219 break; 220 221 case SHT_DYNAMIC: 222 /*The section holds information for dynamic linking. Currently, an object file may have 223 only one dynamic section, but this restriction may be relaxed in the future. See 224 'Dynamic Section' in Part 2 for details.*/ 225 debug debugLog("SHT_DYNAMIC"); 226
