Rename TargetInfo -> LinkingContext.

Also change some local variable names: "ti" -> "context" and
"_targetInfo" -> "_context".

Differential Revision: http://llvm-reviews.chandlerc.com/D1301

llvm-svn: 187823
This commit is contained in:
Rui Ueyama
2013-08-06 22:31:59 +00:00
parent 6fea779c29
commit 0ca149fce9
104 changed files with 1570 additions and 1791 deletions

View File

@@ -49,7 +49,7 @@ Adding an Option to an existing Flavor
#. Add the option to the desired :file:`lib/Driver/{flavor}Options.td`.
#. Add to :cpp:class:`lld::FlavorTargetInfo` a getter and setter method
#. Add to :cpp:class:`lld::FlavorLinkingContext` a getter and setter method
for the option.
#. Modify :cpp:func:`lld::FlavorDriver::parse` in :file:

View File

@@ -14,7 +14,6 @@
namespace lld {
///
/// The ArchiveLibraryFile subclass of File is used to represent unix
/// static library archives. These libraries provide no atoms to the
@@ -34,15 +33,14 @@ public:
/// specified name and return the File object for that member, or nullptr.
virtual const File *find(StringRef name, bool dataSymbolOnly) const = 0;
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const LinkingContext &getLinkingContext() const { return _context; }
protected:
/// only subclasses of ArchiveLibraryFile can be instantiated
ArchiveLibraryFile(const TargetInfo &ti, StringRef path)
: File(path, kindArchiveLibrary), _targetInfo(ti) {
}
ArchiveLibraryFile(const LinkingContext &context, StringRef path)
: File(path, kindArchiveLibrary), _context(context) {}
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
} // namespace lld

View File

@@ -14,7 +14,7 @@
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/range.h"
#include "lld/Core/SharedLibraryAtom.h"
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/Core/UndefinedAtom.h"
#include "llvm/ADT/StringRef.h"
@@ -155,7 +155,7 @@ public:
/// all AbsoluteAtoms in this File.
virtual const atom_collection<AbsoluteAtom> &absolute() const = 0;
virtual const TargetInfo &getTargetInfo() const = 0;
virtual const LinkingContext &getLinkingContext() const = 0;
protected:
/// \brief only subclasses of File can be instantiated
@@ -233,15 +233,15 @@ public:
typedef range<std::vector<const DefinedAtom *>::iterator> DefinedAtomRange;
virtual DefinedAtomRange definedAtoms() = 0;
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const LinkingContext &getLinkingContext() const { return _context; }
protected:
/// \brief only subclasses of MutableFile can be instantiated
MutableFile(const TargetInfo &ti, StringRef p)
: File(p, kindObject), _targetInfo(ti) {}
MutableFile(const LinkingContext &ti, StringRef p)
: File(p, kindObject), _context(ti) {}
private:
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
} // end namespace lld

View File

@@ -1,4 +1,4 @@
//===- lld/Core/TargetInfo.h - Linker Target Info Interface ---------------===//
//===- lld/Core/LinkingContext.h - Linker Target Info Interface -----------===//
//
// The LLVM Linker
//
@@ -25,7 +25,7 @@
#include <vector>
namespace llvm {
class Triple;
class Triple;
}
namespace lld {
@@ -34,33 +34,29 @@ class File;
class Writer;
class InputFiles;
/// \brief The TargetInfo class encapsulates "what and how" to link.
/// \brief The LinkingContext class encapsulates "what and how" to link.
///
/// The base class TargetInfo contains the options needed by core linking.
/// Subclasses of TargetInfo have additional options needed by specific Readers
/// and Writers. For example, ELFTargetInfo has methods that supplies options
/// The base class LinkingContext contains the options needed by core linking.
/// Subclasses of LinkingContext have additional options needed by specific
/// Readers
/// and Writers. For example, ELFLinkingContext has methods that supplies
/// options
/// to the ELF Reader and Writer.
///
/// \todo Consider renaming to something like "LinkingOptions".
class TargetInfo : public Reader {
class LinkingContext : public Reader {
public:
virtual ~TargetInfo();
virtual ~LinkingContext();
/// \name Methods needed by core linking
/// @{
/// Name of symbol linker should use as "entry point" to program,
/// usually "main" or "start".
StringRef entrySymbolName() const {
return _entrySymbolName;
}
StringRef entrySymbolName() const { return _entrySymbolName; }
/// Whether core linking should remove Atoms not reachable by following
/// References from the entry point Atom or from all global scope Atoms
/// if globalsAreDeadStripRoots() is true.
bool deadStrip() const {
return _deadStrip;
}
bool deadStrip() const { return _deadStrip; }
/// Only used if deadStrip() returns true. Means all global scope Atoms
/// should be marked live (along with all Atoms they reference). Usually
@@ -84,9 +80,7 @@ public:
/// object file contains a DefinedAtom which will replace an existing
/// UndefinedAtom. If this method returns true, core linking will actively
/// load every member object file from every archive.
bool forceLoadAllArchives() const {
return _forceLoadAllArchives;
}
bool forceLoadAllArchives() const { return _forceLoadAllArchives; }
/// Archive files (aka static libraries) are normally lazily loaded. That is,
/// object files within an archive are only loaded and linked in, if the
@@ -117,16 +111,12 @@ public:
/// \todo This should be a method core linking calls with a list of the
/// UndefinedAtoms so that different drivers can format the error message
/// as needed.
bool printRemainingUndefines() const {
return _printRemainingUndefines;
}
bool printRemainingUndefines() const { return _printRemainingUndefines; }
/// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
/// SharedLibraryAtom for the link to be successful. This method controls
/// whether core linking considers remaining undefines to be an error.
bool allowRemainingUndefines() const {
return _allowRemainingUndefines;
}
bool allowRemainingUndefines() const { return _allowRemainingUndefines; }
/// In the lld model, a SharedLibraryAtom is a proxy atom for something
/// that will be found in a dynamic shared library when the program runs.
@@ -161,9 +151,7 @@ public:
/// SharedLibraryAtom for the link to be successful. This method controls
/// whether core linking considers remaining undefines from the shared library
/// to be an error.
bool allowShlibUndefines() const {
return _allowShlibUndefines;
}
bool allowShlibUndefines() const { return _allowShlibUndefines; }
/// If true, core linking will write the path to each input file to stdout
/// (i.e. llvm::outs()) as it is used. This is used to implement the -t
@@ -171,31 +159,21 @@ public:
///
/// \todo This should be a method core linking calls so that drivers can
/// format the line as needed.
bool logInputFiles() const {
return _logInputFiles;
}
bool logInputFiles() const { return _logInputFiles; }
/// Parts of LLVM use global variables which are bound to command line
/// options (see llvm::cl::Options). This method returns "command line"
/// options which are used to configure LLVM's command line settings.
/// For instance the -debug-only XXX option can be used to dynamically
/// trace different parts of LLVM and lld.
const std::vector<const char*> &llvmOptions() const {
return _llvmOptions;
}
const std::vector<const char *> &llvmOptions() const { return _llvmOptions; }
/// This method returns the sequence of input files for core linking to
/// process.
///
/// \todo Consider moving this out of TargetInfo so that the same TargetInfo
/// object can be reused for different links.
const std::vector<LinkerInput> &inputFiles() const {
return _inputFiles;
}
const std::vector<LinkerInput> &inputFiles() const { return _inputFiles; }
/// @}
/// \name Methods used by Drivers to configure TargetInfo
/// \name Methods used by Drivers to configure LinkingContext
/// @{
void setOutputPath(StringRef str) { _outputPath = str; }
void setEntrySymbolName(StringRef name) { _entrySymbolName = name; }
@@ -213,30 +191,22 @@ public:
void setWarnIfCoalesableAtomsHaveDifferentLoadName(bool warn) {
_warnIfCoalesableAtomsHaveDifferentLoadName = warn;
}
void setForceLoadAllArchives(bool force) {
_forceLoadAllArchives = force;
}
void setForceLoadAllArchives(bool force) { _forceLoadAllArchives = force; }
void setPrintRemainingUndefines(bool print) {
_printRemainingUndefines = print;
}
void setAllowRemainingUndefines(bool allow) {
_allowRemainingUndefines = allow;
}
void setAllowShlibUndefines(bool allow) {
_allowShlibUndefines = allow;
}
void setLogInputFiles(bool log) {
_logInputFiles = log;
}
void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; }
void setLogInputFiles(bool log) { _logInputFiles = log; }
void appendInputFile(StringRef path) {
_inputFiles.emplace_back(LinkerInput(path));
}
void appendInputFile(std::unique_ptr<llvm::MemoryBuffer> buffer) {
_inputFiles.emplace_back(LinkerInput(std::move(buffer)));
}
void appendLLVMOption(const char *opt) {
_llvmOptions.push_back(opt);
}
void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); }
/// This method adds undefined symbols specified by the -u option to the
/// to the list of undefined symbols known to the linker. This option
@@ -264,7 +234,6 @@ public:
/// \returns true if there is an error with the current settings.
bool validate(raw_ostream &diagnostics);
/// @}
/// \name Methods used by Driver::link()
/// @{
@@ -273,12 +242,10 @@ public:
///
/// \todo To support in-memory linking, we need an abstraction that allows
/// the linker to write to an in-memory buffer.
StringRef outputPath() const {
return _outputPath;
}
StringRef outputPath() const { return _outputPath; }
/// Abstract method to parse a supplied input file buffer into one or
/// more lld::File objects. Subclasses of TargetInfo must implement this
/// more lld::File objects. Subclasses of LinkingContext must implement this
/// method.
///
/// \param inputBuff This is an in-memory read-only copy of the input file.
@@ -290,8 +257,9 @@ public:
/// \param [out] result The instantiated lld::File object is returned here.
/// The \p result is a vector because some input files parse into more than
/// one lld::File (e.g. YAML).
virtual error_code parseFile(std::unique_ptr<MemoryBuffer> &inputBuff,
std::vector<std::unique_ptr<File>> &result) const = 0;
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &inputBuff,
std::vector<std::unique_ptr<File> > &result) const = 0;
/// This is a wrapper around parseFile() where the input file is specified
/// by file system path. The default implementation reads the input file
@@ -299,13 +267,13 @@ public:
///
/// \param path This is the file system path to the input file.
/// \param [out] result The instantiated lld::File object is returned here.
virtual error_code readFile(StringRef path,
std::vector<std::unique_ptr<File>> &result) const;
virtual error_code
readFile(StringRef path, std::vector<std::unique_ptr<File> > &result) const;
/// This method is called by core linking to give the Writer a chance
/// to add file format specific "files" to set of files to be linked. This is
/// how file format specific atoms can be added to the link.
virtual void addImplicitFiles(InputFiles&) const;
virtual void addImplicitFiles(InputFiles &) const;
/// This method is called by core linking to build the list of Passes to be
/// run on the merged/linked graph of all input files.
@@ -318,7 +286,6 @@ public:
/// @}
/// \name Methods needed by YAML I/O and error messages to convert Kind values
/// to and from strings.
/// @{
@@ -333,35 +300,32 @@ public:
/// @}
protected:
TargetInfo(); // Must be subclassed
LinkingContext(); // Must be subclassed
/// Abstract method to lazily instantiate the Writer.
virtual Writer &writer() const = 0;
StringRef _outputPath;
StringRef _entrySymbolName;
bool _deadStrip;
bool _globalsAreDeadStripRoots;
bool _searchArchivesToOverrideTentativeDefinitions;
bool _searchSharedLibrariesToOverrideTentativeDefinitions;
bool _warnIfCoalesableAtomsHaveDifferentCanBeNull;
bool _warnIfCoalesableAtomsHaveDifferentLoadName;
bool _forceLoadAllArchives;
bool _printRemainingUndefines;
bool _allowRemainingUndefines;
bool _logInputFiles;
bool _allowShlibUndefines;
std::vector<StringRef> _deadStripRoots;
StringRef _outputPath;
StringRef _entrySymbolName;
bool _deadStrip;
bool _globalsAreDeadStripRoots;
bool _searchArchivesToOverrideTentativeDefinitions;
bool _searchSharedLibrariesToOverrideTentativeDefinitions;
bool _warnIfCoalesableAtomsHaveDifferentCanBeNull;
bool _warnIfCoalesableAtomsHaveDifferentLoadName;
bool _forceLoadAllArchives;
bool _printRemainingUndefines;
bool _allowRemainingUndefines;
bool _logInputFiles;
bool _allowShlibUndefines;
std::vector<StringRef> _deadStripRoots;
std::vector<LinkerInput> _inputFiles;
std::vector<const char*> _llvmOptions;
std::unique_ptr<Reader> _yamlReader;
StringRefVector _initialUndefinedSymbols;
std::vector<const char *> _llvmOptions;
std::unique_ptr<Reader> _yamlReader;
StringRefVector _initialUndefinedSymbols;
private:
private:
/// Validate the subclass bits. Only called by validate.
virtual bool validateImpl(raw_ostream &diagnostics) = 0;
};

View File

