1/* 2 * Copyright 2011-2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ELF_OBJECT_HXX 18#define ELF_OBJECT_HXX 19 20#include "ELFHeader.h" 21#include "ELFReloc.h" 22#include "ELFSection.h" 23#include "ELFSectionHeaderTable.h" 24#include "StubLayout.h" 25#include "GOT.h" 26#include "ELF.h" 27 28#include <llvm/ADT/SmallVector.h> 29 30#include "utils/rsl_assert.h" 31 32template <unsigned Bitwidth> 33template <typename Archiver> 34inline ELFObject<Bitwidth> * 35ELFObject<Bitwidth>::read(Archiver &AR) { 36 llvm::OwningPtr<ELFObjectTy> object(new ELFObjectTy()); 37 38 // Read header 39 object->header.reset(ELFHeaderTy::read(AR)); 40 if (!object->header) { 41 return 0; 42 } 43 44 // Read section table 45 object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get())); 46 if (!object->shtab) { 47 return 0; 48 } 49 50 // Read each section 51 llvm::SmallVector<size_t, 4> progbits_ndx; 52 for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) { 53 if ((*object->shtab)[i]->getType() == SHT_PROGBITS) { 54 object->stab.push_back(NULL); 55 progbits_ndx.push_back(i); 56 } else { 57 llvm::OwningPtr<ELFSectionTy> sec( 58 ELFSectionTy::read(AR, object.get(), (*object->shtab)[i])); 59 object->stab.push_back(sec.take()); 60 } 61 } 62 63 object->shtab->buildNameMap(); 64 ELFSectionSymTabTy *symtab = 65 static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab")); 66 rsl_assert(symtab && "Symtab is required."); 67 symtab->buildNameMap(); 68 69 for (size_t i = 0; i < progbits_ndx.size(); ++i) { 70 size_t index = progbits_ndx[i]; 71 72 llvm::OwningPtr<ELFSectionTy> sec( 73 ELFSectionTy::read(AR, object.get(), (*object->shtab)[index])); 74 object->stab[index] = sec.take(); 75 } 76 77 return object.take(); 78} 79 80template <unsigned Bitwidth> 81inline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const { 82 ELFSectionTy const *sec = stab[header->getStringSectionIndex()]; 83 84 if (sec) { 85 ELFSectionStrTabTy const &st = 86 static_cast<ELFSectionStrTabTy const &>(*sec); 87 return st[i]; 88 } 89 90 return NULL; 91} 92 93template <unsigned Bitwidth> 94inline ELFSection<Bitwidth> const * 95ELFObject<Bitwidth>::getSectionByIndex(size_t i) const { 96 return stab[i]; 97} 98 99template <unsigned Bitwidth> 100inline ELFSection<Bitwidth> * 101ELFObject<Bitwidth>::getSectionByIndex(size_t i) { 102 return stab[i]; 103} 104 105template <unsigned Bitwidth> 106inline ELFSection<Bitwidth> const * 107ELFObject<Bitwidth>::getSectionByName(std::string const &str) const { 108 size_t idx = getSectionHeaderTable()->getByName(str)->getIndex(); 109 return stab[idx]; 110} 111 112template <unsigned Bitwidth> 113inline ELFSection<Bitwidth> * 114ELFObject<Bitwidth>::getSectionByName(std::string const &str) { 115 ELFObjectTy const *const_this = this; 116 ELFSectionTy const *sptr = const_this->getSectionByName(str); 117 // Const cast for the same API's const and non-const versions. 118 return const_cast<ELFSectionTy *>(sptr); 119} 120 121 122template <unsigned Bitwidth> 123inline void ELFObject<Bitwidth>:: 124relocateARM(void *(*find_sym)(void *context, char const *name), 125 void *context, 126 ELFSectionRelTableTy *reltab, 127 ELFSectionProgBitsTy *text) { 128 // FIXME: Should be implement in independent files. 129 rsl_assert(Bitwidth == 32 && "ARM only have 32 bits."); 130 131 ELFSectionSymTabTy *symtab = 132 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 133 rsl_assert(symtab && "Symtab is required."); 134 135 for (size_t i = 0; i < reltab->size(); ++i) { 136 // FIXME: Can not implement here, use Fixup! 137 ELFRelocTy *rel = (*reltab)[i]; 138 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 139 140 // FIXME: May be not uint32_t *. 141 typedef int32_t Inst_t; 142 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 143 Inst_t P = (Inst_t)(int64_t)inst; 144 Inst_t A = 0; 145 Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_ARM); 146 Inst_t T = 0; 147 148 if (sym->isConcreteFunc() && (sym->getValue() & 0x1)) { 149 T = 1; 150 } 151 152 switch (rel->getType()) { 153 default: 154 rsl_assert(0 && "Not implemented relocation type."); 155 break; 156 157 case R_ARM_ABS32: 158 { 159 if (S == 0 && sym->getType() == STT_NOTYPE) { 160 void *ext_sym = find_sym(context, sym->getName()); 161 if (!ext_sym) { 162 missingSymbols = true; 163 } 164 S = (Inst_t)(uintptr_t)ext_sym; 165 sym->setAddress(ext_sym); 166 } 167 A = *inst; 168 *inst = (S + A) | T; 169 } 170 break; 171 172 // FIXME: Predefine relocation codes. 173 case R_ARM_CALL: 174 case R_ARM_THM_CALL: 175 { 176#define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1))) 177 if (rel->getType() == R_ARM_CALL) { 178 A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24); 179 A <<= 2; 180 } else { 181 // Hack for two 16bit. 182 *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16); 183 Inst_t s = (*inst >> 26) & 0x1u, // 26 184 u = (*inst >> 16) & 0x3FFu, // 25-16 185 l = *inst & 0x7FFu, // 10-0 186 j1 = (*inst >> 13) & 0x1u, // 13 187 j2 = (*inst >> 11) & 0x1u; // 11 188 Inst_t i1 = (~(j1 ^ s)) & 0x1u, 189 i2 = (~(j2 ^ s)) & 0x1u; 190 // [31-25][24][23][22][21-12][11-1][0] 191 // 0 s i1 i2 u l 0 192 A = SIGN_EXTEND((s << 23) | (i1 << 22) | (i2 << 21) | (u << 11) | l, 24); 193 A <<= 1; 194 } 195#undef SIGN_EXTEND 196 197 void *callee_addr = sym->getAddress(EM_ARM); 198 199 switch (sym->getType()) { 200 default: 201 rsl_assert(0 && "Wrong type for R_ARM_CALL relocation."); 202 abort(); 203 break; 204 205 case STT_FUNC: 206 // NOTE: Callee function is in the object file, but it may be 207 // in different PROGBITS section (which may be far call). 208 209 if (callee_addr == 0) { 210 rsl_assert(0 && "We should get function address at previous " 211 "sym->getAddress(EM_ARM) function call."); 212 abort(); 213 } 214 break; 215 216 case STT_NOTYPE: 217 // NOTE: Callee function is an external function. Call find_sym 218 // if it has not resolved yet. 219 220 if (callee_addr == 0) { 221 callee_addr = find_sym(context, sym->getName()); 222 if (!callee_addr) { 223 missingSymbols = true; 224 } 225 sym->setAddress(callee_addr); 226 } 227 break; 228 } 229 230 // Get the stub for this function 231 StubLayout *stub_layout = text->getStubLayout(); 232 233 if (!stub_layout) { 234 llvm::errs() << "unable to get stub layout." << "\n"; 235 abort(); 236 } 237 238 void *stub = stub_layout->allocateStub(callee_addr); 239 240 if (!stub) { 241 llvm::errs() << "unable to allocate stub." << "\n"; 242 abort(); 243 } 244 245 //LOGI("Function %s: using stub %p\n", sym->getName(), stub); 246 S = (uint32_t)(uintptr_t)stub; 247 248 if (rel->getType() == R_ARM_CALL) { 249 // Relocate the R_ARM_CALL relocation type 250 uint32_t result = (S + A - P) >> 2; 251 252 if (result > 0x007FFFFF && result < 0xFF800000) { 253 rsl_assert(0 && "Stub is still too far"); 254 abort(); 255 } 256 257 *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000); 258 } else { 259 P &= ~0x3; // Base address align to 4 bytes. (For BLX.) 260 261 // Relocate the R_ARM_THM_CALL relocation type 262 uint32_t result = (S + A - P) >> 1; 263 264 if (result > 0x007FFFFF && result < 0xFF800000) { 265 rsl_assert(0 && "Stub is still too far"); 266 abort(); 267 } 268 269 //*inst &= 0xF800D000u; 270 // Rewrite instruction to BLX. (Stub is always ARM.) 271 *inst &= 0xF800C000u; 272 // [31-25][24][23][22][21-12][11-1][0] 273 // 0 s i1 i2 u l 0 274 Inst_t s = (result >> 23) & 0x1u, // 26 275 u = (result >> 11) & 0x3FFu, // 25-16 276 // For BLX, bit [0] is 0. 277 l = result & 0x7FEu, // 10-0 278 i1 = (result >> 22) & 0x1u, 279 i2 = (result >> 21) & 0x1u; 280 Inst_t j1 = ((~i1) ^ s) & 0x01u, // 13 281 j2 = ((~i2) ^ s) & 0x01u; // 11 282 *inst |= s << 26; 283 *inst |= u << 16; 284 *inst |= l; 285 *inst |= j1 << 13; 286 *inst |= j2 << 11; 287 // Hack for two 16bit. 288 *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16); 289 } 290 } 291 break; 292 case R_ARM_MOVT_ABS: 293 case R_ARM_MOVW_ABS_NC: 294 case R_ARM_THM_MOVW_ABS_NC: 295 case R_ARM_THM_MOVT_ABS: 296 { 297 if (S == 0 && sym->getType() == STT_NOTYPE) { 298 void *ext_sym = find_sym(context, sym->getName()); 299 if (!ext_sym) { 300 missingSymbols = true; 301 } 302 S = (Inst_t)(uintptr_t)ext_sym; 303 sym->setAddress(ext_sym); 304 } 305 if (rel->getType() == R_ARM_MOVT_ABS 306 || rel->getType() == R_ARM_THM_MOVT_ABS) { 307 S >>= 16; 308 } 309 310 if (rel->getType() == R_ARM_MOVT_ABS 311 || rel->getType() == R_ARM_MOVW_ABS_NC) { 312 // No need sign extend. 313 A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF); 314 uint32_t result = (S + A); 315 *inst = (((result) & 0xF000) << 4) | 316 ((result) & 0xFFF) | 317 (*inst & 0xFFF0F000); 318 } else { 319 // Hack for two 16bit. 320 *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16); 321 // imm16: [19-16][26][14-12][7-0] 322 A = (((*inst >> 4) & 0xF000u) | 323 ((*inst >> 15) & 0x0800u) | 324 ((*inst >> 4) & 0x0700u) | 325 ( *inst & 0x00FFu)); 326 uint32_t result; 327 if (rel->getType() == R_ARM_THM_MOVT_ABS) { 328 result = (S + A); 329 } else { 330 result = (S + A) | T; 331 } 332 // imm16: [19-16][26][14-12][7-0] 333 *inst &= 0xFBF08F00u; 334 *inst |= (result & 0xF000u) << 4; 335 *inst |= (result & 0x0800u) << 15; 336 *inst |= (result & 0x0700u) << 4; 337 *inst |= (result & 0x00FFu); 338 // Hack for two 16bit. 339 *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16); 340 } 341 } 342 break; 343 } 344 //llvm::errs() << "S: " << (void *)S << '\n'; 345 //llvm::errs() << "A: " << (void *)A << '\n'; 346 //llvm::errs() << "P: " << (void *)P << '\n'; 347 //llvm::errs() << "S+A: " << (void *)(S+A) << '\n'; 348 //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n'; 349 } 350} 351 352template <unsigned Bitwidth> 353inline void ELFObject<Bitwidth>:: 354relocateX86_64(void *(*find_sym)(void *context, char const *name), 355 void *context, 356 ELFSectionRelTableTy *reltab, 357 ELFSectionProgBitsTy *text) { 358 rsl_assert(Bitwidth == 64 && "Only support X86_64."); 359 360 ELFSectionSymTabTy *symtab = 361 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 362 rsl_assert(symtab && "Symtab is required."); 363 364 for (size_t i = 0; i < reltab->size(); ++i) { 365 // FIXME: Can not implement here, use Fixup! 366 ELFRelocTy *rel = (*reltab)[i]; 367 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 368 369 //typedef uint64_t Inst_t; 370 typedef int32_t Inst_t; 371 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 372 Inst_t P = (Inst_t)(int64_t)inst; 373 Inst_t A = (Inst_t)(int64_t)rel->getAddend(); 374 Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_X86_64); 375 376 if (S == 0) { 377 S = (Inst_t)(int64_t)find_sym(context, sym->getName()); 378 if (!S) { 379 missingSymbols = true; 380 } 381 sym->setAddress((void *)S); 382 } 383 384 switch (rel->getType()) { 385 default: 386 rsl_assert(0 && "Not implemented relocation type."); 387 break; 388 389 // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here. 390 case 1: // R_X86_64_64 391 *inst = (S+A); 392 break; 393 394 case 2: // R_X86_64_PC32 395 *inst = (S+A-P); 396 break; 397 398 case 10: // R_X86_64_32 399 case 11: // R_X86_64_32S 400 *inst = (S+A); 401 break; 402 } 403 } 404} 405 406template <unsigned Bitwidth> 407inline void ELFObject<Bitwidth>:: 408relocateX86_32(void *(*find_sym)(void *context, char const *name), 409 void *context, 410 ELFSectionRelTableTy *reltab, 411 ELFSectionProgBitsTy *text) { 412 rsl_assert(Bitwidth == 32 && "Only support X86."); 413 414 ELFSectionSymTabTy *symtab = 415 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 416 rsl_assert(symtab && "Symtab is required."); 417 418 for (size_t i = 0; i < reltab->size(); ++i) { 419 // FIXME: Can not implement here, use Fixup! 420 ELFRelocTy *rel = (*reltab)[i]; 421 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 422 423 //typedef uint64_t Inst_t; 424 typedef int32_t Inst_t; 425 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 426 Inst_t P = (Inst_t)(uintptr_t)inst; 427 Inst_t A = (Inst_t)(uintptr_t)*inst; 428 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_386); 429 430 if (S == 0) { 431 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName()); 432 if (!S) { 433 missingSymbols = true; 434 } 435 sym->setAddress((void *)S); 436 } 437 438 switch (rel->getType()) { 439 default: 440 rsl_assert(0 && "Not implemented relocation type."); 441 break; 442 443 case R_386_PC32: 444 *inst = (S+A-P); 445 break; 446 447 case R_386_32: 448 *inst = (S+A); 449 break; 450 } 451 } 452} 453 454template <unsigned Bitwidth> 455inline void ELFObject<Bitwidth>:: 456relocateMIPS(void *(*find_sym)(void *context, char const *name), 457 void *context, 458 ELFSectionRelTableTy *reltab, 459 ELFSectionProgBitsTy *text) { 460 rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS."); 461 462 ELFSectionSymTabTy *symtab = 463 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 464 rsl_assert(symtab && "Symtab is required."); 465 466 for (size_t i = 0; i < reltab->size(); ++i) { 467 // FIXME: Can not implement here, use Fixup! 468 ELFRelocTy *rel = (*reltab)[i]; 469 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 470 471 typedef int32_t Inst_t; 472 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 473 Inst_t P = (Inst_t)(uintptr_t)inst; 474 Inst_t A = (Inst_t)(uintptr_t)*inst; 475 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_MIPS); 476 477 bool need_stub = false; 478 479 if (S == 0 && strcmp (sym->getName(), "_gp_disp") != 0) { 480 need_stub = true; 481 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName()); 482 if (!S) { 483 missingSymbols = true; 484 } 485 sym->setAddress((void *)S); 486 } 487 488 switch (rel->getType()) { 489 default: 490 rsl_assert(0 && "Not implemented relocation type."); 491 break; 492 493 case R_MIPS_NONE: 494 case R_MIPS_JALR: // ignore this 495 break; 496 497 case R_MIPS_16: 498 *inst &= 0xFFFF0000; 499 A = A & 0xFFFF; 500 A = S + (short)A; 501 rsl_assert(A >= -32768 && A <= 32767 && "R_MIPS_16 overflow."); 502 *inst |= (A & 0xFFFF); 503 break; 504 505 case R_MIPS_32: 506 *inst = S + A; 507 break; 508 509 case R_MIPS_26: 510 *inst &= 0xFC000000; 511 if (need_stub == false) { 512 A = (A & 0x3FFFFFF) << 2; 513 if (sym->getBindingAttribute() == STB_LOCAL) { // local binding 514 A |= ((P + 4) & 0xF0000000); 515 A += S; 516 *inst |= ((A >> 2) & 0x3FFFFFF); 517 } else { // external binding 518 if (A & 0x08000000) // Sign extend from bit 27 519 A |= 0xF0000000; 520 A += S; 521 *inst |= ((A >> 2) & 0x3FFFFFF); 522 if (((P + 4) >> 28) != (A >> 28)) { // far local call 523 void *stub = text->getStubLayout()->allocateStub((void *)A); 524 rsl_assert(stub && "cannot allocate stub."); 525 sym->setAddress(stub); 526 S = (int32_t)(intptr_t)stub; 527 *inst |= ((S >> 2) & 0x3FFFFFF); 528 rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far."); 529 } 530 } 531 } else { // shared-library call 532 A = (A & 0x3FFFFFF) << 2; 533 rsl_assert(A == 0 && "R_MIPS_26 addend is not zero."); 534 void *stub = text->getStubLayout()->allocateStub((void *)S); 535 rsl_assert(stub && "cannot allocate stub."); 536 sym->setAddress(stub); 537 S = (int32_t)(intptr_t)stub; 538 *inst |= ((S >> 2) & 0x3FFFFFF); 539 rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far."); 540 } 541 break; 542 543 case R_MIPS_HI16: 544 *inst &= 0xFFFF0000; 545 A = (A & 0xFFFF) << 16; 546 // Find the nearest LO16 relocation type after this entry 547 for (size_t j = i + 1; j < reltab->size(); j++) { 548 ELFRelocTy *this_rel = (*reltab)[j]; 549 ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()]; 550 if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) { 551 Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()]; 552 Inst_t this_A = (Inst_t)(uintptr_t)*this_inst; 553 this_A = this_A & 0xFFFF; 554 A += (short)this_A; 555 break; 556 } 557 } 558 if (strcmp (sym->getName(), "_gp_disp") == 0) { 559 S = (int)(intptr_t)got_address() + GP_OFFSET - (int)P; 560 sym->setAddress((void *)S); 561 } 562 *inst |= (((S + A + (int)0x8000) >> 16) & 0xFFFF); 563 break; 564 565 case R_MIPS_LO16: 566 *inst &= 0xFFFF0000; 567 A = A & 0xFFFF; 568 if (strcmp (sym->getName(), "_gp_disp") == 0) { 569 S = (Inst_t)(intptr_t)sym->getAddress(EM_MIPS); 570 } 571 *inst |= ((S + A) & 0xFFFF); 572 break; 573 574 case R_MIPS_GOT16: 575 case R_MIPS_CALL16: 576 { 577 *inst &= 0xFFFF0000; 578 A = A & 0xFFFF; 579 if (rel->getType() == R_MIPS_GOT16) { 580 if (sym->getBindingAttribute() == STB_LOCAL) { 581 A <<= 16; 582 583 // Find the nearest LO16 relocation type after this entry 584 for (size_t j = i + 1; j < reltab->size(); j++) { 585 ELFRelocTy *this_rel = (*reltab)[j]; 586 ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()]; 587 if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) { 588 Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()]; 589 Inst_t this_A = (Inst_t)(uintptr_t)*this_inst; 590 this_A = this_A & 0xFFFF; 591 A += (short)this_A; 592 break; 593 } 594 } 595 } else { 596 rsl_assert(A == 0 && "R_MIPS_GOT16 addend is not 0."); 597 } 598 } else { // R_MIPS_CALL16 599 rsl_assert(A == 0 && "R_MIPS_CALL16 addend is not 0."); 600 } 601 int got_index = search_got((int)rel->getSymTabIndex(), (void *)(S + A), 602 sym->getBindingAttribute()); 603 int got_offset = (got_index << 2) - GP_OFFSET; 604 *inst |= (got_offset & 0xFFFF); 605 } 606 break; 607 608 case R_MIPS_GPREL32: 609 *inst = A + S - ((int)(intptr_t)got_address() + GP_OFFSET); 610 break; 611 } 612 } 613} 614 615 616// TODO: Refactor all relocations. 617template <unsigned Bitwidth> 618inline void ELFObject<Bitwidth>:: 619relocate(void *(*find_sym)(void *context, char const *name), void *context) { 620 // Init SHNCommonDataSize. 621 // Need refactoring 622 size_t SHNCommonDataSize = 0; 623 624 ELFSectionSymTabTy *symtab = 625 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 626 rsl_assert(symtab && "Symtab is required."); 627 628 for (size_t i = 0; i < symtab->size(); ++i) { 629 ELFSymbolTy *sym = (*symtab)[i]; 630 631 if (sym->getType() != STT_OBJECT) { 632 continue; 633 } 634 635 size_t idx = (size_t)sym->getSectionIndex(); 636 switch (idx) { 637 default: 638 if ((*shtab)[idx]->getType() == SHT_NOBITS) { 639 // FIXME(logan): This is a workaround for .lcomm directives 640 // bug of LLVM ARM MC code generator. Remove this when the 641 // LLVM bug is fixed. 642 643 size_t align = 16; 644 SHNCommonDataSize += (size_t)sym->getSize() + align; 645 } 646 break; 647 648 case SHN_COMMON: 649 { 650 size_t align = (size_t)sym->getValue(); 651 SHNCommonDataSize += (size_t)sym->getSize() + align; 652 } 653 break; 654 655 case SHN_ABS: 656 case SHN_UNDEF: 657 case SHN_XINDEX: 658 break; 659 } 660 } 661 if (!initSHNCommonDataSize(SHNCommonDataSize)) { 662 rsl_assert("Allocate memory for common variable fail!"); 663 } 664 665 for (size_t i = 0; i < stab.size(); ++i) { 666 ELFSectionHeaderTy *sh = (*shtab)[i]; 667 if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) { 668 continue; 669 } 670 ELFSectionRelTableTy *reltab = 671 static_cast<ELFSectionRelTableTy *>(stab[i]); 672 rsl_assert(reltab && "Relocation section can't be NULL."); 673 674 const char *reltab_name = sh->getName(); 675 const char *need_rel_name; 676 if (sh->getType() == SHT_REL) { 677 need_rel_name = reltab_name + 4; 678 // ".rel.xxxx" 679 // ^ start from here. 680 } else { 681 need_rel_name = reltab_name + 5; 682 } 683 684 ELFSectionProgBitsTy *need_rel = 685 static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name)); 686 rsl_assert(need_rel && "Need be relocated section can't be NULL."); 687 688 switch (getHeader()->getMachine()) { 689 case EM_ARM: 690 relocateARM(find_sym, context, reltab, need_rel); 691 break; 692 case EM_386: 693 relocateX86_32(find_sym, context, reltab, need_rel); 694 break; 695 case EM_X86_64: 696 relocateX86_64(find_sym, context, reltab, need_rel); 697 break; 698 case EM_MIPS: 699 relocateMIPS(find_sym, context, reltab, need_rel); 700 break; 701 702 default: 703 rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation."); 704 break; 705 } 706 } 707 708 for (size_t i = 0; i < stab.size(); ++i) { 709 ELFSectionHeaderTy *sh = (*shtab)[i]; 710 if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) { 711 if (stab[i]) { 712 static_cast<ELFSectionBitsTy *>(stab[i])->protect(); 713 } 714 } 715 } 716} 717 718template <unsigned Bitwidth> 719inline void ELFObject<Bitwidth>::print() const { 720 header->print(); 721 shtab->print(); 722 723 for (size_t i = 0; i < stab.size(); ++i) { 724 ELFSectionTy *sec = stab[i]; 725 if (sec) { 726 sec->print(); 727 } 728 } 729} 730 731#endif // ELF_OBJECT_HXX 732