15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ARMLDBackend.h -----------------------------------------------------===// 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//===----------------------------------------------------------------------===// 9551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#ifndef TARGET_ARM_ARMLDBACKEND_H 10551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#define TARGET_ARM_ARMLDBACKEND_H 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ARMELFDynamic.h" 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ARMGOT.h" 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ARMPLT.h" 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSection.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ARMELFAttributeData; 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig; 23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass GNUInfo; 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// ARMGNULDBackend - linker backend of ARM target of GNU ELF format 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass ARMGNULDBackend : public GNULDBackend 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic: 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // max branch offsets for ARM, THUMB, and THUMB2 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // @ref gold/arm.cc:99 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static const int32_t ARM_MAX_FWD_BRANCH_OFFSET = ((((1 << 23) - 1) << 2) + 8); 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static const int32_t ARM_MAX_BWD_BRANCH_OFFSET = ((-((1 << 23) << 2)) + 8); 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static const int32_t THM_MAX_FWD_BRANCH_OFFSET = ((1 << 22) -2 + 4); 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static const int32_t THM_MAX_BWD_BRANCH_OFFSET = (-(1 << 22) + 4); 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static const int32_t THM2_MAX_FWD_BRANCH_OFFSET = (((1 << 24) - 2) + 4); 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4); 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaopublic: 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ~ARMGNULDBackend(); 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic: 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList; 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic: 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// initTargetSections - initialize target dependent sections in output. 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// initTargetSymbols - initialize target dependent symbols in output. 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao /// initRelocator - create and initialize Relocator. 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool initRelocator(); 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 57d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao /// getRelocator - return relocator. 58a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines const Relocator* getRelocator() const; 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao Relocator* getRelocator(); 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// doPreLayout - Backend can do any needed modification before layout 626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void doPreLayout(IRBuilder& pBuilder); 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// doPostLayout -Backend can do any needed modification after layout 656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void doPostLayout(Module& pModule, IRBuilder& pBuilder); 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// dynamic - the dynamic section of the target machine. 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// Use co-variant return type to return its own dynamic section. 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMELFDynamic& dynamic(); 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// dynamic - the dynamic section of the target machine. 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// Use co-variant return type to return its own dynamic section. 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const ARMELFDynamic& dynamic() const; 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// emitSectionData - write out the section data into the memory region. 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// call back target backend to emit the data. 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// Backends handle the target-special tables (plt, gp,...) by themselves. 81cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao /// Backend can put the data of the tables in SectionData directly 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// - LDSection.getSectionData can get the section data. 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// Or, backend can put the data into special data structure 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// - backend can maintain its own map<LDSection, table> to get the table 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// from given LDSection. 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param pSection - the given LDSection 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @param pConfig - all options in the command line. 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param pRegion - the region to write out data 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @return the size of the table in the file. 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t emitSectionData(const LDSection& pSection, 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const; 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT& getGOT(); 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const ARMGOT& getGOT() const; 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT& getPLT(); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const ARMPLT& getPLT() const; 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao OutputRelocSection& getRelDyn(); 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const OutputRelocSection& getRelDyn() const; 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao OutputRelocSection& getRelPLT(); 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const OutputRelocSection& getRelPLT() const; 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMELFAttributeData& getAttributeData(); 10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const ARMELFAttributeData& getAttributeData() const; 10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// getTargetSectionOrder - compute the layout order of ARM target sections 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// finalizeTargetSymbols - finalize the symbol value 1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool finalizeTargetSymbols(); 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// mergeSection - merge target dependent sections 11987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); 12087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 12187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// setUpReachedSectionsForGC - set the reference from section XXX to 12287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// .ARM.exidx.XXX to make sure GC correctly handle section exidx 12387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines void setUpReachedSectionsForGC(const Module& pModule, 12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines GarbageCollection::SectionReachedListMap& pSectReachedListMap) const; 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// readSection - read target dependent sections 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool readSection(Input& pInput, SectionData& pSD); 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 129a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 130a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// function pointer access 131a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const; 132a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate: 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void defineGOTSymbol(IRBuilder& pBuilder); 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 136a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// maxFwdBranchOffset 137a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines int64_t maxFwdBranchOffset(); 138a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// maxBwdBranchOffset 139a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines int64_t maxBwdBranchOffset(); 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// mayRelax - Backends should override this function if they need relaxation 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool mayRelax() { return true; } 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// doRelax - Backend can orevride this function to add its relaxation 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// implementation. Return true if the output (e.g., .text) is "relaxed" 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// (i.e. layout is changed), and set pFinished to true if everything is fit, 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// otherwise set it to false. 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// initTargetStubs 1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool initTargetStubs(); 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// getRelEntrySize - the size in BYTE of rel type relocation 15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t getRelEntrySize() 15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao { return 8; } 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// getRelEntrySize - the size in BYTE of rela type relocation 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t getRelaEntrySize() 15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao { assert(0 && "ARM backend with Rela type relocation\n"); return 12; } 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// doCreateProgramHdrs - backend can implement this function to create the 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// target-dependent segments 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual void doCreateProgramHdrs(Module& pModule); 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate: 166d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao Relocator* m_pRelocator; 167d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT* m_pGOT; 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT* m_pPLT; 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// m_RelDyn - dynamic relocation table of .rel.dyn 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao OutputRelocSection* m_pRelDyn; 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// m_RelPLT - dynamic relocation table of .rel.plt 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao OutputRelocSection* m_pRelPLT; 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// m_pAttrData - attribute data in public ("aeabi") attribute subsection 17687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMELFAttributeData* m_pAttrData; 17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMELFDynamic* m_pDynamic; 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* m_pGOTSymbol; 18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* m_pEXIDXStart; 18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* m_pEXIDXEnd; 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // variable name : ELF 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* m_pEXIDX; // .ARM.exidx 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* m_pEXTAB; // .ARM.extab 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* m_pAttributes; // .ARM.attributes 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// LDSection* m_pPreemptMap; // .ARM.preemptmap 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// LDSection* m_pDebugOverlay; // .ARM.debug_overlay 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// LDSection* m_pOverlayTable; // .ARM.overlay_table 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif 194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 195