1 //===- LinkerScript.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_LINKER_SCRIPT_H 11 #define LLD_ELF_LINKER_SCRIPT_H 12 13 #include "Strings.h" 14 #include "Writer.h" 15 #include "lld/Core/LLVM.h" 16 #include "llvm/ADT/DenseMap.h" 17 #include "llvm/ADT/MapVector.h" 18 #include "llvm/Support/Allocator.h" 19 #include "llvm/Support/MemoryBuffer.h" 20 #include "llvm/Support/Regex.h" 21 #include <functional> 22 23 namespace lld { 24 namespace elf { 25 class DefinedCommon; 26 class ScriptParser; 27 class SymbolBody; 28 template <class ELFT> class InputSectionBase; 29 template <class ELFT> class OutputSectionBase; 30 template <class ELFT> class OutputSectionFactory; 31 class InputSectionData; 32 33 typedef std::function<uint64_t(uint64_t)> Expr; 34 35 // Parses a linker script. Calling this function updates 36 // Config and ScriptConfig. 37 void readLinkerScript(MemoryBufferRef MB); 38 39 void readVersionScript(MemoryBufferRef MB); 40 41 // This enum is used to implement linker script SECTIONS command. 42 // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS 43 enum SectionsCommandKind { 44 AssignmentKind, 45 OutputSectionKind, 46 InputSectionKind, 47 AssertKind 48 }; 49 50 struct BaseCommand { 51 BaseCommand(int K) : Kind(K) {} 52 virtual ~BaseCommand() {} 53 int Kind; 54 }; 55 56 struct SymbolAssignment : BaseCommand { 57 SymbolAssignment(StringRef Name, Expr E, bool IsAbsolute) 58 : BaseCommand(AssignmentKind), Name(Name), Expression(E), 59 IsAbsolute(IsAbsolute) {} 60 static bool classof(const BaseCommand *C); 61 62 // The LHS of an expression. Name is either a symbol name or ".". 63 StringRef Name; 64 SymbolBody *Sym = nullptr; 65 66 // The RHS of an expression. 67 Expr Expression; 68 69 // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN. 70 bool Provide = false; 71 bool Hidden = false; 72 bool IsAbsolute; 73 InputSectionData *GoesAfter = nullptr; 74 }; 75 76 // Linker scripts allow additional constraints to be put on ouput sections. 77 // An output section will only be created if all of its input sections are 78 // read-only 79 // or all of its input sections are read-write by using the keyword ONLY_IF_RO 80 // and ONLY_IF_RW respectively. 81 enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; 82 83 struct OutputSectionCommand : BaseCommand { 84 OutputSectionCommand(StringRef Name) 85 : BaseCommand(OutputSectionKind), Name(Name) {} 86 static bool classof(const BaseCommand *C); 87 StringRef Name; 88 Expr AddrExpr; 89 Expr AlignExpr; 90 Expr LmaExpr; 91 Expr SubalignExpr; 92 std::vector<std::unique_ptr<BaseCommand>> Commands; 93 std::vector<StringRef> Phdrs; 94 std::vector<uint8_t> Filler; 95 ConstraintKind Constraint = ConstraintKind::NoConstraint; 96 }; 97 98 enum SortKind { SortNone, SortByName, SortByAlignment }; 99 100 struct InputSectionDescription : BaseCommand { 101 InputSectionDescription(StringRef FilePattern) 102 : BaseCommand(InputSectionKind), 103 FileRe(compileGlobPatterns({FilePattern})) {} 104 static bool classof(const BaseCommand *C); 105 llvm::Regex FileRe; 106 SortKind SortOuter = SortNone; 107 SortKind SortInner = SortNone; 108 llvm::Regex ExcludedFileRe; 109 llvm::Regex SectionRe; 110 }; 111 112 struct AssertCommand : BaseCommand { 113 AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {} 114 static bool classof(const BaseCommand *C); 115 Expr Expression; 116 }; 117 118 struct PhdrsCommand { 119 StringRef Name; 120 unsigned Type; 121 bool HasFilehdr; 122 bool HasPhdrs; 123 unsigned Flags; 124 Expr LMAExpr; 125 }; 126 127 class LinkerScriptBase { 128 protected: 129 ~LinkerScriptBase() = default; 130 131 public: 132 virtual uint64_t getOutputSectionAddress(StringRef Name) = 0; 133 virtual uint64_t getOutputSectionSize(StringRef Name) = 0; 134 virtual uint64_t getOutputSectionAlign(StringRef Name) = 0; 135 virtual uint64_t getHeaderSize() = 0; 136 virtual uint64_t getSymbolValue(StringRef S) = 0; 137 }; 138 139 // ScriptConfiguration holds linker script parse results. 140 struct ScriptConfiguration { 141 // Used to create symbol assignments outside SECTIONS command. 142 std::vector<std::unique_ptr<SymbolAssignment>> Assignments; 143 // Used to assign addresses to sections. 144 std::vector<std::unique_ptr<BaseCommand>> Commands; 145 146 // Used to assign sections to headers. 147 std::vector<PhdrsCommand> PhdrsCommands; 148 149 bool HasContents = false; 150 151 llvm::BumpPtrAllocator Alloc; 152 153 // List of section patterns specified with KEEP commands. They will 154 // be kept even if they are unused and --gc-sections is specified. 155 std::vector<llvm::Regex *> KeptSections; 156 }; 157 158 extern ScriptConfiguration *ScriptConfig; 159 160 // This is a runner of the linker script. 161 template <class ELFT> class LinkerScript final : public LinkerScriptBase { 162 typedef typename ELFT::uint uintX_t; 163 164 public: 165 LinkerScript(); 166 ~LinkerScript(); 167 void createAssignments(); 168 void createSections(OutputSectionFactory<ELFT> &Factory); 169 170 std::vector<PhdrEntry<ELFT>> createPhdrs(); 171 bool ignoreInterpSection(); 172 173 ArrayRef<uint8_t> getFiller(StringRef Name); 174 Expr getLma(StringRef Name); 175 bool shouldKeep(InputSectionBase<ELFT> *S); 176 void assignAddresses(); 177 int compareSections(StringRef A, StringRef B); 178 bool hasPhdrsCommands(); 179 uint64_t getOutputSectionAddress(StringRef Name) override; 180 uint64_t getOutputSectionSize(StringRef Name) override; 181 uint64_t getOutputSectionAlign(StringRef Name) override; 182 uint64_t getHeaderSize() override; 183 uint64_t getSymbolValue(StringRef S) override; 184 185 std::vector<OutputSectionBase<ELFT> *> *OutputSections; 186 187 private: 188 std::vector<InputSectionBase<ELFT> *> 189 getInputSections(const InputSectionDescription *); 190 191 void discard(OutputSectionCommand &Cmd); 192 193 std::vector<InputSectionBase<ELFT> *> 194 createInputSectionList(OutputSectionCommand &Cmd); 195 196 // "ScriptConfig" is a bit too long, so define a short name for it. 197 ScriptConfiguration &Opt = *ScriptConfig; 198 199 int getSectionIndex(StringRef Name); 200 std::vector<size_t> getPhdrIndices(StringRef SectionName); 201 size_t getPhdrIndex(StringRef PhdrName); 202 203 uintX_t Dot; 204 }; 205 206 // Variable template is a C++14 feature, so we can't template 207 // a global variable. Use a struct to workaround. 208 template <class ELFT> struct Script { static LinkerScript<ELFT> *X; }; 209 template <class ELFT> LinkerScript<ELFT> *Script<ELFT>::X; 210 211 extern LinkerScriptBase *ScriptBase; 212 213 } // namespace elf 214 } // namespace lld 215 216 #endif 217