ELFObject.hxx revision 50b814ae8797a929bc0416d6a97e3551b24eaf30
1/* 2 * Copyright 2011, 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 147 switch (rel->getType()) { 148 default: 149 rsl_assert(0 && "Not implemented relocation type."); 150 break; 151 152 case R_ARM_ABS32: 153 { 154 A = *inst; 155 *inst = (S+A); 156 } 157 break; 158 159 // FIXME: Predefine relocation codes. 160 case R_ARM_CALL: 161 { 162#define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1))) 163 A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24); 164#undef SIGN_EXTEND 165 166 void *callee_addr = sym->getAddress(EM_ARM); 167 168 switch (sym->getType()) { 169 default: 170 rsl_assert(0 && "Wrong type for R_ARM_CALL relocation."); 171 abort(); 172 break; 173 174 case STT_FUNC: 175 // NOTE: Callee function is in the object file, but it may be 176 // in different PROGBITS section (which may be far call). 177 178 if (callee_addr == 0) { 179 rsl_assert(0 && "We should get function address at previous " 180 "sym->getAddress(EM_ARM) function call."); 181 abort(); 182 } 183 break; 184 185 case STT_NOTYPE: 186 // NOTE: Callee function is an external function. Call find_sym 187 // if it has not resolved yet. 188 189 if (callee_addr == 0) { 190 callee_addr = find_sym(context, sym->getName()); 191 if (!callee_addr) { 192 missingSymbols = true; 193 } 194 sym->setAddress(callee_addr); 195 } 196 break; 197 } 198 199 // Get the stub for this function 200 StubLayout *stub_layout = text->getStubLayout(); 201 202 if (!stub_layout) { 203 llvm::errs() << "unable to get stub layout." << "\n"; 204 abort(); 205 } 206 207 void *stub = stub_layout->allocateStub(callee_addr); 208 209 if (!stub) { 210 llvm::errs() << "unable to allocate stub." << "\n"; 211 abort(); 212 } 213 214 //LOGI("Function %s: using stub %p\n", sym->getName(), stub); 215 S = (uint32_t)(uintptr_t)stub; 216 217 // Relocate the R_ARM_CALL relocation type 218 uint32_t result = (S >> 2) - (P >> 2) + A; 219 220 if (result > 0x007fffff && result < 0xff800000) { 221 rsl_assert(0 && "Stub is still too far"); 222 abort(); 223 } 224 225 *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000); 226 } 227 break; 228 case R_ARM_MOVT_ABS: 229 case R_ARM_MOVW_ABS_NC: 230 { 231 if (S==0 && sym->getType() == STT_NOTYPE) 232 { 233 void *ext_sym = find_sym(context, sym->getName()); 234 if (!ext_sym) { 235 missingSymbols = true; 236 } 237 S = (Inst_t)(uintptr_t)ext_sym; 238 sym->setAddress(ext_sym); 239 } 240 if (rel->getType() == R_ARM_MOVT_ABS) { 241 S >>= 16; 242 } 243 244 // No need sign extend. 245 A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF); 246 uint32_t result = (S+A); 247 *inst = (((result) & 0xF000) << 4) | 248 ((result) & 0xFFF) | 249 (*inst & 0xFFF0F000); 250 } 251 break; 252 } 253 //llvm::errs() << "S: " << (void *)S << '\n'; 254 //llvm::errs() << "A: " << (void *)A << '\n'; 255 //llvm::errs() << "P: " << (void *)P << '\n'; 256 //llvm::errs() << "S+A: " << (void *)(S+A) << '\n'; 257 //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n'; 258 } 259} 260 261template <unsigned Bitwidth> 262inline void ELFObject<Bitwidth>:: 263relocateX86_64(void *(*find_sym)(void *context, char const *name), 264 void *context, 265 ELFSectionRelTableTy *reltab, 266 ELFSectionProgBitsTy *text) { 267 rsl_assert(Bitwidth == 64 && "Only support X86_64."); 268 269 ELFSectionSymTabTy *symtab = 270 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 271 rsl_assert(symtab && "Symtab is required."); 272 273 for (size_t i = 0; i < reltab->size(); ++i) { 274 // FIXME: Can not implement here, use Fixup! 275 ELFRelocTy *rel = (*reltab)[i]; 276 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 277 278 //typedef uint64_t Inst_t; 279 typedef int32_t Inst_t; 280 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 281 Inst_t P = (Inst_t)(int64_t)inst; 282 Inst_t A = (Inst_t)(int64_t)rel->getAddend(); 283 Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_X86_64); 284 285 if (S == 0) { 286 S = (Inst_t)(int64_t)find_sym(context, sym->getName()); 287 if (!S) { 288 missingSymbols = true; 289 } 290 sym->setAddress((void *)S); 291 } 292 293 switch (rel->getType()) { 294 default: 295 rsl_assert(0 && "Not implemented relocation type."); 296 break; 297 298 // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here. 299 case 1: // R_X86_64_64 300 *inst = (S+A); 301 break; 302 303 case 2: // R_X86_64_PC32 304 *inst = (S+A-P); 305 break; 306 307 case 10: // R_X86_64_32 308 case 11: // R_X86_64_32S 309 *inst = (S+A); 310 break; 311 } 312 } 313} 314 315template <unsigned Bitwidth> 316inline void ELFObject<Bitwidth>:: 317relocateX86_32(void *(*find_sym)(void *context, char const *name), 318 void *context, 319 ELFSectionRelTableTy *reltab, 320 ELFSectionProgBitsTy *text) { 321 rsl_assert(Bitwidth == 32 && "Only support X86."); 322 323 ELFSectionSymTabTy *symtab = 324 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 325 rsl_assert(symtab && "Symtab is required."); 326 327 for (size_t i = 0; i < reltab->size(); ++i) { 328 // FIXME: Can not implement here, use Fixup! 329 ELFRelocTy *rel = (*reltab)[i]; 330 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 331 332 //typedef uint64_t Inst_t; 333 typedef int32_t Inst_t; 334 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 335 Inst_t P = (Inst_t)(uintptr_t)inst; 336 Inst_t A = (Inst_t)(uintptr_t)*inst; 337 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_386); 338 339 if (S == 0) { 340 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName()); 341 if (!S) { 342 missingSymbols = true; 343 } 344 sym->setAddress((void *)S); 345 } 346 347 switch (rel->getType()) { 348 default: 349 rsl_assert(0 && "Not implemented relocation type."); 350 break; 351 352 case R_386_PC32: 353 *inst = (S+A-P); 354 break; 355 356 case R_386_32: 357 *inst = (S+A); 358 break; 359 } 360 } 361} 362 363template <unsigned Bitwidth> 364inline void ELFObject<Bitwidth>:: 365relocateMIPS(void *(*find_sym)(void *context, char const *name), 366 void *context, 367 ELFSectionRelTableTy *reltab, 368 ELFSectionProgBitsTy *text) { 369 rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS."); 370 371 ELFSectionSymTabTy *symtab = 372 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 373 rsl_assert(symtab && "Symtab is required."); 374 375 for (size_t i = 0; i < reltab->size(); ++i) { 376 // FIXME: Can not implement here, use Fixup! 377 ELFRelocTy *rel = (*reltab)[i]; 378 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 379 380 typedef int32_t Inst_t; 381 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 382 Inst_t P = (Inst_t)(uintptr_t)inst; 383 Inst_t A = (Inst_t)(uintptr_t)*inst; 384 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_MIPS); 385 386 bool need_stub = false; 387 388 if (S == 0 && strcmp (sym->getName(), "_gp_disp") != 0) { 389 need_stub = true; 390 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName()); 391 if (!S) { 392 missingSymbols = true; 393 } 394 sym->setAddress((void *)S); 395 } 396 397 switch (rel->getType()) { 398 default: 399 rsl_assert(0 && "Not implemented relocation type."); 400 break; 401 402 case R_MIPS_NONE: 403 case R_MIPS_JALR: // ignore this 404 break; 405 406 case R_MIPS_16: 407 *inst &= 0xFFFF0000; 408 A = A & 0xFFFF; 409 A = S + (short)A; 410 rsl_assert(A >= -32768 && A <= 32767 && "R_MIPS_16 overflow."); 411 *inst |= (A & 0xFFFF); 412 break; 413 414 case R_MIPS_32: 415 *inst = S + A; 416 break; 417 418 case R_MIPS_26: 419 *inst &= 0xFC000000; 420 if (need_stub == false) { 421 A = (A & 0x3FFFFFF) << 2; 422 if (sym->getBindingAttribute() == STB_LOCAL) { // local binding 423 A |= ((P + 4) & 0xF0000000); 424 A += S; 425 *inst |= ((A >> 2) & 0x3FFFFFF); 426 } 427 else { // external binding 428 if (A & 0x08000000) // Sign extend from bit 27 429 A |= 0xF0000000; 430 A += S; 431 *inst |= ((A >> 2) & 0x3FFFFFF); 432 if (((P + 4) >> 28) != (A >> 28)) { // far local call 433 void *stub = text->getStubLayout()->allocateStub((void *)A); 434 rsl_assert(stub && "cannot allocate stub."); 435 sym->setAddress(stub); 436 S = (int32_t)stub; 437 *inst |= ((S >> 2) & 0x3FFFFFF); 438 rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far."); 439 } 440 } 441 } 442 else { // shared-library call 443 A = (A & 0x3FFFFFF) << 2; 444 rsl_assert(A == 0 && "R_MIPS_26 addend is not zero."); 445 void *stub = text->getStubLayout()->allocateStub((void *)S); 446 rsl_assert(stub && "cannot allocate stub."); 447 sym->setAddress(stub); 448 S = (int32_t)stub; 449 *inst |= ((S >> 2) & 0x3FFFFFF); 450 rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far."); 451 } 452 break; 453 454 case R_MIPS_HI16: 455 *inst &= 0xFFFF0000; 456 A = (A & 0xFFFF) << 16; 457 // Find the nearest LO16 relocation type after this entry 458 for (size_t j = i + 1; j < reltab->size(); j++) { 459 ELFRelocTy *this_rel = (*reltab)[j]; 460 ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()]; 461 if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) { 462 Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()]; 463 Inst_t this_A = (Inst_t)(uintptr_t)*this_inst; 464 this_A = this_A & 0xFFFF; 465 A += (short)this_A; 466 break; 467 } 468 } 469 if (strcmp (sym->getName(), "_gp_disp") == 0) { 470 S = (int)got_address() + GP_OFFSET - (int)P; 471 sym->setAddress((void *)S); 472 } 473 *inst |= (((S + A + (int)0x8000) >> 16) & 0xFFFF); 474 break; 475 476 case R_MIPS_LO16: 477 *inst &= 0xFFFF0000; 478 A = A & 0xFFFF; 479 if (strcmp (sym->getName(), "_gp_disp") == 0) { 480 S = (Inst_t)sym->getAddress(EM_MIPS); 481 } 482 *inst |= ((S + A) & 0xFFFF); 483 break; 484 485 case R_MIPS_GOT16: 486 case R_MIPS_CALL16: 487 { 488 *inst &= 0xFFFF0000; 489 A = A & 0xFFFF; 490 if (rel->getType() == R_MIPS_GOT16) { 491 if (sym->getBindingAttribute() == STB_LOCAL) { 492 A <<= 16; 493 494 // Find the nearest LO16 relocation type after this entry 495 for (size_t j = i + 1; j < reltab->size(); j++) { 496 ELFRelocTy *this_rel = (*reltab)[j]; 497 ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()]; 498 if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) { 499 Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()]; 500 Inst_t this_A = (Inst_t)(uintptr_t)*this_inst; 501 this_A = this_A & 0xFFFF; 502 A += (short)this_A; 503 break; 504 } 505 } 506 } 507 else { 508 rsl_assert(A == 0 && "R_MIPS_GOT16 addend is not 0."); 509 } 510 } 511 else { // R_MIPS_CALL16 512 rsl_assert(A == 0 && "R_MIPS_CALL16 addend is not 0."); 513 } 514 int got_index = search_got((int)rel->getSymTabIndex(), (void *)(S + A), 515 sym->getBindingAttribute()); 516 int got_offset = (got_index << 2) - GP_OFFSET; 517 *inst |= (got_offset & 0xFFFF); 518 } 519 break; 520 521 case R_MIPS_GPREL32: 522 *inst = A + S - ((int)got_address() + GP_OFFSET); 523 break; 524 } 525 } 526} 527 528 529// TODO: Refactor all relocations. 530template <unsigned Bitwidth> 531inline void ELFObject<Bitwidth>:: 532relocate(void *(*find_sym)(void *context, char const *name), void *context) { 533 // Init SHNCommonDataSize. 534 // Need refactoring 535 size_t SHNCommonDataSize = 0; 536 537 ELFSectionSymTabTy *symtab = 538 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 539 rsl_assert(symtab && "Symtab is required."); 540 541 for (size_t i = 0; i < symtab->size(); ++i) { 542 ELFSymbolTy *sym = (*symtab)[i]; 543 544 if (sym->getType() != STT_OBJECT) { 545 continue; 546 } 547 548 size_t idx = (size_t)sym->getSectionIndex(); 549 switch (idx) { 550 default: 551 if ((*shtab)[idx]->getType() == SHT_NOBITS) { 552 // FIXME(logan): This is a workaround for .lcomm directives 553 // bug of LLVM ARM MC code generator. Remove this when the 554 // LLVM bug is fixed. 555 556 size_t align = 16; 557 SHNCommonDataSize += (size_t)sym->getSize() + align; 558 } 559 break; 560 561 case SHN_COMMON: 562 { 563 size_t align = (size_t)sym->getValue(); 564 SHNCommonDataSize += (size_t)sym->getSize() + align; 565 } 566 break; 567 568 case SHN_ABS: 569 case SHN_UNDEF: 570 case SHN_XINDEX: 571 break; 572 } 573 } 574 if (!initSHNCommonDataSize(SHNCommonDataSize)) { 575 rsl_assert("Allocate memory for common variable fail!"); 576 } 577 578 for (size_t i = 0; i < stab.size(); ++i) { 579 ELFSectionHeaderTy *sh = (*shtab)[i]; 580 if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) { 581 continue; 582 } 583 ELFSectionRelTableTy *reltab = 584 static_cast<ELFSectionRelTableTy *>(stab[i]); 585 rsl_assert(reltab && "Relocation section can't be NULL."); 586 587 const char *reltab_name = sh->getName(); 588 const char *need_rel_name; 589 if (sh->getType() == SHT_REL) { 590 need_rel_name = reltab_name + 4; 591 // ".rel.xxxx" 592 // ^ start from here. 593 } else { 594 need_rel_name = reltab_name + 5; 595 } 596 597 ELFSectionProgBitsTy *need_rel = 598 static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name)); 599 rsl_assert(need_rel && "Need be relocated section can't be NULL."); 600 601 switch (getHeader()->getMachine()) { 602 case EM_ARM: 603 relocateARM(find_sym, context, reltab, need_rel); 604 break; 605 case EM_386: 606 relocateX86_32(find_sym, context, reltab, need_rel); 607 break; 608 case EM_X86_64: 609 relocateX86_64(find_sym, context, reltab, need_rel); 610 break; 611 case EM_MIPS: 612 relocateMIPS(find_sym, context, reltab, need_rel); 613 break; 614 615 default: 616 rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation."); 617 break; 618 } 619 } 620 621 for (size_t i = 0; i < stab.size(); ++i) { 622 ELFSectionHeaderTy *sh = (*shtab)[i]; 623 if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) { 624 if (stab[i]) { 625 static_cast<ELFSectionBitsTy *>(stab[i])->protect(); 626 } 627 } 628 } 629} 630 631template <unsigned Bitwidth> 632inline void ELFObject<Bitwidth>::print() const { 633 header->print(); 634 shtab->print(); 635 636 for (size_t i = 0; i < stab.size(); ++i) { 637 ELFSectionTy *sec = stab[i]; 638 if (sec) { 639 sec->print(); 640 } 641 } 642} 643 644#endif // ELF_OBJECT_HXX 645