aboutsummaryrefslogtreecommitdiffstats
path: root/ELF/LinkerScript.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:48:50 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:48:50 +0000
commit1c98619801a5705c688e683be3ef9d70169a0686 (patch)
tree8422105cd1a94c368315f2db16b9ac746cf7c000 /ELF/LinkerScript.h
parentf4f3ce4613680903220815690ad79fc7ba0a2e26 (diff)
downloadsrc-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.h103
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