emitElfStatic-ppc32.C

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 /* 
00032  * holds architecture specific functions for x86 and x86_64 architecture needed for the
00033  * static executable rewriter
00034  */
00035 
00036 #include <cstdlib>
00037 #include <cstdio>
00038 #include <cassert>
00039 #include <iostream>
00040 #include <set>
00041 #include <map>
00042 #include <sstream>
00043 
00044 #include "emitElfStatic.h"
00045 #include "Symtab.h"
00046 #include "Symbol.h"
00047 #include "Archive.h"
00048 #include "Object.h"
00049 #include "Region.h"
00050 #include "debug.h"
00051 
00052 using namespace Dyninst;
00053 using namespace Dyninst::SymtabAPI;
00054 
00055 static const unsigned PPC32_WIDTH = 4;
00056 static const unsigned PPC64_WIDTH = 8;
00057 
00058 static const Elf64_Word X86_HEADER = 0xffffffff;
00059 static const Elf64_Word X86_TRAILER = 0x00000000;
00060 static const Elf64_Xword X86_64_HEADER = 0xffffffffffffffffULL;
00061 static const Elf64_Xword X86_64_TRAILER = 0x0000000000000000ULL;
00062 
00063 unsigned int setBits(unsigned int target, unsigned int pos, unsigned int len, unsigned int value) {
00064     rewrite_printf("setBits target 0x%lx value 0x%lx pos %d len %d \n", target, value, pos, len);
00065     unsigned int mask;
00066     mask = ~(~0 << len);
00067     value = value & mask;
00068 
00069     mask = ~(mask << pos);
00070     value = value << pos;
00071 
00072     target = target & mask;
00073     target = target | value;
00074     rewrite_printf( "setBits target 0x%lx value 0x%lx pos %d len %d \n", target, value, pos, len);
00075     return target;
00076 }
00077 
00078 #if defined(os_freebsd)
00079 #define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
00080 #endif
00081 
00082 // Used in an assert so needs to be a macro
00083 #define UNKNOWN_ADDRESS_WIDTH_ASSERT "An unknown address width was encountered, can't continue"
00084 
00085 /* NOTE:
00086  * As most of these functions are defined per architecture, the description of
00087  * each of these functions is in the emitElfStatic header. Comments describing
00088  * the function interface are explicitly left out.
00089  */
00090 
00091 /** 
00092  *
00093  * Given a relocation, determines if the relocation corresponds to a .ctors or .dtors
00094  * table that requires special consideration. Modifies the passed symbol offset to
00095  * point to the right table, if applicable.
00096  *
00097  * rel          The relocation entry to examine
00098  * globalOffset The offset of the linked code (used for symbol offset calculation)
00099  * lmap         Holds information about .ctors/.dtors tables
00100  * errMsg       Set on error
00101  * symbolOffset Modified by this routine to contain the offset of the table
00102  *
00103  * Returns true, if there are no errors including the case where the relocation 
00104  * entry doesn't reference the .ctors/.dtors tables.
00105  */
00106 
00107 static bool computeCtorDtorAddress(relocationEntry &rel, Offset globalOffset,
00108         LinkMap &lmap, string &errMsg, Offset &symbolOffset)
00109 {
00110     if( rel.name() ==  SYMTAB_CTOR_LIST_REL ) {
00111         // This needs to be: (the location of the .ctors table)
00112         if( lmap.newCtorRegions.size() > 0 ) {
00113             symbolOffset = lmap.ctorRegionOffset + globalOffset;
00114         }else if( lmap.originalCtorRegion != NULL ) {
00115             symbolOffset = lmap.originalCtorRegion->getMemOffset();
00116         }else{
00117             errMsg = "Failed to locate original .ctors Region -- cannot apply relocation";
00118             rewrite_printf("Failed to locate original .ctors Region -- cannot apply relocation\n");
00119             return false;
00120         }
00121     }else if( rel.name() == SYMTAB_DTOR_LIST_REL ) {
00122         // This needs to be: (the location of the .dtors table)
00123         if( lmap.newDtorRegions.size() > 0 ) {
00124             symbolOffset = lmap.dtorRegionOffset + globalOffset;
00125         }else if( lmap.originalDtorRegion != NULL ) {
00126             symbolOffset = lmap.originalDtorRegion->getMemOffset();
00127         }else{
00128             errMsg = "Failed to locate original .dtors Region -- cannot apply relocation";
00129             rewrite_printf("Failed to locate original .dtors Region -- cannot apply relocation\n");
00130             return false;
00131         }
00132     }
00133 
00134     return true;
00135 }
00136 
00137 
00138 bool emitElfStatic::archSpecificRelocation(Symtab *, Symtab *, char *targetData, relocationEntry &rel,
00139        Offset dest, Offset relOffset, Offset globalOffset, LinkMap &lmap,
00140        string &errMsg) 
00141 {
00142     rewrite_printf(" archSpecificRelocation %s  \n",  rel.name().c_str());
00143     if( PPC32_WIDTH == addressWidth_ ) {
00144     int relocation_length = sizeof(Elf32_Word)*8; // in bits
00145     int relocation_pos = 0; // in bits
00146     int branch_pred = -1;
00147         /*
00148          * Referring to the SYSV 386 supplement:
00149          *
00150          * All relocations on x86 are one word32 == Elf32_Word
00151          *
00152          * S = symbolOffset
00153          * A = addend
00154          * P = relOffset
00155          */
00156        
00157         Offset symbolOffset = rel.getDynSym()->getOffset();
00158 
00159         Elf32_Word addend;
00160         if( rel.regionType() == Region::RT_REL ) {
00161             memcpy(&addend, &targetData[dest], sizeof(Elf32_Word));
00162         }else if( rel.regionType() == Region::RT_RELA ) {
00163             addend = rel.addend();
00164         }
00165         
00166     if(!computeCtorDtorAddress(rel, globalOffset, lmap, errMsg, symbolOffset)) {
00167         return false;
00168     }
00169 
00170         rewrite_printf("relocation for '%s': TYPE = %s(%lu) S = %lx A = %lx P = %lx\n",
00171                 rel.name().c_str(), 
00172                 relocationEntry::relType2Str(rel.getRelType(), addressWidth_),
00173                 rel.getRelType(), symbolOffset, addend, relOffset);
00174 
00175         Offset relocation = 0;
00176         map<Symbol *, Offset>::iterator result;
00177         stringstream tmp;
00178 
00179         switch(rel.getRelType()) {
00180 
00181 /* PowerPC relocations defined by the ABIs */
00182 case R_PPC_NONE:/*            0 */
00183     break;
00184 case R_PPC_ADDR32:/*          1        32bit absolute address */
00185     relocation = symbolOffset + addend;
00186     break;
00187 case R_PPC_ADDR24:/*          2        26bit address, 2 bits ignored.  */
00188         relocation_length = 26;
00189         relocation_pos = 2;
00190     relocation = (symbolOffset + addend) >> 2;
00191     break;
00192 case R_PPC_ADDR16:/*          3        16bit absolute address */
00193         relocation_length = 16;
00194         relocation_pos = 16;
00195     relocation = symbolOffset + addend;
00196     break;
00197 case R_PPC_ADDR16_LO:/*       4        lower 16bit of absolute address */
00198         relocation_length = 16;
00199         relocation_pos = 0;
00200         relocation = symbolOffset + addend;
00201     relocation = (relocation & 0xffff);
00202     break;
00203 case R_PPC_ADDR16_HI:/*       5        high 16bit of absolute address */
00204     relocation_length = 16;
00205         relocation_pos = 0;
00206         relocation = symbolOffset + addend;
00207     relocation = ((relocation >> 16) & 0xffff);
00208     break;
00209 case R_PPC_ADDR16_HA:/*       6        adjusted high 16bit */
00210     relocation_length = 16;
00211         relocation_pos = 0;
00212         relocation = symbolOffset + addend;
00213         relocation = (((relocation >> 16) + ((relocation & 0x8000)? 1:0)) & 0xffff);
00214         break;
00215 case R_PPC_ADDR14:/*          7        16bit address, 2 bits ignored */
00216     relocation_length = 14;
00217         relocation_pos = 16;
00218     relocation = (symbolOffset + addend) >> 2;
00219     break;
00220 case R_PPC_ADDR14_BRTAKEN:/*  8 */
00221     relocation_length = 14;
00222         relocation_pos = 16;
00223     relocation = (symbolOffset + addend) >> 2;
00224     // bit 10 is set
00225     branch_pred = 1;
00226     break;
00227 case R_PPC_ADDR14_BRNTAKEN:/* 9 */
00228     relocation_length = 14;
00229         relocation_pos = 16;
00230     relocation = (symbolOffset + addend) >> 2;
00231     // bit 10 is set
00232     branch_pred = 0;
00233     break;
00234 case R_PPC_REL24:/*           10       PC relative 26 bit */
00235     relocation_length = 24;
00236         relocation_pos = 2;
00237         relocation = (symbolOffset + addend - relOffset) >> 2;
00238         break;
00239 case R_PPC_REL14:/*           11       PC relative 16 bit */
00240     relocation_length = 14;
00241         relocation_pos = 16;
00242         relocation = (symbolOffset + addend - relOffset) >> 2;
00243         break;
00244 case R_PPC_REL14_BRTAKEN:/*   12*/
00245     relocation_length = 14;
00246         relocation_pos = 16;
00247         relocation = (symbolOffset + addend - relOffset) >> 2;
00248     branch_pred = 1;
00249         break;
00250 case R_PPC_REL14_BRNTAKEN:/*  13*/
00251     relocation_length = 14;
00252         relocation_pos = 16;
00253         relocation = (symbolOffset + addend - relOffset) >> 2;
00254     branch_pred = 0;
00255         break;
00256 case R_PPC_GOT16:/*           14*/
00257         result = lmap.gotSymbols.find(rel.getDynSym());
00258         if( result == lmap.gotSymbols.end() ) {
00259             errMsg = "Expected GOT symbol does not exist in GOT symbol mapping";
00260             return false;
00261         }
00262         relocation = result->second;
00263     relocation = (relocation) >> 16;
00264         relocation_length = 16;
00265         relocation_pos = 16;
00266         break;
00267 case R_PPC_GOT16_LO:/*        15*/
00268         result = lmap.gotSymbols.find(rel.getDynSym());
00269         if( result == lmap.gotSymbols.end() ) {
00270             errMsg = "Expected GOT symbol does not exist in GOT symbol mapping";
00271             return false;
00272         }
00273         relocation = result->second;
00274     relocation = (relocation & 0xffff);
00275         relocation_length = 16;
00276         relocation_pos = 0;
00277         break;
00278 case R_PPC_GOT16_HI:/*        16*/
00279         result = lmap.gotSymbols.find(rel.getDynSym());
00280         if( result == lmap.gotSymbols.end() ) {
00281             errMsg = "Expected GOT symbol does not exist in GOT symbol mapping";
00282             return false;
00283         }
00284         relocation = result->second;
00285     relocation = ((relocation >> 16) & 0xffff);
00286         relocation_length = 16;
00287         relocation_pos = 0;
00288         break;
00289 case R_PPC_GOT16_HA:/*        17*/
00290         result = lmap.gotSymbols.find(rel.getDynSym());
00291         if( result == lmap.gotSymbols.end() ) {
00292             errMsg = "Expected GOT symbol does not exist in GOT symbol mapping";
00293             return false;
00294         }
00295         relocation = result->second;
00296         relocation = (((relocation >> 16) + ((relocation & 0x8000)? 1:0)) & 0xffff);
00297         relocation_length = 16;
00298         relocation_pos = 0;
00299         break;
00300 case R_PPC_PLTREL24:/*        18*/
00301     relocation_length = 24;
00302         relocation_pos = 2;
00303     relocation = (symbolOffset + addend - relOffset) >> 2;
00304     break;
00305 case R_PPC_COPY:/*            19*/
00306     break;
00307 case R_PPC_GLOB_DAT:/*        20*/
00308     relocation = symbolOffset + addend;
00309     break;
00310 case R_PPC_JMP_SLOT:/*        21*/
00311     break;
00312 case R_PPC_RELATIVE:/*        22*/
00313         tmp << "ERROR: encountered relocation type(" << rel.getRelType() << 
00314                 ") that is meant for use during dynamic linking";
00315         errMsg = tmp.str();
00316         return false;
00317 case R_PPC_LOCAL24PC:/*       23*/
00318     relocation_length = 24;
00319         relocation_pos = 2;
00320     relocation = (symbolOffset + addend - relOffset) >> 2;
00321     break;
00322 case R_PPC_UADDR32:/*         24*/
00323     relocation = symbolOffset + addend ;
00324     break;
00325 case R_PPC_UADDR16:/*         25*/
00326         relocation_length = 16;
00327         relocation_pos = 16;
00328     relocation = symbolOffset + addend;
00329     break;
00330 case R_PPC_REL32:/*           26*/
00331     relocation = symbolOffset + addend - relOffset;
00332         break;
00333 case R_PPC_PLT32:/*           27*/
00334     relocation = symbolOffset + addend;
00335         break;
00336 case R_PPC_PLTREL32:/*        28*/
00337     relocation = symbolOffset + addend - relOffset;
00338         break;
00339 case R_PPC_PLT16_LO:/*        29*/
00340     relocation = symbolOffset + addend;
00341     relocation = (relocation & 0xffff);
00342         break;
00343 case R_PPC_PLT16_HI:/*        30*/
00344     relocation = symbolOffset + addend;
00345     relocation = ((relocation >> 16) & 0xffff);
00346         break;
00347 case R_PPC_PLT16_HA:/*        31*/
00348     relocation = symbolOffset + addend;
00349         relocation = (((relocation >> 16) + ((relocation & 0x8000)? 1:0)) & 0xffff);
00350         break;
00351 case R_PPC_SDAREL16:/*        32*/
00352 case R_PPC_SECTOFF:/*         33*/
00353 case R_PPC_SECTOFF_LO:/*      34*/
00354 case R_PPC_SECTOFF_HI:/*      35*/
00355 case R_PPC_SECTOFF_HA:/*      36*/
00356         tmp << "Relocation type " << rel.getRelType() 
00357             << " currently unimplemented";
00358         errMsg = tmp.str();
00359       rewrite_printf(" Relocation type %s  currently unimplemented \n", relocationEntry::relType2Str(rel.getRelType(), addressWidth_));
00360         return false;
00361 
00362 /* PowerPC relocations defined for the TLS access ABI.  */
00363 case R_PPC_TLS:/*             67  none      (sym+add)@tls */
00364 case R_PPC_DTPMOD32:/*        68  word32    (sym+add)@dtpmod */
00365 case R_PPC_TPREL16:/*         69  half16*   (sym+add)@tprel */
00366 case R_PPC_TPREL16_LO:/*      70  half16    (sym+add)@tprel@l */
00367 case R_PPC_TPREL16_HI:/*      71  half16    (sym+add)@tprel@h */
00368 case R_PPC_TPREL16_HA:/*      72  half16    (sym+add)@tprel@ha */
00369 case R_PPC_TPREL32:/*         73  word32    (sym+add)@tprel */
00370 case R_PPC_DTPREL16:/*        74  half16*   (sym+add)@dtprel */
00371 case R_PPC_DTPREL16_LO:/*     75  half16    (sym+add)@dtprel@l */
00372 case R_PPC_DTPREL16_HI:/*     76  half16    (sym+add)@dtprel@h */
00373 case R_PPC_DTPREL16_HA:/*     77  half16    (sym+add)@dtprel@ha */
00374 case R_PPC_DTPREL32:/*        78  word32    (sym+add)@dtprel */
00375 case R_PPC_GOT_TLSGD16:/*     79  half16*   (sym+add)@got@tlsgd */
00376 case R_PPC_GOT_TLSGD16_LO:/*  80  half16    (sym+add)@got@tlsgd@l */
00377 case R_PPC_GOT_TLSGD16_HI:/*  81  half16    (sym+add)@got@tlsgd@h */
00378 case R_PPC_GOT_TLSGD16_HA:/*  82  half16    (sym+add)@got@tlsgd@ha */
00379 case R_PPC_GOT_TLSLD16:/*     83  half16*   (sym+add)@got@tlsld */
00380 case R_PPC_GOT_TLSLD16_LO:/*  84  half16    (sym+add)@got@tlsld@l */
00381 case R_PPC_GOT_TLSLD16_HI:/*  85  half16    (sym+add)@got@tlsld@h */
00382 case R_PPC_GOT_TLSLD16_HA:/*  86  half16    (sym+add)@got@tlsld@ha */
00383 case R_PPC_GOT_TPREL16:/*     87  half16*   (sym+add)@got@tprel */
00384 case R_PPC_GOT_TPREL16_LO:/*  88  half16    (sym+add)@got@tprel@l */
00385 case R_PPC_GOT_TPREL16_HI:/*  89  half16    (sym+add)@got@tprel@h */
00386 case R_PPC_GOT_TPREL16_HA:/*  90  half16    (sym+add)@got@tprel@ha */
00387 case R_PPC_GOT_DTPREL16:/*    91  half16*   (sym+add)@got@dtprel */
00388 case R_PPC_GOT_DTPREL16_LO:/* 92  half16*   (sym+add)@got@dtprel@l */
00389 case R_PPC_GOT_DTPREL16_HI:/* 93  half16*   (sym+add)@got@dtprel@h */
00390 case R_PPC_GOT_DTPREL16_HA:/* 94  half16*   (sym+add)@got@dtprel@ha */
00391       relocation_length = 16;
00392       relocation_pos = 16;
00393       relocation = symbolOffset + addend;
00394       rewrite_printf(" Relocation type %s  currently unimplemented \n", relocationEntry::relType2Str(rel.getRelType(), addressWidth_));
00395       break;
00396 
00397 /* GNU relocs used in PIC code sequences.  */
00398 /* NOTE: The following relocations are not defined in some elf.h
00399    Hence, using numbers instead of name */
00400 case 249: /*R_PPC_REL16:           249      word32   (sym-.) */
00401     relocation_length = 16;
00402         relocation_pos = 16;
00403         relocation = symbolOffset + addend - relOffset ;
00404         break;
00405 case 250: /*R_PPC_REL16_LO:        250      half16   (sym-.)@l */
00406     relocation_length = 16;
00407         relocation_pos = 16;
00408         relocation = symbolOffset + addend - relOffset ;
00409     relocation = (relocation & 0xffff);
00410         break;
00411 case 251: /*R_PPC_REL16_HI:        251      half16   (sym-.)@h */
00412     relocation_length = 16;
00413         relocation_pos = 16;
00414         relocation = symbolOffset + addend - relOffset ;
00415     relocation = ((relocation >> 16) & 0xffff);
00416         break;
00417 case 252: /*R_PPC_REL16_HA:        252      half16   (sym-.)@ha */
00418     relocation_length = 16;
00419         relocation_pos = 16;
00420         relocation = symbolOffset + addend - relOffset ;
00421         relocation = (((relocation >> 16) + ((relocation & 0x8000)? 1:0)) & 0xffff);
00422         break;
00423 /* This is a phony reloc to handle any old fashioned TOC16 references
00424    that may still be in object files.  */
00425 case 255: /*R_PPC_TOC16:              255*/
00426         break;
00427 
00428 default:
00429      tmp << "Relocation type " << rel.getRelType() 
00430          << " currently unimplemented";
00431      rewrite_printf(" Relocation type %s  currently unimplemented \n", relocationEntry::relType2Str(rel.getRelType(), addressWidth_));
00432      errMsg = tmp.str();
00433      return false;
00434         }
00435 
00436         rewrite_printf(" relocation = 0x%lx @ 0x%lx target data 0x%lx %lx %lx %lx \n", relocation, relOffset, targetData[dest], targetData[dest+1],  targetData[dest+2],  targetData[dest+3]);
00437     if (rel.getRelType() == R_PPC_REL24) {
00438     unsigned int *td = (unsigned int *) targetData;
00439     unsigned int target;
00440     target = td[dest/4];
00441     target = setBits(target, relocation_pos, relocation_length, relocation);
00442         memcpy(&targetData[dest], &target, sizeof(Elf32_Word));
00443     } else {
00444     unsigned int *td = (unsigned int *) targetData;
00445     unsigned int target;
00446     target = td[dest/4];
00447     target = setBits(target, relocation_pos, relocation_length, relocation);
00448         memcpy(&td[dest/4], &target, sizeof(Elf32_Word));
00449 //        memcpy(&targetData[dest], r+2, relocation_size);
00450         rewrite_printf(" relocation = 0x%lx @ 0x%lx target data 0x%lx %lx %lx %lx \n", relocation, relOffset, targetData[dest], targetData[dest+1],  targetData[dest+2],  targetData[dest+3]);
00451     }
00452     if (branch_pred >= 0) {
00453     unsigned int *td = (unsigned int *) targetData;
00454     unsigned int target;
00455     target = td[dest/4];
00456     target = setBits(target, 10, 1, branch_pred);
00457         memcpy(&td[dest/4], &target, sizeof(Elf32_Word));
00458     } 
00459 
00460     } else{
00461         assert(!UNKNOWN_ADDRESS_WIDTH_ASSERT);
00462     }
00463     return true;
00464 }
00465 
00466 bool emitElfStatic::checkSpecialCaseSymbols(Symtab *, Symbol *) {
00467     return true;
00468 }
00469 
00470 /* The TLS implementation on ppc is Variant 1 */
00471 
00472 Offset emitElfStatic::layoutTLSImage(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap) {
00473     return tlsLayoutVariant1(globalOffset, dataTLS, bssTLS, lmap);
00474 }
00475 
00476 Offset emitElfStatic::adjustTLSOffset(Offset curOffset, Offset tlsSize) {
00477     return curOffset;
00478 }
00479 
00480 char emitElfStatic::getPaddingValue(Region::RegionType rtype) {
00481    // TODO: if this matters, we can noop-pad by returning an unsigned
00482    // instead of a char...
00483    return 0x0;
00484 }
00485 
00486 void emitElfStatic::cleanupTLSRegionOffsets(map<Region *, LinkMap::AllocPair> &regionAllocs,
00487         Region *dataTLS, Region *bssTLS) 
00488 {
00489     tlsCleanupVariant2(regionAllocs, dataTLS, bssTLS);
00490 }
00491 
00492 static const string CTOR_NAME(".ctors");
00493 static const string DTOR_NAME(".dtors"); 
00494 Offset emitElfStatic::layoutNewCtorRegion(LinkMap &lmap) {
00495     /* 
00496      * .ctors sections are processed in reverse order on Linux x86. New .ctors
00497      * sections need to be placed before the original .ctors section
00498      */
00499 
00500     Offset retOffset = lmap.ctorRegionOffset;
00501     retOffset += addressWidth_;
00502 
00503     pair<map<Region *, LinkMap::AllocPair>::iterator, bool> result;
00504 
00505     vector<Region *>::iterator reg_it;
00506     for(reg_it = lmap.newCtorRegions.begin(); reg_it != lmap.newCtorRegions.end(); ++reg_it) {
00507         result = lmap.regionAllocs.insert(make_pair(*reg_it, make_pair(0, retOffset)));
00508 
00509         // If the map already contains this Region, this is a logic error
00510         if( !result.second ) {
00511             return ~0UL;
00512         }
00513 
00514         retOffset += (*reg_it)->getDiskSize();
00515     }
00516 
00517     if( lmap.originalCtorRegion != NULL ) {
00518         // Account for original .ctors section (minus the header and trailer)
00519         retOffset += lmap.originalCtorRegion->getDiskSize() - addressWidth_ - addressWidth_;
00520     }
00521     retOffset += addressWidth_;
00522 
00523     return retOffset;
00524 
00525     return 0;
00526 }
00527 
00528 bool emitElfStatic::createNewCtorRegion(LinkMap &lmap) {
00529     char *targetData = lmap.allocatedData;
00530 
00531     if( PPC32_WIDTH != addressWidth_ && PPC64_WIDTH != addressWidth_ ) {
00532         assert(!UNKNOWN_ADDRESS_WIDTH_ASSERT);
00533     }
00534 
00535     unsigned trailerSize, headerSize;
00536 
00537     /* Give the new Region a header and trailer */
00538     Offset headerOffset = lmap.ctorRegionOffset;
00539     Offset trailerOffset;
00540     if( PPC32_WIDTH == addressWidth_ ) {
00541         memcpy(&targetData[headerOffset], &X86_HEADER, sizeof(X86_HEADER));
00542         trailerOffset = lmap.ctorRegionOffset + lmap.ctorSize - sizeof(X86_TRAILER);
00543         memcpy(&targetData[trailerOffset], &X86_TRAILER, sizeof(X86_TRAILER));
00544         headerSize = sizeof(X86_HEADER);
00545         trailerSize = sizeof(X86_TRAILER);
00546     }else{
00547         memcpy(&targetData[headerOffset], &X86_64_HEADER, sizeof(X86_64_HEADER));
00548         trailerOffset = lmap.ctorRegionOffset + lmap.ctorSize - sizeof(X86_64_TRAILER);
00549         memcpy(&targetData[trailerOffset], &X86_64_TRAILER, sizeof(X86_64_TRAILER));
00550         headerSize = sizeof(X86_64_HEADER);
00551         trailerSize = sizeof(X86_64_TRAILER);
00552     }
00553 
00554     if( lmap.originalCtorRegion != NULL ) {
00555         /* Determine where the original .ctors section should be placed */
00556         Offset originalOffset = lmap.ctorRegionOffset + lmap.ctorSize -
00557             trailerSize - (lmap.originalCtorRegion->getDiskSize() - headerSize - trailerSize);
00558 
00559         /* Copy the original .ctors section w/o the header and trailer */
00560         char *rawRegionData = reinterpret_cast<char *>(lmap.originalCtorRegion->getPtrToRawData());
00561         memcpy(&targetData[originalOffset], &rawRegionData[headerSize],
00562                 lmap.originalCtorRegion->getDiskSize() - headerSize - trailerSize);
00563     }
00564 
00565     return true;
00566 }
00567 
00568 
00569 Offset emitElfStatic::layoutNewDtorRegion(LinkMap &lmap) {
00570     /*
00571      * .dtors sections are processed in forward order on Linux x86. So new
00572      * .dtors sections need to be placed after the original .dtors section
00573      */
00574 
00575     Offset retOffset = lmap.dtorRegionOffset;
00576     retOffset += addressWidth_;
00577 
00578     pair<map<Region *, LinkMap::AllocPair>::iterator, bool> result;
00579     if( lmap.originalDtorRegion != NULL ) {
00580         // Account for the original .dtors section (minus the header and trailer)
00581         retOffset += lmap.originalDtorRegion->getDiskSize() - addressWidth_ - addressWidth_;
00582     }
00583 
00584     vector<Region *>::iterator reg_it;
00585     for(reg_it = lmap.newDtorRegions.begin(); reg_it != lmap.newDtorRegions.end(); ++reg_it) {
00586         result = lmap.regionAllocs.insert(make_pair(*reg_it, make_pair(0, retOffset)));
00587 
00588         // If the map already contains this Region, this is a logic error
00589         if( !result.second ) {
00590             return ~0UL;
00591         }
00592 
00593         retOffset += (*reg_it)->getDiskSize();
00594     }
00595 
00596     retOffset += addressWidth_;
00597     return retOffset;
00598 
00599     return 0;
00600 }
00601 
00602 bool emitElfStatic::createNewDtorRegion(LinkMap &lmap) {
00603     char *targetData = lmap.allocatedData;
00604 
00605     if( PPC32_WIDTH != addressWidth_ && PPC64_WIDTH != addressWidth_ ) {
00606         assert(!UNKNOWN_ADDRESS_WIDTH_ASSERT);
00607     }
00608 
00609     unsigned headerSize, trailerSize;
00610 
00611     /* Give the new Region a header and trailer */
00612     Offset headerOffset = lmap.dtorRegionOffset;
00613     Offset trailerOffset;
00614     if( PPC32_WIDTH == addressWidth_ ) {
00615         memcpy(&targetData[headerOffset], &X86_HEADER, sizeof(X86_HEADER));
00616         trailerOffset = lmap.dtorRegionOffset + lmap.dtorSize - sizeof(X86_TRAILER);
00617         memcpy(&targetData[trailerOffset], &X86_TRAILER, sizeof(X86_TRAILER));
00618         headerSize = sizeof(X86_HEADER);
00619         trailerSize = sizeof(X86_TRAILER);
00620     }else{
00621         memcpy(&targetData[headerOffset], &X86_64_HEADER, sizeof(X86_64_HEADER));
00622         trailerOffset = lmap.dtorRegionOffset + lmap.dtorSize - sizeof(X86_64_TRAILER);
00623         memcpy(&targetData[trailerOffset], &X86_64_TRAILER, sizeof(X86_64_TRAILER));
00624         headerSize = sizeof(X86_64_HEADER);
00625         trailerSize = sizeof(X86_64_TRAILER);
00626     }
00627 
00628     if( lmap.originalDtorRegion != NULL ) {
00629         /* Determine where the original .dtors section should be placed */
00630         Offset originalOffset = lmap.dtorRegionOffset + headerSize;
00631 
00632         /* Copy the original .dtors section w/o header and trailer */
00633         char *rawRegionData = reinterpret_cast<char *>(lmap.originalDtorRegion->getPtrToRawData());
00634         memcpy(&targetData[originalOffset], &rawRegionData[headerSize],
00635                 lmap.originalDtorRegion->getDiskSize() - headerSize - trailerSize);
00636     }
00637 
00638     return true;
00639 
00640 }
00641 
00642 bool emitElfStatic::isConstructorRegion(Region *reg) {
00643     return ( CTOR_NAME.compare(reg->getRegionName()) == 0 );
00644 
00645 }
00646 
00647 bool emitElfStatic::isDestructorRegion(Region *reg) {
00648     return ( DTOR_NAME.compare(reg->getRegionName()) == 0 );
00649 }
00650 
00651 bool emitElfStatic::isGOTRegion(Region *) {
00652     return false;
00653 }
00654 
00655 bool emitElfStatic::isGOTRelocation(unsigned long relType) {
00656     if( PPC32_WIDTH == addressWidth_ ) {
00657         switch(relType) {
00658             case R_PPC_GOT16:
00659             case R_PPC_GOT16_LO:
00660             case R_PPC_GOT16_HI:
00661             case R_PPC_GOT16_HA:
00662             case R_PPC_GOT_TPREL16:
00663             case R_PPC_TLS:
00664                 return true;
00665                 break;
00666             default:
00667                 return false;
00668                 break;
00669         }
00670     } else{
00671         assert(!UNKNOWN_ADDRESS_WIDTH_ASSERT);
00672     }
00673 
00674     return false;
00675 }
00676 
00677 Offset emitElfStatic::getGOTSize(Symtab *, LinkMap &, Offset &) {
00678     return 0;
00679 }
00680 
00681 Offset emitElfStatic::getGOTAlign(LinkMap &) {
00682     return 0;
00683 }
00684 
00685 void emitElfStatic::buildGOT(Symtab *, LinkMap &) {
00686 }
00687 
00688 void emitElfStatic::getExcludedSymbolNames(set<string> &) {
00689 }
00690 
00691 Offset emitElfStatic::allocStubRegions(LinkMap &lmap, Offset) {
00692    // Size 0
00693    return lmap.stubRegionOffset;
00694 }
00695 
00696 bool emitElfStatic::updateTOC(Symtab *, LinkMap &, Offset) {
00697   return true;
00698 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1