xref: /llvm-project-15.0.7/lld/ELF/Target.h (revision 4d75e8d6)
1 //===- Target.h -------------------------------------------------*- C++ -*-===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLD_ELF_TARGET_H
11 #define LLD_ELF_TARGET_H
12 
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Object/ELF.h"
15 
16 #include <memory>
17 
18 namespace lld {
19 namespace elf {
20 class SymbolBody;
21 
22 class TargetInfo {
23 public:
24   uint64_t getVAStart() const;
25   virtual bool isTlsLocalDynamicRel(unsigned Type) const;
26   virtual bool isTlsGlobalDynamicRel(unsigned Type) const;
27   virtual unsigned getDynRel(unsigned Type) const { return Type; }
28   virtual bool isTlsDynRel(unsigned Type, const SymbolBody &S) const;
29   virtual unsigned getTlsGotRel(unsigned Type) const { return TlsGotRel; }
30   virtual void writeGotHeader(uint8_t *Buf) const {}
31   virtual void writeGotPltHeader(uint8_t *Buf) const {}
32   virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {};
33 
34   // If lazy binding is supported, the first entry of the PLT has code
35   // to call the dynamic linker to resolve PLT entries the first time
36   // they are called. This function writes that code.
37   virtual void writePltZero(uint8_t *Buf) const {}
38 
39   virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
40                         uint64_t PltEntryAddr, int32_t Index,
41                         unsigned RelOff) const {}
42 
43   // Returns true if a relocation is just a hint for linker to make for example
44   // some code optimization. Such relocations should not be handled as a regular
45   // ones and lead to dynamic relocation creation etc.
46   virtual bool isHintRel(uint32_t Type) const;
47 
48   // Returns true if a relocation is relative to the place being relocated,
49   // such as relocations used for PC-relative instructions. Such relocations
50   // need not be fixed up if an image is loaded to a different address than
51   // the link-time address. So we don't have to emit a relocation for the
52   // dynamic linker if isRelRelative returns true.
53   virtual bool isRelRelative(uint32_t Type) const;
54 
55   virtual bool isSizeRel(uint32_t Type) const;
56   virtual bool needsDynRelative(unsigned Type) const { return false; }
57   virtual bool needsGot(uint32_t Type, SymbolBody &S) const;
58   virtual bool refersToGotEntry(uint32_t Type) const;
59 
60   enum PltNeed { Plt_No, Plt_Explicit, Plt_Implicit };
61   template <class ELFT>
62   PltNeed needsPlt(uint32_t Type, const SymbolBody &S) const;
63 
64   virtual void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
65                            uint64_t P, uint64_t SA, uint64_t ZA = 0,
66                            uint8_t *PairedLoc = nullptr) const = 0;
67   virtual bool isGotRelative(uint32_t Type) const;
68   virtual bool canRelaxTls(unsigned Type, const SymbolBody *S) const;
69   template <class ELFT>
70   bool needsCopyRel(uint32_t Type, const SymbolBody &S) const;
71   virtual unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
72                             uint64_t P, uint64_t SA, const SymbolBody *S) const;
73   virtual ~TargetInfo();
74 
75   unsigned PageSize = 4096;
76 
77   // On freebsd x86_64 the first page cannot be mmaped.
78   // On linux that is controled by vm.mmap_min_addr. At least on some x86_64
79   // installs that is 65536, so the first 15 pages cannot be used.
80   // Given that, the smallest value that can be used in here is 0x10000.
81   // If using 2MB pages, the smallest page aligned address that works is
82   // 0x200000, but it looks like every OS uses 4k pages for executables.
83   uint64_t VAStart = 0x10000;
84 
85   unsigned CopyRel;
86   unsigned GotRel;
87   unsigned PltRel;
88   unsigned RelativeRel;
89   unsigned IRelativeRel;
90   unsigned TlsGotRel = 0;
91   unsigned TlsModuleIndexRel;
92   unsigned TlsOffsetRel;
93   unsigned PltEntrySize = 8;
94   unsigned PltZeroSize = 0;
95   unsigned GotHeaderEntriesNum = 0;
96   unsigned GotPltHeaderEntriesNum = 3;
97   bool UseLazyBinding = false;
98 
99 private:
100   virtual bool needsCopyRelImpl(uint32_t Type) const;
101   virtual bool needsPltImpl(uint32_t Type) const;
102 };
103 
104 uint64_t getPPC64TocBase();
105 
106 template <class ELFT>
107 typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr();
108 
109 template <class ELFT> bool isGnuIFunc(const SymbolBody &S);
110 
111 extern TargetInfo *Target;
112 TargetInfo *createTarget();
113 }
114 }
115 
116 #endif
117