diff options
Diffstat (limited to 'ELF/LinkerScript.h')
-rw-r--r-- | ELF/LinkerScript.h | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/ELF/LinkerScript.h b/ELF/LinkerScript.h index 11131dda8e26..3b790dd4669f 100644 --- a/ELF/LinkerScript.h +++ b/ELF/LinkerScript.h @@ -11,9 +11,9 @@ #define LLD_ELF_LINKER_SCRIPT_H #include "Config.h" -#include "Strings.h" #include "Writer.h" #include "lld/Common/LLVM.h" +#include "lld/Common/Strings.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -75,7 +75,6 @@ enum SectionsCommandKind { AssignmentKind, // . = expr or <sym> = expr OutputSectionKind, InputSectionKind, - AssertKind, // ASSERT(expr) ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) }; @@ -106,6 +105,16 @@ struct SymbolAssignment : BaseCommand { // Holds file name and line number for error reporting. std::string Location; + + // A string representation of this command. We use this for -Map. + std::string CommandString; + + // Address of this assignment command. + unsigned Addr; + + // Size of this assignment command. This is usually 0, but if + // you move '.' this may be greater than 0. + unsigned Size; }; // Linker scripts allow additional constraints to be put on ouput sections. @@ -118,11 +127,17 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; // target memory. Instances of the struct are created by parsing the // MEMORY command. struct MemoryRegion { + MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags, + uint32_t NegFlags) + : Name(Name), Origin(Origin), Length(Length), Flags(Flags), + NegFlags(NegFlags) {} + std::string Name; uint64_t Origin; uint64_t Length; uint32_t Flags; uint32_t NegFlags; + uint64_t CurPos = 0; }; // This struct represents one section match pattern in SECTIONS() command. @@ -161,24 +176,23 @@ struct InputSectionDescription : BaseCommand { std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections; }; -// Represents an ASSERT(). -struct AssertCommand : BaseCommand { - AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {} - - static bool classof(const BaseCommand *C) { return C->Kind == AssertKind; } - - Expr Expression; -}; - // Represents BYTE(), SHORT(), LONG(), or QUAD(). struct ByteCommand : BaseCommand { - ByteCommand(Expr E, unsigned Size) - : BaseCommand(ByteKind), Expression(E), Size(Size) {} + ByteCommand(Expr E, unsigned Size, std::string CommandString) + : BaseCommand(ByteKind), CommandString(CommandString), Expression(E), + Size(Size) {} static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; } + // Keeps string representing the command. Used for -Map" is perhaps better. + std::string CommandString; + Expr Expression; + + // This is just an offset of this assignment command in the output section. unsigned Offset; + + // Size of this data command. unsigned Size; }; @@ -200,8 +214,8 @@ class LinkerScript final { uint64_t ThreadBssOffset = 0; OutputSection *OutSec = nullptr; MemoryRegion *MemRegion = nullptr; - llvm::DenseMap<const MemoryRegion *, uint64_t> MemRegionOffset; - std::function<uint64_t()> LMAOffset; + MemoryRegion *LMARegion = nullptr; + uint64_t LMAOffset = 0; }; llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection; @@ -209,14 +223,13 @@ class LinkerScript final { void addSymbol(SymbolAssignment *Cmd); void assignSymbol(SymbolAssignment *Cmd, bool InSec); void setDot(Expr E, const Twine &Loc, bool InSec); + void expandOutputSection(uint64_t Size); + void expandMemoryRegions(uint64_t Size); std::vector<InputSection *> - computeInputSections(const InputSectionDescription *, - const llvm::DenseMap<SectionBase *, int> &Order); + computeInputSections(const InputSectionDescription *); - std::vector<InputSection *> - createInputSectionList(OutputSection &Cmd, - const llvm::DenseMap<SectionBase *, int> &Order); + std::vector<InputSection *> createInputSectionList(OutputSection &Cmd); std::vector<size_t> getPhdrIndices(OutputSection *Sec); @@ -251,7 +264,6 @@ public: ExprValue getSymbolValue(StringRef Name, const Twine &Loc); void addOrphanSections(); - void removeEmptyCommands(); void adjustSectionsBeforeSorting(); void adjustSectionsAfterSorting(); @@ -262,6 +274,10 @@ public: void assignAddresses(); void allocateHeaders(std::vector<PhdrEntry *> &Phdrs); void processSectionCommands(); + void declareSymbols(); + + // Used to handle INSERT AFTER statements. + void processInsertCommands(); // SECTIONS command list. std::vector<BaseCommand *> SectionCommands; @@ -281,6 +297,11 @@ public: // A list of symbols referenced by the script. std::vector<llvm::StringRef> ReferencedSymbols; + + // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need + // to be inserted into SECTIONS commands list. + llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands; + llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands; }; extern LinkerScript *Script; |