xref: /llvm-project-15.0.7/lld/ELF/Target.h (revision fcef3e46)
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 isTlsInitialExecRel(uint32_t Type) const;
26   virtual bool pointsToLocalDynamicGotEntry(uint32_t Type) const;
27   virtual bool isTlsLocalDynamicRel(uint32_t Type) const;
28   virtual bool isTlsGlobalDynamicRel(uint32_t Type) const;
29   virtual uint32_t getDynRel(uint32_t Type) const { return Type; }
30   virtual uint32_t getTlsGotRel(uint32_t Type) const { return TlsGotRel; }
31   virtual void writeGotHeader(uint8_t *Buf) const {}
32   virtual void writeGotPltHeader(uint8_t *Buf) const {}
33   virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {};
34 
35   // If lazy binding is supported, the first entry of the PLT has code
36   // to call the dynamic linker to resolve PLT entries the first time
37   // they are called. This function writes that code.
38   virtual void writePltZero(uint8_t *Buf) const {}
39 
40   virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
41                         uint64_t PltEntryAddr, int32_t Index,
42                         unsigned RelOff) const {}
43 
44   // Returns true if a relocation is just a hint for linker to make for example
45   // some code optimization. Such relocations should not be handled as a regular
46   // ones and lead to dynamic relocation creation etc.
47   virtual bool isHintRel(uint32_t Type) const;
48 
49   // Returns true if a relocation is relative to the place being relocated,
50   // such as relocations used for PC-relative instructions. Such relocations
51   // need not be fixed up if an image is loaded to a different address than
52   // the link-time address. So we don't have to emit a relocation for the
53   // dynamic linker if isRelRelative returns true.
54   virtual bool isRelRelative(uint32_t Type) const;
55 
56   virtual bool isSizeRel(uint32_t Type) const;
57   virtual bool needsDynRelative(uint32_t Type) const { return false; }
58   virtual bool needsGot(uint32_t Type, SymbolBody &S) const;
59   virtual bool refersToGotEntry(uint32_t Type) const;
60 
61   enum PltNeed { Plt_No, Plt_Explicit, Plt_Implicit };
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   bool canRelaxTls(uint32_t Type, const SymbolBody *S) const;
69   template <class ELFT>
70   bool needsCopyRel(uint32_t Type, const SymbolBody &S) const;
71   size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
72                   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   uint32_t CopyRel;
86   uint32_t GotRel;
87   uint32_t PltRel;
88   uint32_t RelativeRel;
89   uint32_t IRelativeRel;
90   uint32_t TlsGotRel = 0;
91   uint32_t TlsModuleIndexRel;
92   uint32_t 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   virtual size_t relaxTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
104                                 uint64_t P, uint64_t SA) const;
105   virtual size_t relaxTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
106                                 uint64_t P, uint64_t SA) const;
107   virtual size_t relaxTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
108                                 uint64_t P, uint64_t SA) const;
109   virtual size_t relaxTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
110                                 uint64_t P, uint64_t SA) const;
111 };
112 
113 uint64_t getPPC64TocBase();
114 
115 template <class ELFT> typename ELFT::uint getMipsGpAddr();
116 
117 extern TargetInfo *Target;
118 TargetInfo *createTarget();
119 }
120 }
121 
122 #endif
123