blob: f2ca0f092bb3d223afd09d2270e101d7cee51dc1 [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 {
19namespace elf2 {
20class SymbolBody;
21
22class TargetInfo {
23public:
Hal Finkele3c26262015-10-08 22:23:54 +000024 unsigned getPageSize() const { return PageSize; }
Igor Kudrinf6f45472015-11-10 08:39:27 +000025 uint64_t getVAStart() const;
George Rimarbc590fe2015-10-28 16:48:58 +000026 unsigned getCopyReloc() const { return CopyReloc; }
Rafael Espindola7f074422015-09-22 21:35:51 +000027 unsigned getGotReloc() const { return GotReloc; }
George Rimar648a2c32015-10-20 08:54:27 +000028 unsigned getPltReloc() const { return PltReloc; }
Rafael Espindolaae244002015-10-05 19:30:12 +000029 unsigned getRelativeReloc() const { return RelativeReloc; }
Michael J. Spencerecd7f372015-11-13 00:32:58 +000030 bool isTlsLocalDynamicReloc(unsigned Type) const {
31 return Type == TlsLocalDynamicReloc;
32 }
33 bool isTlsGlobalDynamicReloc(unsigned Type) const {
34 return Type == TlsGlobalDynamicReloc;
35 }
Michael J. Spencer1e225612015-11-11 01:00:24 +000036 unsigned getTlsModuleIndexReloc() const { return TlsModuleIndexReloc; }
Michael J. Spencer627ae702015-11-13 00:28:34 +000037 unsigned getTlsOffsetReloc() const { return TlsOffsetReloc; }
George Rimar648a2c32015-10-20 08:54:27 +000038 unsigned getPltZeroEntrySize() const { return PltZeroEntrySize; }
Hal Finkel6c2a3b82015-10-08 21:51:31 +000039 unsigned getPltEntrySize() const { return PltEntrySize; }
George Rimar648a2c32015-10-20 08:54:27 +000040 bool supportsLazyRelocations() const { return LazyRelocations; }
Igor Kudrin15cd9ff2015-11-06 07:43:03 +000041 unsigned getGotHeaderEntriesNum() const { return GotHeaderEntriesNum; }
Igor Kudrin351b41d2015-11-16 17:44:08 +000042 unsigned getGotPltHeaderEntriesNum() const { return GotPltHeaderEntriesNum; }
George Rimard23970f2015-11-25 20:41:53 +000043 virtual unsigned getDynReloc(unsigned Type) const { return Type; }
George Rimar6f17e092015-12-17 09:32:21 +000044 virtual bool isTlsDynReloc(unsigned Type, const SymbolBody &S) const {
45 return false;
46 }
Igor Kudrine7ad0932015-11-17 17:47:53 +000047 virtual unsigned getPltRefReloc(unsigned Type) const;
George Rimar6f17e092015-12-17 09:32:21 +000048 virtual unsigned getTlsGotReloc(unsigned Type = -1) const {
49 return TlsGotReloc;
50 }
Igor Kudrin15cd9ff2015-11-06 07:43:03 +000051 virtual void writeGotHeaderEntries(uint8_t *Buf) const;
Igor Kudrin351b41d2015-11-16 17:44:08 +000052 virtual void writeGotPltHeaderEntries(uint8_t *Buf) const;
George Rimar648a2c32015-10-20 08:54:27 +000053 virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0;
54 virtual void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
55 uint64_t PltEntryAddr) const = 0;
George Rimar77b77792015-11-25 22:15:01 +000056 virtual void writePltEntry(uint8_t *Buf, uint64_t GotAddr,
57 uint64_t GotEntryAddr, uint64_t PltEntryAddr,
58 int32_t Index, unsigned RelOff) const = 0;
Rafael Espindolaae244002015-10-05 19:30:12 +000059 virtual bool isRelRelative(uint32_t Type) const;
George Rimar48651482015-12-11 08:59:37 +000060 virtual bool isSizeDynReloc(uint32_t Type, const SymbolBody &S) const;
George Rimar6f17e092015-12-17 09:32:21 +000061 virtual bool relocNeedsDynRelative(unsigned Type) const { return false; }
Rafael Espindola3ef3a4c2015-09-29 23:22:16 +000062 virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;
Rafael Espindola3ef3a4c2015-09-29 23:22:16 +000063 virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const = 0;
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;
George Rimar6713cf82015-11-25 21:46:05 +000068 virtual bool isTlsOptimized(unsigned Type, const SymbolBody *S) const;
Rui Ueyama02dfd492015-12-17 01:18:40 +000069 virtual bool needsCopyRel(uint32_t Type, const SymbolBody &S) const;
George Rimar6713cf82015-11-25 21:46:05 +000070 virtual unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
George Rimar25411f252015-12-04 11:20:13 +000071 uint32_t Type, uint64_t P, uint64_t SA,
72 const SymbolBody &S) const;
Rafael Espindola01205f72015-09-22 18:19:46 +000073 virtual ~TargetInfo();
74
75protected:
Hal Finkele3c26262015-10-08 22:23:54 +000076 unsigned PageSize = 4096;
Hal Finkel736c7412015-10-15 07:49:07 +000077
78 // On freebsd x86_64 the first page cannot be mmaped.
79 // On linux that is controled by vm.mmap_min_addr. At least on some x86_64
80 // installs that is 65536, so the first 15 pages cannot be used.
81 // Given that, the smallest value that can be used in here is 0x10000.
82 // If using 2MB pages, the smallest page aligned address that works is
83 // 0x200000, but it looks like every OS uses 4k pages for executables.
84 uint64_t VAStart = 0x10000;
85
George Rimarbc590fe2015-10-28 16:48:58 +000086 unsigned CopyReloc;
Rafael Espindola01205f72015-09-22 18:19:46 +000087 unsigned PCRelReloc;
Rafael Espindola7f074422015-09-22 21:35:51 +000088 unsigned GotReloc;
George Rimar648a2c32015-10-20 08:54:27 +000089 unsigned PltReloc;
Rafael Espindolaae244002015-10-05 19:30:12 +000090 unsigned RelativeReloc;
George Rimar687138c2015-11-13 16:28:53 +000091 unsigned TlsGotReloc = 0;
Michael J. Spencer1e225612015-11-11 01:00:24 +000092 unsigned TlsLocalDynamicReloc = 0;
Michael J. Spencer627ae702015-11-13 00:28:34 +000093 unsigned TlsGlobalDynamicReloc = 0;
Michael J. Spencer1e225612015-11-11 01:00:24 +000094 unsigned TlsModuleIndexReloc;
Michael J. Spencer627ae702015-11-13 00:28:34 +000095 unsigned TlsOffsetReloc;
Hal Finkel6c2a3b82015-10-08 21:51:31 +000096 unsigned PltEntrySize = 8;
George Rimar648a2c32015-10-20 08:54:27 +000097 unsigned PltZeroEntrySize = 0;
Igor Kudrin15cd9ff2015-11-06 07:43:03 +000098 unsigned GotHeaderEntriesNum = 0;
Igor Kudrin351b41d2015-11-16 17:44:08 +000099 unsigned GotPltHeaderEntriesNum = 3;
George Rimar648a2c32015-10-20 08:54:27 +0000100 bool LazyRelocations = false;
Rafael Espindola01205f72015-09-22 18:19:46 +0000101};
102
Hal Finkel6f97c2b2015-10-16 21:55:40 +0000103uint64_t getPPC64TocBase();
104
Igor Kudrin15cd9ff2015-11-06 07:43:03 +0000105template <class ELFT>
106typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr();
107
Rafael Espindola01205f72015-09-22 18:19:46 +0000108extern std::unique_ptr<TargetInfo> Target;
Rui Ueyama91004392015-10-13 16:08:15 +0000109TargetInfo *createTarget();
Rafael Espindola01205f72015-09-22 18:19:46 +0000110}
111}
112
113#endif