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