1 //===- Thunks.h --------------------------------------------------------===// 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_THUNKS_H 11 #define LLD_ELF_THUNKS_H 12 13 #include "Relocations.h" 14 15 namespace lld { 16 namespace elf { 17 class Defined; 18 class Symbol; 19 class ThunkSection; 20 // Class to describe an instance of a Thunk. 21 // A Thunk is a code-sequence inserted by the linker in between a caller and 22 // the callee. The relocation to the callee is redirected to the Thunk, which 23 // after executing transfers control to the callee. Typical uses of Thunks 24 // include transferring control from non-pi to pi and changing state on 25 // targets like ARM. 26 // 27 // Thunks can be created for Defined, Shared and Undefined Symbols. 28 // Thunks are assigned to synthetic ThunkSections 29 class Thunk { 30 public: 31 Thunk(Symbol &Destination); 32 virtual ~Thunk(); 33 34 virtual uint32_t size() = 0; 35 virtual void writeTo(uint8_t *Buf) = 0; 36 37 // All Thunks must define at least one symbol, known as the thunk target 38 // symbol, so that we can redirect relocations to it. The thunk may define 39 // additional symbols, but these are never targets for relocations. 40 virtual void addSymbols(ThunkSection &IS) = 0; 41 42 void setOffset(uint64_t Offset); 43 Defined *addSymbol(StringRef Name, uint8_t Type, uint64_t Value, 44 InputSectionBase &Section); 45 46 // Some Thunks must be placed immediately before their Target as they elide 47 // a branch and fall through to the first Symbol in the Target. getTargetInputSection()48 virtual InputSection *getTargetInputSection() const { return nullptr; } 49 50 // To reuse a Thunk the caller as identified by the Type must be 51 // compatible with it. isCompatibleWith(RelType Type)52 virtual bool isCompatibleWith(RelType Type) const { return true; } 53 getThunkTargetSym()54 Defined *getThunkTargetSym() const { return Syms[0]; } 55 56 // The alignment requirement for this Thunk, defaults to the size of the 57 // typical code section alignment. 58 Symbol &Destination; 59 llvm::SmallVector<Defined *, 3> Syms; 60 uint64_t Offset = 0; 61 uint32_t Alignment = 4; 62 }; 63 64 // For a Relocation to symbol S create a Thunk to be added to a synthetic 65 // ThunkSection. At present there are implementations for ARM and Mips Thunks. 66 Thunk *addThunk(RelType Type, Symbol &S); 67 68 } // namespace elf 69 } // namespace lld 70 71 #endif 72