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