2016-02-12 05:17:59 +08:00
|
|
|
//===- 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"
|
2016-02-12 05:38:55 +08:00
|
|
|
#include "llvm/Support/Allocator.h"
|
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
2016-02-12 05:17:59 +08:00
|
|
|
|
|
|
|
namespace lld {
|
2016-02-28 08:25:54 +08:00
|
|
|
namespace elf {
|
2016-02-12 05:17:59 +08:00
|
|
|
|
2016-04-21 04:13:41 +08:00
|
|
|
// Parses a linker script. Calling this function updates
|
|
|
|
// Config and ScriptConfig.
|
|
|
|
void readLinkerScript(MemoryBufferRef MB);
|
|
|
|
|
2016-02-12 05:17:59 +08:00
|
|
|
class ScriptParser;
|
2016-02-13 05:47:28 +08:00
|
|
|
template <class ELFT> class InputSectionBase;
|
2016-04-16 18:10:32 +08:00
|
|
|
template <class ELFT> class OutputSectionBase;
|
2016-02-12 05:17:59 +08:00
|
|
|
|
2016-02-13 05:47:28 +08:00
|
|
|
// This class represents each rule in SECTIONS command.
|
|
|
|
class SectionRule {
|
|
|
|
public:
|
2016-04-22 06:00:51 +08:00
|
|
|
SectionRule(StringRef D, StringRef S)
|
|
|
|
: Dest(D), SectionPattern(S) {}
|
2016-02-13 05:47:28 +08:00
|
|
|
|
|
|
|
// Returns true if S should be in Dest section.
|
|
|
|
template <class ELFT> bool match(InputSectionBase<ELFT> *S);
|
|
|
|
|
|
|
|
StringRef Dest;
|
|
|
|
|
|
|
|
private:
|
|
|
|
StringRef SectionPattern;
|
|
|
|
};
|
|
|
|
|
2016-04-16 18:10:32 +08:00
|
|
|
// This enum represents what we can observe in SECTIONS tag of script:
|
2016-04-19 20:09:25 +08:00
|
|
|
// ExprKind is a location counter change, like ". = . + 0x1000"
|
|
|
|
// SectionKind is a description of output section, like ".data :..."
|
2016-04-19 05:00:45 +08:00
|
|
|
enum SectionsCommandKind { ExprKind, SectionKind };
|
2016-04-16 18:10:32 +08:00
|
|
|
|
2016-04-19 05:00:45 +08:00
|
|
|
struct SectionsCommand {
|
|
|
|
SectionsCommandKind Kind;
|
2016-04-16 18:10:32 +08:00
|
|
|
std::vector<StringRef> Expr;
|
|
|
|
StringRef SectionName;
|
|
|
|
};
|
|
|
|
|
2016-04-21 04:13:41 +08:00
|
|
|
// ScriptConfiguration holds linker script parse results.
|
|
|
|
struct ScriptConfiguration {
|
2016-02-13 05:47:28 +08:00
|
|
|
// SECTIONS commands.
|
|
|
|
std::vector<SectionRule> Sections;
|
2016-02-12 05:17:59 +08:00
|
|
|
|
2016-02-28 13:09:11 +08:00
|
|
|
// Section fill attribute for each section.
|
|
|
|
llvm::StringMap<std::vector<uint8_t>> Filler;
|
2016-02-12 05:38:55 +08:00
|
|
|
|
2016-04-16 18:10:32 +08:00
|
|
|
// Used to assign addresses to sections.
|
2016-04-19 05:00:45 +08:00
|
|
|
std::vector<SectionsCommand> Commands;
|
2016-04-16 18:10:32 +08:00
|
|
|
|
2016-04-21 04:13:41 +08:00
|
|
|
bool DoLayout = false;
|
|
|
|
|
2016-02-12 05:38:55 +08:00
|
|
|
llvm::BumpPtrAllocator Alloc;
|
2016-04-22 06:00:51 +08:00
|
|
|
|
|
|
|
// 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;
|
2016-02-12 05:17:59 +08:00
|
|
|
};
|
|
|
|
|
2016-04-21 04:13:41 +08:00
|
|
|
extern ScriptConfiguration *ScriptConfig;
|
|
|
|
|
|
|
|
// This is a runner of the linker script.
|
|
|
|
template <class ELFT> class LinkerScript {
|
|
|
|
public:
|
|
|
|
StringRef getOutputSection(InputSectionBase<ELFT> *S);
|
|
|
|
ArrayRef<uint8_t> getFiller(StringRef Name);
|
|
|
|
bool isDiscarded(InputSectionBase<ELFT> *S);
|
|
|
|
bool shouldKeep(InputSectionBase<ELFT> *S);
|
2016-04-21 19:21:48 +08:00
|
|
|
void assignAddresses(ArrayRef<OutputSectionBase<ELFT> *> S);
|
2016-04-21 04:13:41 +08:00
|
|
|
int compareSections(StringRef A, StringRef B);
|
|
|
|
|
|
|
|
private:
|
2016-04-22 04:30:00 +08:00
|
|
|
int getSectionIndex(StringRef Name);
|
2016-04-21 04:13:41 +08:00
|
|
|
SectionRule *find(InputSectionBase<ELFT> *S);
|
|
|
|
|
|
|
|
ScriptConfiguration &Opt = *ScriptConfig;
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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;
|
2016-02-12 05:17:59 +08:00
|
|
|
|
2016-02-28 08:25:54 +08:00
|
|
|
} // namespace elf
|
2016-02-12 05:17:59 +08:00
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|