15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ARMRelocationFactory.cpp ----------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/DataTypes.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Layout.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ARMRelocationFactory.h" 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ARMRelocationFunctions.h" 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoDECL_ARM_APPLY_RELOC_FUNCS 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===// 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMRelocationFactory 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::ARMRelocationFactory(size_t pNum, 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGNULDBackend& pParent) 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : RelocationFactory(pNum), 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Target(pParent) { 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::~ARMRelocationFactory() 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMRelocationFactory::applyRelocation(Relocation& pRelocation, 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo) 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::Type type = pRelocation.type(); 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (type > 130) { // 131-255 doesn't noted in ARM spec 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unknown relocation type. " 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "To symbol `") + 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pRelocation.symInfo()->name() + 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// the prototype of applying function 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef Result (*ApplyFunctionType)(Relocation& pReloc, 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent); 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the table entry of applying functions 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao struct ApplyFunctionTriple { 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ApplyFunctionType func; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int type; 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const char* name; 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao }; 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // declare the table of applying functions 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static ApplyFunctionTriple apply_functions[] = { 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao DECL_ARM_APPLY_RELOC_FUNC_PTRS 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao }; 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // apply the relocation 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Result result = apply_functions[type].func(pRelocation, pLDInfo, *this); 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check result 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (OK == result) { 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Overflow == result) { 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Applying relocation `") + 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(apply_functions[type].name) + 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("' causes overflow. on symbol: `") + 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pRelocation.symInfo()->name()) + 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (BadReloc == result) { 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Applying relocation `") + 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(apply_functions[type].name) + 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("' encounters unexpected opcode. " 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "on symbol: `") + 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pRelocation.symInfo()->name()) + 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Unsupport == result) { 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Encounter unsupported relocation `") + 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(apply_functions[type].name) + 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("' on symbol: `") + 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pRelocation.symInfo()->name()) + 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===// 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// non-member functions 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic RelocationFactory::DWord getThumbBit(const Relocation& pReloc) 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Set thumb bit if 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // - symbol has type of STT_FUNC, is defined and with bit 0 of its value set 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RelocationFactory::DWord thumbBit = 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((pReloc.symInfo()->desc() != ResolveInfo::Undefined) && 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (pReloc.symInfo()->type() == ResolveInfo::Function) && 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((pReloc.symValue() & 0x1) != 0))? 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1:0; 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return thumbBit; 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=========================================// 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Relocation helper function // 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=========================================// 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Using uint64_t to make sure those complicate operations won't cause 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// undefined behavior. 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t helper_sign_extend(uint64_t pVal, uint64_t pOri_width) 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pOri_width <= 64); 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t sign_bit = 1 << (pOri_width - 1); 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return (pVal ^ sign_bit) - sign_bit; 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Reverse sign bit, then subtract sign bit. 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t helper_bit_select(uint64_t pA, uint64_t pB, uint64_t pMask) 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return (pA & ~pMask) | (pB & pMask) ; 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Check if symbol can use relocation R_ARM_RELATIVE 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic bool 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_use_relative_reloc(const ResolveInfo& pSym, 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const ARMRelocationFactory& pFactory) 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol is dynamic or undefine or preemptible 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isDyn() || 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pSym.isUndef() || 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFactory.getTarget().isSymbolPreemptible(pSym, 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLDInfo, 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLDInfo.output())) 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGOTEntry& helper_get_GOT_and_init(Relocation& pReloc, 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGNULDBackend& ld_backend = pParent.getTarget(); 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool exist; 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry& got_entry = *ld_backend.getGOT().getEntry(*rsym, exist); 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!exist) { 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we first get this GOT entry, we should initialize it. 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (rsym->reserved() & ARMGNULDBackend::ReserveGOT) { 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // No corresponding dynamic relocation, initialize to the symbol value. 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got_entry.setContent(pReloc.symValue()); 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (rsym->reserved() & ARMGNULDBackend::GOTRel) { 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Initialize corresponding dynamic relocation. 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation& rel_entry = 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *ld_backend.getRelDyn().getEntry(*rsym, true, exist); 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!exist && "GOT entry not exist, but DynRel entry exist!"); 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( rsym->isLocal() || 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_use_relative_reloc(*rsym, pLDInfo, pParent)) { 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Initialize got entry to target symbol address 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got_entry.setContent(pReloc.symValue()); 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setType(llvm::ELF::R_ARM_RELATIVE); 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setSymInfo(0); 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Initialize got entry to 0 for corresponding dynamic relocation. 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got_entry.setContent(0); 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setType(llvm::ELF::R_ARM_GLOB_DAT); 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setSymInfo(rsym); 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.targetRef().assign(got_entry); 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("No GOT entry reserved for GOT type relocation!"); 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return got_entry; 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Address helper_GOT_ORG(ARMRelocationFactory& pParent) 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pParent.getTarget().getGOT().getSection().addr(); 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Address helper_GOT(Relocation& pReloc, 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry& got_entry = helper_get_GOT_and_init(pReloc, pLDInfo, pParent); 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return helper_GOT_ORG(pParent) + pParent.getLayout().getOutputOffset(got_entry); 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPLTEntry& helper_get_PLT_and_init(Relocation& pReloc, 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGNULDBackend& ld_backend = pParent.getTarget(); 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool exist; 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao PLTEntry& plt_entry = *ld_backend.getPLT().getPLTEntry(*rsym, exist); 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!exist) { 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we first get this PLT entry, we should initialize it. 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (rsym->reserved() & ARMGNULDBackend::ReservePLT) { 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry& gotplt_entry = 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *ld_backend.getPLT().getGOTPLTEntry(*rsym, exist); 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Initialize corresponding dynamic relocation. 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation& rel_entry = 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *ld_backend.getRelPLT().getEntry(*rsym, true, exist); 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!exist && "PLT entry not exist, but DynRel entry exist!"); 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setType(llvm::ELF::R_ARM_JUMP_SLOT); 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.targetRef().assign(gotplt_entry); 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setSymInfo(rsym); 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("No PLT entry reserved for PLT type relocation!"); 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return plt_entry; 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Address helper_PLT_ORG(ARMRelocationFactory& pParent) 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pParent.getTarget().getPLT().getSection().addr(); 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Address helper_PLT(Relocation& pReloc, 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao PLTEntry& plt_entry = helper_get_PLT_and_init(pReloc, pParent); 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return helper_PLT_ORG(pParent) + pParent.getLayout().getOutputOffset(plt_entry); 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Get an relocation entry in .rel.dyn and set its type to pType, 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// its FragmentRef to pReloc->targetFrag() and its ResolveInfo to pReloc->symInfo() 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid helper_DynRel(Relocation& pReloc, 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Type pType, 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGNULDBackend& ld_backend = pParent.getTarget(); 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool exist; 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation& rel_entry = 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *ld_backend.getRelDyn().getEntry(*rsym, false, exist); 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setType(pType); 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.targetRef() = pReloc.targetRef(); 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pType == llvm::ELF::R_ARM_RELATIVE) 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setSymInfo(0); 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel_entry.setSymInfo(rsym); 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_extract_movw_movt_addend(ARMRelocationFactory::DWord pTarget) 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // imm16: [19-16][11-0] 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return helper_sign_extend((((pTarget >> 4)) & 0xf000U) | (pTarget & 0xfffU), 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16); 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_insert_val_movw_movt_inst(ARMRelocationFactory::DWord pTarget, 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord pImm) 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // imm16: [19-16][11-0] 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget &= 0xfff0f000U; 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget |= pImm & 0x0fffU; 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget |= (pImm & 0xf000U) << 4; 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pTarget; 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_extract_thumb_movw_movt_addend(ARMRelocationFactory::DWord pTarget) 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: By the rsloader experience: If we use 32bit, we need to consider 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // endianness problem. We'd better have a thumb instruction type. 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // imm16: [19-16][26][14-12][7-0] 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return helper_sign_extend((((pTarget >> 4) & 0xf000U) | 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((pTarget >> 15) & 0x0800U) | 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((pTarget >> 4) & 0x0700U) | 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (pTarget & 0x00ffU)), 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16); 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_insert_val_thumb_movw_movt_inst(ARMRelocationFactory::DWord pTarget, 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord pImm) 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: By the rsloader experience: If we use 32bit, we need to consider 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // endianness problem. We'd better have a thumb instruction type. 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // imm16: [19-16][26][14-12][7-0] 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget &= 0xfbf08f00U; 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget |= (pImm & 0xf000U) << 4; 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget |= (pImm & 0x0800U) << 15; 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget |= (pImm & 0x0700U) << 4; 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pTarget |= (pImm & 0x00ffU); 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pTarget; 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_thumb32_branch_offset(ARMRelocationFactory::DWord pUpper16, 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord pLower16) 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord s = (pUpper16 & (1U << 10)) >> 10, // 26 bit 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao u = pUpper16 & 0x3ffU, // 25-16 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao l = pLower16 & 0x7ffU, // 10-0 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao j1 = (pLower16 & (1U << 13)) >> 13, // 13 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao j2 = (pLower16 & (1U << 11)) >> 11; // 11 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord i1 = j1 ^ s? 0: 1, 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao i2 = j2 ^ s? 0: 1; 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // [31-25][24][23][22][21-12][11-1][0] 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 0 s i1 i2 u l 0 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return helper_sign_extend((s << 24) | (i1 << 23) | (i2 << 22) | 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (u << 12) | (l << 1), 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25); 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_thumb32_branch_upper(ARMRelocationFactory::DWord pUpper16, 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord pOffset) 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t sign = ((pOffset & 0x80000000U) >> 31); 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return (pUpper16 & ~0x7ffU) | ((pOffset >> 12) & 0x3ffU) | (sign << 10); 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic ARMRelocationFactory::DWord 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_thumb32_branch_lower(ARMRelocationFactory::DWord pLower16, 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord pOffset) 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t sign = ((pOffset & 0x80000000U) >> 31); 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ((pLower16 & ~0x2fffU) | 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((((pOffset >> 23) & 1) ^ !sign) << 13) | 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((((pOffset >> 22) & 1) ^ !sign) << 11) | 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ((pOffset >> 1) & 0x7ffU)); 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Return true if overflow 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic bool 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaohelper_check_signed_overflow(ARMRelocationFactory::DWord pValue, 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned bits) 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao int32_t signed_val = static_cast<int32_t>(pValue); 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao int32_t max = (1 << (bits - 1)) - 1; 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao int32_t min = -(1 << (bits - 1)); 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (signed_val > max || signed_val < min) { 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=========================================// 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Each relocation function implementation // 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=========================================// 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_NONE 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result none(Relocation& pReloc, 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_ABS32: (S + A) | T 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result abs32(Relocation& pReloc, 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend(); 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord S = pReloc.symValue(); 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->isLocal() && (rsym->reserved() & 0x1u)) { 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_DynRel(pReloc, llvm::ELF::R_ARM_RELATIVE, pParent); 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (S + A) | T ; 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(!rsym->isLocal()) { 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & 0x8u) { 4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T = 0 ; // PLT is not thumb 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (S + A) | T; 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we generate a dynamic relocation (except R_ARM_RELATIVE) 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // for a place, we should not perform static relocation on it 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in order to keep the addend store in the place correct. 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & 0x1u) { 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(helper_use_relative_reloc(*rsym, pLDInfo, pParent)) { 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_DynRel(pReloc, llvm::ELF::R_ARM_RELATIVE, pParent); 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_DynRel(pReloc, pReloc.type(), pParent); 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // perform static relocation 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (S + A) | T; 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_REL32: ((S + A) | T) - P 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result rel32(Relocation& pReloc, 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // perform static relocation 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend(); 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = ((pReloc.symValue() + A) | T) 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao - pReloc.place(pParent.getLayout()); 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_BASE_PREL: B(S) + A - P 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result base_prel(Relocation& pReloc, 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // perform static relocation 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend(); 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = pReloc.symValue() + A - pReloc.place(pParent.getLayout()); 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_GOTOFF32: ((S + A) | T) - GOT_ORG 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result gotoff32(Relocation& pReloc, 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend(); 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent); 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = ((S + A) | T) - GOT_ORG; 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_GOT_BREL: GOT(S) + A - GOT_ORG 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result got_brel(Relocation& pReloc, 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(!(pReloc.symInfo()->reserved() & 0x6u)) { 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::BadReloc; 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address GOT_S = helper_GOT(pReloc, pLDInfo, pParent); 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend(); 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent); 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Apply relocation. 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = GOT_S + A - GOT_ORG; 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_GOT_PREL: GOT(S) + A - P 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result got_prel(Relocation& pReloc, 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(!(pReloc.symInfo()->reserved() & 0x6u)) { 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::BadReloc; 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address GOT_S = helper_GOT(pReloc, pLDInfo, pParent); 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend(); 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address P = pReloc.place(pParent.getLayout()); 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Apply relocation. 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = GOT_S + A - P; 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_PLT32: ((S + A) | T) - P 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_JUMP24: ((S + A) | T) - P 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_CALL: ((S + A) | T) - P 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result call(Relocation& pReloc, 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: Some issue have not been considered, e.g. thumb, overflow? 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If target is undefined weak symbol, we only need to jump to the 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // next instruction unless it has PLT entry. 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pReloc.symInfo()->isWeak() && pReloc.symInfo()->isUndef() && 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !(pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT)) { 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // change target to NOP : mov r0, r0 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (pReloc.target() & 0xf0000000U) | 0x01a00000; 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S; // S dependent on exist PLT or not. 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_sign_extend((pReloc.target() & 0x00FFFFFFu) << 2, 26) 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao + pReloc.addend(); 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address P = pReloc.place(pParent.getLayout()); 5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = pReloc.symValue(); 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( pReloc.symInfo()->reserved() & 0x8u) { 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T = 0; // PLT is not thumb. 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X = ((S + A) | T) - P; 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (X & 0x03u) { // Lowest two bit is not zero. 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("Target is thumb, need stub!"); 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Check X is 24bit sign int. If not, we should use stub or PLT before apply. 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!helper_check_signed_overflow(X, 26) && "Jump or Call target too far!"); 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Make sure the Imm is 0. Result Mask. 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (pReloc.target() & 0xFF000000u) | ((X & 0x03FFFFFEu) >> 2); 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_THM_CALL: ((S + A) | T) - P 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result thm_call(Relocation& pReloc, 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If target is undefined weak symbol, we only need to jump to the 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // next instruction unless it has PLT entry. 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pReloc.symInfo()->isWeak() && pReloc.symInfo()->isUndef() && 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !(pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT)) { 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (0xe000U << 16) | 0xbf00U; 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: By the rsloader experience: If we use 32bit, we need to consider 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // endianness problem. Here is an ugly solution. We'd better have a thumb 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // instruction type. 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao //uint16_t upper16 = *( 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // reinterpret_cast<uint16_t*>(&pReloc.target()) 5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ), 5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // lower16 = *( 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // reinterpret_cast<uint16_t*>(&pReloc.target()) + 1 5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ); 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord upper16 = ((pReloc.target() & 0xffff0000U) >> 16), 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao lower16 = (pReloc.target() & 0xffffU); 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = helper_thumb32_branch_offset(upper16, 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao lower16); 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address P = pReloc.place(pParent.getLayout()); 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S; 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = pReloc.symValue(); 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol has plt 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( pReloc.symInfo()->reserved() & 0x8u) { 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T = 0; // PLT is not thumb. 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: If the target is not thumb, we should rewrite instruction to BLX. 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X = ((S + A) | T) - P; 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X >>= 1; 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Check bit size is 24(thumb2) or 22? 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 24)) { 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!"Offset is too far. We need stub or PLT for it."); 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // For a BLX instruction, make sure that the relocation is rounded up 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // to a word boundary. This follows the semantics of the instruction 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // which specifies that bit 1 of the target address will come from bit 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1 of the base address. 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((X & 0x5000U) == 0x4000U) { 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = (X + 2) & ~0x3U; 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao upper16 = helper_thumb32_branch_upper(upper16, X); 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao lower16 = helper_thumb32_branch_lower(lower16, X); 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: By the rsloader experience: If we use 32bit, we need to consider 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // endianness problem. Here is an ugly solution. We'd better have a thumb 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // instruction type. 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao //*(reinterpret_cast<uint16_t*>(&preloc.target())) = upper16; 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao //*(reinterpret_cast<uint16_t*>(&preloc.target()) + 1) = lower16; 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (upper16 << 16); 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() |= lower16; 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_MOVW_ABS_NC: (S + A) | T 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result movw_abs_nc(Relocation& pReloc, 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // use plt 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & 0x8u) { 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T = 0 ; // PLT is not thumb 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = (S + A) | T ; 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // perform static relocation 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = (S + A) | T; 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 16)) { 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_MOVW_PREL_NC: ((S + A) | T) - P 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result movw_prel_nc(Relocation& pReloc, 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout()); 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = ((S + A) | T) - P; 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 16)) { 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_MOVT_ABS: S + A 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result movt_abs(Relocation& pReloc, 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // use plt 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & 0x8u) { 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = S + A; 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X >>= 16; 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // perform static relocation 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_MOVT_PREL: S + A - P 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result movt_prel(Relocation& pReloc, 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout()); 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = S + A - P; 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X >>= 16; 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_THM_MOVW_ABS_NC: (S + A) | T 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result thm_movw_abs_nc(Relocation& pReloc, 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend(); 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // use plt 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & 0x8u) { 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T = 0; // PLT is not thumb 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = (S + A) | T; 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check 16-bit overflow 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 16)) { 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(), 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X); 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_THM_MOVW_PREL_NC: ((S + A) | T) - P 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result thm_movw_prel_nc(Relocation& pReloc, 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout()); 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend(); 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = ((S + A) | T) - P; 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check 16-bit overflow 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 16)) { 7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(), 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X); 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_THM_MOVT_ABS: S + A 7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result thm_movt_abs(Relocation& pReloc, 7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend(); 7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // use plt 7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & 0x8u) { 7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = S + A; 7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X >>= 16; 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check 16-bit overflow 7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 16)) { 7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(), 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X); 7925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_THM_MOVT_PREL: S + A - P 7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result thm_movt_prel(Relocation& pReloc, 7985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S = pReloc.symValue(); 8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout()); 8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = 8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend(); 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X; 8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X = S + A - P; 8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X >>= 16; 8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check 16-bit overflow 8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (helper_check_signed_overflow(X, 16)) { 8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(), 8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X); 8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_PREL31: (S + A) | T 8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result prel31(Relocation& pReloc, 8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord target = pReloc.target(); 8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord T = getThumbBit(pReloc); 8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord A = helper_sign_extend(target, 31) + 8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.addend(); 8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::Address S; 8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = pReloc.symValue(); 8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol has plt 8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( pReloc.symInfo()->reserved() & 0x8u) { 8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao S = helper_PLT(pReloc, pParent); 8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T = 0; // PLT is not thumb. 8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory::DWord X = (S + A) | T ; 8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.target() = helper_bit_select(target, X, 0x7fffffffU); 8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(helper_check_signed_overflow(X, 31)) 8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Overflow; 8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::OK; 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_TLS_GD32: GOT(S) + A - P 8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_TLS_IE32: GOT(S) + A - P 8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// R_ARM_TLS_LE32: S + A - tp 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result tls(Relocation& pReloc, 8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("We don't support TLS relocation yet."); 8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Unsupport; 8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMRelocationFactory::Result unsupport(Relocation& pReloc, 8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMRelocationFactory& pParent) 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ARMRelocationFactory::Unsupport; 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 862