/* * See the dyninst/COPYRIGHT file for copyright information. * * We provide the Paradyn Tools (below described as "Paradyn") * on an AS IS basis, and do not warrant its validity or performance. * We reserve the right to update, modify, or discontinue this * software at any time. We shall have no obligation to supply such * updates or modifications or any other form of support to you. * * By your use of Paradyn, you understand and agree that we (or any * other person or entity with proprietary rights in Paradyn) are * under no obligation to provide either maintenance services, * update services, notices of latent defects, or correction of * defects for Paradyn. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _emit_Elf_Static_h_ #define _emit_Elf_Static_h_ #include "Symtab.h" #include "Archive.h" #include "Region.h" #include "Symbol.h" #include "LinkMap.h" #include "Object.h" #include #include #include #include #include #include using namespace std; #include "dyncompat/tuple/tuple.hpp" namespace Dyninst{ namespace SymtabAPI{ /* * XXX * * This class is unnecessary. However, at the time of writing, emitElf was * split into two different classes (one for 32-bit and 64-bit). Instead of * duplicating code, this class was created to share code between the * two emitElf classes. * * Once the emitElf classes are merged, this class can be merged with the new * emitElf class. * * See the implementation for descriptions of functions. */ extern const std::string SYMTAB_CTOR_LIST_REL; extern const std::string SYMTAB_DTOR_LIST_REL; extern const std::string SYMTAB_IREL_START; extern const std::string SYMTAB_IREL_END; /* * The above "not necessary" comment applies to this class as well. * These routines should be in a private namespace inside a unified * emit class file or something. */ class emitElfUtils { public: static Address orderLoadableSections( Symtab *obj, vector & sections); static bool sort_reg(const Region*a, const Region*b); static bool updateHeapVariables(Symtab *obj, unsigned long loadSecsSize); static bool updateRelocation(Symtab *obj, relocationEntry &rel, int library_adjust); }; class emitElfStatic { public: emitElfStatic(unsigned addressWidth, bool isStripped); enum StaticLinkError { No_Static_Link_Error, Link_Location_Error, Symbol_Resolution_Failure, Relocation_Computation_Failure, Storage_Allocation_Failure }; static std::string printStaticLinkError(StaticLinkError); // Entry point for static linking char *linkStatic(Symtab *target, StaticLinkError &err, string &errMsg); bool resolveSymbols(Symtab *target, vector &relocatableObjects, LinkMap &lmap, StaticLinkError &err, string &errMsg); bool createLinkMap(Symtab *target, vector &relocatableObjects, Offset& globalOffset, LinkMap &lmap, StaticLinkError &err, string &errMsg); Offset layoutRegions(deque ®ions, map ®ionAllocs, Offset currentOffset, Offset globalOffset); Offset allocStubRegions(LinkMap &lmap, Offset globalOffset); bool addNewRegions(Symtab *target, Offset globalOffset, LinkMap &lmap); void copyRegions(LinkMap &lmap); bool applyRelocations(Symtab *target, vector &relocatableObjects, Offset globalOffset, LinkMap &lmap, StaticLinkError &err, string &errMsg); bool buildPLT(Symtab *target, Offset globalOffset, LinkMap &lmap, StaticLinkError &err, string &errMsg); bool buildRela(Symtab *target, Offset globalOffset, LinkMap &lmap, StaticLinkError &err, string &errMsg); bool hasRewrittenTLS() const; private: Offset computePadding(Offset candidateOffset, Offset alignment); /** * Architecture specific * * Given the Region type of a combined Region, gets the padding value to * use in between Regions that make up the combined Region. * * rtype The Region type for the combined Region * * Returns the padding character */ char getPaddingValue(Region::RegionType rtype); /** * Architecture specific * * Calculates a relocation and applies it to the specified location in the * target. * * targetData The target buffer * rel The relocation entry * dest The offset in the target buffer * relOffset The absolute offset of the relocation * globalOffset The absolute offset of the newly linked code * lmap Holds information necessary to compute relocation * * Returns true, on success; false, otherwise and sets errMsg */ bool archSpecificRelocation(Symtab *targetSymtab, Symtab *srcSymtab, char *targetData, relocationEntry &rel, Offset dest, Offset relOffset, Offset globalOffset, LinkMap &lmap, string &errMsg); // PPC64 TOC-changing inter-module calls bool handleInterModuleSpecialCase(Symtab *target, Symtab *src, LinkMap &lmap, char *data, relocationEntry rel, Offset newTOC, Offset oldTOC, Offset dest, Offset relOffset, Offset globalOffset); Offset findOrCreateStub(Symbol *sym, LinkMap &lmap, Offset newTOC, Offset oldTOC, char *data, Offset global); void createStub(unsigned *stub, Offset stubOffset, Offset newTOC, Offset oldTOC, Offset dest); // Functions for dealing with special sections (GOT, TLS, CTORS, DTORS, etc) // /** * Architecture specific (similar to layoutRegions) * * Creates a new TLS initialization image from the existing TLS Regions in the * target and any new TLS Regions from the relocatable objects. * * globalOffset The absolute offset of the newly linked code * dataTLS The original TLS data Region from the target (can be NULL) * bssTLS The original TLS bss Region from the target (can be NULL) * lmap Holds information necessary to do layout * * Returns the ending Offset of the Region */ Offset layoutTLSImage(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap); Offset tlsLayoutVariant1(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap); Offset tlsLayoutVariant2(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap); /** * Architecture specific * * Updates the TLS offset of a Symbol, given the size of the new TLS initialization image. * * curOffset The current offset of the TLS symbol * tlsSize The size of the new TLS initialization image * * Returns the adjusted offset */ Offset adjustTLSOffset(Offset curOffset, Offset tlsSize); Offset tlsAdjustVariant2(Offset curOffset, Offset tlsSize); /** * Architecture specific * * In order to simplify the creation of a new TLS initialization image, some cleanup * work may be necessary after the new TLS initialization image is created. * * regionAllocs The map of Regions to their place in the newly linked code * dataTLS The original TLS data section from the target (can be NULL) * bssTLS The original TLS bss section from the target (can be NULL) */ void cleanupTLSRegionOffsets(map ®ionAllocs, Region *dataTLS, Region *bssTLS); void tlsCleanupVariant1(map ®ionAllocs, Region *dataTLS, Region *bssTLS); void tlsCleanupVariant2(map ®ionAllocs, Region *dataTLS, Region *bssTLS); /** * Architecture specific * * Determines if the passed relocation type requires the building of a GOT * * relType The relocation type to check * * Returns true if the relocation type requires a GOT */ bool isGOTRelocation(unsigned long relType); /** * Architecture specific * * Constructions a new GOT Region from information in the LinkMap */ void buildGOT(Symtab *target, LinkMap &lmap); /** * Architecture specific * * Determines the size of the GOT Region from information in the LinkMap */ Offset getGOTSize(Symtab *target, LinkMap &lmap, Offset &layoutStart); /** * Architecture specific * * Determines the GOT Region alignment from information in the LinkMap */ Offset getGOTAlign(LinkMap &lmap); /** * Architecture specific * * Determines if the passed Region corresponds to a constructor table Region */ bool isConstructorRegion(Region *reg); /** * Architecture specific * * Lays out a new constructor table Region from the existing constructor * table in the target and any new constructor Regions in the relocatable files * * Returns the ending offset of the new Region */ Offset layoutNewCtorRegion(LinkMap &lmap); /** * * Creates a new constructor Table Region using information stored in the LinkMap * * Returns true on success */ bool createNewCtorRegion(LinkMap &lmap); /** * Architecture specific * * Determines if the passed Region corresponds to a destructor table Region */ bool isDestructorRegion(Region *reg); bool isGOTRegion(Region *reg); /** * Architecture specific * * Lays out a new destructor table Region from the existing destructor * table in the target and any new destructor Regions in the relocatable files * * Returns the ending offset of the new Region */ Offset layoutNewDtorRegion(LinkMap &lmap); /** * Architecture specific * * Creates a new destructor Table Region using information stored in the LinkMap * * Returns true on success */ bool createNewDtorRegion(LinkMap &lmap); /** * Architecture specific * * Gets the symbols that should be excluded when resolving symbols * * symNames This set is populated by the function */ void getExcludedSymbolNames(std::set &symNames); /** * Architecture specific * * Checks if the specified symbol satisfies a special case that is * currently not handled by emitElfStatic. * * member The reloctable object to examine * checkSym The symbol to check * * Returns false if the symbol satisfies a special case */ bool checkSpecialCaseSymbols(Symtab *member, Symbol *checkSym); /** * More with the architecture specific * * Calculate new TOC values if we care (PPC64) */ bool calculateTOCs(Symtab *target, deque ®ions, Offset GOTbase, Offset newGOToffset, Offset globalOffset); /** * Somewhat architecture specific * * Allocate PLT entries for each INDIRECT-typed symbol * Each PLT entry has an arch-specific size */ Offset allocatePLTEntries(std::map > &entries, Offset pltOffset, Offset &size); /** * Aaand... architecture specific. * Generate a new relocation section that combines relocs * from any indirect symbols with original relocs */ Offset allocateRelocationSection(std::map > &entries, Offset relocOffset, Offset &size, Symtab *target); Offset allocateRelGOTSection(const std::map > &entries, Offset relocOffset, Offset &size); bool addIndirectSymbol(Symbol *sym, LinkMap &lmap); // Update the TOC pointer if necessary (PPC, 64-bit) bool updateTOC(Symtab *file, LinkMap &lmap, Offset globalOffset); unsigned addressWidth_; bool isStripped_; bool hasRewrittenTLS_; typedef dyncompat::tuple TOCstub; std::map stubMap; Offset getStubOffset(TOCstub &t) { return dyncompat::get<0>(t); } Offset getNewTOC(TOCstub &t) { return dyncompat::get<1>(t); } Offset getOldTOC(TOCstub &t) { return dyncompat::get<2>(t); } }; } // Dyninst } // SymtabAPI #endif