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 "ELF.h" 26 27 #include <llvm/ADT/SmallVector.h> 28 29 #include "utils/rsl_assert.h" 30 31 template <unsigned Bitwidth> 32 template <typename Archiver> 33 inline ELFObject<Bitwidth> * 34 ELFObject<Bitwidth>::read(Archiver &AR) { 35 llvm::OwningPtr<ELFObjectTy> object(new ELFObjectTy()); 36 37 // Read header 38 object->header.reset(ELFHeaderTy::read(AR)); 39 if (!object->header) { 40 return 0; 41 } 42 43 // Read section table 44 object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get())); 45 if (!object->shtab) { 46 return 0; 47 } 48 49 // Read each section 50 llvm::SmallVector<size_t, 4> progbits_ndx; 51 for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) { 52 if ((*object->shtab)[i]->getType() == SHT_PROGBITS) { 53 object->stab.push_back(NULL); 54 progbits_ndx.push_back(i); 55 } else { 56 llvm::OwningPtr<ELFSectionTy> sec( 57 ELFSectionTy::read(AR, object.get(), (*object->shtab)[i])); 58 object->stab.push_back(sec.take()); 59 } 60 } 61 62 object->shtab->buildNameMap(); 63 ELFSectionSymTabTy *symtab = 64 static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab")); 65 rsl_assert(symtab && "Symtab is required."); 66 symtab->buildNameMap(); 67 68 for (size_t i = 0; i < progbits_ndx.size(); ++i) { 69 size_t index = progbits_ndx[i]; 70 71 llvm::OwningPtr<ELFSectionTy> sec( 72 ELFSectionTy::read(AR, object.get(), (*object->shtab)[index])); 73 object->stab[index] = sec.take(); 74 } 75 76 return object.take(); 77 } 78 79 template <unsigned Bitwidth> 80 inline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const { 81 ELFSectionTy const *sec = stab[header->getStringSectionIndex()]; 82 83 if (sec) { 84 ELFSectionStrTabTy const &st = 85 static_cast<ELFSectionStrTabTy const &>(*sec); 86 return st[i]; 87 } 88 89 return NULL; 90 } 91 92 template <unsigned Bitwidth> 93 inline ELFSection<Bitwidth> const * 94 ELFObject<Bitwidth>::getSectionByIndex(size_t i) const { 95 return stab[i]; 96 } 97 98 template <unsigned Bitwidth> 99 inline ELFSection<Bitwidth> * 100 ELFObject<Bitwidth>::getSectionByIndex(size_t i) { 101 return stab[i]; 102 } 103 104 template <unsigned Bitwidth> 105 inline ELFSection<Bitwidth> const * 106 ELFObject<Bitwidth>::getSectionByName(std::string const &str) const { 107 size_t idx = getSectionHeaderTable()->getByName(str)->getIndex(); 108 return stab[idx]; 109 } 110 111 template <unsigned Bitwidth> 112 inline ELFSection<Bitwidth> * 113 ELFObject<Bitwidth>::getSectionByName(std::string const &str) { 114 ELFObjectTy const *const_this = this; 115 ELFSectionTy const *sptr = const_this->getSectionByName(str); 116 // Const cast for the same API's const and non-const versions. 117 return const_cast<ELFSectionTy *>(sptr); 118 } 119 120 121 template <unsigned Bitwidth> 122 inline void ELFObject<Bitwidth>:: 123 relocateARM(void *(*find_sym)(void *context, char const *name), 124 void *context, 125 ELFSectionRelTableTy *reltab, 126 ELFSectionProgBitsTy *text) { 127 // FIXME: Should be implement in independent files. 128 rsl_assert(Bitwidth == 32 && "ARM only have 32 bits."); 129 130 ELFSectionSymTabTy *symtab = 131 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 132 rsl_assert(symtab && "Symtab is required."); 133 134 for (size_t i = 0; i < reltab->size(); ++i) { 135 // FIXME: Can not implement here, use Fixup! 136 ELFRelocTy *rel = (*reltab)[i]; 137 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 138 139 // FIXME: May be not uint32_t *. 140 typedef int32_t Inst_t; 141 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 142 Inst_t P = (Inst_t)(int64_t)inst; 143 Inst_t A = 0; 144 Inst_t S = (Inst_t)(int64_t)sym->getAddress(); 145 146 switch (rel->getType()) { 147 default: 148 rsl_assert(0 && "Not implemented relocation type."); 149 break; 150 151 case R_ARM_ABS32: 152 { 153 A = *inst; 154 *inst = (S+A); 155 } 156 break; 157 158 // FIXME: Predefine relocation codes. 159 case R_ARM_CALL: 160 { 161 #define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1))) 162 A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24); 163 #undef SIGN_EXTEND 164 165 switch (sym->getType()) { 166 default: 167 rsl_assert(0 && "Wrong type for R_ARM_CALL relocation."); 168 abort(); 169 break; 170 171 case STT_FUNC: 172 if (S == 0) { 173 rsl_assert(0 && "We should get function address at previous " 174 "sym->getAddress() function call."); 175 abort(); 176 } 177 break; 178 179 case STT_NOTYPE: 180 if (S == 0) { 181 void *ext_func = find_sym(context, sym->getName()); 182 #ifdef SUPPORT_NEAR_JUMP_EVEN_IF_BLc2BLX_NEEDED 183 S = (Inst_t)(uintptr_t)ext_func; 184 sym->setAddress(ext_func); 185 186 uint32_t result = (S >> 2) - (P >> 2) + A; 187 if (result > 0x007fffff && result < 0xff800000) { 188 #endif 189 #ifndef __arm__ 190 // We have not implement function stub in this runtime env 191 rsl_assert(0 && "Target address is far from call instruction"); 192 abort(); 193 #else 194 void *stub = text->getStubLayout()->allocateStub(ext_func); 195 if (!stub) { 196 llvm::errs() << "unable to allocate stub." << "\n"; 197 exit(EXIT_FAILURE); 198 } 199 200 //out() << "stub: for " << ext_func << " at " << stub << "\n"; 201 sym->setAddress(stub); 202 S = (uint32_t)stub; 203 #endif 204 #ifdef SUPPORT_NEAR_JUMP_EVEN_IF_BLc2BLX_NEEDED 205 } 206 #endif 207 } 208 break; 209 } 210 211 uint32_t result = (S >> 2) - (P >> 2) + A; 212 213 if (result > 0x007fffff && result < 0xff800000) { 214 rsl_assert(0 && "Stub is still too far"); 215 abort(); 216 } 217 218 *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000); 219 } 220 break; 221 case R_ARM_MOVT_ABS: 222 case R_ARM_MOVW_ABS_NC: 223 { 224 if (S==0 && sym->getType() == STT_NOTYPE) 225 { 226 void *ext_sym = find_sym(context, sym->getName()); 227 S = (Inst_t)(uintptr_t)ext_sym; 228 sym->setAddress(ext_sym); 229 } 230 if (rel->getType() == R_ARM_MOVT_ABS) { 231 S >>= 16; 232 } 233 234 // No need sign extend. 235 A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF); 236 uint32_t result = (S+A); 237 *inst = (((result) & 0xF000) << 4) | 238 ((result) & 0xFFF) | 239 (*inst & 0xFFF0F000); 240 } 241 break; 242 } 243 //llvm::errs() << "S: " << (void *)S << '\n'; 244 //llvm::errs() << "A: " << (void *)A << '\n'; 245 //llvm::errs() << "P: " << (void *)P << '\n'; 246 //llvm::errs() << "S+A: " << (void *)(S+A) << '\n'; 247 //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n'; 248 } 249 } 250 251 template <unsigned Bitwidth> 252 inline void ELFObject<Bitwidth>:: 253 relocateX86_64(void *(*find_sym)(void *context, char const *name), 254 void *context, 255 ELFSectionRelTableTy *reltab, 256 ELFSectionProgBitsTy *text) { 257 rsl_assert(Bitwidth == 64 && "Only support X86_64."); 258 259 ELFSectionSymTabTy *symtab = 260 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 261 rsl_assert(symtab && "Symtab is required."); 262 263 for (size_t i = 0; i < reltab->size(); ++i) { 264 // FIXME: Can not implement here, use Fixup! 265 ELFRelocTy *rel = (*reltab)[i]; 266 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 267 268 //typedef uint64_t Inst_t; 269 typedef int32_t Inst_t; 270 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 271 Inst_t P = (Inst_t)(int64_t)inst; 272 Inst_t A = (Inst_t)(int64_t)rel->getAddend(); 273 Inst_t S = (Inst_t)(int64_t)sym->getAddress(); 274 275 if (S == 0) { 276 S = (Inst_t)(int64_t)find_sym(context, sym->getName()); 277 sym->setAddress((void *)S); 278 } 279 280 switch (rel->getType()) { 281 default: 282 rsl_assert(0 && "Not implemented relocation type."); 283 break; 284 285 // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here. 286 case 1: // R_X86_64_64 287 *inst = (S+A); 288 break; 289 290 case 2: // R_X86_64_PC32 291 *inst = (S+A-P); 292 break; 293 294 case 10: // R_X86_64_32 295 case 11: // R_X86_64_32S 296 *inst = (S+A); 297 break; 298 } 299 } 300 } 301 302 template <unsigned Bitwidth> 303 inline void ELFObject<Bitwidth>:: 304 relocateX86_32(void *(*find_sym)(void *context, char const *name), 305 void *context, 306 ELFSectionRelTableTy *reltab, 307 ELFSectionProgBitsTy *text) { 308 rsl_assert(Bitwidth == 32 && "Only support X86."); 309 310 ELFSectionSymTabTy *symtab = 311 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 312 rsl_assert(symtab && "Symtab is required."); 313 314 for (size_t i = 0; i < reltab->size(); ++i) { 315 // FIXME: Can not implement here, use Fixup! 316 ELFRelocTy *rel = (*reltab)[i]; 317 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 318 319 //typedef uint64_t Inst_t; 320 typedef int32_t Inst_t; 321 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 322 Inst_t P = (Inst_t)(uintptr_t)inst; 323 Inst_t A = (Inst_t)(uintptr_t)*inst; 324 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(); 325 326 if (S == 0) { 327 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName()); 328 sym->setAddress((void *)S); 329 } 330 331 switch (rel->getType()) { 332 default: 333 rsl_assert(0 && "Not implemented relocation type."); 334 break; 335 336 case R_386_PC32: 337 *inst = (S+A-P); 338 break; 339 340 case R_386_32: 341 *inst = (S+A); 342 break; 343 } 344 } 345 } 346 347 template <unsigned Bitwidth> 348 inline void ELFObject<Bitwidth>:: 349 relocateMIPS(void *(*find_sym)(void *context, char const *name), 350 void *context, 351 ELFSectionRelTableTy *reltab, 352 ELFSectionProgBitsTy *text) { 353 rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS."); 354 355 ELFSectionSymTabTy *symtab = 356 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab")); 357 rsl_assert(symtab && "Symtab is required."); 358 359 for (size_t i = 0; i < reltab->size(); ++i) { 360 // FIXME: Can not implement here, use Fixup! 361 ELFRelocTy *rel = (*reltab)[i]; 362 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()]; 363 364 typedef int32_t Inst_t; 365 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()]; 366 Inst_t P = (Inst_t)(uintptr_t)inst; 367 Inst_t A = (Inst_t)(uintptr_t)*inst; 368 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(); 369 370 if (S == 0) { 371 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName()); 372 sym->setAddress((void *)S); 373 } 374 375 switch (rel->getType()) { 376 default: 377 rsl_assert(0 && "Not implemented relocation type."); 378 break; 379 380 case R_MIPS_HI16: 381 A = A & 0xFFFF; 382 *inst |= (((S + A + 0x8000) >> 16) & 0xFFFF); 383 break; 384 385 case R_MIPS_LO16: 386 A = A & 0xFFFF; 387 *inst |= ((S + A) & 0xFFFF); 388 break; 389 390 case R_MIPS_26: 391 A = A & 0x3FFFFFF; 392 // FIXME: We just support addend = 0. 393 rsl_assert(A == 0 && "R_MIPS_26 addend is not 0."); 394 *inst |= ((S >> 2) & 0x3FFFFFF); 395 rsl_assert((((P + 4) >> 28) != (S >> 28)) && "Cannot relocate R_MIPS_26 due to differences in the upper four bits."); 396 break; 397 398 case R_MIPS_32: 399 *inst = S + A; 400 break; 401 } 402 } 403 } 404 405 406 // TODO: Refactor all relocations. 407 template <unsigned Bitwidth> 408 inline void ELFObject<Bitwidth>:: 409 relocate(void *(*find_sym)(void *context, char const *name), void *context) { 410 // Init SHNCommonDataSize. 411 // Need refactoring 412 size_t SHNCommonDataSize = 0; 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 < symtab->size(); ++i) { 419 ELFSymbolTy *sym = (*symtab)[i]; 420 421 if (sym->getType() != STT_OBJECT) { 422 continue; 423 } 424 425 size_t idx = (size_t)sym->getSectionIndex(); 426 switch (idx) { 427 default: 428 if ((*shtab)[idx]->getType() == SHT_NOBITS) { 429 // FIXME(logan): This is a workaround for .lcomm directives 430 // bug of LLVM ARM MC code generator. Remove this when the 431 // LLVM bug is fixed. 432 433 size_t align = 16; 434 SHNCommonDataSize += (size_t)sym->getSize() + align; 435 } 436 break; 437 438 case SHN_COMMON: 439 { 440 size_t align = (size_t)sym->getValue(); 441 SHNCommonDataSize += (size_t)sym->getSize() + align; 442 } 443 break; 444 445 case SHN_ABS: 446 case SHN_UNDEF: 447 case SHN_XINDEX: 448 break; 449 } 450 } 451 if (!initSHNCommonDataSize(SHNCommonDataSize)) { 452 rsl_assert("Allocate memory for common variable fail!"); 453 } 454 455 for (size_t i = 0; i < stab.size(); ++i) { 456 ELFSectionHeaderTy *sh = (*shtab)[i]; 457 if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) { 458 continue; 459 } 460 ELFSectionRelTableTy *reltab = 461 static_cast<ELFSectionRelTableTy *>(stab[i]); 462 rsl_assert(reltab && "Relocation section can't be NULL."); 463 464 const char *reltab_name = sh->getName(); 465 const char *need_rel_name; 466 if (sh->getType() == SHT_REL) { 467 need_rel_name = reltab_name + 4; 468 // ".rel.xxxx" 469 // ^ start from here. 470 } else { 471 need_rel_name = reltab_name + 5; 472 } 473 474 ELFSectionProgBitsTy *need_rel = 475 static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name)); 476 rsl_assert(need_rel && "Need be relocated section can't be NULL."); 477 478 switch (getHeader()->getMachine()) { 479 case EM_ARM: 480 relocateARM(find_sym, context, reltab, need_rel); 481 break; 482 case EM_386: 483 relocateX86_32(find_sym, context, reltab, need_rel); 484 break; 485 case EM_X86_64: 486 relocateX86_64(find_sym, context, reltab, need_rel); 487 break; 488 case EM_MIPS: 489 relocateMIPS(find_sym, context, reltab, need_rel); 490 break; 491 492 default: 493 rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation."); 494 break; 495 } 496 } 497 498 for (size_t i = 0; i < stab.size(); ++i) { 499 ELFSectionHeaderTy *sh = (*shtab)[i]; 500 if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) { 501 if (stab[i]) { 502 static_cast<ELFSectionBitsTy *>(stab[i])->protect(); 503 } 504 } 505 } 506 } 507 508 template <unsigned Bitwidth> 509 inline void ELFObject<Bitwidth>::print() const { 510 header->print(); 511 shtab->print(); 512 513 for (size_t i = 0; i < stab.size(); ++i) { 514 ELFSectionTy *sec = stab[i]; 515 if (sec) { 516 sec->print(); 517 } 518 } 519 } 520 521 #endif // ELF_OBJECT_HXX 522