Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 1 | //===- Thunks.h --------------------------------------------------------===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #ifndef LLD_ELF_THUNKS_H |
| 10 | #define LLD_ELF_THUNKS_H |
| 11 | |
| 12 | #include "Relocations.h" |
| 13 | |
| 14 | namespace lld { |
| 15 | namespace elf { |
Peter Collingbourne | c5391ce | 2018-03-29 22:32:13 +0000 | [diff] [blame] | 16 | class Defined; |
Fangrui Song | fb2944b | 2019-12-17 11:23:37 -0800 | [diff] [blame^] | 17 | class InputFile; |
Rui Ueyama | f52496e | 2017-11-03 21:21:47 +0000 | [diff] [blame] | 18 | class Symbol; |
George Rimar | 7b82704 | 2017-03-16 10:40:50 +0000 | [diff] [blame] | 19 | class ThunkSection; |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 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 | // |
Peter Collingbourne | e9a9e0a | 2017-11-06 04:35:31 +0000 | [diff] [blame] | 27 | // Thunks can be created for Defined, Shared and Undefined Symbols. |
Peter Smith | 3a52eb0 | 2017-02-01 10:26:03 +0000 | [diff] [blame] | 28 | // Thunks are assigned to synthetic ThunkSections |
George Rimar | 7b82704 | 2017-03-16 10:40:50 +0000 | [diff] [blame] | 29 | class Thunk { |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 30 | public: |
Fangrui Song | bf535ac | 2019-11-23 00:57:54 -0800 | [diff] [blame] | 31 | Thunk(Symbol &destination, int64_t addend); |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 32 | virtual ~Thunk(); |
| 33 | |
Peter Collingbourne | cebab4a | 2018-03-28 21:33:31 +0000 | [diff] [blame] | 34 | virtual uint32_t size() = 0; |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 35 | virtual void writeTo(uint8_t *buf) = 0; |
Rui Ueyama | 3d2bbb1 | 2016-07-09 22:52:30 +0000 | [diff] [blame] | 36 | |
Peter Collingbourne | c5391ce | 2018-03-29 22:32:13 +0000 | [diff] [blame] | 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. |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 40 | virtual void addSymbols(ThunkSection &isec) = 0; |
Peter Smith | 3a52eb0 | 2017-02-01 10:26:03 +0000 | [diff] [blame] | 41 | |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 42 | void setOffset(uint64_t offset); |
| 43 | Defined *addSymbol(StringRef name, uint8_t type, uint64_t value, |
| 44 | InputSectionBase §ion); |
Peter Collingbourne | c5391ce | 2018-03-29 22:32:13 +0000 | [diff] [blame] | 45 | |
Peter Smith | 3a52eb0 | 2017-02-01 10:26:03 +0000 | [diff] [blame] | 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. |
Rafael Espindola | 774ea7d | 2017-02-23 16:49:07 +0000 | [diff] [blame] | 48 | virtual InputSection *getTargetInputSection() const { return nullptr; } |
Peter Smith | 3a52eb0 | 2017-02-01 10:26:03 +0000 | [diff] [blame] | 49 | |
Fangrui Song | 82442ad | 2019-06-06 17:03:00 +0000 | [diff] [blame] | 50 | // To reuse a Thunk the InputSection and the relocation must be compatible |
| 51 | // with it. |
| 52 | virtual bool isCompatibleWith(const InputSection &, |
| 53 | const Relocation &) const { |
| 54 | return true; |
| 55 | } |
Peter Smith | 7d66e84 | 2017-07-05 09:36:03 +0000 | [diff] [blame] | 56 | |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 57 | Defined *getThunkTargetSym() const { return syms[0]; } |
Peter Collingbourne | c5391ce | 2018-03-29 22:32:13 +0000 | [diff] [blame] | 58 | |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 59 | Symbol &destination; |
Fangrui Song | bf535ac | 2019-11-23 00:57:54 -0800 | [diff] [blame] | 60 | int64_t addend; |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 61 | llvm::SmallVector<Defined *, 3> syms; |
| 62 | uint64_t offset = 0; |
Fangrui Song | bf535ac | 2019-11-23 00:57:54 -0800 | [diff] [blame] | 63 | // The alignment requirement for this Thunk, defaults to the size of the |
| 64 | // typical code section alignment. |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 65 | uint32_t alignment = 4; |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 66 | }; |
| 67 | |
Peter Smith | 3a52eb0 | 2017-02-01 10:26:03 +0000 | [diff] [blame] | 68 | // For a Relocation to symbol S create a Thunk to be added to a synthetic |
Fangrui Song | 82442ad | 2019-06-06 17:03:00 +0000 | [diff] [blame] | 69 | // ThunkSection. |
Rui Ueyama | 3837f42 | 2019-07-10 05:00:37 +0000 | [diff] [blame] | 70 | Thunk *addThunk(const InputSection &isec, Relocation &rel); |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 71 | |
Fangrui Song | fb2944b | 2019-12-17 11:23:37 -0800 | [diff] [blame^] | 72 | void writePPC32PltCallStub(uint8_t *buf, uint64_t gotPltVA, |
| 73 | const InputFile *file, int64_t addend); |
Fangrui Song | 45acc35 | 2019-12-13 18:30:21 -0800 | [diff] [blame] | 74 | void writePPC64LoadAndBranch(uint8_t *buf, int64_t offset); |
| 75 | |
Peter Smith | fb05cd9 | 2016-07-08 16:10:27 +0000 | [diff] [blame] | 76 | } // namespace elf |
| 77 | } // namespace lld |
| 78 | |
| 79 | #endif |