emitElfStatic.h

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #if !defined(_emit_Elf_Static_h_)
00032 #define _emit_Elf_Static_h
00033 
00034 #include "Symtab.h"
00035 #include "Archive.h"
00036 #include "Region.h"
00037 #include "Symbol.h"
00038 #include "LinkMap.h"
00039 #include "Object.h"
00040 
00041 #include <deque>
00042 #include <map>
00043 #include <vector>
00044 #include <set>
00045 using namespace std;
00046 
00047 #include "boost/tuple/tuple.hpp"
00048 
00049 namespace Dyninst{
00050 namespace SymtabAPI{
00051 
00052 /*
00053  * XXX
00054  *
00055  * This class is unnecessary. However, at the time of writing, emitElf was
00056  * split into two different classes (one for 32-bit and 64-bit). Instead of
00057  * duplicating code, this class was created to share code between the
00058  * two emitElf classes.
00059  *
00060  * Once the emitElf classes are merged, this class can be merged with the new
00061  * emitElf class.
00062  *
00063  * See the implementation for descriptions of functions.
00064  */
00065 
00066 extern const std::string SYMTAB_CTOR_LIST_REL;
00067 extern const std::string SYMTAB_DTOR_LIST_REL;
00068 extern const std::string SYMTAB_IREL_START;
00069 extern const std::string SYMTAB_IREL_END;
00070 
00071 
00072 /*
00073  * The above "not necessary" comment applies to this class as well.
00074  * These routines should be in a private namespace inside a unified
00075  * emit class file or something.
00076  */
00077 class emitElfUtils {
00078  public:
00079     static Address orderLoadableSections(
00080         Symtab *obj, vector<Region*> & sections);
00081     static bool sort_reg(const Region*a, const Region*b);
00082     static bool updateHeapVariables(Symtab *obj, unsigned long loadSecsSize);
00083     static bool updateRelocation(Symtab *obj, relocationEntry &rel, int library_adjust);
00084 };
00085 
00086 class emitElfStatic {
00087     public:
00088 
00089     emitElfStatic(unsigned addressWidth, bool isStripped);
00090 
00091     enum StaticLinkError {
00092         No_Static_Link_Error,
00093         Link_Location_Error,
00094         Symbol_Resolution_Failure,
00095         Relocation_Computation_Failure,
00096         Storage_Allocation_Failure
00097     };
00098 
00099     static std::string printStaticLinkError(StaticLinkError);
00100 
00101     // Entry point for static linking
00102     char *linkStatic(Symtab *target, 
00103                      StaticLinkError &err, 
00104                      string &errMsg);
00105 
00106     bool resolveSymbols(Symtab *target, 
00107                         vector<Symtab *> &relocatableObjects, 
00108                         LinkMap &lmap,
00109                         StaticLinkError &err, 
00110                         string &errMsg);
00111 
00112     bool createLinkMap(Symtab *target,
00113                        vector<Symtab *> &relocatableObjects,
00114                        Offset& globalOffset,
00115                        LinkMap &lmap,
00116                        StaticLinkError &err, 
00117                        string &errMsg);
00118 
00119     Offset layoutRegions(deque<Region *> &regions, 
00120                            map<Region *, LinkMap::AllocPair> &regionAllocs,
00121                            Offset currentOffset, 
00122                            Offset globalOffset);
00123 
00124     Offset allocStubRegions(LinkMap &lmap, Offset globalOffset);
00125 
00126     bool addNewRegions(Symtab *target,
00127                        Offset globalOffset,
00128                        LinkMap &lmap);
00129     
00130     void copyRegions(LinkMap &lmap); 
00131 
00132     bool applyRelocations(Symtab *target,
00133                           vector<Symtab *> &relocatableObjects,
00134                           Offset globalOffset,
00135                           LinkMap &lmap,
00136                           StaticLinkError &err, 
00137                           string &errMsg);
00138     bool buildPLT(Symtab *target,
00139           Offset globalOffset,
00140           LinkMap &lmap,
00141           StaticLinkError &err,
00142           string &errMsg);
00143 
00144     bool buildRela(Symtab *target,
00145           Offset globalOffset,
00146           LinkMap &lmap,
00147           StaticLinkError &err,
00148           string &errMsg);         
00149 
00150     bool hasRewrittenTLS() const;
00151 
00152     private:
00153 
00154     Offset computePadding(Offset candidateOffset, Offset alignment);
00155 
00156     /**
00157      * Architecture specific
00158      *
00159      * Given the Region type of a combined Region, gets the padding value to
00160      * use in between Regions that make up the combined Region.
00161      *
00162      * rtype    The Region type for the combined Region
00163      *
00164      * Returns the padding character
00165      */
00166     char getPaddingValue(Region::RegionType rtype);
00167 
00168     /**
00169      * Architecture specific
00170      *
00171      * Calculates a relocation and applies it to the specified location in the
00172      * target.
00173      *
00174      * targetData       The target buffer
00175      * rel              The relocation entry
00176      * dest             The offset in the target buffer
00177      * relOffset        The absolute offset of the relocation
00178      * globalOffset     The absolute offset of the newly linked code
00179      * lmap             Holds information necessary to compute relocation
00180      *
00181      * Returns true, on success; false, otherwise and sets errMsg
00182      */
00183     bool archSpecificRelocation(Symtab *targetSymtab,
00184                     Symtab *srcSymtab,
00185                 char *targetData, 
00186                                 relocationEntry &rel, 
00187                                 Offset dest, 
00188                                 Offset relOffset,
00189                                 Offset globalOffset,
00190                                 LinkMap &lmap,
00191                                 string &errMsg);
00192 
00193     // PPC64 TOC-changing inter-module calls
00194     bool handleInterModuleSpecialCase(Symtab *target,
00195                       Symtab *src,
00196                       LinkMap &lmap,
00197                       char *data,
00198                       relocationEntry rel,
00199                       Offset newTOC,
00200                       Offset oldTOC,
00201                       Offset dest,
00202                       Offset relOffset,
00203                       Offset globalOffset);
00204     Offset findOrCreateStub(Symbol *sym, LinkMap &lmap, Offset newTOC, Offset oldTOC, char *data, Offset global);
00205     void createStub(unsigned *stub, Offset stubOffset, Offset newTOC, Offset oldTOC, Offset dest);
00206 
00207     // Functions for dealing with special sections (GOT, TLS, CTORS, DTORS, etc) //
00208 
00209     /**
00210      * Architecture specific (similar to layoutRegions)
00211      *
00212      * Creates a new TLS initialization image from the existing TLS Regions in the
00213      * target and any new TLS Regions from the relocatable objects.
00214      *
00215      * globalOffset     The absolute offset of the newly linked code
00216      * dataTLS          The original TLS data Region from the target (can be NULL)
00217      * bssTLS           The original TLS bss Region from the target (can be NULL)
00218      * lmap             Holds information necessary to do layout
00219      *
00220      * Returns the ending Offset of the Region
00221      */
00222     Offset layoutTLSImage(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap);
00223     Offset tlsLayoutVariant1(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap);
00224     Offset tlsLayoutVariant2(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap);
00225 
00226     /**
00227      * Architecture specific
00228      *
00229      * Updates the TLS offset of a Symbol, given the size of the new TLS initialization image.
00230      *
00231      * curOffset        The current offset of the TLS symbol
00232      * tlsSize          The size of the new TLS initialization image
00233      *
00234      * Returns the adjusted offset
00235      */
00236     Offset adjustTLSOffset(Offset curOffset, Offset tlsSize);
00237     Offset tlsAdjustVariant2(Offset curOffset, Offset tlsSize);
00238 
00239     /**
00240      * Architecture specific
00241      *
00242      * In order to simplify the creation of a new TLS initialization image, some cleanup 
00243      * work may be necessary after the new TLS initialization image is created.
00244      *
00245      * regionAllocs     The map of Regions to their place in the newly linked code
00246      * dataTLS          The original TLS data section from the target (can be NULL)
00247      * bssTLS           The original TLS bss section from the target (can be NULL)
00248      */
00249     void cleanupTLSRegionOffsets(map<Region *, LinkMap::AllocPair> &regionAllocs,
00250             Region *dataTLS, Region *bssTLS);
00251     void tlsCleanupVariant1(map<Region *, LinkMap::AllocPair> &regionAllocs,
00252             Region *dataTLS, Region *bssTLS);
00253     void tlsCleanupVariant2(map<Region *, LinkMap::AllocPair> &regionAllocs,
00254             Region *dataTLS, Region *bssTLS);
00255 
00256     /**
00257      * Architecture specific
00258      *
00259      * Determines if the passed relocation type requires the building of a GOT
00260      *
00261      * relType          The relocation type to check
00262      *
00263      * Returns true if the relocation type requires a GOT
00264      */
00265     bool isGOTRelocation(unsigned long relType);
00266 
00267     /**
00268      * Architecture specific
00269      *
00270      * Constructions a new GOT Region from information in the LinkMap
00271      */
00272     void buildGOT(Symtab *target, LinkMap &lmap);
00273 
00274     /**
00275      * Architecture specific
00276      *
00277      * Determines the size of the GOT Region from information in the LinkMap
00278      */
00279     Offset getGOTSize(Symtab *target, LinkMap &lmap, Offset &layoutStart);
00280 
00281     /**
00282      * Architecture specific
00283      *
00284      * Determines the GOT Region alignment from information in the LinkMap
00285      */
00286     Offset getGOTAlign(LinkMap &lmap);
00287 
00288     /**
00289      * Architecture specific
00290      *
00291      * Determines if the passed Region corresponds to a constructor table Region
00292      */
00293     bool isConstructorRegion(Region *reg);
00294 
00295     /**
00296      * Architecture specific
00297      *
00298      * Lays out a new constructor table Region from the existing constructor
00299      * table in the target and any new constructor Regions in the relocatable files
00300      *
00301      * Returns the ending offset of the new Region
00302      */
00303     Offset layoutNewCtorRegion(LinkMap &lmap);
00304 
00305     /**
00306      *
00307      * Creates a new constructor Table Region using information stored in the LinkMap
00308      *
00309      * Returns true on success
00310      */
00311     bool createNewCtorRegion(LinkMap &lmap);
00312 
00313     /**
00314      * Architecture specific
00315      *
00316      * Determines if the passed Region corresponds to a destructor table Region
00317      */
00318     bool isDestructorRegion(Region *reg);
00319     bool isGOTRegion(Region *reg);
00320 
00321     /**
00322      * Architecture specific
00323      *
00324      * Lays out a new destructor table Region from the existing destructor
00325      * table in the target and any new destructor Regions in the relocatable files
00326      *
00327      * Returns the ending offset of the new Region
00328      */
00329     Offset layoutNewDtorRegion(LinkMap &lmap);
00330 
00331     /**
00332      * Architecture specific
00333      *
00334      * Creates a new destructor Table Region using information stored in the LinkMap
00335      *
00336      * Returns true on success
00337      */
00338     bool createNewDtorRegion(LinkMap &lmap);
00339 
00340     /**
00341      * Architecture specific
00342      *
00343      * Gets the symbols that should be excluded when resolving symbols
00344      *
00345      * symNames         This set is populated by the function
00346      */
00347     void getExcludedSymbolNames(std::set<std::string> &symNames);
00348 
00349     /**
00350      * Architecture specific
00351      *
00352      * Checks if the specified symbol satisfies a special case that is
00353      * currently not handled by emitElfStatic.
00354      *
00355      * member           The reloctable object to examine
00356      * checkSym         The symbol to check
00357      *
00358      * Returns false if the symbol satisfies a special case
00359      */
00360     bool checkSpecialCaseSymbols(Symtab *member, Symbol *checkSym);
00361 
00362     /**
00363      * More with the architecture specific
00364      *
00365      * Calculate new TOC values if we care (PPC64)
00366      */
00367     bool calculateTOCs(Symtab *target, deque<Region *> &regions, Offset GOTbase, Offset newGOToffset, Offset globalOffset);
00368 
00369     /**
00370      * Somewhat architecture specific
00371      *
00372      * Allocate PLT entries for each INDIRECT-typed symbol
00373      * Each PLT entry has an arch-specific size
00374      */
00375     Offset allocatePLTEntries(std::map<Symbol *, std::pair<Offset, Offset> > &entries,
00376                   Offset pltOffset, Offset &size);
00377 
00378     /**
00379      * Aaand... architecture specific. 
00380      * Generate a new relocation section that combines relocs
00381      * from any indirect symbols with original relocs
00382      */
00383     Offset allocateRelocationSection(std::map<Symbol *, std::pair<Offset, Offset> > &entries,
00384                      Offset relocOffset, Offset &size,
00385                      Symtab *target);
00386 
00387     Offset allocateRelGOTSection(const std::map<Symbol *, std::pair<Offset, Offset> > &entries,
00388                  Offset relocOffset, Offset &size);
00389 
00390     bool addIndirectSymbol(Symbol *sym, LinkMap &lmap);
00391     
00392     // Update the TOC pointer if necessary (PPC, 64-bit)
00393     bool updateTOC(Symtab *file, LinkMap &lmap, Offset globalOffset);
00394 
00395     unsigned addressWidth_;
00396     bool isStripped_;
00397     bool hasRewrittenTLS_;
00398 
00399     typedef boost::tuple<Offset, Offset, Offset> TOCstub;
00400     std::map<Symbol *, TOCstub> stubMap;
00401     Offset getStubOffset(TOCstub &t) { return boost::get<0>(t); }
00402     Offset getNewTOC(TOCstub &t) { return boost::get<1>(t); }
00403     Offset getOldTOC(TOCstub &t) { return boost::get<2>(t); }
00404 
00405 };
00406 
00407 } // Dyninst
00408 } // SymtabAPI
00409 
00410 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1