Changeset 271

Show
Ignore:
Timestamp:
11/05/06 10:14:56 (2 years ago)
Author:
pragma
Message:

--

Files:

Legend:

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

    r175 r271  
    3232module ddl.Attributes; 
    3333 
     34/** 
     35    Map designed to hold DynamicModule attributes.  The keys and values stored 
     36    in the map are ASCII/UTF-8 data. 
     37*/ 
    3438alias char[][char[]] Attributes; 
    3539 
    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*/ 
     47Attributes copyInto(Attributes from,inout Attributes to){ 
    3748    if(from == Attributes.init) return from; 
    3849    foreach(char[] key,char[] value; from){ 
  • trunk/ddl/DDLException.d

    r158 r271  
    3939*/ 
    4040class 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    */ 
    4149    public this(char[] fmt,TypeInfo[] arguments,void* argptr){ 
    4250        ExtSprintClass sprint = new ExtSprintClass(fmt.length + 1024); 
     
    4452    } 
    4553     
     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    */ 
    4663    public this(char[] fmt,...){ 
    4764        ExtSprintClass sprint = new ExtSprintClass(fmt.length + 1024); 
     
    4966    } 
    5067     
     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    */ 
    5184    public static char[] boilerplate(char[] message){ 
    5285        return( 
    5386            "[Exception] You have run into a condition not handled, or possibly incorrectly handled, by DDL.\n" ~ 
    5487            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. -" 
    5689        ); 
    5790    } 
  • trunk/ddl/DDLReader.d

    r261 r271  
    4141debug private import mango.io.Stdout; 
    4242 
     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*/ 
    4355public 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    */ 
    4462    public this(void[] data){ 
    4563        super(new Buffer(data,data.length)); 
    4664    } 
    4765     
     66    /** 
     67        IBuffer style constructor. 
     68         
     69        Params: 
     70            buffer = buffer to read 
     71    */ 
    4872    public this (IBuffer buffer){ 
    4973        super(buffer); 
    5074    } 
    5175     
     76    /** 
     77        IConduit style constructor. 
     78         
     79        Params: 
     80            conduit = conduit to read 
     81    */ 
    5282    public this (IConduit conduit){ 
    5383        super(conduit); 
    5484    } 
    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    */ 
    5693    public DDLReader peek(inout ubyte x){ 
    5794        x = (cast(ubyte[])buffer.get(1,false))[0]; 
     
    5996    }    
    6097     
     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    */ 
    61106    public DDLReader peek(inout ubyte[] x,uint elements = uint.max){ 
    62107        if(elements == uint.max) 
     
    69114    } 
    70115     
    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    */ 
    72124    DDLReader getAll(inout void[] x) 
    73125    {        
     126        //props to Kris for suggesting this method of getting 100% of the remaining data in a conduit 
    74127        IConduit conduit = getBuffer.getConduit(); 
    75128         
     
    97150    } 
    98151     
     152    /** 
     153        Returns: (true/false) If the conduit has any more data to be read. 
     154    */ 
    99155    bool hasMore(){ 
    100156         
     
    109165    } 
    110166     
    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    */ 
    113181    void seek(ulong offset, ISeekable.SeekAnchor anchor=ISeekable.SeekAnchor.Begin){ 
    114182        IConduit conduit = getBuffer.getConduit(); 
     
    145213    } 
    146214     
    147     // get the position relative to the current buffer position and status 
     215    /** 
     216        Returns: The position relative to the current buffer position. 
     217    */ 
    148218    ulong getPosition(){ 
    149219        IConduit conduit = getBuffer.getConduit(); 
     
    159229     
    160230    // 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 support 
    173231    debug override protected uint read (void *dst, uint bytes, uint type){   
    174232        try{ 
  • trunk/ddl/DDLWriter.d

    r179 r271  
    3636private import mango.io.model.IConduit; 
    3737 
     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*/ 
    3844public class DDLWriter : Writer{ 
     45    /** 
     46        IBuffer style constructor. 
     47         
     48        Params: 
     49            buffer = buffer to read 
     50    */ 
    3951    public this (IBuffer buffer){ 
    4052        super(buffer); 
    4153    } 
    4254     
     55    /** 
     56        IConduit style constructor. 
     57         
     58        Params: 
     59            conduit = conduit to read 
     60    */   
    4361    public this (IConduit conduit){ 
    4462        super(conduit); 
    4563    } 
    4664     
    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    */ 
    4980    void seek(ulong offset, ISeekable.SeekAnchor anchor=ISeekable.SeekAnchor.Begin){ 
    5081        IConduit conduit = getBuffer.getConduit(); 
     
    83114    } 
    84115     
    85     // get the position relative to the current buffer position and status 
     116    /** 
     117        Returns: The position relative to the current buffer position. 
     118    */ 
    86119    ulong getPosition(){ 
    87120        IConduit conduit = getBuffer.getConduit(); 
  • trunk/ddl/DefaultRegistry.d

    r254 r271  
    4141//private import ddl.coff.COFFLoader; 
    4242 
     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*/ 
    4351class DefaultRegistry : LoaderRegistry{ 
     52    /** 
     53        Default constructor. 
     54    */ 
    4455    public this(){ 
    4556        version(Windows){ // order optimized per OS 
     
    5162            register(new ArchiveLoader());           
    5263    //      register(new COFFObjLoader());           
    53     //        register(new ELFObjLoader());            
     64          register(new ELFObjLoader());            
    5465        } 
    5566        else{ 
  • trunk/ddl/Demangle.d

    r218 r271  
    4545enum DemangleType{ 
    4646    PublicSymbol, 
     47    PublicDSymbol, 
    4748    ClassDefinition, 
    4849    Initalizer, 
     
    128129    }        
    129130    else if(symbol.startsWith("_D")){ 
    130         return DemangleType.PublicSymbol; 
     131        return DemangleType.PublicDSymbol; 
    131132    } 
    132133    // no particular type, default the symbol to a 'public' 
    133134    return DemangleType.PublicSymbol; 
    134135} 
     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*/ 
     147public 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*/ 
     174public 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  
    186186       } 
    187187    } 
    188      
     188 
    189189    template getCtor(TInterface, char [] classname, P1) { 
    190190        TInterface function(P1) getCtor() { 
     
    224224       } 
    225225    } 
    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    */ 
    227237    ExportClass!(T)[] getSubclasses(T)() { 
    228238      ExportClass!(T)[] res; 
     
    247257    } 
    248258     
    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    */ 
    250275    ExportClass!(Tinterface) getClass(Tinterface, char[] classname)() { 
    251276      return new ExportClass!(Tinterface)( 
  • trunk/ddl/ExportClass.d

    r260 r271  
    3232import std.regexp : RegExp; 
    3333 
     34/** 
     35    Dynamic class loading utility. 
     36     
     37    ExportClass provided dynamic class-loading support, as a blended compile-time, run-time 
     38    solution.   
     39*/ 
    3440class ExportClass(T) { 
    3541   alias T           baseType; 
  • trunk/ddl/ExportSymbol.d

    r218 r271  
    3030module ddl.ExportSymbol; 
    3131 
     32/* 
     33    Determines the resolution status of the symbol 
     34**/ 
    3235enum SymbolType: ubyte{ 
    33     Weak, // may or may not be defined, and cannot be not relied upon for linking 
    34     Strong, // defined, can be linked against 
    35     Extern // undefined, needs a strong reference 
     36    Unresolved, // undefined 
     37    Weak, // defined but can be overriden by another defintion during a linker pass 
     38    Strong, // defined and can be linked against 
    3639} 
    3740 
     
    4144struct ExportSymbol{ 
    4245    /** 
     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    /** 
    4355        The type of the symbol. 
    44     */ 
    45      
     56    */   
    4657    public SymbolType type; 
    4758    /**  
     
    7182    **/ 
    7283    bool isResolved(){ 
    73         return type == SymbolType.Weak || SymbolType.Extern
     84        return type == SymbolType.Strong
    7485    } 
    7586 
     
    8798        case SymbolType.Strong: return "strong"; 
    8899        case SymbolType.Weak: return "weak"; 
    89         case SymbolType.Extern: return "extern"; 
     100        case SymbolType.Unresolved: return "unresolved"; 
    90101        default: 
    91102        } 
  • trunk/ddl/FileBuffer.d

    r181 r271  
    7575        return IBuffer.Mixed; 
    7676    } 
     77     
     78    public void close(){ 
     79        this.flush(); 
     80        this.getConduit().close(); 
     81    } 
    7782} 
  • trunk/ddl/Linker.d

    r261 r271  
    11/+ 
    2     Copyright (c) 2005-2006 Eric Anderton 
     2    Copyright (c) 2005-2006 Eric Anderton, Tomasz Stachowiak 
    33         
    44    Permission is hereby granted, free of charge, to any person 
     
    2626    Authors: Eric Anderton 
    2727    License: BSD Derivative (see source for details) 
    28     Copyright: 2005 Eric Anderton 
     28    Copyright: 2005,2006 Eric Anderton 
    2929*/ 
    3030module ddl.Linker; 
     
    9090        down the list. 
    9191    */ 
    92     protected DynamicLibrary[] libraries; 
     92    protected DynamicLibrary[DynamicLibrary] libraries; 
    9393     
    9494    /**  
     
    140140                debug debugLog("-done."); 
    141141            } 
     142            debug debugLog("running ctor [%0.8X]",cast(void*)m.ctor); 
    142143            if (m.ctor) 
    143144            (*m.ctor)(); 
     145            debug debugLog("done running ctor"); 
    144146            m.flags &= ~MIctorstart; 
    145147            m.flags |= MIctordone; 
     
    159161    } 
    160162     
    161     alias ModuleInfo[DynamicModule] ModuleSet;     
     163    alias ModuleInfo[char[]] ModuleSet;    
    162164         
    163165    /** 
     
    172174        moduleSet a set of modules that need initalization following the link pass. 
    173175    */ 
    174     public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve=false){ 
     176    public void link(DynamicModule mod, inout ModuleSet moduleSet, bool canSelfResolve){ 
    175177        uint i; 
    176178         
     
    187189            auto symbol = &(moduleSymbols[i]); 
    188190             
     191            // ensure we're only linking weak and unresolved symbols 
    189192            if(symbol.type == SymbolType.Strong) continue; 
     193             
    190194            // resolve a dependency from out of the registry 
    191195            debug debugLog("searching %d registered libs",this.libraries.length); 
     
    198202                    auto otherSymbol = libMod.getSymbol(symbol.name); 
    199203                    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); 
    201205                        symbol.address = otherSymbol.address; 
    202206                        symbol.type = SymbolType.Strong; 
     207                        symbol.isExternal = true; // set extern status for externally resolved weak symbols 
    203208                        goto nextSymbol; 
    204209                    } 
     
    206211                } 
    207212            } 
    208             // throw if we aboslutely *must* have this symbol resolved on this pass 
    209             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
    211216            } 
     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             
    212223            nextSymbol: 
    213224            {} // 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             } 
    221225        } 
    222226                 
     
    229233         
    230234        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.getNamespace,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); 
    239243            } 
    240244        } 
     
    250254        proceeding with the actual link. 
    251255         
     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                 
    252261        Examples: 
    253262        --- 
     
    261270    public void link(DynamicLibrary lib){ 
    262271        ModuleSet moduleSet; 
    263         Exception exception = null; 
     272         
     273        // determine registration status 
     274        bool canSelfResolve = this.isRegistered(lib); 
    264275         
    265276        // 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); 
    283287    } 
    284288     
     
    308312            debugLog("[Linker.register]: %s",mod.getName); 
    309313        } 
    310         libraries ~= lib; 
     314        libraries[lib] = lib; 
    311315    } 
    312316         
     
    350354        register(result); 
    351355        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    } 
    353364} 
  • trunk/ddl/ar/ArchiveLibrary.d

    r220 r271  
    223223            if(exp.name in crossReference){ 
    224224                switch(exp.type){ 
    225                 case SymbolType.Weak: // replace extern only 
    226                     if(dictionary[exp.name].type == SymbolType.Extern){ 
     225                case SymbolType.Weak: // replace unresolved only 
     226                    if(dictionary[exp.name].type == SymbolType.Unresolved){ 
    227227                        crossReference[exp.name] = mod; 
    228228                        dictionary[exp.name] = exp; 
     
    243243        } 
    244244    } 
     245         
     246    public char[] toString(){ 
     247        char[] result; 
     248         
     249        foreach(mod; modules){ 
     250            result ~= mod.toString(); 
     251        } 
     252        return result; 
     253    } 
    245254     
    246255    /** 
  • trunk/ddl/elf/ELFBinary.d

    r220 r271  
    5050class ELFBinary{ 
    5151public: 
    52     Elf32_Ehdr elfhdr; 
     52    Elf32_Ehdr* elfhdr; 
    5353    Elf32_Shdr[] sechdrs; 
    5454    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             
    6459    char[] shnames; 
    6560    char[] dynsymnames; 
    6661    char[] symtabnames; 
    6762     
    68     bit dynamic; 
    69      
    70     Attributes attributes; 
     63    bool dynamic; 
     64     
     65    void* bitslab; 
     66    uint slabsize; 
    7167     
    7268    /** 
     
    7571    this(){ 
    7672    } 
    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     
    7880    /** 
    7981        Loads an ELF object file from the provided reader. 
     
    8385    */ 
    8486    void parse(ELFReader reader){ 
     87        void[] data; 
     88        reader.getAll(data); 
     89        this.slabsize = data.length; 
     90        this.bitslab = data.ptr; 
     91         
    8592        // Read ELF Header 
    86         reader.get(elfhdr)
     93        elfhdr = cast(Elf32_Ehdr*)bitslab
    8794 
    8895        // Checking sanity of ELF magic string 
     
    132139        } 
    133140 
    134         if ((proghdrs.length = elfhdr.e_phnum) > 0) { 
    135             // Move ahead to program header table 
    136             reader.setPosition(elfhdr.e_phoff); 
    137             
    138             debug debugLog("program headers: %d",proghdrs.length); 
    139             
    140             // Read program headers 
    141             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 table 
    151             reader.setPosition(elfhdr.e_shoff); 
    152              
    153             debug debugLog("section headers: %d",sechdrs.length); 
    154              
    155             // Read section headers 
    156             for (int i = 0; i < sechdrs.length; i++) { 
    157                 Elf32_Shdr eshdr; 
    158                 reader.get(eshdr); 
    159                 sechdrs[i] = eshdr; 
    160             } 
    161         } 
    162141         
     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        /* 
    163145        debug{ 
    164146            debugLog("type: %d",elfhdr.e_type); 
     
    167149            debugLog("section header size: %d",elfhdr.e_shentsize); 
    168150        } 
     151        */ 
    169152     
    170153        // section header index for symbol table 
     
    172155 
    173156        // 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); 
    176158         
    177         // parse sections 
    178         for(int i = 0; i < sechdrs.length; i++) { 
    179             Elf32_Shdr thisSection = sechdrs[i]; 
    180                          
     159        foreach(thisSection; this.sechdrs){              
    181160            switch(thisSection.sh_type){ 
    182161            case SHT_NULL:  
    183162            /*This value marks the section header as inactive; it does not have an associated section. 
    184163            Other members of the section header have undefined values */ 
     164            debug debugLog("SHT_NULL"); 
    185165                break; 
    186166                 
     
    188168            /*The section holds information defined by the program, whose format and meaning are 
    189169            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 
    191177                 
    192178            case SHT_SYMTAB: 
    193             /* symbol table */ 
     179            /* symbol table - static symbols */ 
     180            debug debugLog("SHT_SYMTAB"); 
    194181                // get associated string table 
    195182                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                } 
    206192                break; 
    207193                 
    208194            case SHT_STRTAB:  
    209195            /*The section holds a string table. An object file may have multiple string table sections. */ 
     196            debug debugLog("SHT_STRTAB"); 
    210197                break; 
    211198                 
     
    213200            /*The section holds relocation entries with explicit addends, such as type Elf32_Rela 
    214201            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