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
|
|
|
|
|
2016-07-19 17:25:43 +08:00
|
|
|
#include "Writer.h"
|
2016-02-12 05:17:59 +08:00
|
|
|
#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-07-20 22:43:20 +08:00
|
|
|
template <class ELFT> class InputSectionBase;
|
|
|
|
template <class ELFT> class OutputSectionBase;
|
|
|
|
template <class ELFT> class OutputSectionFactory;
|
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.
|
2016-04-22 08:23:52 +08:00
|
|
|
struct SectionRule {
|
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
|
|
|
|
|
|
|
StringRef Dest;
|
|
|
|
|
|
|
|
StringRef SectionPattern;
|
|
|
|
};
|
|
|
|
|
2016-07-21 14:43:01 +08:00
|
|
|
// This enum represents what we can observe in SECTIONS tag of script.
|
|
|
|
// Each sections-command may of be one of the following:
|
|
|
|
// (https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS)
|
|
|
|
// * An ENTRY command.
|
|
|
|
// * A symbol assignment.
|
|
|
|
// * An output section description.
|
|
|
|
// * An overlay description.
|
|
|
|
// We support only AssignmentKind and OutputSectionKind for now.
|
|
|
|
enum SectionsCommandKind { AssignmentKind, OutputSectionKind };
|
|
|
|
|
|
|
|
struct BaseCommand {
|
|
|
|
BaseCommand(int K) : Kind(K) {}
|
|
|
|
virtual ~BaseCommand() {}
|
|
|
|
int Kind;
|
|
|
|
};
|
2016-04-16 18:10:32 +08:00
|
|
|
|
2016-07-21 14:43:01 +08:00
|
|
|
struct SymbolAssignment : BaseCommand {
|
|
|
|
SymbolAssignment(StringRef Name, std::vector<StringRef> &Expr)
|
|
|
|
: BaseCommand(AssignmentKind), Name(Name), Expr(std::move(Expr)) {}
|
|
|
|
static bool classof(const BaseCommand *C);
|
|
|
|
StringRef Name;
|
2016-04-16 18:10:32 +08:00
|
|
|
std::vector<StringRef> Expr;
|
2016-07-21 14:43:01 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct OutputSectionCommand : BaseCommand {
|
|
|
|
OutputSectionCommand(StringRef Name)
|
|
|
|
: BaseCommand(OutputSectionKind), Name(Name) {}
|
|
|
|
static bool classof(const BaseCommand *C);
|
2016-07-12 14:39:48 +08:00
|
|
|
StringRef Name;
|
2016-07-19 17:25:43 +08:00
|
|
|
std::vector<StringRef> Phdrs;
|
2016-07-21 14:43:01 +08:00
|
|
|
std::vector<uint8_t> Filler;
|
2016-07-19 17:25:43 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct PhdrsCommand {
|
|
|
|
StringRef Name;
|
|
|
|
unsigned Type;
|
|
|
|
bool HasFilehdr;
|
|
|
|
bool HasPhdrs;
|
2016-04-16 18:10:32 +08:00
|
|
|
};
|
|
|
|
|
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-04-16 18:10:32 +08:00
|
|
|
// Used to assign addresses to sections.
|
2016-07-21 14:43:01 +08:00
|
|
|
std::vector<std::unique_ptr<BaseCommand>> Commands;
|
2016-04-16 18:10:32 +08:00
|
|
|
|
2016-07-19 17:25:43 +08:00
|
|
|
// Used to assign sections to headers.
|
2016-07-20 23:09:10 +08:00
|
|
|
std::vector<PhdrsCommand> PhdrsCommands;
|
|
|
|
|
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 {
|
2016-04-23 04:41:07 +08:00
|
|
|
typedef typename ELFT::uint uintX_t;
|
|
|
|
|
2016-04-21 04:13:41 +08:00
|
|
|
public:
|
2016-07-19 20:33:46 +08:00
|
|
|
typedef PhdrEntry<ELFT> Phdr;
|
2016-07-19 17:25:43 +08:00
|
|
|
|
2016-07-21 01:19:03 +08:00
|
|
|
std::vector<OutputSectionBase<ELFT> *>
|
|
|
|
createSections(OutputSectionFactory<ELFT> &Factory);
|
|
|
|
|
2016-04-21 04:13:41 +08:00
|
|
|
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);
|
2016-07-12 14:39:48 +08:00
|
|
|
void addScriptedSymbols();
|
2016-07-19 17:25:43 +08:00
|
|
|
std::vector<Phdr> createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> S);
|
|
|
|
bool hasPhdrsCommands();
|
2016-04-21 04:13:41 +08:00
|
|
|
|
|
|
|
private:
|
2016-04-22 08:03:13 +08:00
|
|
|
// "ScriptConfig" is a bit too long, so define a short name for it.
|
|
|
|
ScriptConfiguration &Opt = *ScriptConfig;
|
|
|
|
|
2016-04-22 04:30:00 +08:00
|
|
|
int getSectionIndex(StringRef Name);
|
2016-07-19 17:25:43 +08:00
|
|
|
std::vector<size_t> getPhdrIndicesForSection(StringRef Name);
|
2016-04-21 04:13:41 +08:00
|
|
|
|
2016-04-23 04:41:07 +08:00
|
|
|
uintX_t Dot;
|
2016-04-21 04:13:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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
|