1ece8a530Spatrick //===- LinkerScript.h -------------------------------------------*- C++ -*-===// 2ece8a530Spatrick // 3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information. 5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ece8a530Spatrick // 7ece8a530Spatrick //===----------------------------------------------------------------------===// 8ece8a530Spatrick 9ece8a530Spatrick #ifndef LLD_ELF_LINKER_SCRIPT_H 10ece8a530Spatrick #define LLD_ELF_LINKER_SCRIPT_H 11ece8a530Spatrick 12ece8a530Spatrick #include "Config.h" 13ece8a530Spatrick #include "Writer.h" 14ece8a530Spatrick #include "lld/Common/LLVM.h" 15ece8a530Spatrick #include "lld/Common/Strings.h" 16ece8a530Spatrick #include "llvm/ADT/ArrayRef.h" 17ece8a530Spatrick #include "llvm/ADT/DenseMap.h" 18ece8a530Spatrick #include "llvm/ADT/MapVector.h" 19ece8a530Spatrick #include "llvm/ADT/StringRef.h" 20*dfe94b16Srobert #include "llvm/Support/Compiler.h" 21ece8a530Spatrick #include <cstddef> 22ece8a530Spatrick #include <cstdint> 23ece8a530Spatrick #include <functional> 24ece8a530Spatrick #include <memory> 25ece8a530Spatrick 26*dfe94b16Srobert namespace lld::elf { 27ece8a530Spatrick 28ece8a530Spatrick class Defined; 291cf9926bSpatrick class InputFile; 30ece8a530Spatrick class InputSection; 31ece8a530Spatrick class InputSectionBase; 32ece8a530Spatrick class OutputSection; 33ece8a530Spatrick class SectionBase; 34ece8a530Spatrick class ThunkSection; 35*dfe94b16Srobert struct OutputDesc; 36ece8a530Spatrick 37ece8a530Spatrick // This represents an r-value in the linker script. 38ece8a530Spatrick struct ExprValue { ExprValueExprValue39ece8a530Spatrick ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val, 40ece8a530Spatrick const Twine &loc) 41*dfe94b16Srobert : sec(sec), val(val), forceAbsolute(forceAbsolute), loc(loc.str()) {} 42ece8a530Spatrick ExprValueExprValue43ece8a530Spatrick ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {} 44ece8a530Spatrick isAbsoluteExprValue45ece8a530Spatrick bool isAbsolute() const { return forceAbsolute || sec == nullptr; } 46ece8a530Spatrick uint64_t getValue() const; 47ece8a530Spatrick uint64_t getSecAddr() const; 48ece8a530Spatrick uint64_t getSectionOffset() const; 49ece8a530Spatrick 50ece8a530Spatrick // If a value is relative to a section, it has a non-null Sec. 51ece8a530Spatrick SectionBase *sec; 52ece8a530Spatrick 53ece8a530Spatrick uint64_t val; 54ece8a530Spatrick uint64_t alignment = 1; 55ece8a530Spatrick 56bb684c34Spatrick // The original st_type if the expression represents a symbol. Any operation 57bb684c34Spatrick // resets type to STT_NOTYPE. 58bb684c34Spatrick uint8_t type = llvm::ELF::STT_NOTYPE; 59bb684c34Spatrick 60*dfe94b16Srobert // True if this expression is enclosed in ABSOLUTE(). 61*dfe94b16Srobert // This flag affects the return value of getValue(). 62*dfe94b16Srobert bool forceAbsolute; 63*dfe94b16Srobert 64ece8a530Spatrick // Original source location. Used for error messages. 65ece8a530Spatrick std::string loc; 66ece8a530Spatrick }; 67ece8a530Spatrick 68ece8a530Spatrick // This represents an expression in the linker script. 69ece8a530Spatrick // ScriptParser::readExpr reads an expression and returns an Expr. 70ece8a530Spatrick // Later, we evaluate the expression by calling the function. 71ece8a530Spatrick using Expr = std::function<ExprValue()>; 72ece8a530Spatrick 73ece8a530Spatrick // This enum is used to implement linker script SECTIONS command. 74ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS 75ece8a530Spatrick enum SectionsCommandKind { 76ece8a530Spatrick AssignmentKind, // . = expr or <sym> = expr 77ece8a530Spatrick OutputSectionKind, 78ece8a530Spatrick InputSectionKind, 79ece8a530Spatrick ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) 80ece8a530Spatrick }; 81ece8a530Spatrick 82*dfe94b16Srobert struct SectionCommand { SectionCommandSectionCommand83*dfe94b16Srobert SectionCommand(int k) : kind(k) {} 84ece8a530Spatrick int kind; 85ece8a530Spatrick }; 86ece8a530Spatrick 87ece8a530Spatrick // This represents ". = <expr>" or "<symbol> = <expr>". 88*dfe94b16Srobert struct SymbolAssignment : SectionCommand { SymbolAssignmentSymbolAssignment89ece8a530Spatrick SymbolAssignment(StringRef name, Expr e, std::string loc) 90*dfe94b16Srobert : SectionCommand(AssignmentKind), name(name), expression(e), 91*dfe94b16Srobert location(loc) {} 92ece8a530Spatrick classofSymbolAssignment93*dfe94b16Srobert static bool classof(const SectionCommand *c) { 94ece8a530Spatrick return c->kind == AssignmentKind; 95ece8a530Spatrick } 96ece8a530Spatrick 97ece8a530Spatrick // The LHS of an expression. Name is either a symbol name or ".". 98ece8a530Spatrick StringRef name; 99ece8a530Spatrick Defined *sym = nullptr; 100ece8a530Spatrick 101ece8a530Spatrick // The RHS of an expression. 102ece8a530Spatrick Expr expression; 103ece8a530Spatrick 104ece8a530Spatrick // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN. 105ece8a530Spatrick bool provide = false; 106ece8a530Spatrick bool hidden = false; 107ece8a530Spatrick 108ece8a530Spatrick // Holds file name and line number for error reporting. 109ece8a530Spatrick std::string location; 110ece8a530Spatrick 111ece8a530Spatrick // A string representation of this command. We use this for -Map. 112ece8a530Spatrick std::string commandString; 113ece8a530Spatrick 114ece8a530Spatrick // Address of this assignment command. 115bb684c34Spatrick uint64_t addr; 116ece8a530Spatrick 117ece8a530Spatrick // Size of this assignment command. This is usually 0, but if 118ece8a530Spatrick // you move '.' this may be greater than 0. 119bb684c34Spatrick uint64_t size; 120ece8a530Spatrick }; 121ece8a530Spatrick 122ece8a530Spatrick // Linker scripts allow additional constraints to be put on output sections. 123ece8a530Spatrick // If an output section is marked as ONLY_IF_RO, the section is created 124ece8a530Spatrick // only if its input sections are read-only. Likewise, an output section 125ece8a530Spatrick // with ONLY_IF_RW is created if all input sections are RW. 126ece8a530Spatrick enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; 127ece8a530Spatrick 128ece8a530Spatrick // This struct is used to represent the location and size of regions of 129ece8a530Spatrick // target memory. Instances of the struct are created by parsing the 130ece8a530Spatrick // MEMORY command. 131ece8a530Spatrick struct MemoryRegion { MemoryRegionMemoryRegion132bb684c34Spatrick MemoryRegion(StringRef name, Expr origin, Expr length, uint32_t flags, 133*dfe94b16Srobert uint32_t invFlags, uint32_t negFlags, uint32_t negInvFlags) 134bb684c34Spatrick : name(std::string(name)), origin(origin), length(length), flags(flags), 135*dfe94b16Srobert invFlags(invFlags), negFlags(negFlags), negInvFlags(negInvFlags) {} 136ece8a530Spatrick 137ece8a530Spatrick std::string name; 138bb684c34Spatrick Expr origin; 139bb684c34Spatrick Expr length; 140*dfe94b16Srobert // A section can be assigned to the region if any of these ELF section flags 141*dfe94b16Srobert // are set... 142ece8a530Spatrick uint32_t flags; 143*dfe94b16Srobert // ... or any of these flags are not set. 144*dfe94b16Srobert // For example, the memory region attribute "r" maps to SHF_WRITE. 145*dfe94b16Srobert uint32_t invFlags; 146*dfe94b16Srobert // A section cannot be assigned to the region if any of these ELF section 147*dfe94b16Srobert // flags are set... 148ece8a530Spatrick uint32_t negFlags; 149*dfe94b16Srobert // ... or any of these flags are not set. 150*dfe94b16Srobert // For example, the memory region attribute "!r" maps to SHF_WRITE. 151*dfe94b16Srobert uint32_t negInvFlags; 152ece8a530Spatrick uint64_t curPos = 0; 153*dfe94b16Srobert compatibleWithMemoryRegion154*dfe94b16Srobert bool compatibleWith(uint32_t secFlags) const { 155*dfe94b16Srobert if ((secFlags & negFlags) || (~secFlags & negInvFlags)) 156*dfe94b16Srobert return false; 157*dfe94b16Srobert return (secFlags & flags) || (~secFlags & invFlags); 158*dfe94b16Srobert } 159ece8a530Spatrick }; 160ece8a530Spatrick 161ece8a530Spatrick // This struct represents one section match pattern in SECTIONS() command. 162ece8a530Spatrick // It can optionally have negative match pattern for EXCLUDED_FILE command. 163ece8a530Spatrick // Also it may be surrounded with SORT() command, so contains sorting rules. 1641cf9926bSpatrick class SectionPattern { 1651cf9926bSpatrick StringMatcher excludedFilePat; 1661cf9926bSpatrick 1671cf9926bSpatrick // Cache of the most recent input argument and result of excludesFile(). 168*dfe94b16Srobert mutable std::optional<std::pair<const InputFile *, bool>> excludesFileCache; 1691cf9926bSpatrick 1701cf9926bSpatrick public: SectionPattern(StringMatcher && pat1,StringMatcher && pat2)171ece8a530Spatrick SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2) 172ece8a530Spatrick : excludedFilePat(pat1), sectionPat(pat2), 173ece8a530Spatrick sortOuter(SortSectionPolicy::Default), 174ece8a530Spatrick sortInner(SortSectionPolicy::Default) {} 175ece8a530Spatrick 1761cf9926bSpatrick bool excludesFile(const InputFile *file) const; 1771cf9926bSpatrick 178ece8a530Spatrick StringMatcher sectionPat; 179ece8a530Spatrick SortSectionPolicy sortOuter; 180ece8a530Spatrick SortSectionPolicy sortInner; 181ece8a530Spatrick }; 182ece8a530Spatrick 183*dfe94b16Srobert class InputSectionDescription : public SectionCommand { 1841cf9926bSpatrick SingleStringMatcher filePat; 1851cf9926bSpatrick 1861cf9926bSpatrick // Cache of the most recent input argument and result of matchesFile(). 187*dfe94b16Srobert mutable std::optional<std::pair<const InputFile *, bool>> matchesFileCache; 1881cf9926bSpatrick 1891cf9926bSpatrick public: 190bb684c34Spatrick InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0, 191bb684c34Spatrick uint64_t withoutFlags = 0) SectionCommand(InputSectionKind)192*dfe94b16Srobert : SectionCommand(InputSectionKind), filePat(filePattern), 193bb684c34Spatrick withFlags(withFlags), withoutFlags(withoutFlags) {} 194ece8a530Spatrick classof(const SectionCommand * c)195*dfe94b16Srobert static bool classof(const SectionCommand *c) { 196ece8a530Spatrick return c->kind == InputSectionKind; 197ece8a530Spatrick } 198ece8a530Spatrick 1991cf9926bSpatrick bool matchesFile(const InputFile *file) const; 200ece8a530Spatrick 201ece8a530Spatrick // Input sections that matches at least one of SectionPatterns 202ece8a530Spatrick // will be associated with this InputSectionDescription. 203*dfe94b16Srobert SmallVector<SectionPattern, 0> sectionPatterns; 204ece8a530Spatrick 205ece8a530Spatrick // Includes InputSections and MergeInputSections. Used temporarily during 206ece8a530Spatrick // assignment of input sections to output sections. 207*dfe94b16Srobert SmallVector<InputSectionBase *, 0> sectionBases; 208ece8a530Spatrick 209ece8a530Spatrick // Used after the finalizeInputSections() pass. MergeInputSections have been 210ece8a530Spatrick // merged into MergeSyntheticSections. 211*dfe94b16Srobert SmallVector<InputSection *, 0> sections; 212ece8a530Spatrick 213ece8a530Spatrick // Temporary record of synthetic ThunkSection instances and the pass that 214ece8a530Spatrick // they were created in. This is used to insert newly created ThunkSections 215ece8a530Spatrick // into Sections at the end of a createThunks() pass. 216*dfe94b16Srobert SmallVector<std::pair<ThunkSection *, uint32_t>, 0> thunkSections; 217bb684c34Spatrick 218bb684c34Spatrick // SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command. 219bb684c34Spatrick uint64_t withFlags; 220bb684c34Spatrick uint64_t withoutFlags; 221ece8a530Spatrick }; 222ece8a530Spatrick 223ece8a530Spatrick // Represents BYTE(), SHORT(), LONG(), or QUAD(). 224*dfe94b16Srobert struct ByteCommand : SectionCommand { ByteCommandByteCommand225ece8a530Spatrick ByteCommand(Expr e, unsigned size, std::string commandString) 226*dfe94b16Srobert : SectionCommand(ByteKind), commandString(commandString), expression(e), 227ece8a530Spatrick size(size) {} 228ece8a530Spatrick classofByteCommand229*dfe94b16Srobert static bool classof(const SectionCommand *c) { return c->kind == ByteKind; } 230ece8a530Spatrick 231ece8a530Spatrick // Keeps string representing the command. Used for -Map" is perhaps better. 232ece8a530Spatrick std::string commandString; 233ece8a530Spatrick 234ece8a530Spatrick Expr expression; 235ece8a530Spatrick 236ece8a530Spatrick // This is just an offset of this assignment command in the output section. 237ece8a530Spatrick unsigned offset; 238ece8a530Spatrick 239ece8a530Spatrick // Size of this data command. 240ece8a530Spatrick unsigned size; 241ece8a530Spatrick }; 242ece8a530Spatrick 243bb684c34Spatrick struct InsertCommand { 244*dfe94b16Srobert SmallVector<StringRef, 0> names; 245bb684c34Spatrick bool isAfter; 246bb684c34Spatrick StringRef where; 247bb684c34Spatrick }; 248bb684c34Spatrick 249ece8a530Spatrick struct PhdrsCommand { 250ece8a530Spatrick StringRef name; 251ece8a530Spatrick unsigned type = llvm::ELF::PT_NULL; 252ece8a530Spatrick bool hasFilehdr = false; 253ece8a530Spatrick bool hasPhdrs = false; 254*dfe94b16Srobert std::optional<unsigned> flags; 255ece8a530Spatrick Expr lmaExpr = nullptr; 256ece8a530Spatrick }; 257ece8a530Spatrick 258ece8a530Spatrick class LinkerScript final { 259ece8a530Spatrick // Temporary state used in processSectionCommands() and assignAddresses() 260ece8a530Spatrick // that must be reinitialized for each call to the above functions, and must 261ece8a530Spatrick // not be used outside of the scope of a call to the above functions. 262ece8a530Spatrick struct AddressState { 263ece8a530Spatrick AddressState(); 264ece8a530Spatrick OutputSection *outSec = nullptr; 265ece8a530Spatrick MemoryRegion *memRegion = nullptr; 266ece8a530Spatrick MemoryRegion *lmaRegion = nullptr; 267ece8a530Spatrick uint64_t lmaOffset = 0; 2681cf9926bSpatrick uint64_t tbssAddr = 0; 269ece8a530Spatrick }; 270ece8a530Spatrick 271*dfe94b16Srobert llvm::DenseMap<llvm::CachedHashStringRef, OutputDesc *> nameToOutputSection; 272ece8a530Spatrick 273ece8a530Spatrick void addSymbol(SymbolAssignment *cmd); 274ece8a530Spatrick void assignSymbol(SymbolAssignment *cmd, bool inSec); 275ece8a530Spatrick void setDot(Expr e, const Twine &loc, bool inSec); 276ece8a530Spatrick void expandOutputSection(uint64_t size); 277ece8a530Spatrick void expandMemoryRegions(uint64_t size); 278ece8a530Spatrick 279*dfe94b16Srobert SmallVector<InputSectionBase *, 0> 280bb684c34Spatrick computeInputSections(const InputSectionDescription *, 281bb684c34Spatrick ArrayRef<InputSectionBase *>); 282ece8a530Spatrick 283*dfe94b16Srobert SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd); 284ece8a530Spatrick 285bb684c34Spatrick void discardSynthetic(OutputSection &); 286bb684c34Spatrick 287*dfe94b16Srobert SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec); 288ece8a530Spatrick 289*dfe94b16Srobert std::pair<MemoryRegion *, MemoryRegion *> 290*dfe94b16Srobert findMemoryRegion(OutputSection *sec, MemoryRegion *hint); 291ece8a530Spatrick 292ece8a530Spatrick void assignOffsets(OutputSection *sec); 293ece8a530Spatrick 294*dfe94b16Srobert // This captures the local AddressState and makes it accessible 295ece8a530Spatrick // deliberately. This is needed as there are some cases where we cannot just 296ece8a530Spatrick // thread the current state through to a lambda function created by the 297ece8a530Spatrick // script parser. 298ece8a530Spatrick // This should remain a plain pointer as its lifetime is smaller than 299ece8a530Spatrick // LinkerScript. 300*dfe94b16Srobert AddressState *state = nullptr; 301ece8a530Spatrick 302ece8a530Spatrick OutputSection *aether; 303ece8a530Spatrick 304ece8a530Spatrick uint64_t dot; 305ece8a530Spatrick 306ece8a530Spatrick public: 307*dfe94b16Srobert OutputDesc *createOutputSection(StringRef name, StringRef location); 308*dfe94b16Srobert OutputDesc *getOrCreateOutputSection(StringRef name); 309ece8a530Spatrick hasPhdrsCommands()310ece8a530Spatrick bool hasPhdrsCommands() { return !phdrsCommands.empty(); } getDot()311ece8a530Spatrick uint64_t getDot() { return dot; } 312*dfe94b16Srobert void discard(InputSectionBase &s); 313ece8a530Spatrick 314ece8a530Spatrick ExprValue getSymbolValue(StringRef name, const Twine &loc); 315ece8a530Spatrick 316ece8a530Spatrick void addOrphanSections(); 317bb684c34Spatrick void diagnoseOrphanHandling() const; 318*dfe94b16Srobert void adjustOutputSections(); 319ece8a530Spatrick void adjustSectionsAfterSorting(); 320ece8a530Spatrick 321*dfe94b16Srobert SmallVector<PhdrEntry *, 0> createPhdrs(); 322ece8a530Spatrick bool needsInterpSection(); 323ece8a530Spatrick 324ece8a530Spatrick bool shouldKeep(InputSectionBase *s); 325ece8a530Spatrick const Defined *assignAddresses(); 326*dfe94b16Srobert void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs); 327ece8a530Spatrick void processSectionCommands(); 328ece8a530Spatrick void processSymbolAssignments(); 329ece8a530Spatrick void declareSymbols(); 330ece8a530Spatrick 331*dfe94b16Srobert bool isDiscarded(const OutputSection *sec) const; 332*dfe94b16Srobert 333ece8a530Spatrick // Used to handle INSERT AFTER statements. 334ece8a530Spatrick void processInsertCommands(); 335ece8a530Spatrick 336ece8a530Spatrick // SECTIONS command list. 337*dfe94b16Srobert SmallVector<SectionCommand *, 0> sectionCommands; 338ece8a530Spatrick 339ece8a530Spatrick // PHDRS command list. 340*dfe94b16Srobert SmallVector<PhdrsCommand, 0> phdrsCommands; 341ece8a530Spatrick 342ece8a530Spatrick bool hasSectionsCommand = false; 343ece8a530Spatrick bool errorOnMissingSection = false; 344ece8a530Spatrick 345ece8a530Spatrick // List of section patterns specified with KEEP commands. They will 346ece8a530Spatrick // be kept even if they are unused and --gc-sections is specified. 347*dfe94b16Srobert SmallVector<InputSectionDescription *, 0> keptSections; 348ece8a530Spatrick 349ece8a530Spatrick // A map from memory region name to a memory region descriptor. 350ece8a530Spatrick llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions; 351ece8a530Spatrick 352ece8a530Spatrick // A list of symbols referenced by the script. 353*dfe94b16Srobert SmallVector<llvm::StringRef, 0> referencedSymbols; 354ece8a530Spatrick 355bb684c34Spatrick // Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need 356bb684c34Spatrick // to be reordered. 357*dfe94b16Srobert SmallVector<InsertCommand, 0> insertCommands; 358bb684c34Spatrick 3591cf9926bSpatrick // OutputSections specified by OVERWRITE_SECTIONS. 360*dfe94b16Srobert SmallVector<OutputDesc *, 0> overwriteSections; 3611cf9926bSpatrick 362bb684c34Spatrick // Sections that will be warned/errored by --orphan-handling. 363*dfe94b16Srobert SmallVector<const InputSectionBase *, 0> orphanSections; 364ece8a530Spatrick }; 365ece8a530Spatrick 366*dfe94b16Srobert LLVM_LIBRARY_VISIBILITY extern std::unique_ptr<LinkerScript> script; 367ece8a530Spatrick 368*dfe94b16Srobert } // end namespace lld::elf 369ece8a530Spatrick 370ece8a530Spatrick #endif // LLD_ELF_LINKER_SCRIPT_H 371