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 "Config.h" 14 #include "Strings.h" 15 #include "Writer.h" 16 #include "lld/Core/LLVM.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/DenseSet.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/Support/Allocator.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include "llvm/Support/Regex.h" 23 #include <functional> 24 25 namespace lld { 26 namespace elf { 27 class DefinedCommon; 28 class ScriptParser; 29 class SymbolBody; 30 template <class ELFT> class InputSectionBase; 31 template <class ELFT> class InputSection; 32 template <class ELFT> class OutputSectionBase; 33 template <class ELFT> class OutputSectionFactory; 34 class InputSectionData; 35 36 // This represents an expression in the linker script. 37 // ScriptParser::readExpr reads an expression and returns an Expr. 38 // Later, we evaluate the expression by calling the function 39 // with the value of special context variable ".". 40 typedef std::function<uint64_t(uint64_t)> Expr; 41 42 // Parses a linker script. Calling this function updates 43 // Config and ScriptConfig. 44 void readLinkerScript(MemoryBufferRef MB); 45 46 // Parses a version script. 47 void readVersionScript(MemoryBufferRef MB); 48 49 // This enum is used to implement linker script SECTIONS command. 50 // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS 51 enum SectionsCommandKind { 52 AssignmentKind, // . = expr or <sym> = expr 53 OutputSectionKind, 54 InputSectionKind, 55 AssertKind, // ASSERT(expr) 56 BytesDataKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) 57 }; 58 59 struct BaseCommand { 60 BaseCommand(int K) : Kind(K) {} 61 virtual ~BaseCommand() {} 62 int Kind; 63 }; 64 65 // This represents ". = <expr>" or "<symbol> = <expr>". 66 struct SymbolAssignment : BaseCommand { 67 SymbolAssignment(StringRef Name, Expr E, bool IsAbsolute) 68 : BaseCommand(AssignmentKind), Name(Name), Expression(E), 69 IsAbsolute(IsAbsolute) {} 70 static bool classof(const BaseCommand *C); 71 72 // The LHS of an expression. Name is either a symbol name or ".". 73 StringRef Name; 74 SymbolBody *Sym = nullptr; 75 76 // The RHS of an expression. 77 Expr Expression; 78 79 // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN. 80 bool Provide = false; 81 bool Hidden = false; 82 bool IsAbsolute; 83 }; 84 85 // Linker scripts allow additional constraints to be put on ouput sections. 86 // If an output section is marked as ONLY_IF_RO, the section is created 87 // only if its input sections are read-only. Likewise, an output section 88 // with ONLY_IF_RW is created if all input sections are RW. 89 enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; 90 91 struct OutputSectionCommand : BaseCommand { 92 OutputSectionCommand(StringRef Name) 93 : BaseCommand(OutputSectionKind), Name(Name) {} 94 static bool classof(const BaseCommand *C); 95 StringRef Name; 96 Expr AddrExpr; 97 Expr AlignExpr; 98 Expr LMAExpr; 99 Expr SubalignExpr; 100 std::vector<std::unique_ptr<BaseCommand>> Commands; 101 std::vector<StringRef> Phdrs; 102 std::vector<uint8_t> Filler; 103 ConstraintKind Constraint = ConstraintKind::NoConstraint; 104 }; 105 106 // This struct represents one section match pattern in SECTIONS() command. 107 // It can optionally have negative match pattern for EXCLUDED_FILE command. 108 // Also it may be surrounded with SORT() command, so contains sorting rules. 109 struct SectionPattern { 110 SectionPattern(llvm::Regex &&Re1, llvm::Regex &&Re2) 111 : ExcludedFileRe(std::forward<llvm::Regex>(Re1)), 112 SectionRe(std::forward<llvm::Regex>(Re2)) {} 113 114 SectionPattern(SectionPattern &&Other) { 115 std::swap(ExcludedFileRe, Other.ExcludedFileRe); 116 std::swap(SectionRe, Other.SectionRe); 117 std::swap(SortOuter, Other.SortOuter); 118 std::swap(SortInner, Other.SortInner); 119 } 120 121 llvm::Regex ExcludedFileRe; 122 llvm::Regex SectionRe; 123 SortSectionPolicy SortOuter; 124 SortSectionPolicy SortInner; 125 }; 126 127 struct InputSectionDescription : BaseCommand { 128 InputSectionDescription(StringRef FilePattern) 129 : BaseCommand(InputSectionKind), 130 FileRe(compileGlobPatterns({FilePattern})) {} 131 static bool classof(const BaseCommand *C); 132 llvm::Regex FileRe; 133 134 // Input sections that matches at least one of SectionPatterns 135 // will be associated with this InputSectionDescription. 136 std::vector<SectionPattern> SectionPatterns; 137 138 std::vector<InputSectionData *> Sections; 139 }; 140 141 // Represents an ASSERT(). 142 struct AssertCommand : BaseCommand { 143 AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {} 144 static bool classof(const BaseCommand *C); 145 Expr Expression; 146 }; 147 148 // Represents BYTE(), SHORT(), LONG(), or QUAD(). 149 struct BytesDataCommand : BaseCommand { 150 BytesDataCommand(uint64_t Data, unsigned Size) 151 : BaseCommand(BytesDataKind), Data(Data), Size(Size) {} 152 static bool classof(const BaseCommand *C); 153 uint64_t Data; 154 unsigned Offset; 155 unsigned Size; 156 }; 157 158 struct PhdrsCommand { 159 StringRef Name; 160 unsigned Type; 161 bool HasFilehdr; 162 bool HasPhdrs; 163 unsigned Flags; 164 Expr LMAExpr; 165 }; 166 167 class LinkerScriptBase { 168 protected: 169 ~LinkerScriptBase() = default; 170 171 public: 172 virtual uint64_t getOutputSectionAddress(StringRef Name) = 0; 173 virtual uint64_t getOutputSectionSize(StringRef Name) = 0; 174 virtual uint64_t getOutputSectionAlign(StringRef Name) = 0; 175 virtual uint64_t getOutputSectionLMA(StringRef Name) = 0; 176 virtual uint64_t getHeaderSize() = 0; 177 virtual uint64_t getSymbolValue(StringRef S) = 0; 178 virtual bool isDefined(StringRef S) = 0; 179 }; 180 181 // ScriptConfiguration holds linker script parse results. 182 struct ScriptConfiguration { 183 // Used to assign addresses to sections. 184 std::vector<std::unique_ptr<BaseCommand>> Commands; 185 186 // Used to assign sections to headers. 187 std::vector<PhdrsCommand> PhdrsCommands; 188 189 bool HasSections = false; 190 191 llvm::BumpPtrAllocator Alloc; 192 193 // List of section patterns specified with KEEP commands. They will 194 // be kept even if they are unused and --gc-sections is specified. 195 std::vector<InputSectionDescription *> KeptSections; 196 }; 197 198 extern ScriptConfiguration *ScriptConfig; 199 200 // This is a runner of the linker script. 201 template <class ELFT> class LinkerScript final : public LinkerScriptBase { 202 typedef typename ELFT::uint uintX_t; 203 204 public: 205 LinkerScript(); 206 ~LinkerScript(); 207 void processCommands(OutputSectionFactory<ELFT> &Factory); 208 void createSections(OutputSectionFactory<ELFT> &Factory); 209 void adjustSectionsBeforeSorting(); 210 211 std::vector<PhdrEntry<ELFT>> createPhdrs(); 212 bool ignoreInterpSection(); 213 214 ArrayRef<uint8_t> getFiller(StringRef Name); 215 void writeDataBytes(StringRef Name, uint8_t *Buf); 216 bool hasLMA(StringRef Name); 217 bool shouldKeep(InputSectionBase<ELFT> *S); 218 void assignOffsets(OutputSectionCommand *Cmd); 219 void assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs); 220 bool hasPhdrsCommands(); 221 uint64_t getOutputSectionAddress(StringRef Name) override; 222 uint64_t getOutputSectionSize(StringRef Name) override; 223 uint64_t getOutputSectionAlign(StringRef Name) override; 224 uint64_t getOutputSectionLMA(StringRef Name) override; 225 uint64_t getHeaderSize() override; 226 uint64_t getSymbolValue(StringRef S) override; 227 bool isDefined(StringRef S) override; 228 229 std::vector<OutputSectionBase<ELFT> *> *OutputSections; 230 231 int getSectionIndex(StringRef Name); 232 233 private: 234 void computeInputSections(InputSectionDescription *); 235 236 void addSection(OutputSectionFactory<ELFT> &Factory, 237 InputSectionBase<ELFT> *Sec, StringRef Name); 238 void discard(ArrayRef<InputSectionBase<ELFT> *> V); 239 240 std::vector<InputSectionBase<ELFT> *> 241 createInputSectionList(OutputSectionCommand &Cmd); 242 243 // "ScriptConfig" is a bit too long, so define a short name for it. 244 ScriptConfiguration &Opt = *ScriptConfig; 245 246 std::vector<size_t> getPhdrIndices(StringRef SectionName); 247 size_t getPhdrIndex(StringRef PhdrName); 248 249 uintX_t Dot; 250 uintX_t LMAOffset = 0; 251 OutputSectionBase<ELFT> *CurOutSec = nullptr; 252 uintX_t ThreadBssOffset = 0; 253 void switchTo(OutputSectionBase<ELFT> *Sec); 254 void flush(); 255 void output(InputSection<ELFT> *Sec); 256 void process(BaseCommand &Base); 257 llvm::DenseSet<OutputSectionBase<ELFT> *> AlreadyOutputOS; 258 llvm::DenseSet<InputSectionData *> AlreadyOutputIS; 259 }; 260 261 // Variable template is a C++14 feature, so we can't template 262 // a global variable. Use a struct to workaround. 263 template <class ELFT> struct Script { static LinkerScript<ELFT> *X; }; 264 template <class ELFT> LinkerScript<ELFT> *Script<ELFT>::X; 265 266 extern LinkerScriptBase *ScriptBase; 267 268 } // namespace elf 269 } // namespace lld 270 271 #endif 272