forked from OSchip/llvm-project
103 lines
2.9 KiB
C++
103 lines
2.9 KiB
C++
//===- 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 { ExprKind, SectionKind };
|
|
|
|
struct SectionsCommand {
|
|
SectionsCommandKind Kind;
|
|
std::vector<StringRef> Expr;
|
|
StringRef SectionName;
|
|
};
|
|
|
|
// 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);
|
|
|
|
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
|