forked from OSchip/llvm-project
parent
df0b43d1f9
commit
d68d6196af
|
@ -1,4 +1,4 @@
|
|||
//===- lld/Driver/LinkerOptions.h - Linker Options ------------------------===//
|
||||
//===- lld/Core/LinkerOptions.h - Linker Options --------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
|
@ -13,8 +13,8 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_DRIVER_LINKER_OPTIONS_H
|
||||
#define LLD_DRIVER_LINKER_OPTIONS_H
|
||||
#ifndef LLD_CORE_LINKER_OPTIONS_H
|
||||
#define LLD_CORE_LINKER_OPTIONS_H
|
||||
|
||||
#include "lld/Core/LLVM.h"
|
||||
|
||||
|
@ -46,8 +46,9 @@ public:
|
|||
: _file(file)
|
||||
, _kind(kind) {}
|
||||
|
||||
LinkerInput(llvm::MemoryBuffer *buffer, InputKind kind = InputKind::Unknown)
|
||||
: _buffer(buffer)
|
||||
LinkerInput(std::unique_ptr<llvm::MemoryBuffer> buffer,
|
||||
InputKind kind = InputKind::Unknown)
|
||||
: _buffer(std::move(buffer))
|
||||
, _file(_buffer->getBufferIdentifier())
|
||||
, _kind(kind) {}
|
||||
|
||||
|
@ -105,37 +106,88 @@ public:
|
|||
return _file;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> takeBuffer() {
|
||||
getBuffer();
|
||||
return std::move(_buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::unique_ptr<llvm::MemoryBuffer> _buffer;
|
||||
std::string _file;
|
||||
mutable InputKind _kind;
|
||||
};
|
||||
|
||||
enum class OutputKind {
|
||||
Executable,
|
||||
Relocatable,
|
||||
Shared,
|
||||
};
|
||||
|
||||
struct LinkerOptions {
|
||||
LinkerOptions() {}
|
||||
LinkerOptions()
|
||||
: _baseAddress(0)
|
||||
, _outputKind(OutputKind::Executable)
|
||||
, _outputCommands(false)
|
||||
, _outputYAML(false)
|
||||
, _noInhibitExec(true)
|
||||
, _deadStrip(false)
|
||||
, _globalsAreDeadStripRoots(false)
|
||||
, _searchArchivesToOverrideTentativeDefinitions(false)
|
||||
, _searchSharedLibrariesToOverrideTentativeDefinitions(false)
|
||||
, _warnIfCoalesableAtomsHaveDifferentCanBeNull(false)
|
||||
, _warnIfCoalesableAtomsHaveDifferentLoadName(false)
|
||||
, _forceLoadArchives(false)
|
||||
, _textRelocations(false)
|
||||
, _relocatable(false) {}
|
||||
|
||||
// This exists because MSVC doesn't support = default :(
|
||||
LinkerOptions(LinkerOptions &&other)
|
||||
: _input(std::move(other._input))
|
||||
, _llvmArgs(std::move(other._llvmArgs))
|
||||
, _deadStripRoots(std::move(other._deadStripRoots))
|
||||
, _target(std::move(other._target))
|
||||
, _outputPath(std::move(other._outputPath))
|
||||
, _entrySymbol(std::move(other._entrySymbol))
|
||||
, _relocatable(other._relocatable)
|
||||
, _baseAddress(other._baseAddress)
|
||||
, _outputKind(other._outputKind)
|
||||
, _outputCommands(other._outputCommands)
|
||||
, _outputYAML(other._outputYAML)
|
||||
, _noInhibitExec(other._noInhibitExec) {}
|
||||
, _noInhibitExec(other._noInhibitExec)
|
||||
, _deadStrip(other._deadStrip)
|
||||
, _globalsAreDeadStripRoots(other._globalsAreDeadStripRoots)
|
||||
, _searchArchivesToOverrideTentativeDefinitions(
|
||||
other._searchArchivesToOverrideTentativeDefinitions)
|
||||
, _searchSharedLibrariesToOverrideTentativeDefinitions(
|
||||
other._searchSharedLibrariesToOverrideTentativeDefinitions)
|
||||
, _warnIfCoalesableAtomsHaveDifferentCanBeNull(
|
||||
other._warnIfCoalesableAtomsHaveDifferentCanBeNull)
|
||||
, _warnIfCoalesableAtomsHaveDifferentLoadName(
|
||||
other._warnIfCoalesableAtomsHaveDifferentLoadName)
|
||||
, _forceLoadArchives(other._forceLoadArchives)
|
||||
, _textRelocations(other._textRelocations)
|
||||
, _relocatable(other._relocatable) {}
|
||||
|
||||
std::vector<LinkerInput> _input;
|
||||
std::vector<std::string> _llvmArgs;
|
||||
std::vector<std::string> _deadStripRoots;
|
||||
std::string _target;
|
||||
std::string _outputPath;
|
||||
std::string _entrySymbol;
|
||||
unsigned _relocatable : 1;
|
||||
uint64_t _baseAddress;
|
||||
OutputKind _outputKind : 2;
|
||||
/// \brief -###
|
||||
unsigned _outputCommands : 1;
|
||||
unsigned _outputYAML : 1;
|
||||
unsigned _noInhibitExec : 1;
|
||||
unsigned _deadStrip : 1;
|
||||
unsigned _globalsAreDeadStripRoots : 1;
|
||||
unsigned _searchArchivesToOverrideTentativeDefinitions : 1;
|
||||
unsigned _searchSharedLibrariesToOverrideTentativeDefinitions : 1;
|
||||
unsigned _warnIfCoalesableAtomsHaveDifferentCanBeNull : 1;
|
||||
unsigned _warnIfCoalesableAtomsHaveDifferentLoadName : 1;
|
||||
unsigned _forceLoadArchives : 1;
|
||||
unsigned _textRelocations : 1;
|
||||
unsigned _relocatable : 1;
|
||||
|
||||
private:
|
||||
LinkerOptions(const LinkerOptions&) LLVM_DELETED_FUNCTION;
|
|
@ -0,0 +1,79 @@
|
|||
//===- lld/Core/TargetInfo.h - Linker Target Info Interface ---------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
///
|
||||
/// Interface for target specific information to be used be readers, writers,
|
||||
/// and the resolver.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_CORE_TARGET_INFO_H
|
||||
#define LLD_CORE_TARGET_INFO_H
|
||||
|
||||
#include "lld/Core/Error.h"
|
||||
#include "lld/Core/LLVM.h"
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class Triple;
|
||||
}
|
||||
|
||||
namespace lld {
|
||||
struct LinkerOptions;
|
||||
class GOTPass;
|
||||
class StubsPass;
|
||||
|
||||
class TargetInfo {
|
||||
protected:
|
||||
TargetInfo(const LinkerOptions &lo) : _options(lo) {}
|
||||
|
||||
public:
|
||||
virtual ~TargetInfo();
|
||||
|
||||
const LinkerOptions &getLinkerOptions() const { return _options; }
|
||||
|
||||
llvm::Triple getTriple() const;
|
||||
virtual bool is64Bits() const;
|
||||
virtual bool isLittleEndian() const;
|
||||
|
||||
virtual uint64_t getPageSize() const = 0;
|
||||
|
||||
virtual StringRef getEntry() const;
|
||||
|
||||
virtual StubsPass *getStubPass() const { return nullptr; }
|
||||
virtual GOTPass *getGOTPass() const { return nullptr; }
|
||||
|
||||
// TODO: Split out to TargetRelocationInfo.
|
||||
virtual ErrorOr<uint32_t> relocKindFromString(StringRef str) const {
|
||||
uint32_t val;
|
||||
if (str.getAsInteger(10, val))
|
||||
return llvm::make_error_code(llvm::errc::invalid_argument);
|
||||
return val;
|
||||
}
|
||||
|
||||
virtual ErrorOr<std::string> stringFromRelocKind(uint32_t kind) const {
|
||||
std::string s;
|
||||
llvm::raw_string_ostream str(s);
|
||||
str << kind;
|
||||
str.flush();
|
||||
return s;
|
||||
}
|
||||
|
||||
protected:
|
||||
const LinkerOptions &_options;
|
||||
};
|
||||
} // end namespace lld
|
||||
|
||||
#endif
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef LLD_DRIVER_LINKER_INVOCATION_H
|
||||
#define LLD_DRIVER_LINKER_INVOCATION_H
|
||||
|
||||
#include "lld/Driver/LinkerOptions.h"
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
|
||||
namespace lld {
|
||||
class LinkerInvocation {
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
#ifndef LLD_DRIVER_TARGET_H
|
||||
#define LLD_DRIVER_TARGET_H
|
||||
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
#include "lld/ReaderWriter/Reader.h"
|
||||
#include "lld/ReaderWriter/Writer.h"
|
||||
#include "lld/Driver/LinkerOptions.h"
|
||||
|
||||
namespace lld {
|
||||
/// \brief Represents a specific target.
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//===- lld/ReaderWriter/ELFTargetInfo.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_ELF_TARGET_INFO_H
|
||||
#define LLD_READER_WRITER_ELF_TARGET_INFO_H
|
||||
|
||||
#include "lld/Core/TargetInfo.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace lld {
|
||||
class ELFTargetInfo : public TargetInfo {
|
||||
protected:
|
||||
ELFTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {}
|
||||
|
||||
public:
|
||||
uint16_t getOutputType() const;
|
||||
uint16_t getOutputMachine() const;
|
||||
|
||||
static std::unique_ptr<ELFTargetInfo> create(const LinkerOptions &lo);
|
||||
};
|
||||
} // end namespace lld
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
//===- lld/ReaderWriter/MachOTargetInfo.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_MACHO_TARGET_INFO_H
|
||||
#define LLD_READER_WRITER_MACHO_TARGET_INFO_H
|
||||
|
||||
#include "lld/Core/TargetInfo.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace lld {
|
||||
class MachOTargetInfo : public TargetInfo {
|
||||
protected:
|
||||
MachOTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {}
|
||||
|
||||
public:
|
||||
uint32_t getCPUType() const;
|
||||
uint32_t getCPUSubType() const;
|
||||
|
||||
virtual uint64_t getPageZeroSize() const = 0;
|
||||
|
||||
static std::unique_ptr<MachOTargetInfo> create(const LinkerOptions &lo);
|
||||
};
|
||||
} // end namespace lld
|
||||
|
||||
#endif
|
|
@ -7,4 +7,5 @@ add_lld_library(lldCore
|
|||
InputFiles.cpp
|
||||
Resolver.cpp
|
||||
SymbolTable.cpp
|
||||
TargetInfo.cpp
|
||||
)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
//===- lib/Core/TargetInfo.cpp - Linker Target Info Interface -------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lld/Core/TargetInfo.h"
|
||||
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
|
||||
namespace lld {
|
||||
TargetInfo::~TargetInfo() {}
|
||||
|
||||
llvm::Triple TargetInfo::getTriple() const {
|
||||
return llvm::Triple(llvm::Triple::normalize(_options._target));
|
||||
}
|
||||
|
||||
bool TargetInfo::is64Bits() const {
|
||||
return getTriple().isArch64Bit();
|
||||
}
|
||||
|
||||
bool TargetInfo::isLittleEndian() const {
|
||||
// TODO: Do this properly. It is not defined purely by arch.
|
||||
return true;
|
||||
}
|
||||
|
||||
StringRef TargetInfo::getEntry() const {
|
||||
return _options._entrySymbol;
|
||||
}
|
||||
} // end namespace lld
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "lld/Driver/Driver.h"
|
||||
|
||||
#include "lld/Driver/LinkerOptions.h"
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "lld/Driver/Target.h"
|
||||
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
#include "lld/ReaderWriter/ReaderArchive.h"
|
||||
#include "lld/ReaderWriter/ReaderELF.h"
|
||||
#include "lld/ReaderWriter/ReaderYAML.h"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
add_lld_library(lldELF
|
||||
ELFTargetInfo.cpp
|
||||
HexagonReference.cpp
|
||||
PPCReference.cpp
|
||||
ReaderELF.cpp
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
//===- lib/ReaderWriter/ELF/ELFTargetInfo.cpp -----------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lld/ReaderWriter/ELFTargetInfo.h"
|
||||
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
|
||||
namespace lld {
|
||||
uint16_t ELFTargetInfo::getOutputType() const {
|
||||
switch (_options._outputKind) {
|
||||
case OutputKind::Executable:
|
||||
return llvm::ELF::ET_EXEC;
|
||||
case OutputKind::Relocatable:
|
||||
return llvm::ELF::ET_REL;
|
||||
case OutputKind::Shared:
|
||||
return llvm::ELF::ET_DYN;
|
||||
}
|
||||
llvm_unreachable("Unhandled OutputKind");
|
||||
}
|
||||
|
||||
uint16_t ELFTargetInfo::getOutputMachine() const {
|
||||
switch (getTriple().getArch()) {
|
||||
case llvm::Triple::x86:
|
||||
return llvm::ELF::EM_386;
|
||||
case llvm::Triple::x86_64:
|
||||
return llvm::ELF::EM_X86_64;
|
||||
case llvm::Triple::hexagon:
|
||||
return llvm::ELF::EM_HEXAGON;
|
||||
case llvm::Triple::ppc:
|
||||
return llvm::ELF::EM_PPC;
|
||||
default:
|
||||
llvm_unreachable("Unhandled arch");
|
||||
}
|
||||
}
|
||||
|
||||
class X86ELFTargetInfo final : public ELFTargetInfo {
|
||||
public:
|
||||
X86ELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
|
||||
|
||||
virtual uint64_t getPageSize() const { return 0x1000; }
|
||||
};
|
||||
|
||||
class HexagonELFTargetInfo final : public ELFTargetInfo {
|
||||
public:
|
||||
HexagonELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
|
||||
|
||||
virtual uint64_t getPageSize() const { return 0x1000; }
|
||||
};
|
||||
|
||||
class PPCELFTargetInfo final : public ELFTargetInfo {
|
||||
public:
|
||||
PPCELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
|
||||
|
||||
virtual bool isLittleEndian() const { return false; }
|
||||
|
||||
virtual uint64_t getPageSize() const { return 0x1000; }
|
||||
};
|
||||
|
||||
std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(const LinkerOptions &lo) {
|
||||
switch (llvm::Triple(llvm::Triple::normalize(lo._target)).getArch()) {
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::x86_64:
|
||||
return std::unique_ptr<ELFTargetInfo>(new X86ELFTargetInfo(lo));
|
||||
case llvm::Triple::hexagon:
|
||||
return std::unique_ptr<ELFTargetInfo>(new HexagonELFTargetInfo(lo));
|
||||
case llvm::Triple::ppc:
|
||||
return std::unique_ptr<ELFTargetInfo>(new PPCELFTargetInfo(lo));
|
||||
default:
|
||||
return std::unique_ptr<ELFTargetInfo>();
|
||||
}
|
||||
}
|
||||
} // end namespace lld
|
|
@ -1,4 +1,5 @@
|
|||
add_lld_library(lldMachO
|
||||
MachOTargetInfo.cpp
|
||||
WriterMachO.cpp
|
||||
WriterOptionsMachO.cpp
|
||||
ReferenceKinds.cpp
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
//===- lib/ReaderWriter/MachO/MachOTargetInfo.cpp -------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lld/ReaderWriter/MachOTargetInfo.h"
|
||||
|
||||
#include "lld/Core/LinkerOptions.h"
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/MachO.h"
|
||||
|
||||
namespace lld {
|
||||
uint32_t MachOTargetInfo::getCPUType() const {
|
||||
switch (getTriple().getArch()) {
|
||||
case llvm::Triple::x86:
|
||||
return llvm::MachO::CPUTypeI386;
|
||||
case llvm::Triple::x86_64:
|
||||
return llvm::MachO::CPUTypeX86_64;
|
||||
case llvm::Triple::arm:
|
||||
return llvm::MachO::CPUTypeARM;
|
||||
default:
|
||||
llvm_unreachable("Unknown arch type");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t MachOTargetInfo::getCPUSubType() const {
|
||||
switch (getTriple().getArch()) {
|
||||
case llvm::Triple::x86:
|
||||
return llvm::MachO::CPUSubType_I386_ALL;
|
||||
case llvm::Triple::x86_64:
|
||||
return llvm::MachO::CPUSubType_X86_64_ALL;
|
||||
case llvm::Triple::arm:
|
||||
return llvm::MachO::CPUSubType_ARM_ALL;
|
||||
default:
|
||||
llvm_unreachable("Unknown arch type");
|
||||
}
|
||||
}
|
||||
|
||||
class GenericMachOTargetInfo final : public MachOTargetInfo {
|
||||
public:
|
||||
GenericMachOTargetInfo(const LinkerOptions &lo) : MachOTargetInfo(lo) {}
|
||||
|
||||
virtual uint64_t getPageSize() const { return 0x1000; }
|
||||
virtual uint64_t getPageZeroSize() const { return getPageSize(); }
|
||||
|
||||
virtual StringRef getEntry() const {
|
||||
if (!_options._entrySymbol.empty())
|
||||
return _options._entrySymbol;
|
||||
return "_main";
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<MachOTargetInfo>
|
||||
MachOTargetInfo::create(const LinkerOptions &lo) {
|
||||
return std::unique_ptr<MachOTargetInfo>(new GenericMachOTargetInfo(lo));
|
||||
}
|
||||
} // end namespace lld
|
Loading…
Reference in New Issue