blob: 535b2c88882660ef90c3939040c889d0c37b0d60 [file] [log] [blame]
Rafael Espindola01205f72015-09-22 18:19:46 +00001//===- 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
Simon Atanasyan49829a12015-09-29 05:34:03 +000013#include "llvm/ADT/StringRef.h"
Igor Kudrin15cd9ff2015-11-06 07:43:03 +000014#include "llvm/Object/ELF.h"
Simon Atanasyan49829a12015-09-29 05:34:03 +000015
Rafael Espindola01205f72015-09-22 18:19:46 +000016#include <memory>
17
18namespace lld {
Rafael Espindolae0df00b2016-02-28 00:25:54 +000019namespace elf {
Rafael Espindola01205f72015-09-22 18:19:46 +000020class SymbolBody;
21
22class TargetInfo {
23public:
Igor Kudrinf6f45472015-11-10 08:39:27 +000024 uint64_t getVAStart() const;
Adhemerval Zanella74bcf032016-02-12 13:43:03 +000025 virtual bool isTlsLocalDynamicRel(unsigned Type) const;
26 virtual bool isTlsGlobalDynamicRel(unsigned Type) const;
Rui Ueyamac516ae12016-01-29 02:33:45 +000027 virtual unsigned getDynRel(unsigned Type) const { return Type; }
Rui Ueyama012eb782016-01-29 04:05:09 +000028 virtual bool isTlsDynRel(unsigned Type, const SymbolBody &S) const;
George Rimar2960c982016-02-11 11:14:46 +000029 virtual unsigned getTlsGotRel(unsigned Type) const { return TlsGotRel; }
Rui Ueyama57b676c2016-01-29 03:51:51 +000030 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 {};
Rui Ueyama69c30ed2016-01-29 03:00:30 +000033
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.
Rui Ueyama57b676c2016-01-29 03:51:51 +000037 virtual void writePltZero(uint8_t *Buf) const {}
Rui Ueyama69c30ed2016-01-29 03:00:30 +000038
Rui Ueyama9398f862016-01-29 04:15:02 +000039 virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
Rui Ueyamac516ae12016-01-29 02:33:45 +000040 uint64_t PltEntryAddr, int32_t Index,
Rui Ueyama57b676c2016-01-29 03:51:51 +000041 unsigned RelOff) const {}
Rui Ueyama2b0edc22016-01-08 02:41:35 +000042
Simon Atanasyan682aeea2016-01-14 20:42:09 +000043 // 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.
Rui Ueyamac516ae12016-01-29 02:33:45 +000046 virtual bool isHintRel(uint32_t Type) const;
Simon Atanasyan682aeea2016-01-14 20:42:09 +000047
Rui Ueyama2b0edc22016-01-08 02:41:35 +000048 // 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.
Rafael Espindolaae244002015-10-05 19:30:12 +000053 virtual bool isRelRelative(uint32_t Type) const;
Rui Ueyama2b0edc22016-01-08 02:41:35 +000054
Rui Ueyamac516ae12016-01-29 02:33:45 +000055 virtual bool isSizeRel(uint32_t Type) const;
56 virtual bool needsDynRelative(unsigned Type) const { return false; }
Rafael Espindolaa0a65f92016-02-09 15:11:01 +000057 virtual bool needsGot(uint32_t Type, SymbolBody &S) const;
Rafael Espindola795dc5a2016-02-24 18:24:23 +000058 virtual bool refersToGotEntry(uint32_t Type) const;
Rafael Espindola852860e2016-02-12 15:47:37 +000059
60 enum PltNeed { Plt_No, Plt_Explicit, Plt_Implicit };
Rafael Espindola795dc5a2016-02-24 18:24:23 +000061 template <class ELFT>
62 PltNeed needsPlt(uint32_t Type, const SymbolBody &S) const;
63
Rui Ueyama96f0e0b2015-10-23 02:40:46 +000064 virtual void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
George Rimar48651482015-12-11 08:59:37 +000065 uint64_t P, uint64_t SA, uint64_t ZA = 0,
Simon Atanasyan09b3e362015-12-01 21:24:45 +000066 uint8_t *PairedLoc = nullptr) const = 0;
George Rimarbfb7bf72015-12-21 10:00:12 +000067 virtual bool isGotRelative(uint32_t Type) const;
Rui Ueyamabaf16512016-01-29 00:20:12 +000068 virtual bool canRelaxTls(unsigned Type, const SymbolBody *S) const;
Rafael Espindolaf7ae3592016-02-23 18:53:29 +000069 template <class ELFT>
Rafael Espindolafb1533b2016-02-22 21:23:29 +000070 bool needsCopyRel(uint32_t Type, const SymbolBody &S) const;
Rui Ueyamac516ae12016-01-29 02:33:45 +000071 virtual unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
72 uint64_t P, uint64_t SA, const SymbolBody *S) const;
Rafael Espindola01205f72015-09-22 18:19:46 +000073 virtual ~TargetInfo();
74
Hal Finkele3c26262015-10-08 22:23:54 +000075 unsigned PageSize = 4096;
Hal Finkel736c7412015-10-15 07:49:07 +000076
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
Rui Ueyama724d6252016-01-29 01:49:32 +000085 unsigned CopyRel;
86 unsigned GotRel;
87 unsigned PltRel;
88 unsigned RelativeRel;
89 unsigned IRelativeRel;
90 unsigned TlsGotRel = 0;
Rui Ueyama724d6252016-01-29 01:49:32 +000091 unsigned TlsModuleIndexRel;
92 unsigned TlsOffsetRel;
Hal Finkel6c2a3b82015-10-08 21:51:31 +000093 unsigned PltEntrySize = 8;
Rui Ueyama62515452016-01-29 03:00:32 +000094 unsigned PltZeroSize = 0;
Igor Kudrin15cd9ff2015-11-06 07:43:03 +000095 unsigned GotHeaderEntriesNum = 0;
Igor Kudrin351b41d2015-11-16 17:44:08 +000096 unsigned GotPltHeaderEntriesNum = 3;
Rui Ueyama724d6252016-01-29 01:49:32 +000097 bool UseLazyBinding = false;
Rafael Espindolafb1533b2016-02-22 21:23:29 +000098
99private:
100 virtual bool needsCopyRelImpl(uint32_t Type) const;
Rafael Espindola993f0272016-02-26 14:27:47 +0000101 virtual bool needsPltImpl(uint32_t Type) const;
Rafael Espindola01205f72015-09-22 18:19:46 +0000102};
103
Hal Finkel6f97c2b2015-10-16 21:55:40 +0000104uint64_t getPPC64TocBase();
105
Igor Kudrin15cd9ff2015-11-06 07:43:03 +0000106template <class ELFT>
107typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr();
108
George Rimara07ff662015-12-21 10:12:06 +0000109template <class ELFT> bool isGnuIFunc(const SymbolBody &S);
110
Rui Ueyamac1c282a2016-02-11 21:18:01 +0000111extern TargetInfo *Target;
Rui Ueyama91004392015-10-13 16:08:15 +0000112TargetInfo *createTarget();
Rafael Espindola01205f72015-09-22 18:19:46 +0000113}
114}
115
116#endif