1 //===- LinkerScript.h -------------------------------------------*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLD_ELF_LINKER_SCRIPT_H 10 #define LLD_ELF_LINKER_SCRIPT_H 11 12 #include "Config.h" 13 #include "Writer.h" 14 #include "lld/Common/LLVM.h" 15 #include "lld/Common/Strings.h" 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/DenseSet.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include <cstddef> 23 #include <cstdint> 24 #include <functional> 25 #include <memory> 26 #include <vector> 27 28 namespace lld { 29 namespace elf { 30 31 class Defined; 32 class InputSection; 33 class InputSectionBase; 34 class InputSectionBase; 35 class OutputSection; 36 class SectionBase; 37 class Symbol; 38 class ThunkSection; 39 40 // This represents an r-value in the linker script. 41 struct ExprValue { 42 ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val, 43 const Twine &Loc) 44 : Sec(Sec), ForceAbsolute(ForceAbsolute), Val(Val), Loc(Loc.str()) {} 45 46 ExprValue(uint64_t Val) : ExprValue(nullptr, false, Val, "") {} 47 48 bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; } 49 uint64_t getValue() const; 50 uint64_t getSecAddr() const; 51 uint64_t getSectionOffset() const; 52 53 // If a value is relative to a section, it has a non-null Sec. 54 SectionBase *Sec; 55 56 // True if this expression is enclosed in ABSOLUTE(). 57 // This flag affects the return value of getValue(). 58 bool ForceAbsolute; 59 60 uint64_t Val; 61 uint64_t Alignment = 1; 62 63 // Original source location. Used for error messages. 64 std::string Loc; 65 }; 66 67 // This represents an expression in the linker script. 68 // ScriptParser::readExpr reads an expression and returns an Expr. 69 // Later, we evaluate the expression by calling the function. 70 using Expr = std::function<ExprValue()>; 71 72 // This enum is used to implement linker script SECTIONS command. 73 // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS 74 enum SectionsCommandKind { 75 AssignmentKind, // . = expr or <sym> = expr 76 OutputSectionKind, 77 InputSectionKind, 78 ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) 79 }; 80 81 struct BaseCommand { 82 BaseCommand(int K) : Kind(K) {} 83 int Kind; 84 }; 85 86 // This represents ". = <expr>" or "<symbol> = <expr>". 87 struct SymbolAssignment : BaseCommand { 88 SymbolAssignment(StringRef Name, Expr E, std::string Loc) 89 : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {} 90 91 static bool classof(const BaseCommand *C) { 92 return C->Kind == AssignmentKind; 93 } 94 95 // The LHS of an expression. Name is either a symbol name or ".". 96 StringRef Name; 97 Defined *Sym = nullptr; 98 99 // The RHS of an expression. 100 Expr Expression; 101 102 // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN. 103 bool Provide = false; 104 bool Hidden = false; 105 106 // Holds file name and line number for error reporting. 107 std::string Location; 108 109 // A string representation of this command. We use this for -Map. 110 std::string CommandString; 111 112 // Address of this assignment command. 113 unsigned Addr; 114 115 // Size of this assignment command. This is usually 0, but if 116 // you move '.' this may be greater than 0. 117 unsigned Size; 118 }; 119 120 // Linker scripts allow additional constraints to be put on ouput sections. 121 // If an output section is marked as ONLY_IF_RO, the section is created 122 // only if its input sections are read-only. Likewise, an output section 123 // with ONLY_IF_RW is created if all input sections are RW. 124 enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; 125 126 // This struct is used to represent the location and size of regions of 127 // target memory. Instances of the struct are created by parsing the 128 // MEMORY command. 129 struct MemoryRegion { 130 MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags, 131 uint32_t NegFlags) 132 : Name(Name), Origin(Origin), Length(Length), Flags(Flags), 133 NegFlags(NegFlags) {} 134 135 std::string Name; 136 uint64_t Origin; 137 uint64_t Length; 138 uint32_t Flags; 139 uint32_t NegFlags; 140 uint64_t CurPos = 0; 141 }; 142 143 // This struct represents one section match pattern in SECTIONS() command. 144 // It can optionally have negative match pattern for EXCLUDED_FILE command. 145 // Also it may be surrounded with SORT() command, so contains sorting rules. 146 struct SectionPattern { 147 SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2) 148 : ExcludedFilePat(Pat1), SectionPat(Pat2), 149 SortOuter(SortSectionPolicy::Default), 150 SortInner(SortSectionPolicy::Default) {} 151 152 StringMatcher ExcludedFilePat; 153 StringMatcher SectionPat; 154 SortSectionPolicy SortOuter; 155 SortSectionPolicy SortInner; 156 }; 157 158 struct InputSectionDescription : BaseCommand { 159 InputSectionDescription(StringRef FilePattern) 160 : BaseCommand(InputSectionKind), FilePat(FilePattern) {} 161 162 static bool classof(const BaseCommand *C) { 163 return C->Kind == InputSectionKind; 164 } 165 166 StringMatcher FilePat; 167 168 // Input sections that matches at least one of SectionPatterns 169 // will be associated with this InputSectionDescription. 170 std::vector<SectionPattern> SectionPatterns; 171 172 std::vector<InputSection *> Sections; 173 174 // Temporary record of synthetic ThunkSection instances and the pass that 175 // they were created in. This is used to insert newly created ThunkSections 176 // into Sections at the end of a createThunks() pass. 177 std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections; 178 }; 179 180 // Represents BYTE(), SHORT(), LONG(), or QUAD(). 181 struct ByteCommand : BaseCommand { 182 ByteCommand(Expr E, unsigned Size, std::string CommandString) 183 : BaseCommand(ByteKind), CommandString(CommandString), Expression(E), 184 Size(Size) {} 185 186 static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; } 187 188 // Keeps string representing the command. Used for -Map" is perhaps better. 189 std::string CommandString; 190 191 Expr Expression; 192 193 // This is just an offset of this assignment command in the output section. 194 unsigned Offset; 195 196 // Size of this data command. 197 unsigned Size; 198 }; 199 200 struct PhdrsCommand { 201 StringRef Name; 202 unsigned Type = llvm::ELF::PT_NULL; 203 bool HasFilehdr = false; 204 bool HasPhdrs = false; 205 llvm::Optional<unsigned> Flags; 206 Expr LMAExpr = nullptr; 207 }; 208 209 class LinkerScript final { 210 // Temporary state used in processSectionCommands() and assignAddresses() 211 // that must be reinitialized for each call to the above functions, and must 212 // not be used outside of the scope of a call to the above functions. 213 struct AddressState { 214 AddressState(); 215 uint64_t ThreadBssOffset = 0; 216 OutputSection *OutSec = nullptr; 217 MemoryRegion *MemRegion = nullptr; 218 MemoryRegion *LMARegion = nullptr; 219 uint64_t LMAOffset = 0; 220 }; 221 222 llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection; 223 224 void addSymbol(SymbolAssignment *Cmd); 225 void assignSymbol(SymbolAssignment *Cmd, bool InSec); 226 void setDot(Expr E, const Twine &Loc, bool InSec); 227 void expandOutputSection(uint64_t Size); 228 void expandMemoryRegions(uint64_t Size); 229 230 std::vector<InputSection *> 231 computeInputSections(const InputSectionDescription *); 232 233 std::vector<InputSection *> createInputSectionList(OutputSection &Cmd); 234 235 std::vector<size_t> getPhdrIndices(OutputSection *Sec); 236 237 MemoryRegion *findMemoryRegion(OutputSection *Sec); 238 239 void switchTo(OutputSection *Sec); 240 uint64_t advance(uint64_t Size, unsigned Align); 241 void output(InputSection *Sec); 242 243 void assignOffsets(OutputSection *Sec); 244 245 // Ctx captures the local AddressState and makes it accessible 246 // deliberately. This is needed as there are some cases where we cannot just 247 // thread the current state through to a lambda function created by the 248 // script parser. 249 // This should remain a plain pointer as its lifetime is smaller than 250 // LinkerScript. 251 AddressState *Ctx = nullptr; 252 253 OutputSection *Aether; 254 255 uint64_t Dot; 256 257 public: 258 OutputSection *createOutputSection(StringRef Name, StringRef Location); 259 OutputSection *getOrCreateOutputSection(StringRef Name); 260 261 bool hasPhdrsCommands() { return !PhdrsCommands.empty(); } 262 uint64_t getDot() { return Dot; } 263 void discard(ArrayRef<InputSection *> V); 264 265 ExprValue getSymbolValue(StringRef Name, const Twine &Loc); 266 267 void addOrphanSections(); 268 void adjustSectionsBeforeSorting(); 269 void adjustSectionsAfterSorting(); 270 271 std::vector<PhdrEntry *> createPhdrs(); 272 bool needsInterpSection(); 273 274 bool shouldKeep(InputSectionBase *S); 275 void assignAddresses(); 276 void allocateHeaders(std::vector<PhdrEntry *> &Phdrs); 277 void processSectionCommands(); 278 void declareSymbols(); 279 280 // Used to handle INSERT AFTER statements. 281 void processInsertCommands(); 282 283 // SECTIONS command list. 284 std::vector<BaseCommand *> SectionCommands; 285 286 // PHDRS command list. 287 std::vector<PhdrsCommand> PhdrsCommands; 288 289 bool HasSectionsCommand = false; 290 bool ErrorOnMissingSection = false; 291 292 // List of section patterns specified with KEEP commands. They will 293 // be kept even if they are unused and --gc-sections is specified. 294 std::vector<InputSectionDescription *> KeptSections; 295 296 // A map from memory region name to a memory region descriptor. 297 llvm::MapVector<llvm::StringRef, MemoryRegion *> MemoryRegions; 298 299 // A list of symbols referenced by the script. 300 std::vector<llvm::StringRef> ReferencedSymbols; 301 302 // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need 303 // to be inserted into SECTIONS commands list. 304 llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands; 305 llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands; 306 }; 307 308 extern LinkerScript *Script; 309 310 } // end namespace elf 311 } // end namespace lld 312 313 #endif // LLD_ELF_LINKER_SCRIPT_H 314