diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
commit | 1c98619801a5705c688e683be3ef9d70169a0686 (patch) | |
tree | 8422105cd1a94c368315f2db16b9ac746cf7c000 /ELF/LinkerScript.h | |
parent | f4f3ce4613680903220815690ad79fc7ba0a2e26 (diff) | |
download | src-1c98619801a5705c688e683be3ef9d70169a0686.tar.gz src-1c98619801a5705c688e683be3ef9d70169a0686.zip |
Vendor import of lld release_39 branch r276489:vendor/lld/lld-release_39-r276489
Notes
Notes:
svn path=/vendor/lld/dist/; revision=303239
svn path=/vendor/lld/lld-release_39-r276489/; revision=303240; tag=vendor/lld/lld-release_39-r276489
Diffstat (limited to 'ELF/LinkerScript.h')
-rw-r--r-- | ELF/LinkerScript.h | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/ELF/LinkerScript.h b/ELF/LinkerScript.h new file mode 100644 index 000000000000..768f78a66468 --- /dev/null +++ b/ELF/LinkerScript.h @@ -0,0 +1,103 @@ +//===- LinkerScript.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_ELF_LINKER_SCRIPT_H +#define LLD_ELF_LINKER_SCRIPT_H + +#include "lld/Core/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/MemoryBuffer.h" + +namespace lld { +namespace elf { + +// Parses a linker script. Calling this function updates +// Config and ScriptConfig. +void readLinkerScript(MemoryBufferRef MB); + +class ScriptParser; +template <class ELFT> class InputSectionBase; +template <class ELFT> class OutputSectionBase; + +// This class represents each rule in SECTIONS command. +struct SectionRule { + SectionRule(StringRef D, StringRef S) + : Dest(D), SectionPattern(S) {} + + StringRef Dest; + + StringRef SectionPattern; +}; + +// This enum represents what we can observe in SECTIONS tag of script: +// ExprKind is a location counter change, like ". = . + 0x1000" +// SectionKind is a description of output section, like ".data :..." +enum SectionsCommandKind { SectionKind, AssignmentKind }; + +struct SectionsCommand { + SectionsCommandKind Kind; + std::vector<StringRef> Expr; + StringRef Name; +}; + +// ScriptConfiguration holds linker script parse results. +struct ScriptConfiguration { + // SECTIONS commands. + std::vector<SectionRule> Sections; + + // Section fill attribute for each section. + llvm::StringMap<std::vector<uint8_t>> Filler; + + // Used to assign addresses to sections. + std::vector<SectionsCommand> Commands; + + bool DoLayout = false; + + llvm::BumpPtrAllocator Alloc; + + // List of section patterns specified with KEEP commands. They will + // be kept even if they are unused and --gc-sections is specified. + std::vector<StringRef> KeptSections; +}; + +extern ScriptConfiguration *ScriptConfig; + +// This is a runner of the linker script. +template <class ELFT> class LinkerScript { + typedef typename ELFT::uint uintX_t; + +public: + StringRef getOutputSection(InputSectionBase<ELFT> *S); + ArrayRef<uint8_t> getFiller(StringRef Name); + bool isDiscarded(InputSectionBase<ELFT> *S); + bool shouldKeep(InputSectionBase<ELFT> *S); + void assignAddresses(ArrayRef<OutputSectionBase<ELFT> *> S); + int compareSections(StringRef A, StringRef B); + void addScriptedSymbols(); + +private: + // "ScriptConfig" is a bit too long, so define a short name for it. + ScriptConfiguration &Opt = *ScriptConfig; + + int getSectionIndex(StringRef Name); + + uintX_t Dot; +}; + +// Variable template is a C++14 feature, so we can't template +// a global variable. Use a struct to workaround. +template <class ELFT> struct Script { static LinkerScript<ELFT> *X; }; +template <class ELFT> LinkerScript<ELFT> *Script<ELFT>::X; + +} // namespace elf +} // namespace lld + +#endif |