00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00083 #define UNKNOWN_ADDRESS_WIDTH_ASSERT "An unknown address width was encountered, can't continue"
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
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
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
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;
00145 int relocation_pos = 0;
00146 int branch_pred = -1;
00147
00148
00149
00150
00151
00152
00153
00154
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
00182 case R_PPC_NONE:
00183 break;
00184 case R_PPC_ADDR32:
00185 relocation = symbolOffset + addend;
00186 break;
00187 case R_PPC_ADDR24:
00188 relocation_length = 26;
00189 relocation_pos = 2;
00190 relocation = (symbolOffset + addend) >> 2;
00191 break;
00192 case R_PPC_ADDR16:
00193 relocation_length = 16;
00194 relocation_pos = 16;
00195 relocation = symbolOffset + addend;
00196 break;
00197 case R_PPC_ADDR16_LO:
00198 relocation_length = 16;
00199 relocation_pos = 0;
00200 relocation = symbolOffset + addend;
00201 relocation = (relocation & 0xffff);
00202 break;
00203 case R_PPC_ADDR16_HI:
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:
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:
00216 relocation_length = 14;
00217 relocation_pos = 16;
00218 relocation = (symbolOffset + addend) >> 2;
00219 break;
00220 case R_PPC_ADDR14_BRTAKEN:
00221 relocation_length = 14;
00222 relocation_pos = 16;
00223 relocation = (symbolOffset + addend) >> 2;
00224
00225 branch_pred = 1;
00226 break;
00227 case R_PPC_ADDR14_BRNTAKEN:
00228 relocation_length = 14;
00229 relocation_pos = 16;
00230 relocation = (symbolOffset + addend) >> 2;
00231
00232 branch_pred = 0;
00233 break;
00234 case R_PPC_REL24:
00235 relocation_length = 24;
00236 relocation_pos = 2;
00237 relocation = (symbolOffset + addend - relOffset) >> 2;
00238 break;
00239 case R_PPC_REL14:
00240 relocation_length = 14;
00241 relocation_pos = 16;
00242 relocation = (symbolOffset + addend - relOffset) >> 2;
00243 break;
00244 case R_PPC_REL14_BRTAKEN:
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:
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:
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:
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:
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:
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:
00301 relocation_length = 24;
00302 relocation_pos = 2;
00303 relocation = (symbolOffset + addend - relOffset) >> 2;
00304 break;
00305 case R_PPC_COPY:
00306 break;
00307 case R_PPC_GLOB_DAT:
00308 relocation = symbolOffset + addend;
00309 break;
00310 case R_PPC_JMP_SLOT:
00311 break;
00312 case R_PPC_RELATIVE:
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:
00318 relocation_length = 24;
00319 relocation_pos = 2;
00320 relocation = (symbolOffset + addend - relOffset) >> 2;
00321 break;
00322 case R_PPC_UADDR32:
00323 relocation = symbolOffset + addend ;
00324 break;
00325 case R_PPC_UADDR16:
00326 relocation_length = 16;
00327 relocation_pos = 16;
00328 relocation = symbolOffset + addend;
00329 break;
00330 case R_PPC_REL32:
00331 relocation = symbolOffset + addend - relOffset;
00332 break;
00333 case R_PPC_PLT32:
00334 relocation = symbolOffset + addend;
00335 break;
00336 case R_PPC_PLTREL32:
00337 relocation = symbolOffset + addend - relOffset;
00338 break;
00339 case R_PPC_PLT16_LO:
00340 relocation = symbolOffset + addend;
00341 relocation = (relocation & 0xffff);
00342 break;
00343 case R_PPC_PLT16_HI:
00344 relocation = symbolOffset + addend;
00345 relocation = ((relocation >> 16) & 0xffff);
00346 break;
00347 case R_PPC_PLT16_HA:
00348 relocation = symbolOffset + addend;
00349 relocation = (((relocation >> 16) + ((relocation & 0x8000)? 1:0)) & 0xffff);
00350 break;
00351 case R_PPC_SDAREL16:
00352 case R_PPC_SECTOFF:
00353 case R_PPC_SECTOFF_LO:
00354 case R_PPC_SECTOFF_HI:
00355 case R_PPC_SECTOFF_HA:
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
00363 case R_PPC_TLS:
00364 case R_PPC_DTPMOD32:
00365 case R_PPC_TPREL16:
00366 case R_PPC_TPREL16_LO:
00367 case R_PPC_TPREL16_HI:
00368 case R_PPC_TPREL16_HA:
00369 case R_PPC_TPREL32:
00370 case R_PPC_DTPREL16:
00371 case R_PPC_DTPREL16_LO:
00372 case R_PPC_DTPREL16_HI:
00373 case R_PPC_DTPREL16_HA:
00374 case R_PPC_DTPREL32:
00375 case R_PPC_GOT_TLSGD16:
00376 case R_PPC_GOT_TLSGD16_LO:
00377 case R_PPC_GOT_TLSGD16_HI:
00378 case R_PPC_GOT_TLSGD16_HA:
00379 case R_PPC_GOT_TLSLD16:
00380 case R_PPC_GOT_TLSLD16_LO:
00381 case R_PPC_GOT_TLSLD16_HI:
00382 case R_PPC_GOT_TLSLD16_HA:
00383 case R_PPC_GOT_TPREL16:
00384 case R_PPC_GOT_TPREL16_LO:
00385 case R_PPC_GOT_TPREL16_HI:
00386 case R_PPC_GOT_TPREL16_HA:
00387 case R_PPC_GOT_DTPREL16:
00388 case R_PPC_GOT_DTPREL16_LO:
00389 case R_PPC_GOT_DTPREL16_HI:
00390 case R_PPC_GOT_DTPREL16_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
00398
00399
00400 case 249:
00401 relocation_length = 16;
00402 relocation_pos = 16;
00403 relocation = symbolOffset + addend - relOffset ;
00404 break;
00405 case 250:
00406 relocation_length = 16;
00407 relocation_pos = 16;
00408 relocation = symbolOffset + addend - relOffset ;
00409 relocation = (relocation & 0xffff);
00410 break;
00411 case 251:
00412 relocation_length = 16;
00413 relocation_pos = 16;
00414 relocation = symbolOffset + addend - relOffset ;
00415 relocation = ((relocation >> 16) & 0xffff);
00416 break;
00417 case 252:
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
00424
00425 case 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
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
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
00482
00483 return 0x0;
00484 }
00485
00486 void emitElfStatic::cleanupTLSRegionOffsets(map<Region *, LinkMap::AllocPair> ®ionAllocs,
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
00497
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
00510 if( !result.second ) {
00511 return ~0UL;
00512 }
00513
00514 retOffset += (*reg_it)->getDiskSize();
00515 }
00516
00517 if( lmap.originalCtorRegion != NULL ) {
00518
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
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
00556 Offset originalOffset = lmap.ctorRegionOffset + lmap.ctorSize -
00557 trailerSize - (lmap.originalCtorRegion->getDiskSize() - headerSize - trailerSize);
00558
00559
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
00572
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
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
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
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
00630 Offset originalOffset = lmap.dtorRegionOffset + headerSize;
00631
00632
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
00693 return lmap.stubRegionOffset;
00694 }
00695
00696 bool emitElfStatic::updateTOC(Symtab *, LinkMap &, Offset) {
00697 return true;
00698 }