@@ -23,17 +23,16 @@
namespace lld {
class Atom;
class TargetInfo;
class LinkingContext;
/// \brief The Resolver is responsible for merging all input object files
/// and producing a merged graph.
class Resolver : public InputFiles::Handler {
public:
Resolver(const TargetInfo &ti, const InputFiles &inputs)
: _targetInfo(ti), _inputFiles(inputs), _symbolTable(ti), _result(ti),
_haveLLVMObjs(false), _addToFinalSection(false),
_completedInitialObjectFiles(false) {
}
Resolver(const LinkingContext &context, const InputFiles &inputs)
: _context(context), _inputFiles(inputs), _symbolTable(context),
_result(context), _haveLLVMObjs(false), _addToFinalSection(false),
_completedInitialObjectFiles(false) {}
// InputFiles::Handler methods
virtual void doDefinedAtom(const DefinedAtom&);
@@ -66,7 +65,8 @@ private:
class MergedFile : public MutableFile {
public:
MergedFile(const TargetInfo &ti) : MutableFile(ti, "<linker-internal>") {}
MergedFile(const LinkingContext &context)
: MutableFile(context, "<linker-internal>") {}
virtual const atom_collection<DefinedAtom> &defined() const {
return _definedAtoms;
@@ -93,10 +93,9 @@ private:
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
};
const TargetInfo &_targetInfo;
const InputFiles &_inputFiles;
SymbolTable _symbolTable;
const LinkingContext &_context;
const InputFiles &_inputFiles;
SymbolTable _symbolTable;
std::vector<const Atom *> _atoms;
std::set<const Atom *> _deadStripRoots;
std::vector<const Atom *> _atomsWithUnresolvedReferences;

View File

@@ -25,9 +25,9 @@ namespace lld {
class AbsoluteAtom;
class Atom;
class DefinedAtom;
class LinkingContext;
class ResolverOptions;
class SharedLibraryAtom;
class TargetInfo;
class UndefinedAtom;
/// \brief The SymbolTable class is responsible for coalescing atoms.
@@ -37,7 +37,7 @@ class UndefinedAtom;
/// if an atom has been coalesced away.
class SymbolTable {
public:
explicit SymbolTable(const TargetInfo &);
explicit SymbolTable(const LinkingContext &);
/// @brief add atom to symbol table
void add(const DefinedAtom &);
@@ -96,10 +96,10 @@ private:
void addByName(const Atom &);
void addByContent(const DefinedAtom &);
const TargetInfo &_targetInfo;
AtomToAtom _replacedAtoms;
NameToAtom _nameTable;
AtomContentSet _contentTable;
const LinkingContext &_context;
AtomToAtom _replacedAtoms;
NameToAtom _nameTable;
AtomContentSet _contentTable;
};
} // namespace lld

View File

@@ -10,7 +10,7 @@
/// \file
///
/// Interface for Drivers which convert command line arguments into
/// TargetInfo objects, then perform the link.
/// LinkingContext objects, then perform the link.
///
//===----------------------------------------------------------------------===//
@@ -26,19 +26,20 @@
#include <vector>
namespace lld {
class TargetInfo;
class CoreTargetInfo;
class MachOTargetInfo;
class PECOFFTargetInfo;
class ELFTargetInfo;
class LinkingContext;
class CoreLinkingContext;
class MachOLinkingContext;
class PECOFFLinkingContext;
class ELFLinkingContext;
/// Base class for all Drivers.
class Driver {
protected:
/// Performs link using specified options.
static bool link(const TargetInfo &targetInfo,
static bool link(const LinkingContext &context,
raw_ostream &diagnostics = llvm::errs());
private:
Driver() LLVM_DELETED_FUNCTION;
};
@@ -68,7 +69,7 @@ public:
/// Uses gnu/binutils style ld command line options to fill in options struct.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[],
std::unique_ptr<ELFTargetInfo> &targetInfo,
std::unique_ptr<ELFLinkingContext> &context,
raw_ostream &diagnostics = llvm::errs());
private:
@@ -86,10 +87,11 @@ public:
static bool linkMachO(int argc, const char *argv[],
raw_ostream &diagnostics = llvm::errs());
/// Uses darwin style ld command line options to update targetInfo object.
/// Uses darwin style ld command line options to update LinkingContext object.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[], MachOTargetInfo &info,
static bool parse(int argc, const char *argv[], MachOLinkingContext &info,
raw_ostream &diagnostics = llvm::errs());
private:
DarwinLdDriver() LLVM_DELETED_FUNCTION;
};
@@ -105,7 +107,7 @@ public:
/// Uses Windows style link command line options to fill in options struct.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[], PECOFFTargetInfo &info,
static bool parse(int argc, const char *argv[], PECOFFLinkingContext &info,
raw_ostream &diagnostics = llvm::errs());
private:
@@ -124,7 +126,7 @@ public:
/// Uses lld-core command line options to fill in options struct.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[], CoreTargetInfo &info,
static bool parse(int argc, const char *argv[], CoreLinkingContext &info,
raw_ostream &diagnostics = llvm::errs());
private:

View File

@@ -0,0 +1,47 @@
//===- lld/ReaderWriter/CoreLinkingContext.h ------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_CORE_LINKER_CONTEXT_H
#define LLD_READER_WRITER_CORE_LINKER_CONTEXT_H
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/Support/ErrorHandling.h"
namespace lld {
class CoreLinkingContext : public LinkingContext {
public:
CoreLinkingContext();
virtual bool validateImpl(raw_ostream &diagnostics);
virtual void addPasses(PassManager &pm) const;
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const;
void addPassNamed(StringRef name) { _passNames.push_back(name); }
protected:
virtual Writer &writer() const;
private:
mutable std::unique_ptr<Reader> _reader;
mutable std::unique_ptr<Writer> _writer;
std::vector<StringRef> _passNames;
};
} // end namespace lld
#endif

View File

@@ -1,49 +0,0 @@
//===- lld/ReaderWriter/CoreTargetInfo.h ---------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_CORE_TARGET_INFO_H
#define LLD_READER_WRITER_CORE_TARGET_INFO_H
#include "lld/Core/TargetInfo.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/Support/ErrorHandling.h"
namespace lld {
class CoreTargetInfo : public TargetInfo {
public:
CoreTargetInfo();
virtual bool validateImpl(raw_ostream &diagnostics);
virtual void addPasses(PassManager &pm) const;
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const;
void addPassNamed(StringRef name) {
_passNames.push_back(name);
}
protected:
virtual Writer &writer() const;
private:
mutable std::unique_ptr<Reader> _reader;
mutable std::unique_ptr<Writer> _writer;
std::vector<StringRef> _passNames;
};
} // end namespace lld
#endif

View File

@@ -1,4 +1,4 @@
//===- lld/ReaderWriter/ELFTargetInfo.h -----------------------------------===//
//===- lld/ReaderWriter/ELFLinkingContext.h -------------------------------===//
//
// The LLVM Linker
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_ELF_TARGET_INFO_H
#define LLD_READER_WRITER_ELF_TARGET_INFO_H
#ifndef LLD_READER_WRITER_ELF_LINKER_CONTEXT_H
#define LLD_READER_WRITER_ELF_LINKER_CONTEXT_H
#include "lld/Core/PassManager.h"
#include "lld/Core/Pass.h"
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
@@ -26,21 +26,23 @@ namespace lld {
class DefinedAtom;
class Reference;
namespace elf { template <typename ELFT> class TargetHandler; }
namespace elf {
template <typename ELFT> class TargetHandler;
}
class TargetHandlerBase {
public:
virtual ~TargetHandlerBase() {}
};
class ELFTargetInfo : public TargetInfo {
class ELFLinkingContext : public LinkingContext {
public:
enum class OutputMagic : uint8_t {
DEFAULT, // The default mode, no specific magic set
NMAGIC, // Disallow shared libraries and dont align sections
// PageAlign Data, Mark Text Segment/Data segment RW
OMAGIC // Disallow shared libraries and dont align sections,
// Mark Text Segment/Data segment RW
DEFAULT, // The default mode, no specific magic set
NMAGIC, // Disallow shared libraries and dont align sections
// PageAlign Data, Mark Text Segment/Data segment RW
OMAGIC // Disallow shared libraries and dont align sections,
// Mark Text Segment/Data segment RW
};
llvm::Triple getTriple() const { return _triple; }
virtual bool is64Bits() const;
@@ -77,16 +79,16 @@ public:
/// having NMAGIC/OMAGIC
virtual bool allowLinkWithDynamicLibraries() const {
if (_outputMagic == OutputMagic::NMAGIC ||
_outputMagic == OutputMagic::OMAGIC ||
_noAllowDynamicLibraries)
_outputMagic == OutputMagic::OMAGIC || _noAllowDynamicLibraries)
return false;
return true;
}
virtual error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const;
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const;
static std::unique_ptr<ELFTargetInfo> create(llvm::Triple);
static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
/// \brief Does this relocation belong in the dynamic plt relocation table?
///
@@ -155,31 +157,32 @@ public:
bool appendLibrary(StringRef libName);
private:
ELFTargetInfo() LLVM_DELETED_FUNCTION;
ELFLinkingContext() LLVM_DELETED_FUNCTION;
protected:
ELFTargetInfo(llvm::Triple, std::unique_ptr<TargetHandlerBase>);
ELFLinkingContext(llvm::Triple, std::unique_ptr<TargetHandlerBase>);
virtual Writer &writer() const;
uint16_t _outputFileType; // e.g ET_EXEC
llvm::Triple _triple;
uint16_t _outputFileType; // e.g ET_EXEC
llvm::Triple _triple;
std::unique_ptr<TargetHandlerBase> _targetHandler;
uint64_t _baseAddress;
bool _isStaticExecutable;
bool _outputYAML;
bool _noInhibitExec;
bool _mergeCommonStrings;
bool _runLayoutPass;
bool _useShlibUndefines;
bool _dynamicLinkerArg;
bool _noAllowDynamicLibraries;
OutputMagic _outputMagic;
StringRefVector _inputSearchPaths;
llvm::BumpPtrAllocator _extraStrings;
std::unique_ptr<Reader> _elfReader;
std::unique_ptr<Writer> _writer;
std::unique_ptr<Reader> _linkerScriptReader;
StringRef _dynamicLinkerPath;
uint64_t _baseAddress;
bool _isStaticExecutable;
bool _outputYAML;
bool _noInhibitExec;
bool _mergeCommonStrings;
bool _runLayoutPass;
bool _useShlibUndefines;
bool _dynamicLinkerArg;
bool _noAllowDynamicLibraries;
OutputMagic _outputMagic;
StringRefVector _inputSearchPaths;
llvm::BumpPtrAllocator _extraStrings;
std::unique_ptr<Reader> _elfReader;
std::unique_ptr<Writer> _writer;
std::unique_ptr<Reader> _linkerScriptReader;
StringRef _dynamicLinkerPath;
};
} // end namespace lld

View File

@@ -1,4 +1,4 @@
//===- lld/ReaderWriter/MachOTargetInfo.h ---------------------------------===//
//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===//
//
// The LLVM Linker
//
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_MACHO_TARGET_INFO_H
#define LLD_READER_WRITER_MACHO_TARGET_INFO_H
#ifndef LLD_READER_WRITER_MACHO_LINKER_CONTEXT_H
#define LLD_READER_WRITER_MACHO_LINKER_CONTEXT_H
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
@@ -19,21 +19,22 @@
namespace lld {
namespace mach_o {
class KindHandler; // defined in lib. this header is in include.
class KindHandler; // defined in lib. this header is in include.
}
class MachOTargetInfo : public TargetInfo {
class MachOLinkingContext : public LinkingContext {
public:
MachOTargetInfo();
~MachOTargetInfo();
MachOLinkingContext();
~MachOLinkingContext();
virtual void addPasses(PassManager &pm) const;
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual bool validateImpl(raw_ostream &diagnostics);
virtual error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const;
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const;
uint32_t getCPUType() const;
uint32_t getCPUSubType() const;
@@ -42,14 +43,12 @@ public:
bool addUnixThreadLoadCommand() const;
bool outputTypeHasEntry() const;
virtual uint64_t pageZeroSize() const {
return _pageZeroSize;
}
virtual uint64_t pageZeroSize() const { return _pageZeroSize; }
mach_o::KindHandler &kindHandler() const;
uint32_t outputFileType() const { return _outputFileType; }
enum Arch {
arch_unknown,
arch_x86,
@@ -58,11 +57,9 @@ public:
arch_armv7,
arch_armv7s,
};
enum class OS {
macOSX,
iOS,
iOS_simulator
macOSX, iOS, iOS_simulator
};
Arch arch() const { return _arch; }
@@ -74,38 +71,39 @@ public:
bool minOS(StringRef mac, StringRef iOS) const;
void setDoNothing(bool value) { _doNothing = value; }
bool doNothing() const { return _doNothing; }
static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype);
static Arch archFromName(StringRef archName);
static uint32_t cpuTypeFromArch(Arch arch);
static uint32_t cpuSubtypeFromArch(Arch arch);
private:
virtual Writer &writer() const;
/// 32-bit packed encoding of "X.Y.Z" where nibbles are xxxx.yy.zz.
/// 32-bit packed encoding of "X.Y.Z" where nibbles are xxxx.yy.zz.
struct PackedVersion {
PackedVersion(StringRef);
static bool parse(StringRef, PackedVersion&);
bool operator<(const PackedVersion&) const;
bool operator>=(const PackedVersion&) const;
bool operator==(const PackedVersion&) const;
private:
PackedVersion(uint32_t v) : _value(v) { }
static bool parse(StringRef, PackedVersion &);
bool operator<(const PackedVersion &) const;
bool operator>=(const PackedVersion &) const;
bool operator==(const PackedVersion &) const;
uint32_t _value;
private:
PackedVersion(uint32_t v) : _value(v) {}
uint32_t _value;
};
uint32_t _outputFileType; // e.g MH_EXECUTE
bool _outputFileTypeStatic; // Disambiguate static vs dynamic prog
bool _doNothing; // for -help and -v which just print info
Arch _arch;
OS _os;
PackedVersion _osMinVersion;
uint64_t _pageZeroSize;
mutable std::unique_ptr<mach_o::KindHandler> _kindHandler;
mutable std::unique_ptr<Reader> _machoReader;
mutable std::unique_ptr<Writer> _writer;
uint32_t _outputFileType; // e.g MH_EXECUTE
bool _outputFileTypeStatic; // Disambiguate static vs dynamic prog
bool _doNothing; // for -help and -v which just print info
Arch _arch;
OS _os;
PackedVersion _osMinVersion;
uint64_t _pageZeroSize;
mutable std::unique_ptr<mach_o::KindHandler> _kindHandler;
mutable std::unique_ptr<Reader> _machoReader;
mutable std::unique_ptr<Writer> _writer;
};
} // end namespace lld

View File

@@ -1,4 +1,4 @@
//===- lld/ReaderWriter/PECOFFTargetInfo.h ---------------------------------===//
//===- lld/ReaderWriter/PECOFFLinkingContext.h ----------------------------===//
//
// The LLVM Linker
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_PECOFF_TARGET_INFO_H
#define LLD_READER_WRITER_PECOFF_TARGET_INFO_H
#ifndef LLD_READER_WRITER_PECOFF_LINKER_CONTEXT_H
#define LLD_READER_WRITER_PECOFF_LINKER_CONTEXT_H
#include <vector>
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
@@ -22,14 +22,14 @@
namespace lld {
class PECOFFTargetInfo : public TargetInfo {
class PECOFFLinkingContext : public LinkingContext {
public:
PECOFFTargetInfo()
PECOFFLinkingContext()
: _baseAddress(0x400000), _stackReserve(1024 * 1024), _stackCommit(4096),
_heapReserve(1024 * 1024), _heapCommit(4096),
_subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN), _minOSVersion(6, 0),
_nxCompat(true), _largeAddressAware(false), _baseRelocationEnabled(true),
_terminalServerAware(true) {}
_nxCompat(true), _largeAddressAware(false),
_baseRelocationEnabled(true), _terminalServerAware(true) {}
struct OSVersion {
OSVersion(int v1, int v2) : majorVersion(v1), minorVersion(v2) {}
@@ -37,9 +37,9 @@ public:
int minorVersion;
};
virtual error_code parseFile(
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const;
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const;
virtual Writer &writer() const;
virtual bool validateImpl(raw_ostream &diagnostics);

View File

@@ -17,10 +17,10 @@
#include <vector>
namespace lld {
class ELFTargetInfo;
class ELFLinkingContext;
class File;
class LinkerInput;
class TargetInfo;
class LinkingContext;
/// \brief An abstract class for reading object files, library files, and
/// executable files.
@@ -44,19 +44,18 @@ public:
protected:
// only concrete subclasses can be instantiated
Reader(const TargetInfo &ti)
: _targetInfo(ti) {}
Reader(const LinkingContext &context) : _context(context) {}
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
typedef ErrorOr<Reader &> ReaderFunc(const LinkerInput &);
std::unique_ptr<Reader> createReaderELF(const ELFTargetInfo &);
std::unique_ptr<Reader> createReaderMachO(const TargetInfo &);
std::unique_ptr<Reader> createReaderNative(const TargetInfo &);
std::unique_ptr<Reader> createReaderPECOFF(const TargetInfo &);
std::unique_ptr<Reader> createReaderYAML(const TargetInfo &);
std::unique_ptr<Reader> createReaderELF(const ELFLinkingContext &);
std::unique_ptr<Reader> createReaderMachO(const LinkingContext &);
std::unique_ptr<Reader> createReaderNative(const LinkingContext &);
std::unique_ptr<Reader> createReaderPECOFF(const LinkingContext &);
std::unique_ptr<Reader> createReaderYAML(const LinkingContext &);
} // end namespace lld
#endif

View File

@@ -23,15 +23,14 @@
namespace lld {
class File;
class LinkingContext;
class LinkerInput;
class TargetInfo;
/// \brief ReaderArchive is a class for reading archive libraries
class ReaderArchive : public Reader {
public:
ReaderArchive(const TargetInfo &ti, const Reader &memberReader)
: Reader(ti) {
}
ReaderArchive(const LinkingContext &context, const Reader &memberReader)
: Reader(context) {}
/// \brief Returns a vector of Files that are contained in the archive file
/// pointed to by the Memorybuffer

View File

@@ -16,13 +16,13 @@
namespace lld {
class File;
class LinkerInput;
class TargetInfo;
class LinkingContext;
/// \brief ReaderLinkerScript is a class for reading linker scripts
class ReaderLinkerScript : public Reader {
public:
explicit ReaderLinkerScript(const TargetInfo &ti)
: Reader(ti) {}
explicit ReaderLinkerScript(const LinkingContext &context)
: Reader(context) {}
/// \brief Returns a vector of Files that are contained in the archive file
/// pointed to by the Memorybuffer

View File

@@ -23,7 +23,8 @@
namespace lld {
class SimpleFile : public MutableFile {
public:
SimpleFile(const TargetInfo &ti, StringRef path) : MutableFile(ti, path) {
SimpleFile(const LinkingContext &context, StringRef path)
: MutableFile(context, path) {
static uint32_t lastOrdinal = 0;
_ordinal = lastOrdinal++;
}
@@ -169,9 +170,7 @@ private:
class SimpleUndefinedAtom : public UndefinedAtom {
public:
SimpleUndefinedAtom(const File &f, StringRef name)
: _file(f)
, _name(name) {
SimpleUndefinedAtom(const File &f, StringRef name) : _file(f), _name(name) {
assert(!name.empty() && "UndefinedAtoms must have a name");
}

View File

@@ -15,12 +15,12 @@
#include <memory>
namespace lld {
class ELFTargetInfo;
class ELFLinkingContext;
class File;
class InputFiles;
class MachOTargetInfo;
class PECOFFTargetInfo;
class TargetInfo;
class MachOLinkingContext;
class PECOFFLinkingContext;
class LinkingContext;
/// \brief The Writer is an abstract class for writing object files, shared
/// library files, and executable files. Each file format (e.g. ELF, mach-o,
@@ -42,11 +42,11 @@ protected:
Writer();
};
std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &);
std::unique_ptr<Writer> createWriterMachO(const MachOTargetInfo &);
std::unique_ptr<Writer> createWriterNative(const TargetInfo &);
std::unique_ptr<Writer> createWriterPECOFF(const PECOFFTargetInfo &);
std::unique_ptr<Writer> createWriterYAML(const TargetInfo &);
std::unique_ptr<Writer> createWriterELF(const ELFLinkingContext &);
std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &);
std::unique_ptr<Writer> createWriterNative(const LinkingContext &);
std::unique_ptr<Writer> createWriterPECOFF(const PECOFFLinkingContext &);
std::unique_ptr<Writer> createWriterYAML(const LinkingContext &);
} // end namespace lld
#endif

View File

@@ -5,8 +5,8 @@ add_lld_library(lldCore
Error.cpp
File.cpp
InputFiles.cpp
LinkingContext.cpp
PassManager.cpp
Resolver.cpp
SymbolTable.cpp
TargetInfo.cpp
)

View File

@@ -1,4 +1,4 @@
//===- lib/Core/TargetInfo.cpp - Linker Target Info Interface -------------===//
//===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===//
//
// The LLVM Linker
//
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/Triple.h"
namespace lld {
TargetInfo::TargetInfo()
LinkingContext::LinkingContext()
: Reader(*this), _deadStrip(false), _globalsAreDeadStripRoots(false),
_searchArchivesToOverrideTentativeDefinitions(false),
_searchSharedLibrariesToOverrideTentativeDefinitions(false),
@@ -24,15 +24,16 @@ TargetInfo::TargetInfo()
_allowRemainingUndefines(false), _logInputFiles(false),
_allowShlibUndefines(false) {}
TargetInfo::~TargetInfo() {}
LinkingContext::~LinkingContext() {}
bool TargetInfo::validate(raw_ostream &diagnostics) {
bool LinkingContext::validate(raw_ostream &diagnostics) {
_yamlReader = createReaderYAML(*this);
return validateImpl(diagnostics);
}
error_code TargetInfo::readFile(StringRef path,
std::vector<std::unique_ptr<File>> &result) const {
error_code
LinkingContext::readFile(StringRef path,
std::vector<std::unique_ptr<File>> &result) const {
OwningPtr<llvm::MemoryBuffer> opmb;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb))
return ec;
@@ -41,16 +42,14 @@ error_code TargetInfo::readFile(StringRef path,
return this->parseFile(mb, result);
}
error_code TargetInfo::writeFile(const File &linkedFile) const {
return this->writer().writeFile(linkedFile, _outputPath);
error_code LinkingContext::writeFile(const File &linkedFile) const {
return this->writer().writeFile(linkedFile, _outputPath);
}
void TargetInfo::addImplicitFiles(InputFiles& inputs) const {
this->writer().addFiles(inputs);
}
void TargetInfo::addPasses(PassManager &pm) const {
void LinkingContext::addImplicitFiles(InputFiles &inputs) const {
this->writer().addFiles(inputs);
}
void LinkingContext::addPasses(PassManager &pm) const {}
} // end namespace lld

View File

@@ -14,7 +14,7 @@
#include "lld/Core/LLVM.h"
#include "lld/Core/Resolver.h"
#include "lld/Core/SymbolTable.h"
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/Core/UndefinedAtom.h"
#include "llvm/Support/Debug.h"
@@ -134,7 +134,7 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) {
// tell symbol table
_symbolTable.add(atom);
if (_targetInfo.deadStrip()) {
if (_context.deadStrip()) {
// add to set of dead-strip-roots, all symbols that
// the compiler marks as don't strip
if (atom.deadStrip() == DefinedAtom::deadStripNever)
@@ -188,9 +188,9 @@ void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) {
void Resolver::resolveUndefines() {
ScopedTask task(getDefaultDomain(), "resolveUndefines");
const bool searchArchives =
_targetInfo.searchArchivesToOverrideTentativeDefinitions();
_context.searchArchivesToOverrideTentativeDefinitions();
const bool searchSharedLibs =
_targetInfo.searchSharedLibrariesToOverrideTentativeDefinitions();
_context.searchSharedLibrariesToOverrideTentativeDefinitions();
// keep looping until no more undefines were added in last loop
unsigned int undefineGenCount = 0xFFFFFFFF;
@@ -273,15 +273,15 @@ void Resolver::markLive(const Atom &atom) {
void Resolver::deadStripOptimize() {
ScopedTask task(getDefaultDomain(), "deadStripOptimize");
// only do this optimization with -dead_strip
if (!_targetInfo.deadStrip())
if (!_context.deadStrip())
return;
// clear liveness on all atoms
_liveAtoms.clear();
// By default, shared libraries are built with all globals as dead strip roots
if (_targetInfo.globalsAreDeadStripRoots()) {
for ( const Atom *atom : _atoms ) {
if (_context.globalsAreDeadStripRoots()) {
for (const Atom *atom : _atoms) {
const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom);
if (defAtom == nullptr)
continue;
@@ -291,7 +291,7 @@ void Resolver::deadStripOptimize() {
}
// Or, use list of names that are dead stip roots.
for (const StringRef &name : _targetInfo.deadStripRoots()) {
for (const StringRef &name : _context.deadStripRoots()) {
const Atom *symAtom = _symbolTable.findByName(name);
assert(symAtom->definition() != Atom::definitionUndefined);
_deadStripRoots.insert(symAtom);
@@ -317,7 +317,7 @@ bool Resolver::checkUndefines(bool final) {
// build vector of remaining undefined symbols
std::vector<const UndefinedAtom *> undefinedAtoms;
_symbolTable.undefines(undefinedAtoms);
if (_targetInfo.deadStrip()) {
if (_context.deadStrip()) {
// When dead code stripping, we don't care if dead atoms are undefined.
undefinedAtoms.erase(std::remove_if(
undefinedAtoms.begin(), undefinedAtoms.end(),
@@ -337,18 +337,18 @@ bool Resolver::checkUndefines(bool final) {
// If this is a library and undefined symbols are allowed on the
// target platform, skip over it.
if (isa<SharedLibraryFile>(f) && _targetInfo.allowShlibUndefines())
if (isa<SharedLibraryFile>(f) && _context.allowShlibUndefines())
continue;
// Seems like this symbol is undefined. Warn that.
foundUndefines = true;
if (_targetInfo.printRemainingUndefines()) {
if (_context.printRemainingUndefines()) {
llvm::errs() << "Undefined Symbol: " << undefAtom->file().path()
<< " : " << undefAtom->name() << "\n";
}
}
if (foundUndefines) {
if (_targetInfo.printRemainingUndefines())
if (_context.printRemainingUndefines())
llvm::errs() << "symbol(s) not found\n";
return true;
}
@@ -393,7 +393,7 @@ bool Resolver::resolve() {
this->updateReferences();
this->deadStripOptimize();
if (this->checkUndefines(false)) {
if (!_targetInfo.allowRemainingUndefines())
if (!_context.allowRemainingUndefines())
return true;
}
this->removeCoalescedAwayAtoms();

View File

@@ -16,7 +16,7 @@
#include "lld/Core/LLVM.h"
#include "lld/Core/Resolver.h"
#include "lld/Core/SharedLibraryAtom.h"
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/Core/UndefinedAtom.h"
#include "llvm/ADT/ArrayRef.h"
@@ -31,7 +31,7 @@
#include <vector>
namespace lld {
SymbolTable::SymbolTable(const TargetInfo &ti) : _targetInfo(ti) {}
SymbolTable::SymbolTable(const LinkingContext &context) : _context(context) {}
void SymbolTable::add(const UndefinedAtom &atom) {
this->addByName(atom);
@@ -183,7 +183,7 @@ void SymbolTable::addByName(const Atom & newAtom) {
useNew = false;
}
else {
if (_targetInfo.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
if (_context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
// FIXME: need diagonstics interface for writing warning messages
llvm::errs() << "lld warning: undefined symbol "
<< existingUndef->name()
@@ -208,7 +208,7 @@ void SymbolTable::addByName(const Atom & newAtom) {
bool sameName = curShLib->loadName().equals(newShLib->loadName());
if ( !sameName ) {
useNew = false;
if (_targetInfo.warnIfCoalesableAtomsHaveDifferentLoadName()) {
if (_context.warnIfCoalesableAtomsHaveDifferentLoadName()) {
// FIXME: need diagonstics interface for writing warning messages
llvm::errs() << "lld warning: shared library symbol "
<< curShLib->name()
@@ -220,7 +220,7 @@ void SymbolTable::addByName(const Atom & newAtom) {
}
else if ( ! sameNullness ) {
useNew = false;
if (_targetInfo.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
if (_context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
// FIXME: need diagonstics interface for writing warning messages
llvm::errs() << "lld warning: shared library symbol "
<< curShLib->name()

View File

@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lld/Driver/Driver.h"
#include "lld/ReaderWriter/CoreTargetInfo.h"
#include "lld/ReaderWriter/CoreLinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "llvm/ADT/ArrayRef.h"
@@ -69,16 +69,15 @@ public:
namespace lld {
bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
CoreTargetInfo info;
CoreLinkingContext info;
if (parse(argc, argv, info))
return true;
return Driver::link(info);
}
bool CoreDriver::parse(int argc, const char *argv[],
CoreTargetInfo &info, raw_ostream &diagnostics) {
bool CoreDriver::parse(int argc, const char *argv[], CoreLinkingContext &info,
raw_ostream &diagnostics) {
// Parse command line options using CoreOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
CoreOptTable table;

View File

@@ -14,7 +14,7 @@
//===----------------------------------------------------------------------===//
#include "lld/Driver/Driver.h"
#include "lld/ReaderWriter/MachOTargetInfo.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
#include "../ReaderWriter/MachO/MachOFormat.hpp"
#include "llvm/ADT/ArrayRef.h"
@@ -73,7 +73,7 @@ namespace lld {
bool DarwinLdDriver::linkMachO(int argc, const char *argv[],
raw_ostream &diagnostics) {
MachOTargetInfo info;
MachOLinkingContext info;
if (parse(argc, argv, info, diagnostics))
return true;
if ( info.doNothing() )
@@ -82,10 +82,9 @@ bool DarwinLdDriver::linkMachO(int argc, const char *argv[],
return link(info, diagnostics);
}
bool DarwinLdDriver::parse(int argc, const char *argv[],
MachOTargetInfo &info, raw_ostream &diagnostics) {
bool DarwinLdDriver::parse(int argc, const char *argv[],
MachOLinkingContext &info,
raw_ostream &diagnostics) {
// Parse command line options using DarwinOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
DarwinLdOptTable table;
@@ -149,10 +148,9 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
// Handle -arch xxx
if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) {
info.setArch(MachOTargetInfo::archFromName(archStr->getValue()));
if (info.arch() == MachOTargetInfo::arch_unknown) {
diagnostics << "error: unknown arch named '"
<< archStr->getValue()
info.setArch(MachOLinkingContext::archFromName(archStr->getValue()));
if (info.arch() == MachOLinkingContext::arch_unknown) {
diagnostics << "error: unknown arch named '" << archStr->getValue()
<< "'\n";
return true;
}
@@ -165,19 +163,20 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
OPT_ios_simulator_version_min)) {
switch (minOS->getOption().getID()) {
case OPT_macosx_version_min:
if (info.setOS(MachOTargetInfo::OS::macOSX, minOS->getValue())) {
if (info.setOS(MachOLinkingContext::OS::macOSX, minOS->getValue())) {
diagnostics << "error: malformed macosx_version_min value\n";
return true;
}
break;
case OPT_ios_version_min:
if (info.setOS(MachOTargetInfo::OS::iOS, minOS->getValue())) {
if (info.setOS(MachOLinkingContext::OS::iOS, minOS->getValue())) {
diagnostics << "error: malformed ios_version_min value\n";
return true;
}
break;
case OPT_ios_simulator_version_min:
if (info.setOS(MachOTargetInfo::OS::iOS_simulator, minOS->getValue())) {
if (info.setOS(MachOLinkingContext::OS::iOS_simulator,
minOS->getValue())) {
diagnostics << "error: malformed ios_simulator_version_min value\n";
return true;
}

View File

@@ -29,33 +29,33 @@
namespace lld {
/// This is where the link is actually performed.
bool Driver::link(const TargetInfo &targetInfo, raw_ostream &diagnostics) {
bool Driver::link(const LinkingContext &context, raw_ostream &diagnostics) {
// Honor -mllvm
if (!targetInfo.llvmOptions().empty()) {
unsigned numArgs = targetInfo.llvmOptions().size();
const char **args = new const char*[numArgs + 2];
if (!context.llvmOptions().empty()) {
unsigned numArgs = context.llvmOptions().size();
const char **args = new const char *[numArgs + 2];
args[0] = "lld (LLVM option parsing)";
for (unsigned i = 0; i != numArgs; ++i)
args[i + 1] = targetInfo.llvmOptions()[i];
args[i + 1] = context.llvmOptions()[i];
args[numArgs + 1] = 0;
llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
}
// Read inputs
ScopedTask readTask(getDefaultDomain(), "Read Args");
std::vector<std::vector<std::unique_ptr<File>>> files(
targetInfo.inputFiles().size());
std::vector<std::vector<std::unique_ptr<File>> > files(
context.inputFiles().size());
size_t index = 0;
std::atomic<bool> fail(false);
TaskGroup tg;
for (const auto &input : targetInfo.inputFiles()) {
if (targetInfo.logInputFiles())
for (const auto &input : context.inputFiles()) {
if (context.logInputFiles())
llvm::outs() << input.getPath() << "\n";
tg.spawn([&, index] {
if (error_code ec = targetInfo.readFile(input.getPath(), files[index])) {
diagnostics << "Failed to read file: " << input.getPath()
<< ": " << ec.message() << "\n";
tg.spawn([ &, index]{
if (error_code ec = context.readFile(input.getPath(), files[index])) {
diagnostics << "Failed to read file: " << input.getPath() << ": "
<< ec.message() << "\n";
fail = true;
return;
}
@@ -73,16 +73,16 @@ bool Driver::link(const TargetInfo &targetInfo, raw_ostream &diagnostics) {
inputs.appendFiles(f);
// Give target a chance to add files.
targetInfo.addImplicitFiles(inputs);
context.addImplicitFiles(inputs);
// assign an ordinal to each file so sort() can preserve command line order
inputs.assignFileOrdinals();
// Do core linking.
ScopedTask resolveTask(getDefaultDomain(), "Resolve");
Resolver resolver(targetInfo, inputs);
Resolver resolver(context, inputs);
if (resolver.resolve()) {
if (!targetInfo.allowRemainingUndefines())
if (!context.allowRemainingUndefines())
return true;
}
MutableFile &merged = resolver.resultFile();
@@ -91,14 +91,14 @@ bool Driver::link(const TargetInfo &targetInfo, raw_ostream &diagnostics) {
// Run passes on linked atoms.
ScopedTask passTask(getDefaultDomain(), "Passes");
PassManager pm;
targetInfo.addPasses(pm);
context.addPasses(pm);
pm.runOnFile(merged);
passTask.end();
// Give linked atoms to Writer to generate output file.
ScopedTask writeTask(getDefaultDomain(), "Write");
if (error_code ec = targetInfo.writeFile(merged)) {
diagnostics << "Failed to write file '" << targetInfo.outputPath()
if (error_code ec = context.writeFile(merged)) {
diagnostics << "Failed to write file '" << context.outputPath()
<< "': " << ec.message() << "\n";
return true;
}
@@ -106,6 +106,4 @@ bool Driver::link(const TargetInfo &targetInfo, raw_ostream &diagnostics) {
return false;
}
} // namespace

View File

@@ -14,7 +14,7 @@
//===----------------------------------------------------------------------===//
#include "lld/Driver/Driver.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
@@ -75,7 +75,7 @@ public:
bool GnuLdDriver::linkELF(int argc, const char *argv[],
raw_ostream &diagnostics) {
std::unique_ptr<ELFTargetInfo> options;
std::unique_ptr<ELFLinkingContext> options;
bool error = parse(argc, argv, options, diagnostics);
if (error)
return true;
@@ -86,7 +86,7 @@ bool GnuLdDriver::linkELF(int argc, const char *argv[],
}
bool GnuLdDriver::parse(int argc, const char *argv[],
std::unique_ptr<ELFTargetInfo> &targetInfo,
std::unique_ptr<ELFLinkingContext> &context,
raw_ostream &diagnostics) {
// Parse command line options using LDOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
@@ -115,13 +115,13 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
return false;
}
// Use -target or use default target triple to instantiate TargetInfo
// Use -target or use default target triple to instantiate LinkingContext
llvm::Triple triple;
if (llvm::opt::Arg *trip = parsedArgs->getLastArg(OPT_target))
triple = llvm::Triple(trip->getValue());
else
triple = getDefaultTarget(argv[0]);
std::unique_ptr<ELFTargetInfo> options(ELFTargetInfo::create(triple));
std::unique_ptr<ELFLinkingContext> options(ELFLinkingContext::create(triple));
if (!options) {
diagnostics << "unknown target triple\n";
@@ -205,15 +205,15 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
// Handle NMAGIC
if (parsedArgs->getLastArg(OPT_nmagic))
options->setOutputMagic(ELFTargetInfo::OutputMagic::NMAGIC);
options->setOutputMagic(ELFLinkingContext::OutputMagic::NMAGIC);
// Handle OMAGIC
if (parsedArgs->getLastArg(OPT_omagic))
options->setOutputMagic(ELFTargetInfo::OutputMagic::OMAGIC);
options->setOutputMagic(ELFLinkingContext::OutputMagic::OMAGIC);
// Handle --no-omagic
if (parsedArgs->getLastArg(OPT_no_omagic)) {
options->setOutputMagic(ELFTargetInfo::OutputMagic::DEFAULT);
options->setOutputMagic(ELFLinkingContext::OutputMagic::DEFAULT);
options->setNoAllowDynamicLibraries();
}
@@ -268,7 +268,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
if (options->validate(diagnostics))
return true;
targetInfo.swap(options);
context.swap(options);
return false;
}

View File

@@ -24,7 +24,7 @@
#include "llvm/Support/Path.h"
#include "lld/Driver/Driver.h"
#include "lld/ReaderWriter/PECOFFTargetInfo.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
namespace lld {
@@ -93,8 +93,8 @@ bool parseMemoryOption(const StringRef &arg, raw_ostream &diagnostics,
// Parse /base command line option. The argument for the parameter is in the
// form of "<address>[:<size>]".
bool parseBaseOption(PECOFFTargetInfo &info, const StringRef &arg,
raw_ostream &diagnostics) {
bool parseBaseOption(PECOFFLinkingContext &context, const StringRef &arg,
raw_ostream &diagnostics) {
// Size should be set to SizeOfImage field in the COFF header, and if it's
// smaller than the actual size, the linker should warn about that. Currently
// we just ignore the value of size parameter.
@@ -107,31 +107,31 @@ bool parseBaseOption(PECOFFTargetInfo &info, const StringRef &arg,
<< addr << "\n";
return false;
}
info.setBaseAddress(addr);
context.setBaseAddress(addr);
return true;
}
// Parse /stack command line option
bool parseStackOption(PECOFFTargetInfo &info, const StringRef &arg,
bool parseStackOption(PECOFFLinkingContext &context, const StringRef &arg,
raw_ostream &diagnostics) {
uint64_t reserve;
uint64_t commit = info.getStackCommit();
uint64_t commit = context.getStackCommit();
if (!parseMemoryOption(arg, diagnostics, reserve, commit))
return false;
info.setStackReserve(reserve);
info.setStackCommit(commit);
context.setStackReserve(reserve);
context.setStackCommit(commit);
return true;
}
// Parse /heap command line option.
bool parseHeapOption(PECOFFTargetInfo &info, const StringRef &arg,
bool parseHeapOption(PECOFFLinkingContext &context, const StringRef &arg,
raw_ostream &diagnostics) {
uint64_t reserve;
uint64_t commit = info.getHeapCommit();
uint64_t commit = context.getHeapCommit();
if (!parseMemoryOption(arg, diagnostics, reserve, commit))
return false;
info.setHeapReserve(reserve);
info.setHeapCommit(commit);
context.setHeapReserve(reserve);
context.setHeapCommit(commit);
return true;
}
@@ -144,8 +144,8 @@ llvm::COFF::WindowsSubsystem stringToWinSubsystem(StringRef str) {
.Default(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN);
}
bool parseMinOSVersion(PECOFFTargetInfo &info, const StringRef &osVersion,
raw_ostream &diagnostics) {
bool parseMinOSVersion(PECOFFLinkingContext &context,
const StringRef &osVersion, raw_ostream &diagnostics) {
StringRef majorVersion, minorVersion;
llvm::tie(majorVersion, minorVersion) = osVersion.split('.');
if (minorVersion.empty())
@@ -154,22 +154,22 @@ bool parseMinOSVersion(PECOFFTargetInfo &info, const StringRef &osVersion,
return false;
if (!checkNumber(minorVersion, "invalid OS minor version: ", diagnostics))
return false;
PECOFFTargetInfo::OSVersion minOSVersion(atoi(majorVersion.str().c_str()),
atoi(minorVersion.str().c_str()));
info.setMinOSVersion(minOSVersion);
PECOFFLinkingContext::OSVersion minOSVersion(
atoi(majorVersion.str().c_str()), atoi(minorVersion.str().c_str()));
context.setMinOSVersion(minOSVersion);
return true;
}
// Parse /subsystem command line option. The form of /subsystem is
// "subsystem_name[,majorOSVersion[.minorOSVersion]]".
bool parseSubsystemOption(PECOFFTargetInfo &info, std::string arg,
bool parseSubsystemOption(PECOFFLinkingContext &context, std::string arg,
raw_ostream &diagnostics) {
StringRef subsystemStr, osVersionStr;
llvm::tie(subsystemStr, osVersionStr) = StringRef(arg).split(',');
// Parse optional OS version if exists.
if (!osVersionStr.empty())
if (!parseMinOSVersion(info, osVersionStr, diagnostics))
if (!parseMinOSVersion(context, osVersionStr, diagnostics))
return false;
// Parse subsystem name.
@@ -178,16 +178,17 @@ bool parseSubsystemOption(PECOFFTargetInfo &info, std::string arg,
diagnostics << "error: unknown subsystem name: " << subsystemStr << "\n";
return false;
}
info.setSubsystem(subsystem);
context.setSubsystem(subsystem);
return true;
}
// Replace a file extension with ".exe". If the given file has no
// extension, just add ".exe".
StringRef getDefaultOutputFileName(PECOFFTargetInfo &info, StringRef path) {
StringRef getDefaultOutputFileName(PECOFFLinkingContext &context,
StringRef path) {
SmallString<128> smallStr = path;
llvm::sys::path::replace_extension(smallStr, ".exe");
return info.allocateString(smallStr.str());
return context.allocateString(smallStr.str());
}
// Split the given string with spaces.
@@ -231,16 +232,17 @@ bool handleFailIfMismatchOption(StringRef option,
// Add ".lib" extension if the path does not already have the extension to mimic
// link.exe behavior.
StringRef canonicalizeImportLibraryPath(PECOFFTargetInfo &info, StringRef path) {
StringRef canonicalizeImportLibraryPath(PECOFFLinkingContext &context,
StringRef path) {
std::string s(path.lower());
if (StringRef(s).endswith(".lib"))
return path;
return info.allocateString(std::string(path).append(".lib"));
return context.allocateString(std::string(path).append(".lib"));
}
// Process "LINK" environment variable. If defined, the value of the variable
// should be processed as command line arguments.
std::vector<const char *> processLinkEnv(PECOFFTargetInfo &info,
std::vector<const char *> processLinkEnv(PECOFFLinkingContext &context,
int argc, const char **argv) {
std::vector<const char *> ret;
// The first argument is the name of the command. This should stay at the head
@@ -251,7 +253,7 @@ std::vector<const char *> processLinkEnv(PECOFFTargetInfo &info,
// Add arguments specified by the LINK environment variable.
if (char *envp = ::getenv("LINK"))
for (std::string &arg : splitArgList(envp))
ret.push_back(info.allocateString(arg).data());
ret.push_back(context.allocateString(arg).data());
// Add the rest of arguments passed via the command line.
for (int i = 1; i < argc; ++i)
@@ -262,10 +264,10 @@ std::vector<const char *> processLinkEnv(PECOFFTargetInfo &info,
// Process "LIB" environment variable. The variable contains a list of search
// paths separated by semicolons.
void processLibEnv(PECOFFTargetInfo &info) {
void processLibEnv(PECOFFLinkingContext &context) {
if (char *envp = ::getenv("LIB"))
for (StringRef path : splitPathList(envp))
info.appendInputSearchPath(info.allocateString(path));
context.appendInputSearchPath(context.allocateString(path));
}
// Parses the given command line options and returns the result. Returns NULL if
@@ -300,16 +302,17 @@ std::unique_ptr<llvm::opt::InputArgList> parseArgs(int argc, const char *argv[],
bool WinLinkDriver::linkPECOFF(int argc, const char *argv[],
raw_ostream &diagnostics) {
PECOFFTargetInfo info;
std::vector<const char *> newargv = processLinkEnv(info, argc, argv);
processLibEnv(info);
if (parse(newargv.size() - 1, &newargv[0], info, diagnostics))
PECOFFLinkingContext context;
std::vector<const char *> newargv = processLinkEnv(context, argc, argv);
processLibEnv(context);
if (parse(newargv.size() - 1, &newargv[0], context, diagnostics))
return true;
return link(info, diagnostics);
return link(context, diagnostics);
}
bool WinLinkDriver::parse(int argc, const char *argv[],
PECOFFTargetInfo &info, raw_ostream &diagnostics) {
PECOFFLinkingContext &context,
raw_ostream &diagnostics) {
// Parse the options.
std::unique_ptr<llvm::opt::InputArgList> parsedArgs = parseArgs(
argc, argv, diagnostics);
@@ -327,70 +330,70 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_mllvm),
ie = parsedArgs->filtered_end();
it != ie; ++it) {
info.appendLLVMOption((*it)->getValue());
context.appendLLVMOption((*it)->getValue());
}
// handle /base
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_base))
if (!parseBaseOption(info, arg->getValue(), diagnostics))
if (!parseBaseOption(context, arg->getValue(), diagnostics))
return true;
// handle /stack
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_stack))
if (!parseStackOption(info, arg->getValue(), diagnostics))
if (!parseStackOption(context, arg->getValue(), diagnostics))
return true;
// handle /heap
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_heap))
if (!parseHeapOption(info, arg->getValue(), diagnostics))
if (!parseHeapOption(context, arg->getValue(), diagnostics))
return true;
// handle /subsystem
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_subsystem))
if (!parseSubsystemOption(info, arg->getValue(), diagnostics))
if (!parseSubsystemOption(context, arg->getValue(), diagnostics))
return true;
// handle /entry
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_entry))
info.setEntrySymbolName(arg->getValue());
context.setEntrySymbolName(arg->getValue());
// handle /libpath
for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_libpath),
ie = parsedArgs->filtered_end();
it != ie; ++it) {
info.appendInputSearchPath((*it)->getValue());
context.appendInputSearchPath((*it)->getValue());
}
// handle /force
if (parsedArgs->getLastArg(OPT_force))
info.setAllowRemainingUndefines(true);
context.setAllowRemainingUndefines(true);
// handle /nxcompat:no
if (parsedArgs->getLastArg(OPT_no_nxcompat))
info.setNxCompat(false);
context.setNxCompat(false);
// handle /largeaddressaware
if (parsedArgs->getLastArg(OPT_largeaddressaware))
info.setLargeAddressAware(true);
context.setLargeAddressAware(true);
// handle /fixed
if (parsedArgs->getLastArg(OPT_fixed))
info.setBaseRelocationEnabled(false);
context.setBaseRelocationEnabled(false);
// handle /tsaware:no
if (parsedArgs->getLastArg(OPT_no_tsaware))
info.setTerminalServerAware(false);
context.setTerminalServerAware(false);
// handle /include
for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_incl),
ie = parsedArgs->filtered_end();
it != ie; ++it) {
info.addInitialUndefinedSymbol((*it)->getValue());
context.addInitialUndefinedSymbol((*it)->getValue());
}
// handle /out
if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_out))
info.setOutputPath(outpath->getValue());
context.setOutputPath(outpath->getValue());
// handle /defaultlib
std::vector<StringRef> defaultLibs;
@@ -427,22 +430,22 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
// Add input files specified via the command line.
for (const StringRef path : inputPaths)
info.appendInputFileOrLibrary(path);
context.appendInputFileOrLibrary(path);
// Add the library files specified by /defaultlib option. The files
// specified by the option should have lower precedence than the other files
// added above, which is important for link.exe compatibility.
for (const StringRef path : defaultLibs)
info.appendLibraryFile(canonicalizeImportLibraryPath(info, path));
context.appendLibraryFile(canonicalizeImportLibraryPath(context, path));
// If /out option was not specified, the default output file name is
// constructed by replacing an extension of the first input file
// with ".exe".
if (info.outputPath().empty() && !inputPaths.empty())
info.setOutputPath(getDefaultOutputFileName(info, inputPaths[0]));
if (context.outputPath().empty() && !inputPaths.empty())
context.setOutputPath(getDefaultOutputFileName(context, inputPaths[0]));
// Validate the combination of options used.
return info.validate(diagnostics);
return context.validate(diagnostics);
}
} // namespace lld

View File

@@ -6,7 +6,7 @@ add_subdirectory(Native)
add_subdirectory(PECOFF)
add_subdirectory(YAML)
add_lld_library(lldReaderWriter
CoreTargetInfo.cpp
CoreLinkingContext.cpp
LinkerScript.cpp
Reader.cpp
ReaderArchive.cpp

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/CoreTargetInfo.cpp --------------------------------===//
//===- lib/ReaderWriter/CoreLinkingContext.cpp ----------------------------===//
//
// The LLVM Linker
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "lld/ReaderWriter/CoreTargetInfo.h"
#include "lld/ReaderWriter/CoreLinkingContext.h"
#include "lld/Core/Pass.h"
#include "lld/Core/PassManager.h"
@@ -15,7 +15,6 @@
#include "llvm/ADT/ArrayRef.h"
using namespace lld;
namespace {
@@ -23,74 +22,48 @@ namespace {
/// \brief Simple atom created by the stubs pass.
class TestingStubAtom : public DefinedAtom {
public:
TestingStubAtom(const File &F, const Atom&) : _file(F) {
TestingStubAtom(const File &F, const Atom &) : _file(F) {
static uint32_t lastOrdinal = 0;
_ordinal = lastOrdinal++;
}
virtual const File &file() const {
return _file;
}
virtual const File &file() const { return _file; }
virtual StringRef name() const {
return StringRef();
}
virtual StringRef name() const { return StringRef(); }
virtual uint64_t ordinal() const {
return _ordinal;
}
virtual uint64_t ordinal() const { return _ordinal; }
virtual uint64_t size() const {
return 0;
}
virtual uint64_t size() const { return 0; }
virtual Scope scope() const {
return DefinedAtom::scopeLinkageUnit;
}
virtual Scope scope() const { return DefinedAtom::scopeLinkageUnit; }
virtual Interposable interposable() const {
return DefinedAtom::interposeNo;
}
virtual Interposable interposable() const { return DefinedAtom::interposeNo; }
virtual Merge merge() const {
return DefinedAtom::mergeNo;
}
virtual Merge merge() const { return DefinedAtom::mergeNo; }
virtual ContentType contentType() const {
return DefinedAtom::typeStub;
}
virtual ContentType contentType() const { return DefinedAtom::typeStub; }
virtual Alignment alignment() const {
return Alignment(0, 0);
}
virtual Alignment alignment() const { return Alignment(0, 0); }
virtual SectionChoice sectionChoice() const {
return DefinedAtom::sectionBasedOnContent;
}
virtual StringRef customSectionName() const {
return StringRef();
}
virtual SectionPosition sectionPosition() const {
return sectionPositionAny;
}
virtual StringRef customSectionName() const { return StringRef(); }
virtual SectionPosition sectionPosition() const { return sectionPositionAny; }
virtual DeadStripKind deadStrip() const {
return DefinedAtom::deadStripNormal;
}
virtual ContentPermissions permissions() const {
virtual ContentPermissions permissions() const {
return DefinedAtom::permR_X;
}
virtual bool isAlias() const {
return false;
}
virtual bool isAlias() const { return false; }
virtual ArrayRef<uint8_t> rawContent() const {
return ArrayRef<uint8_t>();
}
virtual ArrayRef<uint8_t> rawContent() const { return ArrayRef<uint8_t>(); }
virtual reference_iterator begin() const {
return reference_iterator(*this, nullptr);
@@ -104,8 +77,7 @@ public:
return nullptr;
}
virtual void incrementIterator(const void *&iter) const {
}
virtual void incrementIterator(const void *&iter) const {}
private:
const File &_file;
@@ -115,74 +87,48 @@ private:
/// \brief Simple atom created by the GOT pass.
class TestingGOTAtom : public DefinedAtom {
public:
TestingGOTAtom(const File &F, const Atom&) : _file(F) {
TestingGOTAtom(const File &F, const Atom &) : _file(F) {
static uint32_t lastOrdinal = 0;
_ordinal = lastOrdinal++;
}
virtual const File &file() const {
return _file;
}
virtual const File &file() const { return _file; }
virtual StringRef name() const {
return StringRef();
}
virtual StringRef name() const { return StringRef(); }
virtual uint64_t ordinal() const {
return _ordinal;
}
virtual uint64_t ordinal() const { return _ordinal; }
virtual uint64_t size() const {
return 0;
}
virtual uint64_t size() const { return 0; }
virtual Scope scope() const {
return DefinedAtom::scopeLinkageUnit;
}
virtual Scope scope() const { return DefinedAtom::scopeLinkageUnit; }
virtual Interposable interposable() const {
return DefinedAtom::interposeNo;
}
virtual Interposable interposable() const { return DefinedAtom::interposeNo; }
virtual Merge merge() const {
return DefinedAtom::mergeNo;
}
virtual Merge merge() const { return DefinedAtom::mergeNo; }
virtual ContentType contentType() const {
return DefinedAtom::typeGOT;
}
virtual ContentType contentType() const { return DefinedAtom::typeGOT; }
virtual Alignment alignment() const {
return Alignment(3, 0);
}
virtual Alignment alignment() const { return Alignment(3, 0); }
virtual SectionChoice sectionChoice() const {
return DefinedAtom::sectionBasedOnContent;
}
virtual StringRef customSectionName() const {
return StringRef();
}
virtual StringRef customSectionName() const { return StringRef(); }
virtual SectionPosition sectionPosition() const {
return sectionPositionAny;
}
virtual SectionPosition sectionPosition() const { return sectionPositionAny; }
virtual DeadStripKind deadStrip() const {
return DefinedAtom::deadStripNormal;
}
virtual ContentPermissions permissions() const {
virtual ContentPermissions permissions() const {
return DefinedAtom::permRW_;
}
virtual bool isAlias() const {
return false;
}
virtual bool isAlias() const { return false; }
virtual ArrayRef<uint8_t> rawContent() const {
return ArrayRef<uint8_t>();
}
virtual ArrayRef<uint8_t> rawContent() const { return ArrayRef<uint8_t>(); }
virtual reference_iterator begin() const {
return reference_iterator(*this, nullptr);
@@ -196,8 +142,7 @@ public:
return nullptr;
}
virtual void incrementIterator(const void *&iter) const {
}
virtual void incrementIterator(const void *&iter) const {}
private:
const File &_file;
@@ -206,7 +151,7 @@ private:
class TestingPassFile : public MutableFile {
public:
TestingPassFile(const TargetInfo &ti) : MutableFile(ti, "Testing pass") {}
TestingPassFile(const LinkingContext &ti) : MutableFile(ti, "Testing pass") {}
virtual void addAtom(const Atom &atom) {
if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom))
@@ -216,10 +161,10 @@ public:
}
virtual DefinedAtomRange definedAtoms() {
return range<std::vector<const DefinedAtom*>::iterator>(
_definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
return range<std::vector<const DefinedAtom *>::iterator>(
_definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
}
virtual const atom_collection<DefinedAtom> &defined() const {
return _definedAtoms;
}
@@ -234,43 +179,37 @@ public:
}
private:
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
};
struct TestingKindMapping {
const char *string;
int32_t value;
bool isBranch;
bool isGotLoad;
bool isGotUse;
const char *string;
int32_t value;
bool isBranch;
bool isGotLoad;
bool isGotUse;
};
//
// Table of fixup kinds in YAML documents used for testing
//
const TestingKindMapping sKinds[] = {
{"in-group", -3, false, false, false},
{"layout-after", -2, false, false, false},
{"layout-before", -1, false, false, false},
{"call32", 2, true, false, false},
{"pcrel32", 3, false, false, false},
{"gotLoad32", 7, false, true, true},
{"gotUse32", 9, false, false, true},
{"lea32wasGot", 8, false, false, false},
{nullptr, 0, false, false, false}
};
{ "in-group", -3, false, false, false },
{ "layout-after", -2, false, false, false },
{ "layout-before", -1, false, false, false },
{ "call32", 2, true, false, false }, { "pcrel32", 3, false, false, false },
{ "gotLoad32", 7, false, true, true }, { "gotUse32", 9, false, false, true },
{ "lea32wasGot", 8, false, false, false }, { nullptr, 0, false, false, false }
};
class TestingStubsPass : public StubsPass {
public:
TestingStubsPass(const TargetInfo &ti) : _file(TestingPassFile(ti))
{}
TestingStubsPass(const LinkingContext &ti) : _file(TestingPassFile(ti)) {}
virtual bool noTextRelocs() {
return true;
}
virtual bool noTextRelocs() { return true; }
virtual bool isCallSite(int32_t kind) {
for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
@@ -287,7 +226,7 @@ public:
}
virtual void addStubAtoms(MutableFile &mergedFile) {
for (const DefinedAtom *stub : _file.defined() ) {
for (const DefinedAtom *stub : _file.defined()) {
mergedFile.addAtom(*stub);
}
}
@@ -298,12 +237,9 @@ private:
class TestingGOTPass : public GOTPass {
public:
TestingGOTPass(const TargetInfo &ti) : _file(TestingPassFile(ti))
{}
TestingGOTPass(const LinkingContext &ti) : _file(TestingPassFile(ti)) {}
virtual bool noTextRelocs() {
return true;
}
virtual bool noTextRelocs() { return true; }
virtual bool isGOTAccess(int32_t kind, bool &canBypassGOT) {
for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
@@ -317,9 +253,9 @@ public:
virtual void updateReferenceToGOT(const Reference *ref, bool targetIsNowGOT) {
if (targetIsNowGOT)
const_cast<Reference*>(ref)->setKind(3); // pcrel32
const_cast<Reference *>(ref)->setKind(3); // pcrel32
else
const_cast<Reference*>(ref)->setKind(8); // lea32wasGot
const_cast<Reference *>(ref)->setKind(8); // lea32wasGot
}
virtual const DefinedAtom *makeGOTEntry(const Atom &target) {
@@ -332,43 +268,41 @@ private:
} // anonymous namespace
CoreLinkingContext::CoreLinkingContext() {}
CoreTargetInfo::CoreTargetInfo() {
}
bool CoreTargetInfo::validateImpl(raw_ostream &diagnostics) {
bool CoreLinkingContext::validateImpl(raw_ostream &diagnostics) {
return false;
}
void CoreTargetInfo::addPasses(PassManager &pm) const {
void CoreLinkingContext::addPasses(PassManager &pm) const {
for (StringRef name : _passNames) {
if ( name.equals("layout") )
if (name.equals("layout"))
pm.add(std::unique_ptr<Pass>((new LayoutPass())));
else if ( name.equals("GOT") )
else if (name.equals("GOT"))
pm.add(std::unique_ptr<Pass>(new TestingGOTPass(*this)));
else if ( name.equals("stubs") )
else if (name.equals("stubs"))
pm.add(std::unique_ptr<Pass>(new TestingStubsPass(*this)));
else
llvm_unreachable("bad pass name");
}
}
error_code CoreTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
error_code CoreLinkingContext::parseFile(
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
if (!_reader)
_reader = createReaderYAML(*this);
return _reader->parseFile(mb,result);
return _reader->parseFile(mb, result);
}
Writer &CoreTargetInfo::writer() const {
Writer &CoreLinkingContext::writer() const {
if (!_writer)
_writer = createWriterYAML(*this);
return *_writer;
}
ErrorOr<Reference::Kind>
CoreTargetInfo::relocKindFromString(StringRef str) const {
ErrorOr<Reference::Kind>
CoreLinkingContext::relocKindFromString(StringRef str) const {
for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
if (str.equals(p->string))
return p->value;
@@ -376,14 +310,11 @@ CoreTargetInfo::relocKindFromString(StringRef str) const {
return make_error_code(yaml_reader_error::illegal_value);
}
ErrorOr<std::string>
CoreTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
ErrorOr<std::string>
CoreLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
if (kind == p->value)
return std::string(p->string);
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -211,7 +211,7 @@ public:
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
if (!_targetAtomHandler) {
const ELFTargetInfo &eti = (_owningFile.getTargetInfo());
const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}
@@ -250,7 +250,7 @@ public:
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
if (!_targetAtomHandler) {
const ELFTargetInfo &eti = (_owningFile.getTargetInfo());
const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}
@@ -277,7 +277,7 @@ public:
((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
_symbol->st_shndx < llvm::ELF::SHN_HIPROC))) {
if (!_targetAtomHandler) {
const ELFTargetInfo &eti = (_owningFile.getTargetInfo());
const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}
@@ -341,7 +341,7 @@ public:
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
if (!_targetAtomHandler) {
const ELFTargetInfo &eti = (_owningFile.getTargetInfo());
const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}
@@ -391,7 +391,7 @@ public:
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
if (!_targetAtomHandler) {
const ELFTargetInfo &eti = (_owningFile.getTargetInfo());
const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}

View File

@@ -1,5 +1,5 @@
add_lld_library(lldELF
ELFTargetInfo.cpp
ELFLinkingContext.cpp
Reader.cpp
Writer.cpp
)
@@ -7,10 +7,10 @@ add_lld_library(lldELF
target_link_libraries(lldELF
lldHexagonELFTarget
lldPPCELFTarget
lldReaderWriter
lldX86_64ELFTarget
lldX86ELFTarget
lldPasses
lldReaderWriter
lldX86ELFTarget
lldX86_64ELFTarget
)
include_directories(.)

View File

@@ -22,7 +22,7 @@
#include "llvm/Support/FileOutputBuffer.h"
namespace lld {
class ELFTargetInfo;
class ELFLinkingContext;
namespace elf {
class ELFWriter;
@@ -51,9 +51,9 @@ public:
CT_Tls,
};
Chunk(StringRef name, Kind kind, const ELFTargetInfo &ti)
Chunk(StringRef name, Kind kind, const ELFLinkingContext &context)
: _name(name), _kind(kind), _fsize(0), _msize(0), _align2(0), _order(0),
_ordinal(1), _start(0), _fileoffset(0), _targetInfo(ti) {}
_ordinal(1), _start(0), _fileoffset(0), _context(context) {}
virtual ~Chunk() {}
// Does the chunk occupy disk space
virtual bool occupiesNoDiskSpace() const { return false; }
@@ -98,7 +98,7 @@ protected:
uint64_t _ordinal;
uint64_t _start;
uint64_t _fileoffset;
const ELFTargetInfo &_targetInfo;
const ELFLinkingContext &_context;
};
} // end namespace elf

View File

@@ -154,7 +154,7 @@ public:
typedef typename std::vector<lld::AtomLayout *>::iterator AbsoluteAtomIterT;
DefaultLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
DefaultLayout(const ELFLinkingContext &context) : _context(context) {}
/// \brief Return the section order for a input section
virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType,
@@ -261,7 +261,7 @@ public:
RelocationTable<ELFT> *getDynamicRelocationTable() {
if (!_dynamicRelocationTable) {
_dynamicRelocationTable.reset(new (_allocator) RelocationTable<ELFT>(
_targetInfo, ".rela.dyn", ORDER_DYNAMIC_RELOCS));
_context, ".rela.dyn", ORDER_DYNAMIC_RELOCS));
addSection(_dynamicRelocationTable.get());
}
return _dynamicRelocationTable.get();
@@ -271,7 +271,7 @@ public:
RelocationTable<ELFT> *getPLTRelocationTable() {
if (!_pltRelocationTable) {
_pltRelocationTable.reset(new (_allocator) RelocationTable<ELFT>(
_targetInfo, ".rela.plt", ORDER_DYNAMIC_PLT_RELOCS));
_context, ".rela.plt", ORDER_DYNAMIC_PLT_RELOCS));
addSection(_pltRelocationTable.get());
}
return _pltRelocationTable.get();
@@ -305,7 +305,7 @@ private:
LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _dynamicRelocationTable;
LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _pltRelocationTable;
std::vector<lld::AtomLayout *> _absoluteAtoms;
const ELFTargetInfo &_targetInfo;
const ELFLinkingContext &_context;
};
template <class ELFT>
@@ -473,8 +473,8 @@ template <class ELFT>
AtomSection<ELFT> *DefaultLayout<ELFT>::createSection(
StringRef sectionName, int32_t contentType,
DefinedAtom::ContentPermissions permissions, SectionOrder sectionOrder) {
return new (_allocator) AtomSection<ELFT>(
_targetInfo, sectionName, contentType, permissions, sectionOrder);
return new (_allocator) AtomSection<ELFT>(_context, sectionName, contentType,
permissions, sectionOrder);
}
template <class ELFT>
@@ -513,9 +513,9 @@ ErrorOr<const lld::AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom)
getSection(sectionName, contentType, permissions);
// Add runtime relocations to the .rela section.
for (const auto &reloc : *definedAtom)
if (_targetInfo.isDynamicRelocation(*definedAtom, *reloc))
if (_context.isDynamicRelocation(*definedAtom, *reloc))
getDynamicRelocationTable()->addRelocation(*definedAtom, *reloc);
else if (_targetInfo.isPLTRelocation(*definedAtom, *reloc))
else if (_context.isPLTRelocation(*definedAtom, *reloc))
getPLTRelocationTable()->addRelocation(*definedAtom, *reloc);
return section->appendAtom(atom);
} else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) {
@@ -555,7 +555,7 @@ DefaultLayout<ELFT>::mergeSimiliarSections() {
template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
ScopedTask task(getDefaultDomain(), "assignSectionsToSegments");
ELFTargetInfo::OutputMagic outputMagic = _targetInfo.getOutputMagic();
ELFLinkingContext::OutputMagic outputMagic = _context.getOutputMagic();
// TODO: Do we want to give a chance for the targetHandlers
// to sort segments in an arbitrary order ?
// sort the sections by their order as defined by the layout
@@ -609,8 +609,8 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
if (!additionalSegmentInsert.second) {
segment = additionalSegmentInsert.first->second;
} else {
segment = new (_allocator)
Segment<ELFT>(_targetInfo, segmentName, segmentType);
segment = new (_allocator) Segment<ELFT>(_context, segmentName,
segmentType);
additionalSegmentInsert.first->second = segment;
_segments.push_back(segment);
}
@@ -620,8 +620,8 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
// If the output magic is set to OutputMagic::NMAGIC or
// OutputMagic::OMAGIC, Place the data alongside text in one single
// segment
if (outputMagic == ELFTargetInfo::OutputMagic::NMAGIC ||
outputMagic == ELFTargetInfo::OutputMagic::OMAGIC)
if (outputMagic == ELFLinkingContext::OutputMagic::NMAGIC ||
outputMagic == ELFLinkingContext::OutputMagic::OMAGIC)
lookupSectionFlag = llvm::ELF::SHF_EXECINSTR | llvm::ELF::SHF_ALLOC |
llvm::ELF::SHF_WRITE;
@@ -634,8 +634,8 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
if (!segmentInsert.second) {
segment = segmentInsert.first->second;
} else {
segment = new (_allocator)
Segment<ELFT>(_targetInfo, "PT_LOAD", llvm::ELF::PT_LOAD);
segment = new (_allocator) Segment<ELFT>(_context, "PT_LOAD",
llvm::ELF::PT_LOAD);
segmentInsert.first->second = segment;
_segments.push_back(segment);
}
@@ -643,9 +643,9 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
}
}
}
if (_targetInfo.isDynamic()) {
if (_context.isDynamic()) {
Segment<ELFT> *segment =
new (_allocator) ProgramHeaderSegment<ELFT>(_targetInfo);
new (_allocator) ProgramHeaderSegment<ELFT>(_context);
_segments.push_back(segment);
segment->append(_header);
segment->append(_programHeader);
@@ -676,8 +676,8 @@ DefaultLayout<ELFT>::assignVirtualAddress() {
if (_segments.empty())
return;
uint64_t virtualAddress = _targetInfo.getBaseAddress();
ELFTargetInfo::OutputMagic outputMagic = _targetInfo.getOutputMagic();
uint64_t virtualAddress = _context.getBaseAddress();
ELFLinkingContext::OutputMagic outputMagic = _context.getOutputMagic();
// HACK: This is a super dirty hack. The elf header and program header are
// not part of a section, but we need them to be loaded at the base address
@@ -710,10 +710,10 @@ DefaultLayout<ELFT>::assignVirtualAddress() {
continue;
// Align the segment to a page boundary only if the output mode is
// not OutputMagic::NMAGIC/OutputMagic::OMAGIC
if (outputMagic != ELFTargetInfo::OutputMagic::NMAGIC &&
outputMagic != ELFTargetInfo::OutputMagic::OMAGIC)
if (outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)
fileoffset =
llvm::RoundUpToAlignment(fileoffset, _targetInfo.getPageSize());
llvm::RoundUpToAlignment(fileoffset, _context.getPageSize());
si->assignOffsets(fileoffset);
fileoffset = si->fileOffset() + si->fileSize();
}
@@ -728,10 +728,10 @@ DefaultLayout<ELFT>::assignVirtualAddress() {
// first segment to the pagesize
(*si)->assignVirtualAddress(address);
(*si)->setMemSize(address - virtualAddress);
if (outputMagic != ELFTargetInfo::OutputMagic::NMAGIC &&
outputMagic != ELFTargetInfo::OutputMagic::OMAGIC)
if (outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)
virtualAddress =
llvm::RoundUpToAlignment(address, _targetInfo.getPageSize());
llvm::RoundUpToAlignment(address, _context.getPageSize());
}
_programHeader->resetProgramHeaders();
}

View File

@@ -13,7 +13,7 @@
#include "DefaultLayout.h"
#include "TargetHandler.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ELF.h"
@@ -23,9 +23,8 @@ namespace elf {
template <class ELFT>
class DefaultTargetHandler : public TargetHandler<ELFT> {
public:
DefaultTargetHandler(ELFTargetInfo &targetInfo)
: TargetHandler<ELFT>(targetInfo) {
}
DefaultTargetHandler(ELFLinkingContext &context)
: TargetHandler<ELFT>(context) {}
bool doesOverrideHeader() { return false; }

View File

@@ -13,7 +13,7 @@
#include "Atoms.h"
#include "lld/Core/SharedLibraryFile.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Path.h"
@@ -24,8 +24,8 @@ namespace lld {
namespace elf {
template <class ELFT> class DynamicFile LLVM_FINAL : public SharedLibraryFile {
public:
static ErrorOr<std::unique_ptr<DynamicFile> > create(
const ELFTargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb) {
static ErrorOr<std::unique_ptr<DynamicFile> >
create(const ELFLinkingContext &ti, std::unique_ptr<llvm::MemoryBuffer> mb) {
std::unique_ptr<DynamicFile> file(
new DynamicFile(ti, mb->getBufferIdentifier()));
llvm::OwningPtr<llvm::object::Binary> binaryFile;
@@ -110,15 +110,17 @@ public:
*this, name, _soname, sym->second._symbol);
}
virtual const ELFTargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const ELFLinkingContext &getLinkingContext() const {
return _context;
}
private:
DynamicFile(const ELFTargetInfo &ti, StringRef name)
: SharedLibraryFile(name), _targetInfo(ti) {}
DynamicFile(const ELFLinkingContext &context, StringRef name)
: SharedLibraryFile(name), _context(context) {}
mutable llvm::BumpPtrAllocator _alloc;
const ELFTargetInfo &_targetInfo;
std::unique_ptr<llvm::object::ELFObjectFile<ELFT>> _objFile;
const ELFLinkingContext &_context;
std::unique_ptr<llvm::object::ELFObjectFile<ELFT> > _objFile;
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;

View File

@@ -25,8 +25,8 @@ class DynamicLibraryWriter;
template<class ELFT>
class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
public:
DynamicLibraryWriter(const ELFTargetInfo &ti):OutputELFWriter<ELFT>(ti)
{}
DynamicLibraryWriter(const ELFLinkingContext &context)
: OutputELFWriter<ELFT>(context) {}
private:
void buildDynamicSymbolTable(const File &file);

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/ELF/ELFTargetInfo.cpp -----------------------------===//
//===- lib/ReaderWriter/ELF/ELFLinkingContext.cpp -------------------------===//
//
// The LLVM Linker
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "TargetHandler.h"
#include "Targets.h"
@@ -22,34 +22,28 @@
#include "llvm/Support/Path.h"
namespace lld {
ELFTargetInfo::ELFTargetInfo(llvm::Triple triple,
std::unique_ptr<TargetHandlerBase> targetHandler)
: _outputFileType(elf::ET_EXEC),
_triple(triple),
_targetHandler(std::move(targetHandler)),
_baseAddress(0),
_isStaticExecutable(false),
_outputYAML(false),
_noInhibitExec(false),
_mergeCommonStrings(false),
_runLayoutPass(true),
_useShlibUndefines(false),
_dynamicLinkerArg(false),
ELFLinkingContext::ELFLinkingContext(
llvm::Triple triple, std::unique_ptr<TargetHandlerBase> targetHandler)
: _outputFileType(elf::ET_EXEC), _triple(triple),
_targetHandler(std::move(targetHandler)), _baseAddress(0),
_isStaticExecutable(false), _outputYAML(false), _noInhibitExec(false),
_mergeCommonStrings(false), _runLayoutPass(true),
_useShlibUndefines(false), _dynamicLinkerArg(false),
_outputMagic(OutputMagic::DEFAULT) {}
bool ELFTargetInfo::is64Bits() const { return getTriple().isArch64Bit(); }
bool ELFLinkingContext::is64Bits() const { return getTriple().isArch64Bit(); }
bool ELFTargetInfo::isLittleEndian() const {
bool ELFLinkingContext::isLittleEndian() const {
// TODO: Do this properly. It is not defined purely by arch.
return true;
}
void ELFTargetInfo::addPasses(PassManager &pm) const {
void ELFLinkingContext::addPasses(PassManager &pm) const {
if (_runLayoutPass)
pm.add(std::unique_ptr<Pass>(new LayoutPass()));
}
uint16_t ELFTargetInfo::getOutputMachine() const {
uint16_t ELFLinkingContext::getOutputMachine() const {
switch (getTriple().getArch()) {
case llvm::Triple::x86:
return llvm::ELF::EM_386;
@@ -64,9 +58,8 @@ uint16_t ELFTargetInfo::getOutputMachine() const {
}
}
bool ELFTargetInfo::validateImpl(raw_ostream &diagnostics) {
if (_outputFileType == elf::ET_EXEC &&
_entrySymbolName.empty()) {
bool ELFLinkingContext::validateImpl(raw_ostream &diagnostics) {
if (_outputFileType == elf::ET_EXEC && _entrySymbolName.empty()) {
_entrySymbolName = "_start";
}
@@ -81,7 +74,7 @@ bool ELFTargetInfo::validateImpl(raw_ostream &diagnostics) {
return false;
}
bool ELFTargetInfo::isDynamic() const {
bool ELFLinkingContext::isDynamic() const {
switch (_outputFileType) {
case llvm::ELF::ET_EXEC:
return !_isStaticExecutable;
@@ -91,11 +84,13 @@ bool ELFTargetInfo::isDynamic() const {
return false;
}
bool ELFTargetInfo::isRelativeReloc(const Reference &) const { return false; }
bool ELFLinkingContext::isRelativeReloc(const Reference &) const {
return false;
}
error_code
ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const {
error_code ELFLinkingContext::parseFile(
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
ScopedTask task(getDefaultDomain(), "parseFile");
error_code ec = _elfReader->parseFile(mb, result);
if (!ec)
@@ -113,29 +108,29 @@ ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
return _linkerScriptReader->parseFile(mb, result);
}
Writer &ELFTargetInfo::writer() const {
return *_writer;
}
Writer &ELFLinkingContext::writer() const { return *_writer; }
std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(llvm::Triple triple) {
std::unique_ptr<ELFLinkingContext>
ELFLinkingContext::create(llvm::Triple triple) {
switch (triple.getArch()) {
case llvm::Triple::x86:
return std::unique_ptr<ELFTargetInfo>(new lld::elf::X86TargetInfo(triple));
return std::unique_ptr<ELFLinkingContext>(
new lld::elf::X86LinkingContext(triple));
case llvm::Triple::x86_64:
return std::unique_ptr<
ELFTargetInfo>(new lld::elf::X86_64TargetInfo(triple));
return std::unique_ptr<ELFLinkingContext>(
new lld::elf::X86_64LinkingContext(triple));
case llvm::Triple::hexagon:
return std::unique_ptr<
ELFTargetInfo>(new lld::elf::HexagonTargetInfo(triple));
return std::unique_ptr<ELFLinkingContext>(
new lld::elf::HexagonLinkingContext(triple));
case llvm::Triple::ppc:
return std::unique_ptr<ELFTargetInfo>(new lld::elf::PPCTargetInfo(triple));
return std::unique_ptr<ELFLinkingContext>(
new lld::elf::PPCLinkingContext(triple));
default:
return nullptr;
}
}
bool ELFTargetInfo::appendLibrary(StringRef libName) {
bool ELFLinkingContext::appendLibrary(StringRef libName) {
bool foundFile = false;
StringRef pathref;
for (StringRef dir : _inputSearchPaths) {

View File

@@ -29,8 +29,8 @@ namespace elf {
template <class ELFT> class CRuntimeFile : public ELFFile<ELFT> {
public:
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
CRuntimeFile(const ELFTargetInfo &ti, StringRef name = "C runtime")
: ELFFile<ELFT>(ti, name) {}
CRuntimeFile(const ELFLinkingContext &context, StringRef name = "C runtime")
: ELFFile<ELFT>(context, name) {}
/// \brief add a global absolute atom
virtual void addAbsoluteAtom(StringRef symbolName) {

View File

@@ -25,9 +25,8 @@ class ExecutableWriter;
template<class ELFT>
class ExecutableWriter : public OutputELFWriter<ELFT> {
public:
ExecutableWriter(const ELFTargetInfo &ti)
: OutputELFWriter<ELFT>(ti), _runtimeFile(ti)
{}
ExecutableWriter(const ELFLinkingContext &context)
: OutputELFWriter<ELFT>(context), _runtimeFile(context) {}
private:
virtual void addDefaultAtoms();
@@ -46,7 +45,7 @@ private:
/// absolute symbols
template<class ELFT>
void ExecutableWriter<ELFT>::addDefaultAtoms() {
_runtimeFile.addUndefinedAtom(this->_targetInfo.entrySymbolName());
_runtimeFile.addUndefinedAtom(this->_context.entrySymbolName());
_runtimeFile.addAbsoluteAtom("__bss_start");
_runtimeFile.addAbsoluteAtom("__bss_end");
_runtimeFile.addAbsoluteAtom("_end");
@@ -75,10 +74,10 @@ void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
template <class ELFT> void ExecutableWriter<ELFT>::createDefaultSections() {
OutputELFWriter<ELFT>::createDefaultSections();
if (this->_targetInfo.isDynamic()) {
if (this->_context.isDynamic()) {
_interpSection.reset(new (this->_alloc) InterpSection<ELFT>(
this->_targetInfo, ".interp", DefaultLayout<ELFT>::ORDER_INTERP,
this->_targetInfo.getInterpreter()));
this->_context, ".interp", DefaultLayout<ELFT>::ORDER_INTERP,
this->_context.getInterpreter()));
this->_layout->addSection(_interpSection.get());
}
}

View File

@@ -14,7 +14,7 @@
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "lld/ReaderWriter/ReaderArchive.h"
#include "llvm/ADT/ArrayRef.h"
@@ -117,13 +117,13 @@ template <class ELFT> class ELFFile : public File {
typedef typename MergedSectionMapT::iterator MergedSectionMapIterT;
public:
ELFFile(const ELFTargetInfo &ti, StringRef name)
: File(name, kindObject), _elfTargetInfo(ti) {}
ELFFile(const ELFLinkingContext &context, StringRef name)
: File(name, kindObject), _elfLinkingContext(context) {}
ELFFile(const ELFTargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> MB,
llvm::error_code &EC)
: File(MB->getBufferIdentifier(), kindObject), _elfTargetInfo(ti),
_ordinal(0), _doStringsMerge(false) {
ELFFile(const ELFLinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)
: File(MB->getBufferIdentifier(), kindObject),
_elfLinkingContext(context), _ordinal(0), _doStringsMerge(false) {
llvm::OwningPtr<llvm::object::Binary> binaryFile;
EC = createBinary(MB.release(), binaryFile);
if (EC)
@@ -140,7 +140,7 @@ public:
binaryFile.take();
_doStringsMerge = _elfTargetInfo.mergeCommonStrings();
_doStringsMerge = _elfLinkingContext.mergeCommonStrings();
// Read input sections from the input file that need to be converted to
// atoms
@@ -487,7 +487,9 @@ public:
return _absoluteAtoms;
}
virtual const ELFTargetInfo &getTargetInfo() const { return _elfTargetInfo; }
virtual const ELFLinkingContext &getLinkingContext() const {
return _elfLinkingContext;
}
Atom *findAtom(const Elf_Sym *symbol) {
return _symbolToAtomMapping.lookup(symbol);
@@ -552,7 +554,8 @@ private:
void updateReferences() {
/// cached value of target relocation handler
const TargetRelocationHandler<ELFT> &_targetRelocationHandler =
_elfTargetInfo.template getTargetHandler<ELFT>().getRelocationHandler();
_elfLinkingContext.template getTargetHandler<ELFT>()
.getRelocationHandler();
for (auto &ri : _references) {
if (ri->kind() >= lld::Reference::kindTargetLow) {
@@ -667,7 +670,7 @@ private:
// not. Let the TargetHandler to make a decision if that's the case.
if (isTargetSpecificAtom(section, symbol)) {
TargetHandler<ELFT> &targetHandler =
_elfTargetInfo.template getTargetHandler<ELFT>();
_elfLinkingContext.template getTargetHandler<ELFT>();
TargetAtomHandler<ELFT> &targetAtomHandler =
targetHandler.targetAtomHandler();
return targetAtomHandler.getType(symbol) == llvm::ELF::STT_COMMON;
@@ -716,7 +719,7 @@ private:
_relocationReferences;
std::vector<ELFReference<ELFT> *> _references;
llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
const ELFTargetInfo &_elfTargetInfo;
const ELFLinkingContext &_elfLinkingContext;
/// \brief Atoms that are created for a section that has the merge property
/// set

View File

@@ -29,7 +29,7 @@ class Header : public Chunk<ELFT> {
public:
typedef llvm::object::Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
Header(const ELFTargetInfo &);
Header(const ELFLinkingContext &);
void e_ident(int I, unsigned char C) { _eh.e_ident[I] = C; }
void e_type(uint16_t type) { _eh.e_type = type; }
@@ -66,8 +66,8 @@ private:
};
template <class ELFT>
Header<ELFT>::Header(const ELFTargetInfo &ti)
: Chunk<ELFT>("elfhdr", Chunk<ELFT>::K_Header, ti) {
Header<ELFT>::Header(const ELFLinkingContext &context)
: Chunk<ELFT>("elfhdr", Chunk<ELFT>::K_Header, context) {
this->_align2 = ELFT::Is64Bits ? 8 : 4;
this->_fsize = sizeof(Elf_Ehdr);
this->_msize = sizeof(Elf_Ehdr);
@@ -117,8 +117,8 @@ public:
uint64_t _flagsClear;
};
ProgramHeader(const ELFTargetInfo &ti)
: Chunk<ELFT>("elfphdr", Chunk<ELFT>::K_ProgramHeader, ti) {
ProgramHeader(const ELFLinkingContext &context)
: Chunk<ELFT>("elfphdr", Chunk<ELFT>::K_ProgramHeader, context) {
this->_align2 = ELFT::Is64Bits ? 8 : 4;
resetProgramHeaders();
}
@@ -193,7 +193,7 @@ private:
template <class ELFT>
bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) {
bool allocatedNew = false;
ELFTargetInfo::OutputMagic outputMagic = this->_targetInfo.getOutputMagic();
ELFLinkingContext::OutputMagic outputMagic = this->_context.getOutputMagic();
// For segments that are not a loadable segment, we
// just pick the values directly from the segment as there
// wouldnt be any slices within that
@@ -222,8 +222,8 @@ bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) {
phdr->p_filesz = slice->fileSize();
phdr->p_memsz = slice->memSize();
phdr->p_flags = segment->flags();
if (outputMagic != ELFTargetInfo::OutputMagic::NMAGIC &&
outputMagic != ELFTargetInfo::OutputMagic::OMAGIC)
if (outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)
phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ? segment->pageSize()
: slice->align2();
else
@@ -253,7 +253,7 @@ class SectionHeader : public Chunk<ELFT> {
public:
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
SectionHeader(const ELFTargetInfo &, int32_t order);
SectionHeader(const ELFLinkingContext &, int32_t order);
void appendSection(MergedSections<ELFT> *section);
@@ -294,8 +294,9 @@ private:
};
template <class ELFT>
SectionHeader<ELFT>::SectionHeader(const ELFTargetInfo &ti, int32_t order)
: Chunk<ELFT>("shdr", Chunk<ELFT>::K_SectionHeader, ti) {
SectionHeader<ELFT>::SectionHeader(const ELFLinkingContext &context,
int32_t order)
: Chunk<ELFT>("shdr", Chunk<ELFT>::K_SectionHeader, context) {
this->_fsize = 0;
this->_align2 = 8;
this->setOrder(order);

View File

@@ -1,7 +1,7 @@
add_lld_library(lldHexagonELFTarget
HexagonTargetHandler.cpp
HexagonTargetInfo.cpp
HexagonLinkingContext.cpp
HexagonRelocationHandler.cpp
HexagonTargetHandler.cpp
)
target_link_libraries(lldHexagonELFTarget

View File

@@ -15,15 +15,13 @@
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
class HexagonTargetInfo;
class HexagonLinkingContext;
template <class HexagonELFType> class HexagonRuntimeFile
: public CRuntimeFile<HexagonELFType> {
public:
HexagonRuntimeFile(const HexagonTargetInfo &hti)
:CRuntimeFile<HexagonELFType>(hti, "Hexagon runtime file")
{}
HexagonRuntimeFile(const HexagonLinkingContext &context)
: CRuntimeFile<HexagonELFType>(context, "Hexagon runtime file") {}
};
} // elf
} // lld

View File

@@ -0,0 +1,170 @@
//===- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp -------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "HexagonLinkingContext.h"
#include "lld/Core/File.h"
#include "lld/Core/Pass.h"
#include "lld/Core/PassManager.h"
#include "lld/ReaderWriter/Simple.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringSwitch.h"
using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind>
elf::HexagonLinkingContext::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_HEX_NONE)
LLD_CASE(R_HEX_B22_PCREL) LLD_CASE(R_HEX_B15_PCREL)
LLD_CASE(R_HEX_B7_PCREL) LLD_CASE(R_HEX_LO16) LLD_CASE(R_HEX_HI16)
LLD_CASE(R_HEX_32) LLD_CASE(R_HEX_16) LLD_CASE(R_HEX_8)
LLD_CASE(R_HEX_GPREL16_0) LLD_CASE(R_HEX_GPREL16_1)
LLD_CASE(R_HEX_GPREL16_2) LLD_CASE(R_HEX_GPREL16_3) LLD_CASE(R_HEX_HL16)
LLD_CASE(R_HEX_B13_PCREL) LLD_CASE(R_HEX_B9_PCREL)
LLD_CASE(R_HEX_B32_PCREL_X) LLD_CASE(R_HEX_32_6_X)
LLD_CASE(R_HEX_B22_PCREL_X) LLD_CASE(R_HEX_B15_PCREL_X)
LLD_CASE(R_HEX_B13_PCREL_X) LLD_CASE(R_HEX_B9_PCREL_X)
LLD_CASE(R_HEX_B7_PCREL_X) LLD_CASE(R_HEX_16_X) LLD_CASE(R_HEX_12_X)
LLD_CASE(R_HEX_11_X) LLD_CASE(R_HEX_10_X) LLD_CASE(R_HEX_9_X)
LLD_CASE(R_HEX_8_X) LLD_CASE(R_HEX_7_X) LLD_CASE(R_HEX_6_X)
LLD_CASE(R_HEX_32_PCREL) LLD_CASE(R_HEX_COPY) LLD_CASE(R_HEX_GLOB_DAT)
LLD_CASE(R_HEX_JMP_SLOT) LLD_CASE(R_HEX_RELATIVE)
LLD_CASE(R_HEX_PLT_B22_PCREL) LLD_CASE(R_HEX_GOTREL_LO16)
LLD_CASE(R_HEX_GOTREL_HI16) LLD_CASE(R_HEX_GOTREL_32)
LLD_CASE(R_HEX_GOT_LO16) LLD_CASE(R_HEX_GOT_HI16) LLD_CASE(R_HEX_GOT_32)
LLD_CASE(R_HEX_GOT_16) LLD_CASE(R_HEX_DTPMOD_32)
LLD_CASE(R_HEX_DTPREL_LO16) LLD_CASE(R_HEX_DTPREL_HI16)
LLD_CASE(R_HEX_DTPREL_32) LLD_CASE(R_HEX_DTPREL_16)
LLD_CASE(R_HEX_GD_PLT_B22_PCREL) LLD_CASE(R_HEX_GD_GOT_LO16)
LLD_CASE(R_HEX_GD_GOT_HI16) LLD_CASE(R_HEX_GD_GOT_32)
LLD_CASE(R_HEX_GD_GOT_16) LLD_CASE(R_HEX_IE_LO16) LLD_CASE(R_HEX_IE_HI16)
LLD_CASE(R_HEX_IE_32) LLD_CASE(R_HEX_IE_GOT_LO16)
LLD_CASE(R_HEX_IE_GOT_HI16) LLD_CASE(R_HEX_IE_GOT_32)
LLD_CASE(R_HEX_IE_GOT_16) LLD_CASE(R_HEX_TPREL_LO16)
LLD_CASE(R_HEX_TPREL_HI16) LLD_CASE(R_HEX_TPREL_32)
LLD_CASE(R_HEX_TPREL_16) LLD_CASE(R_HEX_6_PCREL_X)
LLD_CASE(R_HEX_GOTREL_32_6_X) LLD_CASE(R_HEX_GOTREL_16_X)
LLD_CASE(R_HEX_GOTREL_11_X) LLD_CASE(R_HEX_GOT_32_6_X)
LLD_CASE(R_HEX_GOT_16_X) LLD_CASE(R_HEX_GOT_11_X)
LLD_CASE(R_HEX_DTPREL_32_6_X) LLD_CASE(R_HEX_DTPREL_16_X)
LLD_CASE(R_HEX_DTPREL_11_X) LLD_CASE(R_HEX_GD_GOT_32_6_X)
LLD_CASE(R_HEX_GD_GOT_16_X) LLD_CASE(R_HEX_GD_GOT_11_X)
LLD_CASE(R_HEX_IE_32_6_X) LLD_CASE(R_HEX_IE_16_X)
LLD_CASE(R_HEX_IE_GOT_32_6_X) LLD_CASE(R_HEX_IE_GOT_16_X)
LLD_CASE(R_HEX_IE_GOT_11_X) LLD_CASE(R_HEX_TPREL_32_6_X)
LLD_CASE(R_HEX_TPREL_16_X) LLD_CASE(R_HEX_TPREL_11_X).Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) \
case llvm::ELF::name: \
return std::string(#name);
ErrorOr<std::string>
elf::HexagonLinkingContext::stringFromRelocKind(int32_t kind) const {
switch (kind) {
LLD_CASE(R_HEX_NONE)
LLD_CASE(R_HEX_B22_PCREL)
LLD_CASE(R_HEX_B15_PCREL)
LLD_CASE(R_HEX_B7_PCREL)
LLD_CASE(R_HEX_LO16)
LLD_CASE(R_HEX_HI16)
LLD_CASE(R_HEX_32)
LLD_CASE(R_HEX_16)
LLD_CASE(R_HEX_8)
LLD_CASE(R_HEX_GPREL16_0)
LLD_CASE(R_HEX_GPREL16_1)
LLD_CASE(R_HEX_GPREL16_2)
LLD_CASE(R_HEX_GPREL16_3)
LLD_CASE(R_HEX_HL16)
LLD_CASE(R_HEX_B13_PCREL)
LLD_CASE(R_HEX_B9_PCREL)
LLD_CASE(R_HEX_B32_PCREL_X)
LLD_CASE(R_HEX_32_6_X)
LLD_CASE(R_HEX_B22_PCREL_X)
LLD_CASE(R_HEX_B15_PCREL_X)
LLD_CASE(R_HEX_B13_PCREL_X)
LLD_CASE(R_HEX_B9_PCREL_X)
LLD_CASE(R_HEX_B7_PCREL_X)
LLD_CASE(R_HEX_16_X)
LLD_CASE(R_HEX_12_X)
LLD_CASE(R_HEX_11_X)
LLD_CASE(R_HEX_10_X)
LLD_CASE(R_HEX_9_X)
LLD_CASE(R_HEX_8_X)
LLD_CASE(R_HEX_7_X)
LLD_CASE(R_HEX_6_X)
LLD_CASE(R_HEX_32_PCREL)
LLD_CASE(R_HEX_COPY)
LLD_CASE(R_HEX_GLOB_DAT)
LLD_CASE(R_HEX_JMP_SLOT)
LLD_CASE(R_HEX_RELATIVE)
LLD_CASE(R_HEX_PLT_B22_PCREL)
LLD_CASE(R_HEX_GOTREL_LO16)
LLD_CASE(R_HEX_GOTREL_HI16)
LLD_CASE(R_HEX_GOTREL_32)
LLD_CASE(R_HEX_GOT_LO16)
LLD_CASE(R_HEX_GOT_HI16)
LLD_CASE(R_HEX_GOT_32)
LLD_CASE(R_HEX_GOT_16)
LLD_CASE(R_HEX_DTPMOD_32)
LLD_CASE(R_HEX_DTPREL_LO16)
LLD_CASE(R_HEX_DTPREL_HI16)
LLD_CASE(R_HEX_DTPREL_32)
LLD_CASE(R_HEX_DTPREL_16)
LLD_CASE(R_HEX_GD_PLT_B22_PCREL)
LLD_CASE(R_HEX_GD_GOT_LO16)
LLD_CASE(R_HEX_GD_GOT_HI16)
LLD_CASE(R_HEX_GD_GOT_32)
LLD_CASE(R_HEX_GD_GOT_16)
LLD_CASE(R_HEX_IE_LO16)
LLD_CASE(R_HEX_IE_HI16)
LLD_CASE(R_HEX_IE_32)
LLD_CASE(R_HEX_IE_GOT_LO16)
LLD_CASE(R_HEX_IE_GOT_HI16)
LLD_CASE(R_HEX_IE_GOT_32)
LLD_CASE(R_HEX_IE_GOT_16)
LLD_CASE(R_HEX_TPREL_LO16)
LLD_CASE(R_HEX_TPREL_HI16)
LLD_CASE(R_HEX_TPREL_32)
LLD_CASE(R_HEX_TPREL_16)
LLD_CASE(R_HEX_6_PCREL_X)
LLD_CASE(R_HEX_GOTREL_32_6_X)
LLD_CASE(R_HEX_GOTREL_16_X)
LLD_CASE(R_HEX_GOTREL_11_X)
LLD_CASE(R_HEX_GOT_32_6_X)
LLD_CASE(R_HEX_GOT_16_X)
LLD_CASE(R_HEX_GOT_11_X)
LLD_CASE(R_HEX_DTPREL_32_6_X)
LLD_CASE(R_HEX_DTPREL_16_X)
LLD_CASE(R_HEX_DTPREL_11_X)
LLD_CASE(R_HEX_GD_GOT_32_6_X)
LLD_CASE(R_HEX_GD_GOT_16_X)
LLD_CASE(R_HEX_GD_GOT_11_X)
LLD_CASE(R_HEX_IE_32_6_X)
LLD_CASE(R_HEX_IE_16_X)
LLD_CASE(R_HEX_IE_GOT_32_6_X)
LLD_CASE(R_HEX_IE_GOT_16_X)
LLD_CASE(R_HEX_IE_GOT_11_X)
LLD_CASE(R_HEX_TPREL_32_6_X)
LLD_CASE(R_HEX_TPREL_16_X)
LLD_CASE(R_HEX_TPREL_11_X)
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h -------------------===//
//===- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h ---------------===//
//
// The LLVM Linker
//
@@ -12,7 +12,7 @@
#include "HexagonTargetHandler.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/ELF.h"
@@ -20,11 +20,11 @@
namespace lld {
namespace elf {
class HexagonTargetInfo LLVM_FINAL : public ELFTargetInfo {
class HexagonLinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
HexagonTargetInfo(llvm::Triple triple)
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(
new HexagonTargetHandler(*this))) {}
HexagonLinkingContext(llvm::Triple triple)
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new HexagonTargetHandler(*this))) {}
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
@@ -33,7 +33,7 @@ public:
virtual bool isDynamicRelocation(const DefinedAtom &,
const Reference &r) const {
switch (r.kind()){
switch (r.kind()) {
case llvm::ELF::R_HEX_RELATIVE:
case llvm::ELF::R_HEX_GLOB_DAT:
return true;
@@ -42,9 +42,8 @@ public:
}
}
virtual bool isPLTRelocation(const DefinedAtom &,
const Reference &r) const {
switch (r.kind()){
virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const {
switch (r.kind()) {
case llvm::ELF::R_HEX_JMP_SLOT:
return true;
default:

View File

@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "HexagonTargetHandler.h"
#include "HexagonTargetInfo.h"
#include "HexagonLinkingContext.h"
#include "HexagonRelocationHandler.h"
#include "HexagonRelocationFunctions.h"
@@ -343,9 +343,9 @@ ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
default : {
std::string str;
llvm::raw_string_ostream s(str);
auto name = _targetInfo.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: "
<< (name ? *name : "<unknown>" ) << " (" << ref.kind() << ")";
auto name = _context.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: " << (name ? *name : "<unknown>") << " ("
<< ref.kind() << ")";
s.flush();
llvm_unreachable(str.c_str());
}

View File

@@ -17,7 +17,7 @@ namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
class HexagonTargetInfo;
class HexagonLinkingContext;
class HexagonTargetHandler;
template <class HexagonELFType> class HexagonTargetLayout;
@@ -25,15 +25,15 @@ class HexagonTargetRelocationHandler LLVM_FINAL :
public TargetRelocationHandler<HexagonELFType> {
public:
HexagonTargetRelocationHandler(
const HexagonTargetInfo &ti, const HexagonTargetHandler &tH,
const HexagonLinkingContext &context, const HexagonTargetHandler &tH,
const HexagonTargetLayout<HexagonELFType> &layout)
: _targetInfo(ti), _targetHandler(tH), _targetLayout(layout) {}
: _context(context), _targetHandler(tH), _targetLayout(layout) {}
virtual ErrorOr<void>
applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &, const Reference &) const;
private:
const HexagonTargetInfo &_targetInfo;
const HexagonLinkingContext &_context;
const HexagonTargetHandler &_targetHandler;
const HexagonTargetLayout<HexagonELFType> &_targetLayout;
};

View File

@@ -15,15 +15,15 @@ namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
template <typename ELFT> class HexagonTargetLayout;
class HexagonTargetInfo;
class HexagonLinkingContext;
/// \brief Handle Hexagon SData section
template <class HexagonELFType>
class SDataSection : public AtomSection<HexagonELFType> {
public:
SDataSection(const HexagonTargetInfo &hti)
SDataSection(const HexagonLinkingContext &context)
: AtomSection<HexagonELFType>(
hti, ".sdata", DefinedAtom::typeDataFast, 0,
context, ".sdata", DefinedAtom::typeDataFast, 0,
HexagonTargetLayout<HexagonELFType>::ORDER_SDATA) {
this->_type = SHT_PROGBITS;
this->_flags = SHF_ALLOC | SHF_WRITE;

View File

@@ -7,4 +7,4 @@
//
//===----------------------------------------------------------------------===//
#include "HexagonTargetInfo.h"
#include "HexagonLinkingContext.h"

View File

@@ -8,17 +8,17 @@
//===----------------------------------------------------------------------===//
#include "HexagonTargetHandler.h"
#include "HexagonTargetInfo.h"
#include "HexagonLinkingContext.h"
using namespace lld;
using namespace elf;
using namespace llvm::ELF;
HexagonTargetHandler::HexagonTargetHandler(HexagonTargetInfo &targetInfo)
: DefaultTargetHandler(targetInfo), _targetLayout(targetInfo),
_relocationHandler(targetInfo, *this, _targetLayout),
_hexagonRuntimeFile(targetInfo) {}
HexagonTargetHandler::HexagonTargetHandler(HexagonLinkingContext &context)
: DefaultTargetHandler(context), _targetLayout(context),
_relocationHandler(context, *this, _targetLayout),
_hexagonRuntimeFile(context) {}
namespace {
@@ -107,7 +107,7 @@ public:
class ELFPassFile : public SimpleFile {
public:
ELFPassFile(const ELFTargetInfo &eti) : SimpleFile(eti, "ELFPassFile") {}
ELFPassFile(const ELFLinkingContext &eti) : SimpleFile(eti, "ELFPassFile") {}
llvm::BumpPtrAllocator _alloc;
};
@@ -144,7 +144,7 @@ protected:
}
public:
GOTPLTPass(const ELFTargetInfo &ti)
GOTPLTPass(const ELFLinkingContext &ti)
: _file(ti), _null(nullptr), _PLT0(nullptr), _got0(nullptr) {}
/// \brief Do the pass.
@@ -212,7 +212,7 @@ protected:
class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> {
public:
DynamicGOTPLTPass(const elf::HexagonTargetInfo &ti) : GOTPLTPass(ti) {
DynamicGOTPLTPass(const elf::HexagonLinkingContext &ti) : GOTPLTPass(ti) {
_got0 = new (_file._alloc) HexagonGOTPLT0Atom(_file);
#ifndef NDEBUG
_got0->_name = "__got0";
@@ -291,8 +291,8 @@ public:
};
} // end anonymous namespace
void elf::HexagonTargetInfo::addPasses(PassManager &pm) const {
void elf::HexagonLinkingContext::addPasses(PassManager &pm) const {
if (isDynamic())
pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
ELFTargetInfo::addPasses(pm);
ELFLinkingContext::addPasses(pm);
}

View File

@@ -19,8 +19,7 @@
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
class HexagonTargetInfo;
class HexagonLinkingContext;
/// \brief Handle Hexagon specific Atoms
template <class HexagonELFType>
@@ -85,7 +84,7 @@ public:
ORDER_SDATA = 205
};
HexagonTargetLayout(const HexagonTargetInfo &hti)
HexagonTargetLayout(const HexagonLinkingContext &hti)
: TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr) {
_sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti);
}
@@ -145,7 +144,7 @@ private:
class HexagonTargetHandler LLVM_FINAL :
public DefaultTargetHandler<HexagonELFType> {
public:
HexagonTargetHandler(HexagonTargetInfo &targetInfo);
HexagonTargetHandler(HexagonLinkingContext &targetInfo);
bool doesOverrideHeader() { return true; }
@@ -170,7 +169,7 @@ public:
void addDefaultAtoms() {
_hexagonRuntimeFile.addAbsoluteAtom("_SDA_BASE_");
if (_targetInfo.isDynamic()) {
if (_context.isDynamic()) {
_hexagonRuntimeFile.addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
_hexagonRuntimeFile.addAbsoluteAtom("_DYNAMIC");
}
@@ -185,7 +184,7 @@ public:
auto sdabaseAtomIter = _targetLayout.findAbsoluteAtom("_SDA_BASE_");
(*sdabaseAtomIter)->_virtualAddr =
_targetLayout.getSDataSection()->virtualAddr();
if (_targetInfo.isDynamic()) {
if (_context.isDynamic()) {
auto gotAtomIter =
_targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
_gotSymAtom = (*gotAtomIter);

View File

@@ -1,218 +0,0 @@
//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp -----------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "HexagonTargetInfo.h"
#include "lld/Core/File.h"
#include "lld/Core/Pass.h"
#include "lld/Core/PassManager.h"
#include "lld/ReaderWriter/Simple.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringSwitch.h"
using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind>
elf::HexagonTargetInfo::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str)
LLD_CASE(R_HEX_NONE)
LLD_CASE(R_HEX_B22_PCREL)
LLD_CASE(R_HEX_B15_PCREL)
LLD_CASE(R_HEX_B7_PCREL)
LLD_CASE(R_HEX_LO16)
LLD_CASE(R_HEX_HI16)
LLD_CASE(R_HEX_32)
LLD_CASE(R_HEX_16)
LLD_CASE(R_HEX_8)
LLD_CASE(R_HEX_GPREL16_0)
LLD_CASE(R_HEX_GPREL16_1)
LLD_CASE(R_HEX_GPREL16_2)
LLD_CASE(R_HEX_GPREL16_3)
LLD_CASE(R_HEX_HL16)
LLD_CASE(R_HEX_B13_PCREL)
LLD_CASE(R_HEX_B9_PCREL)
LLD_CASE(R_HEX_B32_PCREL_X)
LLD_CASE(R_HEX_32_6_X)
LLD_CASE(R_HEX_B22_PCREL_X)
LLD_CASE(R_HEX_B15_PCREL_X)
LLD_CASE(R_HEX_B13_PCREL_X)
LLD_CASE(R_HEX_B9_PCREL_X)
LLD_CASE(R_HEX_B7_PCREL_X)
LLD_CASE(R_HEX_16_X)
LLD_CASE(R_HEX_12_X)
LLD_CASE(R_HEX_11_X)
LLD_CASE(R_HEX_10_X)
LLD_CASE(R_HEX_9_X)
LLD_CASE(R_HEX_8_X)
LLD_CASE(R_HEX_7_X)
LLD_CASE(R_HEX_6_X)
LLD_CASE(R_HEX_32_PCREL)
LLD_CASE(R_HEX_COPY)
LLD_CASE(R_HEX_GLOB_DAT)
LLD_CASE(R_HEX_JMP_SLOT)
LLD_CASE(R_HEX_RELATIVE)
LLD_CASE(R_HEX_PLT_B22_PCREL)
LLD_CASE(R_HEX_GOTREL_LO16)
LLD_CASE(R_HEX_GOTREL_HI16)
LLD_CASE(R_HEX_GOTREL_32)
LLD_CASE(R_HEX_GOT_LO16)
LLD_CASE(R_HEX_GOT_HI16)
LLD_CASE(R_HEX_GOT_32)
LLD_CASE(R_HEX_GOT_16)
LLD_CASE(R_HEX_DTPMOD_32)
LLD_CASE(R_HEX_DTPREL_LO16)
LLD_CASE(R_HEX_DTPREL_HI16)
LLD_CASE(R_HEX_DTPREL_32)
LLD_CASE(R_HEX_DTPREL_16)
LLD_CASE(R_HEX_GD_PLT_B22_PCREL)
LLD_CASE(R_HEX_GD_GOT_LO16)
LLD_CASE(R_HEX_GD_GOT_HI16)
LLD_CASE(R_HEX_GD_GOT_32)
LLD_CASE(R_HEX_GD_GOT_16)
LLD_CASE(R_HEX_IE_LO16)
LLD_CASE(R_HEX_IE_HI16)
LLD_CASE(R_HEX_IE_32)
LLD_CASE(R_HEX_IE_GOT_LO16)
LLD_CASE(R_HEX_IE_GOT_HI16)
LLD_CASE(R_HEX_IE_GOT_32)
LLD_CASE(R_HEX_IE_GOT_16)
LLD_CASE(R_HEX_TPREL_LO16)
LLD_CASE(R_HEX_TPREL_HI16)
LLD_CASE(R_HEX_TPREL_32)
LLD_CASE(R_HEX_TPREL_16)
LLD_CASE(R_HEX_6_PCREL_X)
LLD_CASE(R_HEX_GOTREL_32_6_X)
LLD_CASE(R_HEX_GOTREL_16_X)
LLD_CASE(R_HEX_GOTREL_11_X)
LLD_CASE(R_HEX_GOT_32_6_X)
LLD_CASE(R_HEX_GOT_16_X)
LLD_CASE(R_HEX_GOT_11_X)
LLD_CASE(R_HEX_DTPREL_32_6_X)
LLD_CASE(R_HEX_DTPREL_16_X)
LLD_CASE(R_HEX_DTPREL_11_X)
LLD_CASE(R_HEX_GD_GOT_32_6_X)
LLD_CASE(R_HEX_GD_GOT_16_X)
LLD_CASE(R_HEX_GD_GOT_11_X)
LLD_CASE(R_HEX_IE_32_6_X)
LLD_CASE(R_HEX_IE_16_X)
LLD_CASE(R_HEX_IE_GOT_32_6_X)
LLD_CASE(R_HEX_IE_GOT_16_X)
LLD_CASE(R_HEX_IE_GOT_11_X)
LLD_CASE(R_HEX_TPREL_32_6_X)
LLD_CASE(R_HEX_TPREL_16_X)
LLD_CASE(R_HEX_TPREL_11_X)
.Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
ErrorOr<std::string> elf::HexagonTargetInfo::stringFromRelocKind(
int32_t kind) const {
switch (kind) {
LLD_CASE(R_HEX_NONE)
LLD_CASE(R_HEX_B22_PCREL)
LLD_CASE(R_HEX_B15_PCREL)
LLD_CASE(R_HEX_B7_PCREL)
LLD_CASE(R_HEX_LO16)
LLD_CASE(R_HEX_HI16)
LLD_CASE(R_HEX_32)
LLD_CASE(R_HEX_16)
LLD_CASE(R_HEX_8)
LLD_CASE(R_HEX_GPREL16_0)
LLD_CASE(R_HEX_GPREL16_1)
LLD_CASE(R_HEX_GPREL16_2)
LLD_CASE(R_HEX_GPREL16_3)
LLD_CASE(R_HEX_HL16)
LLD_CASE(R_HEX_B13_PCREL)
LLD_CASE(R_HEX_B9_PCREL)
LLD_CASE(R_HEX_B32_PCREL_X)
LLD_CASE(R_HEX_32_6_X)
LLD_CASE(R_HEX_B22_PCREL_X)
LLD_CASE(R_HEX_B15_PCREL_X)
LLD_CASE(R_HEX_B13_PCREL_X)
LLD_CASE(R_HEX_B9_PCREL_X)
LLD_CASE(R_HEX_B7_PCREL_X)
LLD_CASE(R_HEX_16_X)
LLD_CASE(R_HEX_12_X)
LLD_CASE(R_HEX_11_X)
LLD_CASE(R_HEX_10_X)
LLD_CASE(R_HEX_9_X)
LLD_CASE(R_HEX_8_X)
LLD_CASE(R_HEX_7_X)
LLD_CASE(R_HEX_6_X)
LLD_CASE(R_HEX_32_PCREL)
LLD_CASE(R_HEX_COPY)
LLD_CASE(R_HEX_GLOB_DAT)
LLD_CASE(R_HEX_JMP_SLOT)
LLD_CASE(R_HEX_RELATIVE)
LLD_CASE(R_HEX_PLT_B22_PCREL)
LLD_CASE(R_HEX_GOTREL_LO16)
LLD_CASE(R_HEX_GOTREL_HI16)
LLD_CASE(R_HEX_GOTREL_32)
LLD_CASE(R_HEX_GOT_LO16)
LLD_CASE(R_HEX_GOT_HI16)
LLD_CASE(R_HEX_GOT_32)
LLD_CASE(R_HEX_GOT_16)
LLD_CASE(R_HEX_DTPMOD_32)
LLD_CASE(R_HEX_DTPREL_LO16)
LLD_CASE(R_HEX_DTPREL_HI16)
LLD_CASE(R_HEX_DTPREL_32)
LLD_CASE(R_HEX_DTPREL_16)
LLD_CASE(R_HEX_GD_PLT_B22_PCREL)
LLD_CASE(R_HEX_GD_GOT_LO16)
LLD_CASE(R_HEX_GD_GOT_HI16)
LLD_CASE(R_HEX_GD_GOT_32)
LLD_CASE(R_HEX_GD_GOT_16)
LLD_CASE(R_HEX_IE_LO16)
LLD_CASE(R_HEX_IE_HI16)
LLD_CASE(R_HEX_IE_32)
LLD_CASE(R_HEX_IE_GOT_LO16)
LLD_CASE(R_HEX_IE_GOT_HI16)
LLD_CASE(R_HEX_IE_GOT_32)
LLD_CASE(R_HEX_IE_GOT_16)
LLD_CASE(R_HEX_TPREL_LO16)
LLD_CASE(R_HEX_TPREL_HI16)
LLD_CASE(R_HEX_TPREL_32)
LLD_CASE(R_HEX_TPREL_16)
LLD_CASE(R_HEX_6_PCREL_X)
LLD_CASE(R_HEX_GOTREL_32_6_X)
LLD_CASE(R_HEX_GOTREL_16_X)
LLD_CASE(R_HEX_GOTREL_11_X)
LLD_CASE(R_HEX_GOT_32_6_X)
LLD_CASE(R_HEX_GOT_16_X)
LLD_CASE(R_HEX_GOT_11_X)
LLD_CASE(R_HEX_DTPREL_32_6_X)
LLD_CASE(R_HEX_DTPREL_16_X)
LLD_CASE(R_HEX_DTPREL_11_X)
LLD_CASE(R_HEX_GD_GOT_32_6_X)
LLD_CASE(R_HEX_GD_GOT_16_X)
LLD_CASE(R_HEX_GD_GOT_11_X)
LLD_CASE(R_HEX_IE_32_6_X)
LLD_CASE(R_HEX_IE_16_X)
LLD_CASE(R_HEX_IE_GOT_32_6_X)
LLD_CASE(R_HEX_IE_GOT_16_X)
LLD_CASE(R_HEX_IE_GOT_11_X)
LLD_CASE(R_HEX_TPREL_32_6_X)
LLD_CASE(R_HEX_TPREL_16_X)
LLD_CASE(R_HEX_TPREL_11_X)
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -11,7 +11,7 @@
#include "lld/Core/Instrumentation.h"
#include "lld/Core/Parallel.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/StringSet.h"
@@ -33,8 +33,8 @@ class OutputELFWriter;
/// as -u, or --defsym option.
template <class ELFT> class LinkerInternalFile : public CRuntimeFile<ELFT> {
public:
LinkerInternalFile(const ELFTargetInfo &ti)
: CRuntimeFile<ELFT>(ti, "Linker Internal File") {};
LinkerInternalFile(const ELFLinkingContext &context)
: CRuntimeFile<ELFT>(context, "Linker Internal File") {};
};
//===----------------------------------------------------------------------===//
@@ -51,7 +51,7 @@ public:
typedef Elf_Sym_Impl<ELFT> Elf_Sym;
typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
OutputELFWriter(const ELFTargetInfo &ti);
OutputELFWriter(const ELFLinkingContext &context);
protected:
// build the sections that need to be created
@@ -103,7 +103,7 @@ protected:
llvm::BumpPtrAllocator _alloc;
const ELFTargetInfo &_targetInfo;
const ELFLinkingContext &_context;
TargetHandler<ELFT> &_targetHandler;
typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
@@ -130,9 +130,9 @@ protected:
// OutputELFWriter
//===----------------------------------------------------------------------===//
template <class ELFT>
OutputELFWriter<ELFT>::OutputELFWriter(const ELFTargetInfo &ti)
: _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
_linkerInternalFile(ti) {
OutputELFWriter<ELFT>::OutputELFWriter(const ELFLinkingContext &context)
: _context(context), _targetHandler(context.getTargetHandler<ELFT>()),
_linkerInternalFile(context) {
_layout = &_targetHandler.targetLayout();
}
@@ -240,26 +240,26 @@ void OutputELFWriter<ELFT>::addFiles(InputFiles &inputFiles) {
_targetHandler.addFiles(inputFiles);
// Add all symbols that are specified by the -u option
// as part of the command line argument to lld
for (auto ai : _targetInfo.initialUndefinedSymbols())
for (auto ai : _context.initialUndefinedSymbols())
_linkerInternalFile.addUndefinedAtom(ai);
// Make the linker internal file to be the first file
inputFiles.prependFile(_linkerInternalFile);
}
template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
_Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
_programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
_Header.reset(new (_alloc) Header<ELFT>(_context));
_programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_context));
_layout->setHeader(_Header.get());
_layout->setProgramHeader(_programHeader.get());
_symtab.reset(new (_alloc) SymbolTable<ELFT>(
_targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
_context, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
_strtab.reset(new (_alloc) StringTable<ELFT>(
_targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
_context, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
_shstrtab.reset(new (_alloc) StringTable<ELFT>(
_targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
_context, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
_shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
_targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
_context, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
_layout->addSection(_symtab.get());
_layout->addSection(_strtab.get());
_layout->addSection(_shstrtab.get());
@@ -267,16 +267,15 @@ template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
_symtab->setStringSection(_strtab.get());
_layout->addSection(_shdrtab.get());
if (_targetInfo.isDynamic()) {
if (_context.isDynamic()) {
_dynamicTable.reset(new (_alloc) DynamicTable<ELFT>(
_targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
_context, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
_dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
_targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS,
true));
_context, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS, true));
_dynamicSymbolTable.reset(new (_alloc) DynamicSymbolTable<ELFT>(
_targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
_context, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
_hashTable.reset(new (_alloc) HashSection<ELFT>(
_targetInfo, ".hash", DefaultLayout<ELFT>::ORDER_HASH));
_context, ".hash", DefaultLayout<ELFT>::ORDER_HASH));
// Set the hash table in the dynamic symbol table so that the entries in the
// hash table can be created
_dynamicSymbolTable->setHashTable(_hashTable.get());
@@ -313,7 +312,7 @@ error_code OutputELFWriter<ELFT>::buildOutput(const File &file) {
_layout->assignSectionsToSegments();
// Create the dynamic table entries
if (_targetInfo.isDynamic()) {
if (_context.isDynamic()) {
_dynamicTable->createDefaultEntries();
buildDynamicSymbolTable(file);
}
@@ -344,7 +343,7 @@ error_code OutputELFWriter<ELFT>::buildOutput(const File &file) {
// for sections with no segments
assignSectionsWithNoSegments();
if (_targetInfo.isDynamic())
if (_context.isDynamic())
_dynamicTable->updateDynamicTable();
return error_code::success();
@@ -366,12 +365,12 @@ error_code OutputELFWriter<ELFT>::writeFile(const File &file, StringRef path) {
if (ec)
return ec;
_Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
ELF::ELFCLASS32);
_Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
_Header->e_type(_targetInfo.getOutputType());
_Header->e_machine(_targetInfo.getOutputMachine());
_Header->e_ident(ELF::EI_CLASS,
_context.is64Bits() ? ELF::ELFCLASS64 : ELF::ELFCLASS32);
_Header->e_ident(ELF::EI_DATA, _context.isLittleEndian() ? ELF::ELFDATA2LSB
: ELF::ELFDATA2MSB);
_Header->e_type(_context.getOutputType());
_Header->e_machine(_context.getOutputMachine());
if (!_targetHandler.doesOverrideHeader()) {
_Header->e_ident(ELF::EI_VERSION, 1);
@@ -389,7 +388,7 @@ error_code OutputELFWriter<ELFT>::writeFile(const File &file, StringRef path) {
_Header->e_shnum(_shdrtab->numHeaders());
_Header->e_shstrndx(_shstrtab->ordinal());
uint64_t virtualAddr = 0;
_layout->findAtomAddrByName(_targetInfo.entrySymbolName(), virtualAddr);
_layout->findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
_Header->e_entry(virtualAddr);
// HACK: We have to write out the header and program header here even though

View File

@@ -1,6 +1,6 @@
add_lld_library(lldPPCELFTarget
PPCLinkingContext.cpp
PPCTargetHandler.cpp
PPCTargetInfo.cpp
)
target_link_libraries(lldPPCELFTarget

View File

@@ -0,0 +1,36 @@
#include "PPCLinkingContext.h"
#include "lld/Core/LLVM.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorOr.h"
using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind>
elf::PPCLinkingContext::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_PPC_NONE)
LLD_CASE(R_PPC_ADDR32).Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) \
case llvm::ELF::name: \
return std::string(#name);
ErrorOr<std::string>
elf::PPCLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_PPC_NONE)
LLD_CASE(R_PPC_ADDR32)
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/ELF/Hexagon/PPCTargetInfo.h -----------------------===//
//===- lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h -----------------------===//
//
// The LLVM Linker
//
@@ -12,17 +12,18 @@
#include "PPCTargetHandler.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/ELF.h"
namespace lld {
namespace elf {
class PPCTargetInfo LLVM_FINAL : public ELFTargetInfo {
class PPCLinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
PPCTargetInfo(llvm::Triple triple)
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(new PPCTargetHandler(*this))) {}
PPCLinkingContext(llvm::Triple triple)
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new PPCTargetHandler(*this))) {}
virtual bool isLittleEndian() const { return false; }

View File

@@ -7,4 +7,4 @@
//
//===----------------------------------------------------------------------===//
#include "PPCTargetInfo.h"
#include "PPCLinkingContext.h"

View File

@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "PPCTargetHandler.h"
#include "PPCTargetInfo.h"
#include "PPCLinkingContext.h"
using namespace lld;
using namespace elf;
@@ -56,9 +56,9 @@ ErrorOr<void> PPCTargetRelocationHandler::applyRelocation(
default : {
std::string str;
llvm::raw_string_ostream s(str);
auto name = _targetInfo.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: "
<< (name ? *name : "<unknown>" ) << " (" << ref.kind() << ")";
auto name = _context.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: " << (name ? *name : "<unknown>") << " ("
<< ref.kind() << ")";
s.flush();
llvm_unreachable(str.c_str());
}
@@ -67,7 +67,6 @@ ErrorOr<void> PPCTargetRelocationHandler::applyRelocation(
return error_code::success();
}
PPCTargetHandler::PPCTargetHandler(PPCTargetInfo &targetInfo)
PPCTargetHandler::PPCTargetHandler(PPCLinkingContext &targetInfo)
: DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
_targetLayout(targetInfo) {
}
_targetLayout(targetInfo) {}

View File

@@ -16,25 +16,26 @@
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::big, 4, false> PPCELFType;
class PPCTargetInfo;
class PPCLinkingContext;
class PPCTargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<PPCELFType> {
public:
PPCTargetRelocationHandler(const PPCTargetInfo &ti) : _targetInfo(ti) {}
PPCTargetRelocationHandler(const PPCLinkingContext &context)
: _context(context) {}
virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
const Reference &)const;
private:
const PPCTargetInfo &_targetInfo;
const PPCLinkingContext &_context;
};
class PPCTargetHandler LLVM_FINAL
: public DefaultTargetHandler<PPCELFType> {
public:
PPCTargetHandler(PPCTargetInfo &targetInfo);
PPCTargetHandler(PPCLinkingContext &targetInfo);
virtual TargetLayout<PPCELFType> &targetLayout() {
return _targetLayout;

View File

@@ -1,36 +0,0 @@
#include "PPCTargetInfo.h"
#include "lld/Core/LLVM.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorOr.h"
using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind> elf::PPCTargetInfo::relocKindFromString(
StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str)
LLD_CASE(R_PPC_NONE)
LLD_CASE(R_PPC_ADDR32)
.Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
ErrorOr<std::string>
elf::PPCTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_PPC_NONE)
LLD_CASE(R_PPC_ADDR32)
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -21,7 +21,7 @@
#include "File.h"
#include "lld/Core/Reference.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "lld/ReaderWriter/ReaderArchive.h"
#include "llvm/ADT/ArrayRef.h"
@@ -53,7 +53,7 @@ struct DynamicFileCreateELFTraits {
typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
template <class ELFT>
static result_type create(const lld::ELFTargetInfo &ti,
static result_type create(const lld::ELFLinkingContext &ti,
std::unique_ptr<llvm::MemoryBuffer> mb) {
return lld::elf::DynamicFile<ELFT>::create(ti, std::move(mb));
}
@@ -63,7 +63,7 @@ struct ELFFileCreateELFTraits {
typedef std::unique_ptr<lld::File> result_type;
template <class ELFT>
static result_type create(const lld::ELFTargetInfo &ti,
static result_type create(const lld::ELFLinkingContext &ti,
std::unique_ptr<llvm::MemoryBuffer> mb,
lld::error_code &ec) {
return std::unique_ptr<lld::File>(
@@ -78,12 +78,11 @@ namespace elf {
/// memory buffer for ELF class and bit width
class ELFReader : public Reader {
public:
ELFReader(const ELFTargetInfo &ti)
: lld::Reader(ti), _elfTargetInfo(ti), _readerArchive(ti, *this) {
}
ELFReader(const ELFLinkingContext &ti)
: lld::Reader(ti), _elfLinkingContext(ti), _readerArchive(ti, *this) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const {
std::vector<std::unique_ptr<File>> &result) const {
using llvm::object::ELFType;
llvm::sys::fs::file_magic FileType =
llvm::sys::fs::identify_magic(mb->getBuffer());
@@ -95,7 +94,7 @@ public:
switch (FileType) {
case llvm::sys::fs::file_magic::elf_relocatable: {
std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>(
getElfArchType(&*mb), MaxAlignment, _elfTargetInfo, std::move(mb),
getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, std::move(mb),
ec));
if (ec)
return ec;
@@ -105,10 +104,11 @@ public:
case llvm::sys::fs::file_magic::elf_shared_object: {
// If the link doesnot allow dynamic libraries to be present during the
// link, lets not parse the file and just return
if (!_elfTargetInfo.allowLinkWithDynamicLibraries())
if (!_elfLinkingContext.allowLinkWithDynamicLibraries())
return llvm::make_error_code(llvm::errc::executable_format_error);
auto f = createELF<DynamicFileCreateELFTraits>(
getElfArchType(&*mb), MaxAlignment, _elfTargetInfo, std::move(mb));
getElfArchType(&*mb), MaxAlignment, _elfLinkingContext,
std::move(mb));
if (!f)
return f;
result.push_back(std::move(*f));
@@ -129,12 +129,12 @@ public:
}
private:
const ELFTargetInfo &_elfTargetInfo;
const ELFLinkingContext &_elfLinkingContext;
ReaderArchive _readerArchive;
};
} // end namespace elf
std::unique_ptr<Reader> createReaderELF(const ELFTargetInfo &targetinfo) {
return std::unique_ptr<Reader>(new elf::ELFReader(targetinfo));
std::unique_ptr<Reader> createReaderELF(const ELFLinkingContext &context) {
return std::unique_ptr<Reader>(new elf::ELFReader(context));
}
} // end namespace lld

View File

@@ -47,9 +47,9 @@ template <class ELFT> class Segment;
/// \brief An ELF section.
template <class ELFT> class Section : public Chunk<ELFT> {
public:
Section(const ELFTargetInfo &ti, StringRef name,
Section(const ELFLinkingContext &context, StringRef name,
typename Chunk<ELFT>::Kind k = Chunk<ELFT>::K_ELFSection)
: Chunk<ELFT>(name, k, ti), _parent(nullptr), _flags(0), _entSize(0),
: Chunk<ELFT>(name, k, context), _parent(nullptr), _flags(0), _entSize(0),
_type(0), _link(0), _info(0), _segmentType(SHT_NULL) {}
/// \brief Modify the section contents before assigning virtual addresses
@@ -133,9 +133,9 @@ protected:
/// \brief A section containing atoms.
template <class ELFT> class AtomSection : public Section<ELFT> {
public:
AtomSection(const ELFTargetInfo &ti, StringRef name, int32_t contentType,
int32_t permissions, int32_t order)
: Section<ELFT>(ti, name, Chunk<ELFT>::K_AtomSection),
AtomSection(const ELFLinkingContext &context, StringRef name,
int32_t contentType, int32_t permissions, int32_t order)
: Section<ELFT>(context, name, Chunk<ELFT>::K_AtomSection),
_contentType(contentType), _contentPermissions(permissions) {
this->setOrder(order);
switch (contentType) {
@@ -354,7 +354,7 @@ template <class ELFT>
void AtomSection<ELFT>::write(ELFWriter *writer,
llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
parallel_for_each(_atoms.begin(), _atoms.end(), [&] (lld::AtomLayout *ai) {
parallel_for_each(_atoms.begin(), _atoms.end(), [&](lld::AtomLayout * ai) {
DEBUG_WITH_TYPE("Section",
llvm::dbgs() << "Writing atom: " << ai->_atom->name()
<< " | " << ai->_fileOffset << "\n");
@@ -370,8 +370,7 @@ void AtomSection<ELFT>::write(ELFWriter *writer,
uint8_t *atomContent = chunkBuffer + ai->_fileOffset;
std::memcpy(atomContent, content.data(), contentSize);
const TargetRelocationHandler<ELFT> &relHandler =
this->_targetInfo.template getTargetHandler<ELFT>()
.getRelocationHandler();
this->_context.template getTargetHandler<ELFT>().getRelocationHandler();
for (const auto ref : *definedAtom)
relHandler.applyRelocation(*writer, buffer, *ai, *ref);
});
@@ -516,7 +515,7 @@ MergedSections<ELFT>::appendSection(Chunk<ELFT> *c) {
template<class ELFT>
class StringTable : public Section<ELFT> {
public:
StringTable(const ELFTargetInfo &, const char *str, int32_t order,
StringTable(const ELFLinkingContext &, const char *str, int32_t order,
bool dynamic = false);
uint64_t addString(StringRef symname);
@@ -547,9 +546,9 @@ private:
};
template <class ELFT>
StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str,
int32_t order, bool dynamic)
: Section<ELFT>(ti, str) {
StringTable<ELFT>::StringTable(const ELFLinkingContext &context,
const char *str, int32_t order, bool dynamic)
: Section<ELFT>(context, str) {
// the string table has a NULL entry for which
// add an empty string
_strings.push_back("");
@@ -612,7 +611,7 @@ class SymbolTable : public Section<ELFT> {
};
public:
SymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order);
SymbolTable(const ELFLinkingContext &context, const char *str, int32_t order);
/// \brief set the number of entries that would exist in the symbol
/// table for the current link
@@ -671,9 +670,9 @@ protected:
/// ELF Symbol Table
template <class ELFT>
SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str,
int32_t order)
: Section<ELFT>(ti, str) {
SymbolTable<ELFT>::SymbolTable(const ELFLinkingContext &context,
const char *str, int32_t order)
: Section<ELFT>(context, str) {
this->setOrder(order);
Elf_Sym symbol;
std::memset(&symbol, 0, sizeof(Elf_Sym));
@@ -850,8 +849,9 @@ template <class ELFT> class HashSection;
template <class ELFT> class DynamicSymbolTable : public SymbolTable<ELFT> {
public:
DynamicSymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order)
: SymbolTable<ELFT>(ti, str, order), _hashTable(nullptr) {
DynamicSymbolTable(const ELFLinkingContext &context, const char *str,
int32_t order)
: SymbolTable<ELFT>(context, str, order), _hashTable(nullptr) {
this->_type = SHT_DYNSYM;
this->_flags = SHF_ALLOC;
this->_msize = this->_fsize;
@@ -895,8 +895,9 @@ template <class ELFT> class RelocationTable : public Section<ELFT> {
public:
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
RelocationTable(const ELFTargetInfo &ti, StringRef str, int32_t order)
: Section<ELFT>(ti, str), _symbolTable(nullptr) {
RelocationTable(const ELFLinkingContext &context, StringRef str,
int32_t order)
: Section<ELFT>(context, str), _symbolTable(nullptr) {
this->setOrder(order);
this->_entSize = sizeof(Elf_Rela);
this->_align2 = llvm::alignOf<Elf_Rela>();
@@ -949,13 +950,13 @@ public:
writer->addressOfAtom(rel.first) + rel.second->offsetInAtom();
r->r_addend = 0;
// The addend is used only by relative relocations
if (this->_targetInfo.isRelativeReloc(*rel.second))
if (this->_context.isRelativeReloc(*rel.second))
r->r_addend =
writer->addressOfAtom(rel.second->target()) + rel.second->addend();
dest += sizeof(Elf_Rela);
DEBUG_WITH_TYPE(
"ELFRelocationTable",
llvm::dbgs() << kindOrUnknown(this->_targetInfo.stringFromRelocKind(
llvm::dbgs() << kindOrUnknown(this->_context.stringFromRelocKind(
rel.second->kind())) << " relocation at "
<< rel.first->name() << "@" << r->r_offset << " to "
<< rel.second->target()->name() << "@" << r->r_addend
@@ -975,8 +976,8 @@ template <class ELFT> class DynamicTable : public Section<ELFT> {
typedef std::vector<Elf_Dyn> EntriesT;
public:
DynamicTable(const ELFTargetInfo &ti, StringRef str, int32_t order)
: Section<ELFT>(ti, str) {
DynamicTable(const ELFLinkingContext &context, StringRef str, int32_t order)
: Section<ELFT>(context, str) {
this->setOrder(order);
this->_entSize = sizeof(Elf_Dyn);
this->_align2 = llvm::alignOf<Elf_Dyn>();
@@ -985,7 +986,7 @@ public:
this->_msize = sizeof(Elf_Dyn);
this->_type = SHT_DYNAMIC;
this->_flags = SHF_ALLOC;
_layout = &ti.getTargetHandler<ELFT>().targetLayout();
_layout = &context.getTargetHandler<ELFT>().targetLayout();
}
range<typename EntriesT::iterator> entries() { return _entries; }
@@ -1105,10 +1106,9 @@ private:
template <class ELFT> class InterpSection : public Section<ELFT> {
public:
InterpSection(const ELFTargetInfo &ti, StringRef str, int32_t order,
InterpSection(const ELFLinkingContext &context, StringRef str, int32_t order,
StringRef interp)
: Section<ELFT>(ti, str),
_interp(interp){
: Section<ELFT>(context, str), _interp(interp) {
this->setOrder(order);
this->_align2 = 1;
// + 1 for null term.
@@ -1155,14 +1155,14 @@ template <class ELFT> class HashSection : public Section<ELFT> {
};
public:
HashSection(const ELFTargetInfo &ti, StringRef name, int32_t order)
: Section<ELFT>(ti, name), _symbolTable(nullptr) {
HashSection(const ELFLinkingContext &context, StringRef name, int32_t order)
: Section<ELFT>(context, name), _symbolTable(nullptr) {
this->setOrder(order);
this->_entSize = 4;
this->_type = SHT_HASH;
this->_flags = SHF_ALLOC;
// Set the alignment properly depending on the target architecture
if (ti.is64Bits())
if (context.is64Bits())
this->_align2 = 8;
else
this->_align2 = 4;

View File

@@ -111,7 +111,7 @@ public:
typedef typename std::vector<SegmentSlice<ELFT> *>::iterator SliceIter;
typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
Segment(const ELFTargetInfo &ti, StringRef name,
Segment(const ELFLinkingContext &context, StringRef name,
const Layout::SegmentType type);
/// \brief the Order of segments that appear in the output file
@@ -225,7 +225,7 @@ public:
}
}
inline int pageSize() const { return this->_targetInfo.getPageSize(); }
inline int pageSize() const { return this->_context.getPageSize(); }
inline int rawflags() const { return _atomflags; }
@@ -275,13 +275,13 @@ private:
/// \brief Check if the chunk needs to be aligned
bool needAlign(Chunk<ELFT> *chunk) const {
if (chunk->getContentType() == Chunk<ELFT>::CT_Data &&
_outputMagic == ELFTargetInfo::OutputMagic::NMAGIC)
_outputMagic == ELFLinkingContext::OutputMagic::NMAGIC)
return true;
return false;
}
// Cached value of outputMagic
ELFTargetInfo::OutputMagic _outputMagic;
ELFLinkingContext::OutputMagic _outputMagic;
protected:
/// \brief Section or some other chunk type.
@@ -297,8 +297,8 @@ protected:
/// The segment doesnot contain any slice
template <class ELFT> class ProgramHeaderSegment : public Segment<ELFT> {
public:
ProgramHeaderSegment(const ELFTargetInfo &ti)
: Segment<ELFT>(ti, "PHDR", llvm::ELF::PT_PHDR) {
ProgramHeaderSegment(const ELFLinkingContext &context)
: Segment<ELFT>(context, "PHDR", llvm::ELF::PT_PHDR) {
this->_align2 = 8;
this->_flags = (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR);
}
@@ -325,13 +325,13 @@ protected:
};
template <class ELFT>
Segment<ELFT>::Segment(const ELFTargetInfo &ti, StringRef name,
Segment<ELFT>::Segment(const ELFLinkingContext &context, StringRef name,
const Layout::SegmentType type)
: Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment, ti), _segmentType(type),
: Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment, context), _segmentType(type),
_flags(0), _atomflags(0) {
this->_align2 = 0;
this->_fsize = 0;
_outputMagic = ti.getOutputMagic();
_outputMagic = context.getOutputMagic();
}
// This function actually is used, but not in all instantiations of Segment.
@@ -429,8 +429,8 @@ template <class ELFT> void Segment<ELFT>::assignOffsets(uint64_t startOffset) {
// If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
// to a page boundary
if (!isDataPageAlignedForNMagic && needAlign(*si)) {
startOffset = llvm::RoundUpToAlignment(startOffset,
this->_targetInfo.getPageSize());
startOffset =
llvm::RoundUpToAlignment(startOffset, this->_context.getPageSize());
isDataPageAlignedForNMagic = true;
}
// align the startOffset to the section alignment
@@ -447,17 +447,17 @@ template <class ELFT> void Segment<ELFT>::assignOffsets(uint64_t startOffset) {
// If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
// to a page boundary
if (!isDataPageAlignedForNMagic && needAlign(*si)) {
curOffset = llvm::RoundUpToAlignment(curOffset,
this->_targetInfo.getPageSize());
curOffset =
llvm::RoundUpToAlignment(curOffset, this->_context.getPageSize());
isDataPageAlignedForNMagic = true;
}
uint64_t newOffset = llvm::RoundUpToAlignment(curOffset, (*si)->align2());
SegmentSlice<ELFT> *slice = nullptr;
// If the newOffset computed is more than a page away, lets create
// a seperate segment, so that memory is not used up while running
if (((newOffset - curOffset) > this->_targetInfo.getPageSize()) &&
(_outputMagic != ELFTargetInfo::OutputMagic::NMAGIC &&
_outputMagic != ELFTargetInfo::OutputMagic::OMAGIC)) {
if (((newOffset - curOffset) > this->_context.getPageSize()) &&
(_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
_outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
// TODO: use std::find here
for (auto s : slices()) {
@@ -475,8 +475,8 @@ template <class ELFT> void Segment<ELFT>::assignOffsets(uint64_t startOffset) {
slice->setSections(make_range(startSectionIter, endSectionIter));
slice->setSize(curSliceSize);
slice->setAlign(sliceAlign);
uint64_t newPageOffset = llvm::RoundUpToAlignment(
curOffset, this->_targetInfo.getPageSize());
uint64_t newPageOffset =
llvm::RoundUpToAlignment(curOffset, this->_context.getPageSize());
newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2());
curSliceFileOffset = newOffset;
startSectionIter = endSectionIter;
@@ -525,9 +525,9 @@ template <class ELFT> void Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
for (auto slice : slices()) {
// Align to a page only if the output is not
// OutputMagic::NMAGIC/OutputMagic::OMAGIC
if (_outputMagic != ELFTargetInfo::OutputMagic::NMAGIC &&
_outputMagic != ELFTargetInfo::OutputMagic::OMAGIC)
addr = llvm::RoundUpToAlignment(addr, this->_targetInfo.getPageSize());
if (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
_outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)
addr = llvm::RoundUpToAlignment(addr, this->_context.getPageSize());
// Align to the slice alignment
addr = llvm::RoundUpToAlignment(addr, slice->align2());
@@ -537,7 +537,7 @@ template <class ELFT> void Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
// If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
// to a page boundary
if (!isDataPageAlignedForNMagic && needAlign(section)) {
addr = llvm::RoundUpToAlignment(addr, this->_targetInfo.getPageSize());
addr = llvm::RoundUpToAlignment(addr, this->_context.getPageSize());
isDataPageAlignedForNMagic = true;
}
// Align the section address

View File

@@ -20,8 +20,8 @@
#include "lld/Core/InputFiles.h"
#include "lld/Core/LLVM.h"
#include "lld/Core/TargetInfo.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/FileOutputBuffer.h"
@@ -84,7 +84,7 @@ public:
template <class ELFT> class TargetHandler : public TargetHandlerBase {
public:
TargetHandler(ELFTargetInfo &targetInfo) : _targetInfo(targetInfo) {}
TargetHandler(ELFLinkingContext &targetInfo) : _context(targetInfo) {}
/// If the target overrides ELF header information, this API would
/// return true, so that the target can set all fields specific to
@@ -119,7 +119,7 @@ public:
virtual void allocateCommons() = 0;
protected:
const ELFTargetInfo &_targetInfo;
const ELFLinkingContext &_context;
};
} // end namespace elf
} // end namespace lld

View File

@@ -21,8 +21,8 @@ namespace elf {
/// be changed in the final layout
template <class ELFT> class TargetLayout : public DefaultLayout<ELFT> {
public:
TargetLayout(const ELFTargetInfo &targetInfo)
: DefaultLayout<ELFT>(targetInfo) {}
TargetLayout(const ELFLinkingContext &context)
: DefaultLayout<ELFT>(context) {}
};
} // end namespace elf
} // end namespace lld

View File

@@ -17,7 +17,7 @@ using namespace llvm;
using namespace llvm::object;
namespace lld {
std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &info) {
std::unique_ptr<Writer> createWriterELF(const ELFLinkingContext &info) {
using llvm::object::ELFType;
// Set the default layout to be the static executable layout
// We would set the layout to a dynamic executable layout

View File

@@ -1,5 +1,5 @@
add_lld_library(lldX86ELFTarget
X86TargetInfo.cpp
X86LinkingContext.cpp
X86TargetHandler.cpp
)

View File

@@ -0,0 +1,36 @@
#include "X86LinkingContext.h"
#include "lld/Core/LLVM.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorOr.h"
using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind>
elf::X86LinkingContext::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_386_NONE)
LLD_CASE(R_386_PC32).Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) \
case llvm::ELF::name: \
return std::string(#name);
ErrorOr<std::string>
elf::X86LinkingContext::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_386_NONE)
LLD_CASE(R_386_PC32)
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/ELF/X86/X86TargetInfo.h ---------------------------===//
//===- lib/ReaderWriter/ELF/X86/X86LinkingContext.h -----------------------===//
//
// The LLVM Linker
//
@@ -12,18 +12,18 @@
#include "X86TargetHandler.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/ELF.h"
namespace lld {
namespace elf {
class X86TargetInfo LLVM_FINAL : public ELFTargetInfo {
class X86LinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
X86TargetInfo(llvm::Triple triple)
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(
new X86TargetHandler(*this))) {}
X86LinkingContext(llvm::Triple triple)
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new X86TargetHandler(*this))) {}
/// \brief X86 has only two relative relocation
/// a) for supporting IFUNC relocs - R_386_IRELATIVE

View File

@@ -7,4 +7,4 @@
//
//===----------------------------------------------------------------------===//
#include "X86TargetInfo.h"
#include "X86LinkingContext.h"

View File

@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "X86TargetHandler.h"
#include "X86TargetInfo.h"
#include "X86LinkingContext.h"
using namespace lld;
using namespace elf;
@@ -55,9 +55,9 @@ ErrorOr<void> X86TargetRelocationHandler::applyRelocation(
default : {
std::string str;
llvm::raw_string_ostream s(str);
auto name = _targetInfo.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: "
<< (name ? *name : "<unknown>" ) << " (" << ref.kind() << ")";
auto name = _context.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: " << (name ? *name : "<unknown>") << " ("
<< ref.kind() << ")";
s.flush();
llvm_unreachable(str.c_str());
}
@@ -66,7 +66,6 @@ ErrorOr<void> X86TargetRelocationHandler::applyRelocation(
return error_code::success();
}
X86TargetHandler::X86TargetHandler(X86TargetInfo &targetInfo)
X86TargetHandler::X86TargetHandler(X86LinkingContext &targetInfo)
: DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
_targetLayout(targetInfo) {
}
_targetLayout(targetInfo) {}

View File

@@ -16,25 +16,26 @@
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 4, false> X86ELFType;
class X86TargetInfo;
class X86LinkingContext;
class X86TargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<X86ELFType> {
public:
X86TargetRelocationHandler(const X86TargetInfo &ti) : _targetInfo(ti) {}
X86TargetRelocationHandler(const X86LinkingContext &context)
: _context(context) {}
virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
const Reference &)const;
private:
const X86TargetInfo &_targetInfo;
const X86LinkingContext &_context;
};
class X86TargetHandler LLVM_FINAL
: public DefaultTargetHandler<X86ELFType> {
public:
X86TargetHandler(X86TargetInfo &targetInfo);
X86TargetHandler(X86LinkingContext &context);
virtual TargetLayout<X86ELFType> &targetLayout() {
return _targetLayout;

View File

@@ -1,36 +0,0 @@
#include "X86TargetInfo.h"
#include "lld/Core/LLVM.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorOr.h"
using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind> elf::X86TargetInfo::relocKindFromString(
StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str)
LLD_CASE(R_386_NONE)
LLD_CASE(R_386_PC32)
.Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
ErrorOr<std::string>
elf::X86TargetInfo::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_386_NONE)
LLD_CASE(R_386_PC32)
}
return make_error_code(yaml_reader_error::illegal_value);
}

View File

@@ -1,5 +1,5 @@
add_lld_library(lldX86_64ELFTarget
X86_64TargetInfo.cpp
X86_64LinkingContext.cpp
X86_64TargetHandler.cpp
X86_64RelocationHandler.cpp
)

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp -------------------===//
//===- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp ---------------===//
//
// The LLVM Linker
//
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "Atoms.h"
#include "X86_64TargetInfo.h"
#include "X86_64LinkingContext.h"
#include "lld/Core/File.h"
#include "lld/Core/Instrumentation.h"
@@ -77,7 +77,7 @@ public:
class ELFPassFile : public SimpleFile {
public:
ELFPassFile(const ELFTargetInfo &eti) : SimpleFile(eti, "ELFPassFile") {}
ELFPassFile(const ELFLinkingContext &eti) : SimpleFile(eti, "ELFPassFile") {}
llvm::BumpPtrAllocator _alloc;
};
@@ -201,7 +201,7 @@ protected:
}
public:
GOTPLTPass(const ELFTargetInfo &ti)
GOTPLTPass(const ELFLinkingContext &ti)
: _file(ti), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
_got1(nullptr) {}
@@ -280,7 +280,7 @@ protected:
/// TLS always assumes module 1 and attempts to remove indirection.
class StaticGOTPLTPass LLVM_FINAL : public GOTPLTPass<StaticGOTPLTPass> {
public:
StaticGOTPLTPass(const elf::X86_64TargetInfo &ti) : GOTPLTPass(ti) {}
StaticGOTPLTPass(const elf::X86_64LinkingContext &ti) : GOTPLTPass(ti) {}
ErrorOr<void> handlePLT32(const Reference &ref) {
// __tls_get_addr is handled elsewhere.
@@ -291,7 +291,8 @@ public:
// Static code doesn't need PLTs.
const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
// Handle IFUNC.
if (const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target()))
if (const DefinedAtom *da =
dyn_cast_or_null<const DefinedAtom>(ref.target()))
if (da->contentType() == DefinedAtom::typeResolver)
return handleIFUNC(ref);
return error_code::success();
@@ -302,7 +303,7 @@ public:
class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> {
public:
DynamicGOTPLTPass(const elf::X86_64TargetInfo &ti) : GOTPLTPass(ti) {}
DynamicGOTPLTPass(const elf::X86_64LinkingContext &ti) : GOTPLTPass(ti) {}
const PLT0Atom *getPLT0() {
if (_PLT0)
@@ -351,7 +352,8 @@ public:
// Turn this into a PC32 to the PLT entry.
const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
// Handle IFUNC.
if (const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target()))
if (const DefinedAtom *da =
dyn_cast_or_null<const DefinedAtom>(ref.target()))
if (da->contentType() == DefinedAtom::typeResolver)
return handleIFUNC(ref);
if (isa<const SharedLibraryAtom>(ref.target()))
@@ -393,7 +395,7 @@ public:
};
} // end anon namespace
void elf::X86_64TargetInfo::addPasses(PassManager &pm) const {
void elf::X86_64LinkingContext::addPasses(PassManager &pm) const {
switch (_outputFileType) {
case llvm::ELF::ET_EXEC:
if (_isStaticExecutable)
@@ -409,15 +411,48 @@ void elf::X86_64TargetInfo::addPasses(PassManager &pm) const {
default:
llvm_unreachable("Unhandled output file type");
}
ELFTargetInfo::addPasses(pm);
ELFLinkingContext::addPasses(pm);
}
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
ErrorOr<Reference::Kind>
elf::X86_64TargetInfo::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str)
elf::X86_64LinkingContext::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_X86_64_NONE)
LLD_CASE(R_X86_64_64) LLD_CASE(R_X86_64_PC32) LLD_CASE(R_X86_64_GOT32)
LLD_CASE(R_X86_64_PLT32) LLD_CASE(R_X86_64_COPY)
LLD_CASE(R_X86_64_GLOB_DAT) LLD_CASE(R_X86_64_JUMP_SLOT)
LLD_CASE(R_X86_64_RELATIVE) LLD_CASE(R_X86_64_GOTPCREL)
LLD_CASE(R_X86_64_32) LLD_CASE(R_X86_64_32S) LLD_CASE(R_X86_64_16)
LLD_CASE(R_X86_64_PC16) LLD_CASE(R_X86_64_8) LLD_CASE(R_X86_64_PC8)
LLD_CASE(R_X86_64_DTPMOD64) LLD_CASE(R_X86_64_DTPOFF64)
LLD_CASE(R_X86_64_TPOFF64) LLD_CASE(R_X86_64_TLSGD)
LLD_CASE(R_X86_64_TLSLD) LLD_CASE(R_X86_64_DTPOFF32)
LLD_CASE(R_X86_64_GOTTPOFF) LLD_CASE(R_X86_64_TPOFF32)
LLD_CASE(R_X86_64_PC64) LLD_CASE(R_X86_64_GOTOFF64)
LLD_CASE(R_X86_64_GOTPC32) LLD_CASE(R_X86_64_GOT64)
LLD_CASE(R_X86_64_GOTPCREL64) LLD_CASE(R_X86_64_GOTPC64)
LLD_CASE(R_X86_64_GOTPLT64) LLD_CASE(R_X86_64_PLTOFF64)
LLD_CASE(R_X86_64_SIZE32) LLD_CASE(R_X86_64_SIZE64)
LLD_CASE(R_X86_64_GOTPC32_TLSDESC) LLD_CASE(R_X86_64_TLSDESC_CALL)
LLD_CASE(R_X86_64_TLSDESC) LLD_CASE(R_X86_64_IRELATIVE)
.Case("LLD_R_X86_64_GOTRELINDEX", LLD_R_X86_64_GOTRELINDEX)
.Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) \
case llvm::ELF::name: \
return std::string(#name);
ErrorOr<std::string>
elf::X86_64LinkingContext::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_X86_64_NONE)
LLD_CASE(R_X86_64_64)
LLD_CASE(R_X86_64_PC32)
@@ -456,59 +491,6 @@ elf::X86_64TargetInfo::relocKindFromString(StringRef str) const {
LLD_CASE(R_X86_64_TLSDESC_CALL)
LLD_CASE(R_X86_64_TLSDESC)
LLD_CASE(R_X86_64_IRELATIVE)
.Case("LLD_R_X86_64_GOTRELINDEX", LLD_R_X86_64_GOTRELINDEX)
.Default(-1);
if (ret == -1)
return make_error_code(yaml_reader_error::illegal_value);
return ret;
}
#undef LLD_CASE
#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
ErrorOr<std::string>
elf::X86_64TargetInfo::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_X86_64_NONE)
LLD_CASE(R_X86_64_64)
LLD_CASE(R_X86_64_PC32)
LLD_CASE(R_X86_64_GOT32)
LLD_CASE(R_X86_64_PLT32)
LLD_CASE(R_X86_64_COPY)
LLD_CASE(R_X86_64_GLOB_DAT)
LLD_CASE(R_X86_64_JUMP_SLOT)
LLD_CASE(R_X86_64_RELATIVE)
LLD_CASE(R_X86_64_GOTPCREL)
LLD_CASE(R_X86_64_32)
LLD_CASE(R_X86_64_32S)
LLD_CASE(R_X86_64_16)
LLD_CASE(R_X86_64_PC16)
LLD_CASE(R_X86_64_8)
LLD_CASE(R_X86_64_PC8)
LLD_CASE(R_X86_64_DTPMOD64)
LLD_CASE(R_X86_64_DTPOFF64)
LLD_CASE(R_X86_64_TPOFF64)
LLD_CASE(R_X86_64_TLSGD)
LLD_CASE(R_X86_64_TLSLD)
LLD_CASE(R_X86_64_DTPOFF32)
LLD_CASE(R_X86_64_GOTTPOFF)
LLD_CASE(R_X86_64_TPOFF32)
LLD_CASE(R_X86_64_PC64)
LLD_CASE(R_X86_64_GOTOFF64)
LLD_CASE(R_X86_64_GOTPC32)
LLD_CASE(R_X86_64_GOT64)
LLD_CASE(R_X86_64_GOTPCREL64)
LLD_CASE(R_X86_64_GOTPC64)
LLD_CASE(R_X86_64_GOTPLT64)
LLD_CASE(R_X86_64_PLTOFF64)
LLD_CASE(R_X86_64_SIZE32)
LLD_CASE(R_X86_64_SIZE64)
LLD_CASE(R_X86_64_GOTPC32_TLSDESC)
LLD_CASE(R_X86_64_TLSDESC_CALL)
LLD_CASE(R_X86_64_TLSDESC)
LLD_CASE(R_X86_64_IRELATIVE)
case LLD_R_X86_64_GOTRELINDEX:
return std::string("LLD_R_X86_64_GOTRELINDEX");
}

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h ---------------------===//
//===- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h -----------------===//
//
// The LLVM Linker
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_ELF_X86_64_TARGETINFO_H
#define LLD_READER_WRITER_ELF_X86_64_TARGETINFO_H
#ifndef LLD_READER_WRITER_ELF_X86_64_LINKER_CONTEXT_H
#define LLD_READER_WRITER_ELF_X86_64_LINKER_CONTEXT_H
#include "X86_64TargetHandler.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/ELF.h"
@@ -26,11 +26,11 @@ enum {
LLD_R_X86_64_GOTRELINDEX = 1024,
};
class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo {
class X86_64LinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
X86_64TargetInfo(llvm::Triple triple)
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(
new X86_64TargetHandler(*this))) {}
X86_64LinkingContext(llvm::Triple triple)
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new X86_64TargetHandler(*this))) {}
virtual void addPasses(PassManager &) const;
@@ -42,7 +42,7 @@ public:
virtual bool isDynamicRelocation(const DefinedAtom &,
const Reference &r) const {
switch (r.kind()){
switch (r.kind()) {
case llvm::ELF::R_X86_64_RELATIVE:
case llvm::ELF::R_X86_64_GLOB_DAT:
return true;
@@ -51,9 +51,8 @@ public:
}
}
virtual bool isPLTRelocation(const DefinedAtom &,
const Reference &r) const {
switch (r.kind()){
virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const {
switch (r.kind()) {
case llvm::ELF::R_X86_64_JUMP_SLOT:
case llvm::ELF::R_X86_64_IRELATIVE:
return true;
@@ -77,7 +76,6 @@ public:
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
};
} // end namespace elf
} // end namespace lld

View File

@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "X86_64TargetHandler.h"
#include "X86_64TargetInfo.h"
#include "X86_64LinkingContext.h"
using namespace lld;
using namespace elf;
@@ -85,8 +85,8 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
case R_X86_64_TPOFF64:
case R_X86_64_DTPOFF32:
case R_X86_64_TPOFF32: {
_tlsSize = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
.getTLSSize();
_tlsSize =
_context.getTargetHandler<X86_64ELFType>().targetLayout().getTLSSize();
if (ref.kind() == R_X86_64_TPOFF32 || ref.kind() == R_X86_64_DTPOFF32) {
int32_t result = (int32_t)(targetVAddress - _tlsSize);
*reinterpret_cast<llvm::support::little32_t *>(location) = result;
@@ -109,7 +109,7 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
for (const Reference *r : *target) {
if (r->kind() == R_X86_64_JUMP_SLOT) {
uint32_t index;
if (!_targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
if (!_context.getTargetHandler<X86_64ELFType>().targetLayout()
.getPLTRelocationTable()->getRelocationIndex(*r, index))
llvm_unreachable("Relocation doesn't exist");
reloc32(location, 0, index, 0);
@@ -133,7 +133,7 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
default: {
std::string str;
llvm::raw_string_ostream s(str);
auto name = _targetInfo.stringFromRelocKind(ref.kind());
auto name = _context.stringFromRelocKind(ref.kind());
s << "Unhandled relocation: " << atom._atom->file().path() << ":"
<< atom._atom->name() << "@" << ref.offsetInAtom() << " "
<< (name ? *name : "<unknown>") << " (" << ref.kind() << ")";

View File

@@ -16,13 +16,13 @@
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 8, true> X86_64ELFType;
class X86_64TargetInfo;
class X86_64LinkingContext;
class X86_64TargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<X86_64ELFType> {
public:
X86_64TargetRelocationHandler(const X86_64TargetInfo &ti)
: _tlsSize(0), _targetInfo(ti) {}
X86_64TargetRelocationHandler(const X86_64LinkingContext &context)
: _tlsSize(0), _context(context) {}
virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
@@ -33,7 +33,7 @@ public:
private:
// Cached size of the TLS segment.
mutable uint64_t _tlsSize;
const X86_64TargetInfo &_targetInfo;
const X86_64LinkingContext &_context;
};
} // end namespace elf

View File

@@ -7,4 +7,4 @@
//
//===----------------------------------------------------------------------===//
#include "X86_64TargetInfo.h"
#include "X86_64LinkingContext.h"

View File

@@ -9,14 +9,14 @@
#include "Atoms.h"
#include "X86_64TargetHandler.h"
#include "X86_64TargetInfo.h"
#include "X86_64LinkingContext.h"
using namespace lld;
using namespace elf;
X86_64TargetHandler::X86_64TargetHandler(X86_64TargetInfo &targetInfo)
: DefaultTargetHandler(targetInfo), _gotFile(targetInfo),
_relocationHandler(targetInfo), _targetLayout(targetInfo) {}
X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &context)
: DefaultTargetHandler(context), _gotFile(context),
_relocationHandler(context), _targetLayout(context) {}
void X86_64TargetHandler::addFiles(InputFiles &f) {
_gotFile.addAtom(*new (_gotFile._alloc) GLOBAL_OFFSET_TABLEAtom(_gotFile));

View File

@@ -19,12 +19,12 @@
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 8, true> X86_64ELFType;
class X86_64TargetInfo;
class X86_64LinkingContext;
class X86_64TargetHandler LLVM_FINAL
: public DefaultTargetHandler<X86_64ELFType> {
public:
X86_64TargetHandler(X86_64TargetInfo &targetInfo);
X86_64TargetHandler(X86_64LinkingContext &targetInfo);
virtual TargetLayout<X86_64ELFType> &targetLayout() {
return _targetLayout;
@@ -39,7 +39,7 @@ public:
private:
class GOTFile : public SimpleFile {
public:
GOTFile(const ELFTargetInfo &eti) : SimpleFile(eti, "GOTFile") {}
GOTFile(const ELFLinkingContext &eti) : SimpleFile(eti, "GOTFile") {}
llvm::BumpPtrAllocator _alloc;
} _gotFile;

View File

@@ -1,7 +1,7 @@
add_lld_library(lldMachO
MachOTargetInfo.cpp
WriterMachO.cpp
MachOLinkingContext.cpp
ReferenceKinds.cpp
WriterMachO.cpp
)
target_link_libraries(lldMachO

View File

@@ -15,7 +15,7 @@
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
#include "lld/Core/TargetInfo.h"
#include "lld/Core/LinkingContext.h"
#include "lld/ReaderWriter/Simple.h"
namespace lld {
@@ -28,10 +28,11 @@ namespace mach_o {
//
class CRuntimeFile : public SimpleFile {
public:
CRuntimeFile(const MachOTargetInfo &ti)
: SimpleFile(ti, "C runtime"), _undefMain(*this, ti.entrySymbolName()) {
CRuntimeFile(const MachOLinkingContext &context)
: SimpleFile(context, "C runtime"),
_undefMain(*this, context.entrySymbolName()) {
// only main executables need _main
if (ti.outputFileType() == MH_EXECUTE) {
if (context.outputFileType() == MH_EXECUTE) {
this->addAtom(_undefMain);
}
}
@@ -40,10 +41,7 @@ private:
SimpleUndefinedAtom _undefMain;
};
} // namespace mach_o
} // namespace lld
} // namespace mach_o
} // namespace lld
#endif // LLD_READER_WRITER_MACHO_EXECUTABLE_ATOM_H_

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/MachO/MachOTargetInfo.cpp -------------------------===//
//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
//
// The LLVM Linker
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "lld/ReaderWriter/MachOTargetInfo.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
#include "GOTPass.hpp"
#include "StubsPass.hpp"
#include "ReferenceKinds.h"
@@ -23,34 +23,32 @@
using lld::mach_o::KindHandler;
namespace lld {
MachOTargetInfo::PackedVersion::PackedVersion(StringRef str) {
MachOLinkingContext::PackedVersion::PackedVersion(StringRef str) {
if (parse(str, *this))
llvm_unreachable("bad version string");
}
/// Construct 32-bit PackedVersion from string "X.Y.Z" where
/// bits are xxxx.yy.zz. Largest number is 65535.255.255
bool MachOTargetInfo::PackedVersion::parse(StringRef str,
MachOTargetInfo::PackedVersion &result) {
bool MachOLinkingContext::PackedVersion::parse(
StringRef str, MachOLinkingContext::PackedVersion &result) {
result._value = 0;
if (str.empty())
if (str.empty())
return false;
SmallVector<StringRef, 3> parts;
llvm::SplitString(str, parts, ".");
unsigned long long num;
if (llvm::getAsUnsignedInteger(parts[0], 10, num))
return true;
if (num > 65535)
return true;
result._value = num << 16;
if (parts.size() > 1) {
if (llvm::getAsUnsignedInteger(parts[1], 10, num))
return true;
@@ -58,7 +56,7 @@ bool MachOTargetInfo::PackedVersion::parse(StringRef str,
return true;
result._value |= (num << 8);
}
if (parts.size() > 2) {
if (llvm::getAsUnsignedInteger(parts[2], 10, num))
return true;
@@ -66,58 +64,58 @@ bool MachOTargetInfo::PackedVersion::parse(StringRef str,
return true;
result._value |= num;
}
return false;
}
bool MachOTargetInfo::PackedVersion::operator<(
const PackedVersion &rhs) const {
bool MachOLinkingContext::PackedVersion::
operator<(const PackedVersion &rhs) const {
return _value < rhs._value;
}
bool MachOTargetInfo::PackedVersion::operator>=(
const PackedVersion &rhs) const {
bool MachOLinkingContext::PackedVersion::
operator>=(const PackedVersion &rhs) const {
return _value >= rhs._value;
}
bool MachOTargetInfo::PackedVersion::operator==(
const PackedVersion &rhs) const {
bool MachOLinkingContext::PackedVersion::
operator==(const PackedVersion &rhs) const {
return _value == rhs._value;
}
struct ArchInfo {
StringRef archName;
MachOTargetInfo::Arch arch;
uint32_t cputype;
uint32_t cpusubtype;
StringRef archName;
MachOLinkingContext::Arch arch;
uint32_t cputype;
uint32_t cpusubtype;
};
static ArchInfo archInfos[] = {
{ "x86_64", MachOTargetInfo::arch_x86_64, mach_o::CPU_TYPE_X86_64,
mach_o::CPU_SUBTYPE_X86_64_ALL },
{ "i386", MachOTargetInfo::arch_x86, mach_o::CPU_TYPE_I386,
mach_o::CPU_SUBTYPE_X86_ALL },
{ "armv6", MachOTargetInfo::arch_armv6, mach_o::CPU_TYPE_ARM,
mach_o::CPU_SUBTYPE_ARM_V6 },
{ "armv7", MachOTargetInfo::arch_armv7, mach_o::CPU_TYPE_ARM,
mach_o::CPU_SUBTYPE_ARM_V7 },
{ "armv7s", MachOTargetInfo::arch_armv7s, mach_o::CPU_TYPE_ARM,
mach_o::CPU_SUBTYPE_ARM_V7S },
{ StringRef(), MachOTargetInfo::arch_unknown, 0, 0 }
{ "x86_64", MachOLinkingContext::arch_x86_64, mach_o::CPU_TYPE_X86_64,
mach_o::CPU_SUBTYPE_X86_64_ALL },
{ "i386", MachOLinkingContext::arch_x86, mach_o::CPU_TYPE_I386,
mach_o::CPU_SUBTYPE_X86_ALL },
{ "armv6", MachOLinkingContext::arch_armv6, mach_o::CPU_TYPE_ARM,
mach_o::CPU_SUBTYPE_ARM_V6 },
{ "armv7", MachOLinkingContext::arch_armv7, mach_o::CPU_TYPE_ARM,
mach_o::CPU_SUBTYPE_ARM_V7 },
{ "armv7s", MachOLinkingContext::arch_armv7s, mach_o::CPU_TYPE_ARM,
mach_o::CPU_SUBTYPE_ARM_V7S },
{ StringRef(), MachOLinkingContext::arch_unknown, 0, 0 }
};
MachOTargetInfo::Arch
MachOTargetInfo::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
MachOLinkingContext::Arch
MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
for (ArchInfo *info = archInfos; !info->archName.empty(); ++info) {
if ( (info->cputype == cputype) && (info->cpusubtype == cpusubtype)) {
if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype)) {
return info->arch;
}
}
return arch_unknown;
}
MachOTargetInfo::Arch MachOTargetInfo::archFromName(StringRef archName) {
MachOLinkingContext::Arch
MachOLinkingContext::archFromName(StringRef archName) {
for (ArchInfo *info = archInfos; !info->archName.empty(); ++info) {
if (info->archName.equals(archName)) {
return info->arch;
@@ -126,7 +124,7 @@ MachOTargetInfo::Arch MachOTargetInfo::archFromName(StringRef archName) {
return arch_unknown;
}
uint32_t MachOTargetInfo::cpuTypeFromArch(Arch arch) {
uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
assert(arch != arch_unknown);
for (ArchInfo *info = archInfos; !info->archName.empty(); ++info) {
if (info->arch == arch) {
@@ -136,7 +134,7 @@ uint32_t MachOTargetInfo::cpuTypeFromArch(Arch arch) {
llvm_unreachable("Unknown arch type");
}
uint32_t MachOTargetInfo::cpuSubtypeFromArch(Arch arch) {
uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
assert(arch != arch_unknown);
for (ArchInfo *info = archInfos; !info->archName.empty(); ++info) {
if (info->arch == arch) {
@@ -146,32 +144,22 @@ uint32_t MachOTargetInfo::cpuSubtypeFromArch(Arch arch) {
llvm_unreachable("Unknown arch type");
}
MachOLinkingContext::MachOLinkingContext()
: _outputFileType(mach_o::MH_EXECUTE), _outputFileTypeStatic(false),
_doNothing(false), _arch(arch_unknown), _os(OS::macOSX),
_osMinVersion("0.0"), _pageZeroSize(0x1000), _kindHandler(nullptr) {}
MachOTargetInfo::MachOTargetInfo()
: _outputFileType(mach_o::MH_EXECUTE)
, _outputFileTypeStatic(false)
, _doNothing(false)
, _arch(arch_unknown)
, _os(OS::macOSX)
, _osMinVersion("0.0")
, _pageZeroSize(0x1000)
, _kindHandler(nullptr) {
}
MachOLinkingContext::~MachOLinkingContext() {}
MachOTargetInfo::~MachOTargetInfo() {
}
uint32_t MachOTargetInfo::getCPUType() const {
uint32_t MachOLinkingContext::getCPUType() const {
return cpuTypeFromArch(_arch);
}
uint32_t MachOTargetInfo::getCPUSubType() const {
uint32_t MachOLinkingContext::getCPUSubType() const {
return cpuSubtypeFromArch(_arch);
}
bool MachOTargetInfo::outputTypeHasEntry() const {
bool MachOLinkingContext::outputTypeHasEntry() const {
switch (_outputFileType) {
case mach_o::MH_EXECUTE:
case mach_o::MH_DYLINKER:
@@ -182,8 +170,7 @@ bool MachOTargetInfo::outputTypeHasEntry() const {
}
}
bool MachOTargetInfo::minOS(StringRef mac, StringRef iOS) const {
bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
switch (_os) {
case OS::macOSX:
return (_osMinVersion >= PackedVersion(mac));
@@ -194,14 +181,14 @@ bool MachOTargetInfo::minOS(StringRef mac, StringRef iOS) const {
llvm_unreachable("target not configured for iOS or MacOSX");
}
bool MachOTargetInfo::addEntryPointLoadCommand() const {
bool MachOLinkingContext::addEntryPointLoadCommand() const {
if ((_outputFileType == mach_o::MH_EXECUTE) && !_outputFileTypeStatic) {
return minOS("10.8", "6.0");
}
return false;
}
bool MachOTargetInfo::addUnixThreadLoadCommand() const {
bool MachOLinkingContext::addUnixThreadLoadCommand() const {
switch (_outputFileType) {
case mach_o::MH_EXECUTE:
if (_outputFileTypeStatic)
@@ -217,7 +204,7 @@ bool MachOTargetInfo::addUnixThreadLoadCommand() const {
}
}
bool MachOTargetInfo::validateImpl(raw_ostream &diagnostics) {
bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
if (_inputFiles.empty()) {
diagnostics << "no object files specified\n";
return true;
@@ -226,8 +213,7 @@ bool MachOTargetInfo::validateImpl(raw_ostream &diagnostics) {
if ((_outputFileType == mach_o::MH_EXECUTE) && _entrySymbolName.empty()) {
if (_outputFileTypeStatic) {
_entrySymbolName = "start";
}
else {
} else {
// If targeting newer OS, use _main
if (addEntryPointLoadCommand())
_entrySymbolName = "_main";
@@ -241,52 +227,51 @@ bool MachOTargetInfo::validateImpl(raw_ostream &diagnostics) {
return false;
}
bool MachOTargetInfo::setOS(OS os, StringRef minOSVersion) {
bool MachOLinkingContext::setOS(OS os, StringRef minOSVersion) {
_os = os;
return PackedVersion::parse(minOSVersion, _osMinVersion);
}
void MachOTargetInfo::addPasses(PassManager &pm) const {
void MachOLinkingContext::addPasses(PassManager &pm) const {
pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
pm.add(std::unique_ptr<Pass>(new LayoutPass()));
}
error_code MachOTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
// if (!_machoReader)
// _machoReader = createReaderMachO(*this);
// error_code ec = _machoReader->parseFile(mb,result);
// if (ec) {
return _yamlReader->parseFile(mb, result);
// }
error_code MachOLinkingContext::parseFile(
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
// if (!_machoReader)
// _machoReader = createReaderMachO(*this);
// error_code ec = _machoReader->parseFile(mb,result);
// if (ec) {
return _yamlReader->parseFile(mb, result);
// }
return error_code::success();
}
Writer &MachOTargetInfo::writer() const {
Writer &MachOLinkingContext::writer() const {
if (!_writer) {
_writer = createWriterMachO(*this);
}
return *_writer;
}
KindHandler &MachOTargetInfo::kindHandler() const {
KindHandler &MachOLinkingContext::kindHandler() const {
if (!_kindHandler)
_kindHandler = KindHandler::create(_arch);
return *_kindHandler;
}
ErrorOr<Reference::Kind>
MachOTargetInfo::relocKindFromString(StringRef str) const {
ErrorOr<Reference::Kind>
MachOLinkingContext::relocKindFromString(StringRef str) const {
return kindHandler().stringToKind(str);
}
}
ErrorOr<std::string>
MachOTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
ErrorOr<std::string>
MachOLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
return std::string(kindHandler().kindToString(kind));
}
} // end namespace lld

View File

@@ -30,16 +30,16 @@ KindHandler::KindHandler() {
KindHandler::~KindHandler() {
}
std::unique_ptr<mach_o::KindHandler> KindHandler::create(
MachOTargetInfo::Arch arch) {
switch( arch ) {
case MachOTargetInfo::arch_x86_64:
return std::unique_ptr<mach_o::KindHandler>(new KindHandler_x86_64());
case MachOTargetInfo::arch_x86:
return std::unique_ptr<mach_o::KindHandler>(new KindHandler_x86());
case MachOTargetInfo::arch_armv6:
case MachOTargetInfo::arch_armv7:
case MachOTargetInfo::arch_armv7s:
std::unique_ptr<mach_o::KindHandler>
KindHandler::create(MachOLinkingContext::Arch arch) {
switch (arch) {
case MachOLinkingContext::arch_x86_64:
return std::unique_ptr<mach_o::KindHandler>(new KindHandler_x86_64());
case MachOLinkingContext::arch_x86:
return std::unique_ptr<mach_o::KindHandler>(new KindHandler_x86());
case MachOLinkingContext::arch_armv6:
case MachOLinkingContext::arch_armv7:
case MachOLinkingContext::arch_armv7s:
return std::unique_ptr<mach_o::KindHandler>(new KindHandler_arm());
default:
llvm_unreachable("Unknown arch");

View File

@@ -10,7 +10,7 @@
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
#include "lld/ReaderWriter/MachOTargetInfo.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
#include "llvm/ADT/Triple.h"
@@ -30,9 +30,9 @@ class KindHandler {
public:
typedef Reference::Kind Kind;
static std::unique_ptr<mach_o::KindHandler> create(MachOTargetInfo::Arch);
virtual ~KindHandler();
virtual Kind stringToKind(StringRef str) = 0;
static std::unique_ptr<mach_o::KindHandler> create(MachOLinkingContext::Arch);
virtual ~KindHandler();
virtual Kind stringToKind(StringRef str) = 0;
virtual StringRef kindToString(Kind) = 0;
virtual bool isCallSite(Kind) = 0;
virtual bool isPointer(Kind) = 0;

View File

@@ -28,10 +28,10 @@ namespace mach_o {
class StubsPass : public lld::StubsPass {
public:
StubsPass(const MachOTargetInfo &ti)
: _targetInfo(ti)
, _kindHandler(_targetInfo.kindHandler())
, _file(ti)
StubsPass(const MachOLinkingContext &context)
: _context(context)
, _kindHandler(_context.kindHandler())
, _file(context)
, _helperCommonAtom(nullptr)
, _helperCacheAtom(nullptr)
, _helperBinderAtom(nullptr) {
@@ -59,14 +59,14 @@ public:
}
const DefinedAtom* makeStub(const Atom& target) {
switch (_targetInfo.arch()) {
case MachOTargetInfo::arch_x86_64:
switch (_context.arch()) {
case MachOLinkingContext::arch_x86_64:
return makeStub_x86_64(target);
case MachOTargetInfo::arch_x86:
case MachOLinkingContext::arch_x86:
return makeStub_x86(target);
case MachOTargetInfo::arch_armv6:
case MachOTargetInfo::arch_armv7:
case MachOTargetInfo::arch_armv7s:
case MachOLinkingContext::arch_armv6:
case MachOLinkingContext::arch_armv7:
case MachOLinkingContext::arch_armv7s:
return makeStub_arm(target);
default:
llvm_unreachable("Unknown mach-o arch");
@@ -149,11 +149,11 @@ private:
class File : public SimpleFile {
public:
File(const MachOTargetInfo &ti) : SimpleFile(ti, "MachO Stubs pass") {
}
File(const MachOLinkingContext &context)
: SimpleFile(context, "MachO Stubs pass") {}
};
const MachOTargetInfo &_targetInfo;
const MachOLinkingContext &_context;
mach_o::KindHandler &_kindHandler;
File _file;
llvm::DenseMap<const Atom*, const DefinedAtom*> _targetToStub;

View File

@@ -30,7 +30,7 @@
#include "lld/Core/InputFiles.h"
#include "lld/Core/Reference.h"
#include "lld/Core/SharedLibraryAtom.h"
#include "lld/ReaderWriter/MachOTargetInfo.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
#include <vector>
#include <map>
@@ -145,9 +145,8 @@ private:
//
class MachHeaderChunk : public Chunk {
public:
MachHeaderChunk(const MachOTargetInfo &ti,
const File &file);
virtual StringRef segmentName() const;
MachHeaderChunk(const MachOLinkingContext &context, const File &file);
virtual StringRef segmentName() const;
virtual void write(uint8_t *fileBuffer);
virtual const char* info();
void recordLoadCommand(load_command*);
@@ -168,10 +167,9 @@ private:
//
class LoadCommandsChunk : public Chunk {
public:
LoadCommandsChunk(MachHeaderChunk&,
const MachOTargetInfo &,
MachOWriter&);
virtual StringRef segmentName() const;
LoadCommandsChunk(MachHeaderChunk &, const MachOLinkingContext &,
MachOWriter &);
virtual StringRef segmentName() const;
virtual void write(uint8_t *fileBuffer);
virtual const char* info();
void computeSize(const lld::File &file);
@@ -195,9 +193,9 @@ private:
};
MachHeaderChunk &_mh;
const MachOTargetInfo &_targetInfo;
MachOWriter &_writer;
segment_command *_linkEditSegment;
const MachOLinkingContext &_context;
MachOWriter &_writer;
segment_command *_linkEditSegment;
symtab_command *_symbolTableLoadCommand;
entry_point_command *_entryPointLoadCommand;
thread_command *_threadLoadCommand;
@@ -338,7 +336,7 @@ private:
//
class MachOWriter : public Writer {
public:
MachOWriter(const MachOTargetInfo &ti);
MachOWriter(const MachOLinkingContext &context);
virtual error_code writeFile(const lld::File &file, StringRef path);
virtual void addFiles(InputFiles&);
@@ -369,9 +367,9 @@ private:
typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
const MachOTargetInfo &_targetInfo;
mach_o::KindHandler &_referenceKindHandler;
CRuntimeFile _cRuntimeFile;
const MachOLinkingContext &_context;
mach_o::KindHandler &_referenceKindHandler;
CRuntimeFile _cRuntimeFile;
LoadCommandsChunk *_loadCommandsChunk;
LoadCommandPaddingChunk *_paddingChunk;
AtomToAddress _atomToAddress;
@@ -581,13 +579,14 @@ void SectionChunk::write(uint8_t *chunkBuffer) {
// MachHeaderChunk
//===----------------------------------------------------------------------===//
MachHeaderChunk::MachHeaderChunk(const MachOTargetInfo &ti, const File &file) {
MachHeaderChunk::MachHeaderChunk(const MachOLinkingContext &context,
const File &file) {
// Set up mach_header based on options
_mh.magic = this->magic(ti.getCPUType());
_mh.cputype = ti.getCPUType();
_mh.cpusubtype = ti.getCPUSubType();
_mh.filetype = ti.outputFileType();
_mh.ncmds = 0;
_mh.magic = this->magic(context.getCPUType());
_mh.cputype = context.getCPUType();
_mh.cpusubtype = context.getCPUSubType();
_mh.filetype = context.outputFileType();
_mh.ncmds = 0;
_mh.sizeofcmds = 0;
_mh.flags = 0;
_mh.reserved = 0;
@@ -635,14 +634,11 @@ uint32_t MachHeaderChunk::magic(uint32_t cpuType) {
//===----------------------------------------------------------------------===//
LoadCommandsChunk::LoadCommandsChunk(MachHeaderChunk &mh,
const MachOTargetInfo &ti,
MachOWriter& writer)
: _mh(mh), _targetInfo(ti), _writer(writer),
_linkEditSegment(nullptr), _symbolTableLoadCommand(nullptr),
_entryPointLoadCommand(nullptr), _threadLoadCommand(nullptr),
_dyldInfoLoadCommand(nullptr) {
}
const MachOLinkingContext &context,
MachOWriter &writer)
: _mh(mh), _context(context), _writer(writer), _linkEditSegment(nullptr),
_symbolTableLoadCommand(nullptr), _entryPointLoadCommand(nullptr),
_threadLoadCommand(nullptr), _dyldInfoLoadCommand(nullptr) {}
StringRef LoadCommandsChunk::segmentName() const {
return StringRef("__TEXT");
@@ -685,8 +681,8 @@ uint32_t LoadCommandsChunk::permissionsFromSections(
void LoadCommandsChunk::computeSize(const lld::File &file) {
const bool is64 = _writer.use64BitMachO();
// Main executables have a __PAGEZERO segment.
uint64_t pageZeroSize = _targetInfo.pageZeroSize();
if ( pageZeroSize != 0 ) {
uint64_t pageZeroSize = _context.pageZeroSize();
if (pageZeroSize != 0) {
assert(is64 || (pageZeroSize < 0xFFFFFFFF));
segment_command* pzSegCmd = new segment_command(0, is64);
strcpy(pzSegCmd->segname, "__PAGEZERO");
@@ -767,11 +763,11 @@ void LoadCommandsChunk::computeSize(const lld::File &file) {
this->addLoadCommand(_dyldInfoLoadCommand);
// Add entry point load command to main executables
if (_targetInfo.addEntryPointLoadCommand()) {
if (_context.addEntryPointLoadCommand()) {
_entryPointLoadCommand = new entry_point_command(is64);
this->addLoadCommand(_entryPointLoadCommand);
} else if (_targetInfo.addUnixThreadLoadCommand()) {
_threadLoadCommand = new thread_command(_targetInfo.getCPUType(), is64);
} else if (_context.addUnixThreadLoadCommand()) {
_threadLoadCommand = new thread_command(_context.getCPUType(), is64);
this->addLoadCommand(_threadLoadCommand);
}
@@ -1265,14 +1261,11 @@ uint32_t SymbolStringsChunk::stringIndex(StringRef str) {
// MachOWriter
//===----------------------------------------------------------------------===//
MachOWriter::MachOWriter(const MachOTargetInfo &ti)
: _targetInfo(ti),
_referenceKindHandler(ti.kindHandler()),
_cRuntimeFile(ti),
_bindingInfo(nullptr), _lazyBindingInfo(nullptr),
_symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
_linkEditStartOffset(0), _linkEditStartAddress(0) {
}
MachOWriter::MachOWriter(const MachOLinkingContext &context)
: _context(context), _referenceKindHandler(context.kindHandler()),
_cRuntimeFile(context), _bindingInfo(nullptr), _lazyBindingInfo(nullptr),
_symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
_linkEditStartOffset(0), _linkEditStartAddress(0) {}
void MachOWriter::build(const lld::File &file) {
// Create objects for each chunk.
@@ -1322,10 +1315,10 @@ void MachOWriter::createChunks(const lld::File &file) {
// Make chunks in __TEXT for mach_header and load commands at start.
MachHeaderChunk *mhc = new MachHeaderChunk(_targetInfo, file);
MachHeaderChunk *mhc = new MachHeaderChunk(_context, file);
_chunks.push_back(mhc);
_loadCommandsChunk = new LoadCommandsChunk(*mhc, _targetInfo, *this);
_loadCommandsChunk = new LoadCommandsChunk(*mhc, _context, *this);
_chunks.push_back(_loadCommandsChunk);
_paddingChunk = new LoadCommandPaddingChunk(*_loadCommandsChunk);
@@ -1358,14 +1351,13 @@ void MachOWriter::addLinkEditChunk(LinkEditChunk *chunk) {
void MachOWriter::buildAtomToAddressMap() {
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
<< "assign atom addresses:\n");
const bool lookForEntry = _targetInfo.outputTypeHasEntry();
for (SectionChunk *chunk : _sectionChunks ) {
for (const SectionChunk::AtomInfo &info : chunk->atoms() ) {
const bool lookForEntry = _context.outputTypeHasEntry();
for (SectionChunk *chunk : _sectionChunks) {
for (const SectionChunk::AtomInfo &info : chunk->atoms()) {
_atomToAddress[info.atom] = chunk->address() + info.offsetInSection;
if ( lookForEntry
&& (info.atom->contentType() == DefinedAtom::typeCode)
&& (info.atom->size() != 0)
&& info.atom->name() == _targetInfo.entrySymbolName()) {
if (lookForEntry && (info.atom->contentType() == DefinedAtom::typeCode) &&
(info.atom->size() != 0) &&
info.atom->name() == _context.entrySymbolName()) {
_entryAtom = info.atom;
}
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
@@ -1388,9 +1380,9 @@ void MachOWriter::assignFileOffsets() {
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
<< "assign file offsets:\n");
uint64_t offset = 0;
uint64_t address = _targetInfo.pageZeroSize();
for ( Chunk *chunk : _chunks ) {
if ( chunk->segmentName().equals("__LINKEDIT") ) {
uint64_t address = _context.pageZeroSize();
for (Chunk *chunk : _chunks) {
if (chunk->segmentName().equals("__LINKEDIT")) {
_linkEditStartOffset = Chunk::alignTo(offset, 12);
_linkEditStartAddress = Chunk::alignTo(address, 12);
break;
@@ -1426,8 +1418,8 @@ void MachOWriter::findSegment(StringRef segmentName, uint32_t *segIndex,
const uint64_t kInvalidAddress = (uint64_t)(-1);
StringRef lastSegName("__TEXT");
*segIndex = 0;
if ( _targetInfo.pageZeroSize() != 0 ) {
*segIndex = 1;
if (_context.pageZeroSize() != 0) {
*segIndex = 1;
}
*segStartAddr = kInvalidAddress;
*segEndAddr = kInvalidAddress;
@@ -1450,14 +1442,14 @@ void MachOWriter::findSegment(StringRef segmentName, uint32_t *segIndex,
}
bool MachOWriter::use64BitMachO() const {
switch (_targetInfo.arch()) {
case MachOTargetInfo::arch_x86_64:
return true;
case MachOTargetInfo::arch_x86:
case MachOTargetInfo::arch_armv6:
case MachOTargetInfo::arch_armv7:
case MachOTargetInfo::arch_armv7s:
return false;
switch (_context.arch()) {
case MachOLinkingContext::arch_x86_64:
return true;
case MachOLinkingContext::arch_x86:
case MachOLinkingContext::arch_armv6:
case MachOLinkingContext::arch_armv7:
case MachOLinkingContext::arch_armv7s:
return false;
default:
llvm_unreachable("Unknown mach-o arch");
}
@@ -1501,9 +1493,8 @@ void MachOWriter::addFiles(InputFiles &inputFiles) {
} // namespace mach_o
std::unique_ptr<Writer> createWriterMachO(const MachOTargetInfo &ti) {
return std::unique_ptr<Writer>(new lld::mach_o::MachOWriter(ti));
std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &context) {
return std::unique_ptr<Writer>(new lld::mach_o::MachOWriter(context));
}
} // namespace lld

View File

@@ -238,9 +238,10 @@ public:
/// Instantiates a File object from a native object file. Ownership
/// of the MemoryBuffer is transfered to the resulting File object.
static error_code make(
const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> &mb,
StringRef path, std::vector<std::unique_ptr<lld::File> > &result) {
static error_code make(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> &mb,
StringRef path,
std::vector<std::unique_ptr<lld::File>> &result) {
const uint8_t *const base =
reinterpret_cast<const uint8_t *>(mb->getBufferStart());
const NativeFileHeader* const header =
@@ -262,7 +263,7 @@ public:
<< header->chunkCount << "\n");
// instantiate NativeFile object and add values to it as found
std::unique_ptr<File> file(new File(ti, std::move(mb), path));
std::unique_ptr<File> file(new File(context, std::move(mb), path));
// process each chunk
for (uint32_t i = 0; i < header->chunkCount; ++i) {
@@ -367,7 +368,7 @@ public:
virtual const atom_collection<AbsoluteAtom> &absolute() const {
return _absoluteAtoms;
}
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const LinkingContext &getLinkingContext() const { return _context; }
private:
friend NativeDefinedAtomV1;
@@ -722,14 +723,14 @@ private:
}
// private constructor, only called by make()
File(const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb,
File(const LinkingContext &context, std::unique_ptr<llvm::MemoryBuffer> mb,
StringRef path)
: lld::File(path, kindObject),
_buffer(std::move(mb)), // Reader now takes ownership of buffer
_header(nullptr), _targetsTable(nullptr), _targetsTableCount(0),
_strings(nullptr), _stringsMaxOffset(0), _addends(nullptr),
_addendsMaxIndex(0), _contentStart(nullptr), _contentEnd(nullptr),
_targetInfo(ti) {
_context(context) {
_header =
reinterpret_cast<const NativeFileHeader *>(_buffer->getBufferStart());
}
@@ -794,7 +795,7 @@ private:
uint32_t _addendsMaxIndex;
const uint8_t *_contentStart;
const uint8_t *_contentEnd;
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
inline const lld::File &NativeDefinedAtomV1::file() const {
@@ -909,18 +910,17 @@ inline void NativeReferenceV1::setAddend(Addend a) {
class Reader : public lld::Reader {
public:
Reader(const TargetInfo &ti)
: lld::Reader(ti) {}
Reader(const LinkingContext &context) : lld::Reader(context) {}
virtual error_code parseFile(
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<lld::File> > &result) const {
return File::make(_targetInfo, mb, mb->getBufferIdentifier(), result);
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<lld::File>> &result) const {
return File::make(_context, mb, mb->getBufferIdentifier(), result);
}
};
} // end namespace native
std::unique_ptr<Reader> createReaderNative(const TargetInfo &ti) {
return std::unique_ptr<Reader>(new lld::native::Reader(ti));
std::unique_ptr<Reader> createReaderNative(const LinkingContext &context) {
return std::unique_ptr<Reader>(new lld::native::Reader(context));
}
} // end namespace lld

View File

@@ -28,7 +28,7 @@ namespace native {
///
class Writer : public lld::Writer {
public:
Writer(const TargetInfo &ti) {}
Writer(const LinkingContext &context) {}
virtual error_code writeFile(const lld::File &file, StringRef outPath) {
// reserve first byte for unnamed atoms
@@ -552,7 +552,7 @@ private:
out.write((char*)&addends[0], maxAddendIndex*sizeof(Reference::Addend));
}
typedef std::vector<std::pair<StringRef, uint32_t> > NameToOffsetVector;
typedef std::vector<std::pair<StringRef, uint32_t>> NameToOffsetVector;
typedef llvm::DenseMap<const Atom*, uint32_t> TargetToIndex;
typedef llvm::DenseMap<Reference::Addend, uint32_t> AddendToIndex;
@@ -579,7 +579,7 @@ private:
};
} // end namespace native
std::unique_ptr<Writer> createWriterNative(const TargetInfo &ti) {
return std::unique_ptr<Writer>(new native::Writer(ti));
std::unique_ptr<Writer> createWriterNative(const LinkingContext &context) {
return std::unique_ptr<Writer>(new native::Writer(context));
}
} // end namespace lld

View File

@@ -1,5 +1,5 @@
add_lld_library(lldPECOFF
PECOFFTargetInfo.cpp
PECOFFLinkingContext.cpp
ReaderCOFF.cpp
ReaderImportHeader.cpp
WriterPECOFF.cpp

View File

@@ -92,9 +92,9 @@ protected:
/// field in the import directory table entry.
class DLLNameAtom : public IdataAtom {
public:
DLLNameAtom(Context &ctx, StringRef name)
: IdataAtom(ctx.file, stringRefToVector(name)) {
ctx.dllNameAtoms.push_back(this);
DLLNameAtom(Context &context, StringRef name)
: IdataAtom(context.file, stringRefToVector(name)) {
context.dllNameAtoms.push_back(this);
}
private:
@@ -116,10 +116,10 @@ private:
/// loader can find the symbol quickly.
class HintNameAtom : public IdataAtom {
public:
HintNameAtom(Context &ctx, uint16_t hint, StringRef importName)
: IdataAtom(ctx.file, assembleRawContent(hint, importName)),
HintNameAtom(Context &context, uint16_t hint, StringRef importName)
: IdataAtom(context.file, assembleRawContent(hint, importName)),
_importName(importName) {
ctx.hintNameAtoms.push_back(this);
context.hintNameAtoms.push_back(this);
}
StringRef getContentString() { return _importName; }
@@ -128,7 +128,8 @@ private:
// The first two bytes of the content is a hint, followed by a null-terminated
// symbol name. The total size needs to be multiple of 2.
vector<uint8_t> assembleRawContent(uint16_t hint, StringRef importName) {
size_t size = llvm::RoundUpToAlignment(sizeof(hint) + importName.size() + 1, 2);
size_t size =
llvm::RoundUpToAlignment(sizeof(hint) + importName.size() + 1, 2);
vector<uint8_t> ret(size);
ret[importName.size()] = 0;
ret[importName.size() - 1] = 0;
@@ -142,8 +143,8 @@ private:
class ImportTableEntryAtom : public IdataAtom {
public:
explicit ImportTableEntryAtom(Context &ctx, uint32_t contents)
: IdataAtom(ctx.file, assembleRawContent(contents)) {}
explicit ImportTableEntryAtom(Context &context, uint32_t contents)
: IdataAtom(context.file, assembleRawContent(contents)) {}
private:
vector<uint8_t> assembleRawContent(uint32_t contents) {
@@ -159,38 +160,40 @@ private:
/// items. The executable has one ImportDirectoryAtom per one imported DLL.
class ImportDirectoryAtom : public IdataAtom {
public:
ImportDirectoryAtom(Context &ctx, StringRef loadName,
ImportDirectoryAtom(Context &context, StringRef loadName,
const vector<COFFSharedLibraryAtom *> &sharedAtoms)
: IdataAtom(ctx.file, vector<uint8_t>(20, 0)) {
addRelocations(ctx, loadName, sharedAtoms);
ctx.importDirectories.push_back(this);
: IdataAtom(context.file, vector<uint8_t>(20, 0)) {
addRelocations(context, loadName, sharedAtoms);
context.importDirectories.push_back(this);
}
private:
void addRelocations(Context &ctx, StringRef loadName,
void addRelocations(Context &context, StringRef loadName,
const vector<COFFSharedLibraryAtom *> &sharedAtoms) {
size_t lookupEnd = ctx.importLookupTables.size();
size_t addressEnd = ctx.importAddressTables.size();
size_t lookupEnd = context.importLookupTables.size();
size_t addressEnd = context.importAddressTables.size();
// Create parallel arrays. The contents of the two are initially the
// same. The PE/COFF loader overwrites the import address tables with the
// pointers to the referenced items after loading the executable into
// memory.
addImportTableAtoms(ctx, sharedAtoms, false, ctx.importLookupTables);
addImportTableAtoms(ctx, sharedAtoms, true, ctx.importAddressTables);
addImportTableAtoms(context, sharedAtoms, false,
context.importLookupTables);
addImportTableAtoms(context, sharedAtoms, true,
context.importAddressTables);
addDir32NBReloc(this, ctx.importLookupTables[lookupEnd],
addDir32NBReloc(this, context.importLookupTables[lookupEnd],
offsetof(ImportDirectoryTableEntry, ImportLookupTableRVA));
addDir32NBReloc(this, ctx.importAddressTables[addressEnd],
addDir32NBReloc(this, context.importAddressTables[addressEnd],
offsetof(ImportDirectoryTableEntry, ImportAddressTableRVA));
addDir32NBReloc(this, new (_alloc) DLLNameAtom(ctx, loadName),
addDir32NBReloc(this, new (_alloc) DLLNameAtom(context, loadName),
offsetof(ImportDirectoryTableEntry, NameRVA));
}
// Creates atoms for an import lookup table. The import lookup table is an
// array of pointers to hint/name atoms. The array needs to be terminated with
// the NULL entry.
void addImportTableAtoms(Context &ctx,
void addImportTableAtoms(Context &context,
const vector<COFFSharedLibraryAtom *> &sharedAtoms,
bool shouldAddReference,
vector<ImportTableEntryAtom *> &ret) const {
@@ -199,11 +202,11 @@ private:
if (atom->importName().empty()) {
// Import by ordinal
uint32_t hint = (1U << 31) | atom->hint();
entry = new (_alloc) ImportTableEntryAtom(ctx, hint);
entry = new (_alloc) ImportTableEntryAtom(context, hint);
} else {
// Import by name
entry = new (_alloc) ImportTableEntryAtom(ctx, 0);
HintNameAtom *hintName = createHintNameAtom(ctx, atom);
entry = new (_alloc) ImportTableEntryAtom(context, 0);
HintNameAtom *hintName = createHintNameAtom(context, atom);
addDir32NBReloc(entry, hintName);
}
ret.push_back(entry);
@@ -211,12 +214,12 @@ private:
atom->setImportTableEntry(entry);
}
// Add the NULL entry.
ret.push_back(new (_alloc) ImportTableEntryAtom(ctx, 0));
ret.push_back(new (_alloc) ImportTableEntryAtom(context, 0));
}
HintNameAtom *createHintNameAtom(
Context &ctx, const COFFSharedLibraryAtom *atom) const {
return new (_alloc) HintNameAtom(ctx, atom->hint(), atom->importName());
HintNameAtom *createHintNameAtom(Context &context,
const COFFSharedLibraryAtom *atom) const {
return new (_alloc) HintNameAtom(context, atom->hint(), atom->importName());
}
mutable llvm::BumpPtrAllocator _alloc;
@@ -225,9 +228,9 @@ private:
/// The last NULL entry in the import directory.
class NullImportDirectoryAtom : public IdataAtom {
public:
explicit NullImportDirectoryAtom(Context &ctx)
: IdataAtom(ctx.file, vector<uint8_t>(20, 0)) {
ctx.importDirectories.push_back(this);
explicit NullImportDirectoryAtom(Context &context)
: IdataAtom(context.file, vector<uint8_t>(20, 0)) {
context.importDirectories.push_back(this);
}
};
@@ -239,18 +242,18 @@ public:
if (file.sharedLibrary().size() == 0)
return;
Context ctx(file);
map<StringRef, vector<COFFSharedLibraryAtom *>> sharedAtoms =
Context context(file);
map<StringRef, vector<COFFSharedLibraryAtom *> > sharedAtoms =
groupByLoadName(file);
for (auto i : sharedAtoms) {
StringRef loadName = i.first;
vector<COFFSharedLibraryAtom *> &atoms = i.second;
createImportDirectory(ctx, loadName, atoms);
createImportDirectory(context, loadName, atoms);
}
new (_alloc) NullImportDirectoryAtom(ctx);
connectAtoms(ctx);
createDataDirectoryAtoms(ctx);
replaceSharedLibraryAtoms(ctx);
new (_alloc) NullImportDirectoryAtom(context);
connectAtoms(context);
createDataDirectoryAtoms(context);
replaceSharedLibraryAtoms(context);
}
private:
@@ -268,18 +271,17 @@ private:
return std::move(ret);
}
void
createImportDirectory(Context &ctx, StringRef loadName,
vector<COFFSharedLibraryAtom *> &dllAtoms) {
new (_alloc) ImportDirectoryAtom(ctx, loadName, dllAtoms);
void createImportDirectory(Context &context, StringRef loadName,
vector<COFFSharedLibraryAtom *> &dllAtoms) {
new (_alloc) ImportDirectoryAtom(context, loadName, dllAtoms);
}
void connectAtoms(Context &ctx) {
coff::connectAtomsWithLayoutEdge(ctx.importDirectories);
coff::connectAtomsWithLayoutEdge(ctx.importLookupTables);
coff::connectAtomsWithLayoutEdge(ctx.importAddressTables);
coff::connectAtomsWithLayoutEdge(ctx.hintNameAtoms);
coff::connectAtomsWithLayoutEdge(ctx.dllNameAtoms);
void connectAtoms(Context &context) {
coff::connectAtomsWithLayoutEdge(context.importDirectories);
coff::connectAtomsWithLayoutEdge(context.importLookupTables);
coff::connectAtomsWithLayoutEdge(context.importAddressTables);
coff::connectAtomsWithLayoutEdge(context.hintNameAtoms);
coff::connectAtomsWithLayoutEdge(context.dllNameAtoms);
}
/// The addresses of the import dirctory and the import address table needs to
@@ -287,23 +289,25 @@ private:
/// represents an entry in the data directory header. We create atoms of class
/// COFFDataDirectoryAtom and set relocations to them, so that the address
/// will be set by the writer.
void createDataDirectoryAtoms(Context &ctx) {
void createDataDirectoryAtoms(Context &context) {
auto *dir = new (_alloc) coff::COFFDataDirectoryAtom(
ctx.file, llvm::COFF::DataDirectoryIndex::IMPORT_TABLE,
ctx.importDirectories.size() * ctx.importDirectories[0]->size());
addDir32NBReloc(dir, ctx.importDirectories[0]);
ctx.file.addAtom(*dir);
context.file, llvm::COFF::DataDirectoryIndex::IMPORT_TABLE,
context.importDirectories.size() *
context.importDirectories[0]->size());
addDir32NBReloc(dir, context.importDirectories[0]);
context.file.addAtom(*dir);
auto *iat = new (_alloc) coff::COFFDataDirectoryAtom(
ctx.file, llvm::COFF::DataDirectoryIndex::IAT,
ctx.importAddressTables.size() * ctx.importAddressTables[0]->size());
addDir32NBReloc(iat, ctx.importAddressTables[0]);
ctx.file.addAtom(*iat);
context.file, llvm::COFF::DataDirectoryIndex::IAT,
context.importAddressTables.size() *
context.importAddressTables[0]->size());
addDir32NBReloc(iat, context.importAddressTables[0]);
context.file.addAtom(*iat);
}
/// Transforms a reference to a COFFSharedLibraryAtom to a real reference.
void replaceSharedLibraryAtoms(Context &ctx) {
for (const DefinedAtom *atom : ctx.file.defined()) {
void replaceSharedLibraryAtoms(Context &context) {
for (const DefinedAtom *atom : context.file.defined()) {
for (const Reference *ref : *atom) {
const Atom *target = ref->target();
auto *sharedAtom = dyn_cast<SharedLibraryAtom>(target);

View File

@@ -1,4 +1,4 @@
//===- lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp -----------------------===//
//===- lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp -------------------===//
//
// The LLVM Linker
//
@@ -17,7 +17,7 @@
#include "lld/Core/InputFiles.h"
#include "lld/Core/PassManager.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/ReaderWriter/PECOFFTargetInfo.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Simple.h"
#include "lld/ReaderWriter/Writer.h"
@@ -37,26 +37,26 @@ bool containDirectoryName(StringRef path) {
/// symbols.
class UndefinedSymbolFile : public SimpleFile {
public:
UndefinedSymbolFile(const TargetInfo &ti)
UndefinedSymbolFile(const LinkingContext &ti)
: SimpleFile(ti, "Linker Internal File") {
for (StringRef symbol : ti.initialUndefinedSymbols()) {
UndefinedAtom *atom = new (_alloc) coff::COFFUndefinedAtom(*this, symbol);
addAtom(*atom);
}
};
}
private:
llvm::BumpPtrAllocator _alloc;
};
} // anonymous namespace
error_code PECOFFTargetInfo::parseFile(
error_code PECOFFLinkingContext::parseFile(
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
return _reader->parseFile(mb, result);
}
bool PECOFFTargetInfo::validateImpl(raw_ostream &diagnostics) {
bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {
if (_inputFiles.empty()) {
diagnostics << "No input files\n";
return true;
@@ -64,15 +64,15 @@ bool PECOFFTargetInfo::validateImpl(raw_ostream &diagnostics) {
if (_stackReserve < _stackCommit) {
diagnostics << "Invalid stack size: reserve size must be equal to or "
<< "greater than commit size, but got "
<< _stackCommit << " and " << _stackReserve << ".\n";
<< "greater than commit size, but got " << _stackCommit
<< " and " << _stackReserve << ".\n";
return true;
}
if (_heapReserve < _heapCommit) {
diagnostics << "Invalid heap size: reserve size must be equal to or "
<< "greater than commit size, but got "
<< _heapCommit << " and " << _heapReserve << ".\n";
<< "greater than commit size, but got " << _heapCommit
<< " and " << _heapReserve << ".\n";
return true;
}
@@ -81,7 +81,7 @@ bool PECOFFTargetInfo::validateImpl(raw_ostream &diagnostics) {
return false;
}
void PECOFFTargetInfo::addImplicitFiles(InputFiles &files) const {
void PECOFFLinkingContext::addImplicitFiles(InputFiles &files) const {
// Add a pseudo file for "/include" linker option.
auto *file = new (_alloc) UndefinedSymbolFile(*this);
files.prependFile(*file);
@@ -89,7 +89,7 @@ void PECOFFTargetInfo::addImplicitFiles(InputFiles &files) const {
/// Append the given file to the input file list. The file must be an object
/// file or an import library file.
void PECOFFTargetInfo::appendInputFileOrLibrary(std::string path) {
void PECOFFLinkingContext::appendInputFileOrLibrary(std::string path) {
StringRef ext = llvm::sys::path::extension(path);
// This is an import library file. Look for the library file in the search
// paths, unless the path contains a directory name.
@@ -110,7 +110,7 @@ void PECOFFTargetInfo::appendInputFileOrLibrary(std::string path) {
/// Try to find the input library file from the search paths and append it to
/// the input file list. Returns true if the library file is found.
void PECOFFTargetInfo::appendLibraryFile(StringRef filename) {
void PECOFFLinkingContext::appendLibraryFile(StringRef filename) {
// Current directory always takes precedence over the search paths.
if (llvm::sys::fs::exists(filename)) {
appendInputFile(filename);
@@ -128,21 +128,19 @@ void PECOFFTargetInfo::appendLibraryFile(StringRef filename) {
appendInputFile(filename);
}
Writer &PECOFFTargetInfo::writer() const {
return *_writer;
}
Writer &PECOFFLinkingContext::writer() const { return *_writer; }
ErrorOr<Reference::Kind>
PECOFFTargetInfo::relocKindFromString(StringRef str) const {
PECOFFLinkingContext::relocKindFromString(StringRef str) const {
return make_error_code(yaml_reader_error::illegal_value);
}
ErrorOr<std::string>
PECOFFTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
PECOFFLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
return make_error_code(yaml_reader_error::illegal_value);
}
void PECOFFTargetInfo::addPasses(PassManager &pm) const {
void PECOFFLinkingContext::addPasses(PassManager &pm) const {
pm.add(std::unique_ptr<Pass>(new pecoff::GroupedSectionsPass()));
pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass()));
pm.add(std::unique_ptr<Pass>(new LayoutPass()));

View File

@@ -84,13 +84,13 @@ private:
typedef vector<const coff_symbol *> SymbolVectorT;
typedef std::map<const coff_section *, SymbolVectorT> SectionToSymbolsT;
typedef std::map<const StringRef, Atom *> SymbolNameToAtomT;
typedef std::map<const coff_section *, vector<COFFDefinedFileAtom *> >
SectionToAtomsT;
typedef std::map<const coff_section *, vector<COFFDefinedFileAtom *>>
SectionToAtomsT;
public:
FileCOFF(const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb,
error_code &ec)
: File(mb->getBufferIdentifier(), kindObject), _targetInfo(ti) {
FileCOFF(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb, error_code &ec)
: File(mb->getBufferIdentifier(), kindObject), _context(context) {
llvm::OwningPtr<llvm::object::Binary> bin;
ec = llvm::object::createBinary(mb.release(), bin);
if (ec)
@@ -138,7 +138,7 @@ public:
return _absoluteAtoms;
}
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const LinkingContext &getLinkingContext() const { return _context; }
StringRef getLinkerDirectives() const { return _directives; }
@@ -525,7 +525,7 @@ private:
std::map<uint32_t, COFFDefinedAtom *>> _definedAtomLocations;
mutable llvm::BumpPtrAllocator _alloc;
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
class BumpPtrStringSaver : public llvm::cl::StringSaver {
@@ -543,18 +543,18 @@ private:
class ReaderCOFF : public Reader {
public:
explicit ReaderCOFF(const TargetInfo &ti)
: Reader(ti), _readerArchive(ti, *this) {}
explicit ReaderCOFF(const LinkingContext &context)
: Reader(context), _readerArchive(context, *this) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const {
std::vector<std::unique_ptr<File>> &result) const {
StringRef magic(mb->getBufferStart(), mb->getBufferSize());
llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(magic);
if (fileType == llvm::sys::fs::file_magic::coff_object)
return parseCOFFFile(mb, result);
if (fileType == llvm::sys::fs::file_magic::archive)
return _readerArchive.parseFile(mb, result);
return lld::coff::parseCOFFImportLibrary(_targetInfo, mb, result);
return lld::coff::parseCOFFImportLibrary(_context, mb, result);
}
private:
@@ -569,10 +569,11 @@ private:
llvm::dbgs() << ".drectve: " << directives << "\n";
});
// Remove const from _targetInfo.
// FIXME: Rename TargetInfo -> LinkingContext and treat it a mutable object
// Remove const from _context.
// FIXME: Rename LinkingContext -> LinkingContext and treat it a mutable
// object
// in the core linker.
PECOFFTargetInfo *targetInfo = (PECOFFTargetInfo *)&_targetInfo;
PECOFFLinkingContext *targetInfo = (PECOFFLinkingContext *)&_context;
// Split the string into tokens, as the shell would do for argv.
SmallVector<const char *, 16> tokens;
@@ -601,11 +602,10 @@ private:
}
error_code parseCOFFFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const {
std::vector<std::unique_ptr<File>> &result) const {
// Parse the memory buffer as PECOFF file.
error_code ec;
std::unique_ptr<FileCOFF> file(
new FileCOFF(_targetInfo, std::move(mb), ec));
std::unique_ptr<FileCOFF> file(new FileCOFF(_context, std::move(mb), ec));
if (ec)
return ec;
@@ -635,8 +635,7 @@ private:
} // end namespace anonymous
namespace lld {
std::unique_ptr<Reader> createReaderPECOFF(const TargetInfo & ti) {
return std::unique_ptr<Reader>(new ReaderCOFF(ti));
std::unique_ptr<Reader> createReaderPECOFF(const LinkingContext &context) {
return std::unique_ptr<Reader>(new ReaderCOFF(context));
}
}

View File

@@ -181,10 +181,10 @@ std::vector<uint8_t> FuncAtom::rawContent(
class FileImportLibrary : public File {
public:
FileImportLibrary(const TargetInfo &ti,
FileImportLibrary(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb,
llvm::error_code &ec)
: File(mb->getBufferIdentifier(), kindSharedLibrary), _targetInfo(ti) {
: File(mb->getBufferIdentifier(), kindSharedLibrary), _context(context) {
const char *buf = mb->getBufferStart();
const char *end = mb->getBufferEnd();
@@ -239,7 +239,7 @@ public:
return _noAbsoluteAtoms;
}
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const LinkingContext &getLinkingContext() const { return _context; }
private:
const COFFSharedLibraryAtom *
@@ -263,7 +263,7 @@ private:
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
const TargetInfo &_targetInfo;
const LinkingContext &_context;
mutable llvm::BumpPtrAllocator _alloc;
// Convert the given symbol name to the import symbol name exported by the
@@ -295,9 +295,9 @@ private:
} // end anonymous namespace
error_code parseCOFFImportLibrary(const TargetInfo &targetInfo,
error_code parseCOFFImportLibrary(const LinkingContext &targetInfo,
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) {
std::vector<std::unique_ptr<File>> &result) {
// Check the file magic.
const char *buf = mb->getBufferStart();
const char *end = mb->getBufferEnd();

View File

@@ -19,15 +19,15 @@ class error_code;
}
namespace lld {
class TargetInfo;
class LinkingContext;
class File;
namespace coff {
llvm::error_code
parseCOFFImportLibrary(const TargetInfo &targetInfo,
std::unique_ptr<llvm::MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result);
parseCOFFImportLibrary(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result);
}
}

View File

@@ -32,7 +32,7 @@
#include "lld/Core/File.h"
#include "lld/Core/InputFiles.h"
#include "lld/ReaderWriter/AtomLayout.h"
#include "lld/ReaderWriter/PECOFFTargetInfo.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/ArrayRef.h"
@@ -137,7 +137,7 @@ private:
/// A PEHeaderChunk represents PE header including COFF header.
class PEHeaderChunk : public HeaderChunk {
public:
explicit PEHeaderChunk(const PECOFFTargetInfo &targetInfo) : HeaderChunk() {
explicit PEHeaderChunk(const PECOFFLinkingContext &context) : HeaderChunk() {
// Set the size of the chunk and initialize the header with null bytes.
_size = sizeof(llvm::COFF::PEMagic) + sizeof(_coffHeader)
+ sizeof(_peHeader);
@@ -153,7 +153,7 @@ public:
// Attributes of the executable.
uint16_t characteristics = llvm::COFF::IMAGE_FILE_32BIT_MACHINE |
llvm::COFF::IMAGE_FILE_EXECUTABLE_IMAGE;
if (targetInfo.getLargeAddressAware())
if (context.getLargeAddressAware())
characteristics |= llvm::COFF::IMAGE_FILE_LARGE_ADDRESS_AWARE;
_coffHeader.Characteristics = characteristics;
@@ -166,7 +166,7 @@ public:
// The address of the executable when loaded into memory. The default for
// DLLs is 0x10000000. The default for executables is 0x400000.
_peHeader.ImageBase = targetInfo.getBaseAddress();
_peHeader.ImageBase = context.getBaseAddress();
// Sections should be page-aligned when loaded into memory, which is 4KB on
// x86.
@@ -178,7 +178,7 @@ public:
// The required Windows version number. This is the internal version and
// shouldn't be confused with product name. Windows 7 is version 6.1 and
// Windows 8 is 6.2, for example.
PECOFFTargetInfo::OSVersion minOSVersion = targetInfo.getMinOSVersion();
PECOFFLinkingContext::OSVersion minOSVersion = context.getMinOSVersion();
_peHeader.MajorOperatingSystemVersion = minOSVersion.majorVersion;
_peHeader.MinorOperatingSystemVersion = minOSVersion.minorVersion;
_peHeader.MajorSubsystemVersion = minOSVersion.majorVersion;
@@ -188,7 +188,7 @@ public:
// between the end of the header and the beginning of the first section.
// Must be multiple of FileAlignment.
_peHeader.SizeOfHeaders = 512;
_peHeader.Subsystem = targetInfo.getSubsystem();
_peHeader.Subsystem = context.getSubsystem();
// Despite its name, DLL characteristics field has meaning both for
// executables and DLLs. We are not very sure if the following bits must
@@ -196,19 +196,19 @@ public:
// them.
uint16_t dllCharacteristics =
llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NO_SEH;
if (targetInfo.isTerminalServerAware())
if (context.isTerminalServerAware())
dllCharacteristics |=
llvm::COFF::IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
if (targetInfo.isNxCompat())
if (context.isNxCompat())
dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
if (targetInfo.getBaseRelocationEnabled())
if (context.getBaseRelocationEnabled())
dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
_peHeader.DLLCharacteristics = dllCharacteristics;
_peHeader.SizeOfStackReserve = targetInfo.getStackReserve();
_peHeader.SizeOfStackCommit = targetInfo.getStackCommit();
_peHeader.SizeOfHeapReserve = targetInfo.getHeapReserve();
_peHeader.SizeOfHeapCommit = targetInfo.getHeapCommit();
_peHeader.SizeOfStackReserve = context.getStackReserve();
_peHeader.SizeOfStackCommit = context.getStackCommit();
_peHeader.SizeOfHeapReserve = context.getHeapReserve();
_peHeader.SizeOfHeapCommit = context.getHeapCommit();
// The number of data directory entries. We always have 16 entries.
_peHeader.NumberOfRvaAndSize = 16;
@@ -727,15 +727,15 @@ private:
class ExecutableWriter : public Writer {
public:
explicit ExecutableWriter(const PECOFFTargetInfo &targetInfo)
: _PECOFFTargetInfo(targetInfo), _numSections(0),
_imageSizeInMemory(PAGE_SIZE), _imageSizeOnDisk(0) {}
explicit ExecutableWriter(const PECOFFLinkingContext &context)
: _PECOFFLinkingContext(context), _numSections(0),
_imageSizeInMemory(PAGE_SIZE), _imageSizeOnDisk(0) {}
// Create all chunks that consist of the output file.
void build(const File &linkedFile) {
// Create file chunks and add them to the list.
auto *dosStub = new DOSStubChunk();
auto *peHeader = new PEHeaderChunk(_PECOFFTargetInfo);
auto *peHeader = new PEHeaderChunk(_PECOFFLinkingContext);
auto *dataDirectory = new DataDirectoryChunk(linkedFile);
auto *sectionTable = new SectionHeaderTableChunk();
auto *text = new TextSectionChunk(linkedFile);
@@ -743,7 +743,7 @@ public:
auto *data = new DataSectionChunk(linkedFile);
auto *bss = new BssSectionChunk(linkedFile);
BaseRelocChunk *baseReloc = nullptr;
if (_PECOFFTargetInfo.getBaseRelocationEnabled())
if (_PECOFFLinkingContext.getBaseRelocationEnabled())
baseReloc = new BaseRelocChunk(linkedFile);
addChunk(dosStub);
@@ -818,7 +818,7 @@ private:
for (auto &cp : _chunks)
if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
chunk->applyRelocations(bufferStart, atomRva,
_PECOFFTargetInfo.getBaseAddress());
_PECOFFLinkingContext.getBaseAddress());
}
void addChunk(Chunk *chunk) {
@@ -851,7 +851,7 @@ private:
}
std::vector<std::unique_ptr<Chunk>> _chunks;
const PECOFFTargetInfo &_PECOFFTargetInfo;
const PECOFFLinkingContext &_PECOFFLinkingContext;
uint32_t _numSections;
// The size of the image in memory. This is initialized with PAGE_SIZE, as the
@@ -870,7 +870,7 @@ private:
} // end namespace pecoff
std::unique_ptr<Writer> createWriterPECOFF(const PECOFFTargetInfo &info) {
std::unique_ptr<Writer> createWriterPECOFF(const PECOFFLinkingContext &info) {
return std::unique_ptr<Writer>(new pecoff::ExecutableWriter(info));
}

View File

@@ -45,10 +45,10 @@ public:
OwningPtr<MemoryBuffer> buff;
if (ci->getMemoryBuffer(buff, true))
return nullptr;
if (_targetInfo.logInputFiles())
if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n";
std::unique_ptr<MemoryBuffer> mb(buff.take());
if (_targetInfo.parseFile(mb, result))
if (_context.parseFile(mb, result))
return nullptr;
assert(result.size() == 1);
@@ -131,9 +131,9 @@ private:
public:
/// only subclasses of ArchiveLibraryFile can be instantiated
FileArchive(const TargetInfo &ti,
FileArchive(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb, error_code &ec)
: ArchiveLibraryFile(ti, mb->getBufferIdentifier()) {
: ArchiveLibraryFile(context, mb->getBufferIdentifier()) {
std::unique_ptr<llvm::object::Archive> archive_obj(
new llvm::object::Archive(mb.release(), ec));
if (ec)
@@ -163,7 +163,7 @@ error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
error_code ec;
if (_targetInfo.forceLoadAllArchives()) {
if (_context.forceLoadAllArchives()) {
_archive.reset(new llvm::object::Archive(mb.release(), ec));
if (ec)
return ec;
@@ -174,14 +174,14 @@ error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
if ((ec = mf->getMemoryBuffer(buff, true)))
return ec;
std::unique_ptr<MemoryBuffer> mbc(buff.take());
if (_targetInfo.logInputFiles())
if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n";
if ((ec = _targetInfo.parseFile(mbc, result)))
if ((ec = _context.parseFile(mbc, result)))
return ec;
}
} else {
std::unique_ptr<File> f;
f.reset(new FileArchive(_targetInfo, std::move(mb), ec));
f.reset(new FileArchive(_context, std::move(mb), ec));
if (ec)
return ec;

View File

@@ -19,10 +19,11 @@ using namespace script;
namespace {
class LinkerScriptFile : public File {
public:
static ErrorOr<std::unique_ptr<LinkerScriptFile> >
create(const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb) {
static ErrorOr<std::unique_ptr<LinkerScriptFile>>
create(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb) {
std::unique_ptr<LinkerScriptFile> file(
new LinkerScriptFile(ti, std::move(mb)));
new LinkerScriptFile(context, std::move(mb)));
file->_script = file->_parser.parse();
if (!file->_script)
return linker_script_reader_error::parse_error;
@@ -37,7 +38,7 @@ public:
_ordinal = ordinal++;
}
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
virtual const LinkingContext &getLinkingContext() const { return _context; }
virtual const atom_collection<DefinedAtom> &defined() const {
return _definedAtoms;
@@ -60,14 +61,12 @@ public:
}
private:
LinkerScriptFile(const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb)
: File(mb->getBufferIdentifier(), kindLinkerScript),
_targetInfo(ti),
_lexer(std::move(mb)),
_parser(_lexer),
_script(nullptr) {}
LinkerScriptFile(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb)
: File(mb->getBufferIdentifier(), kindLinkerScript), _context(context),
_lexer(std::move(mb)), _parser(_lexer), _script(nullptr) {}
const TargetInfo &_targetInfo;
const LinkingContext &_context;
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
@@ -79,10 +78,10 @@ private:
} // end anon namespace
namespace lld {
error_code
ReaderLinkerScript::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
std::vector<std::unique_ptr<File> > &result) const {
auto lsf = LinkerScriptFile::create(_targetInfo, std::move(mb));
error_code ReaderLinkerScript::parseFile(
std::unique_ptr<llvm::MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
auto lsf = LinkerScriptFile::create(_context, std::move(mb));
if (!lsf)
return lsf;
const LinkerScript *ls = (*lsf)->getScript();
@@ -90,7 +89,7 @@ ReaderLinkerScript::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
for (const auto &c : ls->_commands) {
if (auto group = dyn_cast<Group>(c))
for (const auto &path : group->getPaths()) {
if (error_code ec = _targetInfo.readFile(path._path, result))
if (error_code ec = _context.readFile(path._path, result))
return ec;
}
}

View File

@@ -53,10 +53,11 @@ namespace {
/// supplies contextual information.
class ContextInfo {
public:
ContextInfo(const TargetInfo &ti) : _currentFile(nullptr), _targetInfo(ti) {}
ContextInfo(const LinkingContext &context)
: _currentFile(nullptr), _context(context) {}
lld::File *_currentFile;
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
/// Used when writing yaml files.
@@ -300,7 +301,7 @@ struct ScalarTraits<RefKind> {
out << "in-group";
break;
default:
if (auto relocStr = info->_targetInfo.stringFromRelocKind(value))
if (auto relocStr = info->_context.stringFromRelocKind(value))
out << *relocStr;
else
out << "<unknown>";
@@ -311,7 +312,7 @@ struct ScalarTraits<RefKind> {
static StringRef input(StringRef scalar, void *ctxt, RefKind &value) {
assert(ctxt != nullptr);
ContextInfo *info = reinterpret_cast<ContextInfo*>(ctxt);
auto relocKind = info->_targetInfo.relocKindFromString(scalar);
auto relocKind = info->_context.relocKindFromString(scalar);
if (!relocKind) {
if (scalar.equals("layout-after")) {
value = lld::Reference::kindLayoutAfter;
@@ -615,9 +616,8 @@ struct ScalarTraits<ImplicitHex8> {
// YAML conversion for std::vector<const lld::File*>
template<>
struct DocumentListTraits< std::vector<const lld::File*> > {
static size_t size(IO &io, std::vector<const lld::File*> &seq) {
template <> struct DocumentListTraits<std::vector<const lld::File *>> {
static size_t size(IO &io, std::vector<const lld::File *> &seq) {
return seq.size();
}
static const lld::File *&element(IO &io, std::vector<const lld::File*> &seq,
@@ -636,12 +636,10 @@ struct MappingTraits<const lld::File*> {
class NormArchiveFile : public lld::ArchiveLibraryFile {
public:
NormArchiveFile(IO &io)
: ArchiveLibraryFile(((ContextInfo *)io.getContext())->_targetInfo,
""),
_path() {
}
: ArchiveLibraryFile(((ContextInfo *)io.getContext())->_context, ""),
_path() {}
NormArchiveFile(IO &io, const lld::File *file)
: ArchiveLibraryFile(((ContextInfo *)io.getContext())->_targetInfo,
: ArchiveLibraryFile(((ContextInfo *)io.getContext())->_context,
file->path()),
_path(file->path()) {
// If we want to support writing archives, this constructor would
@@ -725,8 +723,8 @@ struct MappingTraits<const lld::File*> {
return _absoluteAtoms;
}
virtual const TargetInfo &getTargetInfo() const {
return ((ContextInfo *)_IO.getContext())->_targetInfo;
virtual const LinkingContext &getLinkingContext() const {
return ((ContextInfo *)_IO.getContext())->_context;
}
// Allocate a new copy of this string and keep track of allocations
@@ -1314,7 +1312,7 @@ namespace yaml {
class Writer : public lld::Writer {
public:
Writer(const TargetInfo &ti) : _targetInfo(ti) {}
Writer(const LinkingContext &context) : _context(context) {}
virtual error_code writeFile(const lld::File &file, StringRef outPath) {
// Create stream to path.
@@ -1324,7 +1322,7 @@ public:
return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
// Create yaml Output writer, using yaml options for context.
ContextInfo context(_targetInfo);
ContextInfo context(_context);
llvm::yaml::Output yout(out, &context);
// Write yaml output.
@@ -1335,12 +1333,12 @@ public:
}
private:
const TargetInfo &_targetInfo;
const LinkingContext &_context;
};
class ReaderYAML : public Reader {
public:
ReaderYAML(const TargetInfo &ti) : Reader(ti) {}
ReaderYAML(const LinkingContext &context) : Reader(context) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const {
@@ -1352,7 +1350,7 @@ public:
// is deallocated.
// Create YAML Input parser.
ContextInfo context(_targetInfo);
ContextInfo context(_context);
llvm::yaml::Input yin(mb->getBuffer(), &context);
// Fill vector with File objects created by parsing yaml.
@@ -1373,11 +1371,11 @@ public:
};
} // end namespace yaml
std::unique_ptr<Writer> createWriterYAML(const TargetInfo &ti) {
return std::unique_ptr<Writer>(new lld::yaml::Writer(ti));
std::unique_ptr<Writer> createWriterYAML(const LinkingContext &context) {
return std::unique_ptr<Writer>(new lld::yaml::Writer(context));
}
std::unique_ptr<Reader> createReaderYAML(const TargetInfo &ti) {
return std::unique_ptr<Reader>(new lld::yaml::ReaderYAML(ti));
std::unique_ptr<Reader> createReaderYAML(const LinkingContext &context) {
return std::unique_ptr<Reader>(new lld::yaml::ReaderYAML(context));
}
} // end namespace lld

View File

@@ -108,7 +108,7 @@ TEST(Range, passing) {
// MSVC Can't compile make_ptr_range.
#ifndef _MSC_VER
static_assert(
std::is_same<decltype(make_ptr_range(v)), lld::range<int *> >::value,
std::is_same<decltype(make_ptr_range(v)), lld::range<int *>>::value,
"make_ptr_range should return a range of pointers");
takes_range(make_ptr_range(v));
takes_range(make_ptr_range(implicit_cast<const std::vector<int> &>(v)));
@@ -185,12 +185,12 @@ TEST(Range, slice) {
// -fsanitize=undefined complains about this, but only if optimizations are
// enabled.
#if 0
test_slice<std::forward_list<int> >();
test_slice<std::forward_list<int>>();
#endif
test_slice<std::list<int> >();
// This doesn't build with libstdc++ 4.7
test_slice<std::list<int>>();
// This doesn't build with libstdc++ 4.7
#if 0
test_slice<std::deque<int> >();
test_slice<std::deque<int>>();
#endif
}
@@ -204,7 +204,7 @@ TEST(Range, istream_range) {
// MSVC interprets input as a function declaration if you don't declare start
// and instead directly pass std::istream_iterator<int>(stream).
auto start = std::istream_iterator<int>(stream);
lld::range<std::istream_iterator<int> > input(
lld::range<std::istream_iterator<int>> input(
start, std::istream_iterator<int>());
EXPECT_TRUE(input.front() == 1);
input.pop_front();

Some files were not shown because too many files have changed in this diff Show More