[lld] r200177 - [ELF] Make changes to all the targets supported currently
Shankar Easwaran
shankare at codeaurora.org
Sun Jan 26 17:21:03 PST 2014
Author: shankare
Date: Sun Jan 26 19:21:02 2014
New Revision: 200177
URL: http://llvm.org/viewvc/llvm-project?rev=200177&view=rev
Log:
[ELF] Make changes to all the targets supported currently
X86_64,X86,PPC,Hexagon,Mips
No change in functionality.
Added:
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h
lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
Modified:
lld/trunk/lib/ReaderWriter/ELF/Chunk.h
lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
lld/trunk/test/elf/Hexagon/dynlib-syms.test
Modified: lld/trunk/lib/ReaderWriter/ELF/Chunk.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Sun Jan 26 19:21:02 2014
@@ -27,6 +27,8 @@ class ELFLinkingContext;
namespace elf {
class ELFWriter;
+template <class ELFT> class TargetLayout;
+
/// \brief A chunk is a contiguous region of space
template<class ELFT>
class Chunk {
@@ -73,7 +75,8 @@ public:
// Whats the contentType of the chunk ?
virtual int getContentType() const = 0;
// Writer the chunk
- virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0;
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) = 0;
// Finalize the chunk before assigning offsets/virtual addresses
virtual void doPreFlight() = 0;
// Finalize the chunk before writing
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -29,49 +29,10 @@ public:
DefaultTargetHandler(ELFLinkingContext &context)
: TargetHandler<ELFT>(context) {}
- bool doesOverrideELFHeader() { return false; }
-
- void setELFHeader(ELFHeader<ELFT> *elfHeader) {
- llvm_unreachable("Target should provide implementation for function ");
- }
-
const TargetRelocationHandler<ELFT> &getRelocationHandler() const {
llvm_unreachable("Target should provide implementation for function ");
}
- /// Create a set of Default target sections that a target might needj
- void createDefaultSections() {}
-
- /// \brief Add a section to the current Layout
- void addSection(Section<ELFT> *section) {}
-
- /// \brief add new symbol file
- bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) {
- return true;
- }
-
- /// \brief Finalize the symbol values
- void finalizeSymbolValues() {}
-
- /// \brief allocate Commons, some architectures may move small common
- /// symbols over to small data, this would also be used
- void allocateCommons() {}
-
- /// \brief create dynamic table
- LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() {
- return LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)(
- new (_alloc) DynamicTable<ELFT>(
- this->_context, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
- }
-
- /// \brief create dynamic symbol table
- LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable() {
- return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)(
- new (_alloc) DynamicSymbolTable<ELFT>(
- this->_context, ".dynsym",
- DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
- }
-
virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
return std::unique_ptr<Reader>(new ELFObjectReader(atomizeStrings));
}
@@ -80,64 +41,9 @@ public:
return std::unique_ptr<Reader>(new ELFDSOReader(useShlibUndefines));
}
- virtual std::unique_ptr<Writer> getWriter();
-
-protected:
- llvm::BumpPtrAllocator _alloc;
+ virtual std::unique_ptr<Writer> getWriter() = 0;
};
-template <class ELFT>
-std::unique_ptr<Writer> DefaultTargetHandler<ELFT>::getWriter() {
- switch (this->_context.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- if (this->_context.is64Bits()) {
- if (this->_context.isLittleEndian())
- return std::unique_ptr<Writer>(
- new elf::ExecutableWriter<ELFType<support::little, 8, true>>(
- this->_context));
- else
- return std::unique_ptr<Writer>(
- new elf::ExecutableWriter<ELFType<support::big, 8, true>>(
- this->_context));
- } else {
- if (this->_context.isLittleEndian())
- return std::unique_ptr<Writer>(
- new elf::ExecutableWriter<ELFType<support::little, 4, false>>(
- this->_context));
- else
- return std::unique_ptr<Writer>(
- new elf::ExecutableWriter<ELFType<support::big, 4, false>>(
- this->_context));
- }
- break;
- case llvm::ELF::ET_DYN:
- if (this->_context.is64Bits()) {
- if (this->_context.isLittleEndian())
- return std::unique_ptr<Writer>(
- new elf::DynamicLibraryWriter<ELFType<support::little, 8, true>>(
- this->_context));
- else
- return std::unique_ptr<Writer>(
- new elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(
- this->_context));
- } else {
- if (this->_context.isLittleEndian())
- return std::unique_ptr<Writer>(
- new elf::DynamicLibraryWriter<ELFType<support::little, 4, false>>(
- this->_context));
- else
- return std::unique_ptr<Writer>(
- new elf::DynamicLibraryWriter<ELFType<support::big, 4, false>>(
- this->_context));
- }
- break;
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
-}
-
} // end namespace elf
} // end namespace lld
#endif
Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -25,17 +25,18 @@ class DynamicLibraryWriter;
template<class ELFT>
class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
public:
- DynamicLibraryWriter(const ELFLinkingContext &context)
- : OutputELFWriter<ELFT>(context),
+ DynamicLibraryWriter(const ELFLinkingContext &context,
+ TargetLayout<ELFT> &layout)
+ : OutputELFWriter<ELFT>(context, layout),
_runtimeFile(new CRuntimeFile<ELFT>(context)) {}
-private:
- void buildDynamicSymbolTable(const File &file);
- void addDefaultAtoms();
+protected:
+ virtual void buildDynamicSymbolTable(const File &file);
+ virtual void addDefaultAtoms();
virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
- void finalizeDefaultAtomValues();
+ virtual void finalizeDefaultAtomValues();
- llvm::BumpPtrAllocator _alloc;
+protected:
std::unique_ptr<CRuntimeFile<ELFT> > _runtimeFile;
};
@@ -47,7 +48,7 @@ void DynamicLibraryWriter<ELFT>::buildDy
// Add all the defined symbols to the dynamic symbol table
// we need hooks into the Atom to find out which atoms need
// to be exported
- for (auto sec : this->_layout->sections())
+ for (auto sec : this->_layout.sections())
if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
for (const auto &atom : section->atoms()) {
const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
@@ -71,7 +72,7 @@ template <class ELFT>
bool DynamicLibraryWriter<ELFT>::createImplicitFiles(
std::vector<std::unique_ptr<File> > &result) {
// Add the default atoms as defined by executables
- addDefaultAtoms();
+ DynamicLibraryWriter<ELFT>::addDefaultAtoms();
OutputELFWriter<ELFT>::createImplicitFiles(result);
result.push_back(std::move(_runtimeFile));
return true;
@@ -79,17 +80,15 @@ bool DynamicLibraryWriter<ELFT>::createI
template <class ELFT>
void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
- auto underScoreEndAtomIter = this->_layout->findAbsoluteAtom("_end");
+ auto underScoreEndAtomIter = this->_layout.findAbsoluteAtom("_end");
- if (auto bssSection = this->_layout->findOutputSection(".bss")) {
+ if (auto bssSection = this->_layout.findOutputSection(".bss")) {
(*underScoreEndAtomIter)->_virtualAddr =
bssSection->virtualAddr() + bssSection->memSize();
- } else if (auto dataSection = this->_layout->findOutputSection(".data")) {
+ } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
(*underScoreEndAtomIter)->_virtualAddr =
dataSection->virtualAddr() + dataSection->memSize();
}
-
- this->_targetHandler.finalizeSymbolValues();
}
} // namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -25,11 +25,11 @@ class ExecutableWriter;
template<class ELFT>
class ExecutableWriter : public OutputELFWriter<ELFT> {
public:
- ExecutableWriter(const ELFLinkingContext &context)
- : OutputELFWriter<ELFT>(context),
+ ExecutableWriter(const ELFLinkingContext &context, TargetLayout<ELFT> &layout)
+ : OutputELFWriter<ELFT>(context, layout),
_runtimeFile(new CRuntimeFile<ELFT>(context)) {}
-private:
+protected:
virtual void addDefaultAtoms();
virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
virtual void finalizeDefaultAtomValues();
@@ -71,7 +71,7 @@ template <class ELFT>
bool ExecutableWriter<ELFT>::createImplicitFiles(
std::vector<std::unique_ptr<File> > &result) {
// Add the default atoms as defined by executables
- addDefaultAtoms();
+ ExecutableWriter<ELFT>::addDefaultAtoms();
OutputELFWriter<ELFT>::createImplicitFiles(result);
result.push_back(std::move(_runtimeFile));
return true;
@@ -83,17 +83,17 @@ template <class ELFT> void ExecutableWri
_interpSection.reset(new (this->_alloc) InterpSection<ELFT>(
this->_context, ".interp", DefaultLayout<ELFT>::ORDER_INTERP,
this->_context.getInterpreter()));
- this->_layout->addSection(_interpSection.get());
+ this->_layout.addSection(_interpSection.get());
}
}
/// Finalize the value of all the absolute symbols that we
/// created
template <class ELFT> void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
- auto bssStartAtomIter = this->_layout->findAbsoluteAtom("__bss_start");
- auto bssEndAtomIter = this->_layout->findAbsoluteAtom("__bss_end");
- auto underScoreEndAtomIter = this->_layout->findAbsoluteAtom("_end");
- auto endAtomIter = this->_layout->findAbsoluteAtom("end");
+ auto bssStartAtomIter = this->_layout.findAbsoluteAtom("__bss_start");
+ auto bssEndAtomIter = this->_layout.findAbsoluteAtom("__bss_end");
+ auto underScoreEndAtomIter = this->_layout.findAbsoluteAtom("_end");
+ auto endAtomIter = this->_layout.findAbsoluteAtom("end");
auto startEnd = [&](StringRef sym, StringRef sec) -> void {
// TODO: This looks like a good place to use Twine...
@@ -102,9 +102,9 @@ template <class ELFT> void ExecutableWri
start += "_start";
end += sym;
end += "_end";
- auto s = this->_layout->findAbsoluteAtom(start);
- auto e = this->_layout->findAbsoluteAtom(end);
- auto section = this->_layout->findOutputSection(sec);
+ auto s = this->_layout.findAbsoluteAtom(start);
+ auto e = this->_layout.findAbsoluteAtom(end);
+ auto section = this->_layout.findOutputSection(sec);
if (section) {
(*s)->_virtualAddr = section->virtualAddr();
(*e)->_virtualAddr = section->virtualAddr() + section->memSize();
@@ -122,13 +122,13 @@ template <class ELFT> void ExecutableWri
startEnd("rel_iplt", ".rel.plt");
startEnd("fini_array", ".fini_array");
- assert(!(bssStartAtomIter == this->_layout->absoluteAtoms().end() ||
- bssEndAtomIter == this->_layout->absoluteAtoms().end() ||
- underScoreEndAtomIter == this->_layout->absoluteAtoms().end() ||
- endAtomIter == this->_layout->absoluteAtoms().end()) &&
+ assert(!(bssStartAtomIter == this->_layout.absoluteAtoms().end() ||
+ bssEndAtomIter == this->_layout.absoluteAtoms().end() ||
+ underScoreEndAtomIter == this->_layout.absoluteAtoms().end() ||
+ endAtomIter == this->_layout.absoluteAtoms().end()) &&
"Unable to find the absolute atoms that have been added by lld");
- auto bssSection = this->_layout->findOutputSection(".bss");
+ auto bssSection = this->_layout.findOutputSection(".bss");
// If we don't find a bss section, then don't set these values
if (bssSection) {
@@ -137,14 +137,11 @@ template <class ELFT> void ExecutableWri
bssSection->virtualAddr() + bssSection->memSize();
(*underScoreEndAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;
(*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;
- } else if (auto dataSection = this->_layout->findOutputSection(".data")) {
+ } else if (auto dataSection = this->_layout.findOutputSection(".data")) {
(*underScoreEndAtomIter)->_virtualAddr =
dataSection->virtualAddr() + dataSection->memSize();
(*endAtomIter)->_virtualAddr = (*underScoreEndAtomIter)->_virtualAddr;
}
-
- // Give a chance for the target to finalize its atom values
- this->_targetHandler.finalizeSymbolValues();
}
} // namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h Sun Jan 26 19:21:02 2014
@@ -52,7 +52,8 @@ public:
inline int getContentType() const { return Chunk<ELFT>::ContentType::Header; }
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
virtual void doPreFlight() {}
@@ -78,7 +79,8 @@ ELFHeader<ELFT>::ELFHeader(const ELFLink
}
template <class ELFT>
-void ELFHeader<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+void ELFHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *atomContent = chunkBuffer + this->fileOffset();
memcpy(atomContent, &_eh, fileSize());
@@ -132,7 +134,8 @@ public:
return c->Kind() == Chunk<ELFT>::Kind::ProgramHeader;
}
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
/// \brief find a program header entry in the list of program headers
ReversePhIterT
@@ -231,8 +234,8 @@ bool ProgramHeader<ELFT>::addSegment(Seg
}
template <class ELFT>
-void ProgramHeader<ELFT>::write(ELFWriter *writer,
- llvm::FileOutputBuffer &buffer) {
+void ProgramHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
for (auto phi : _ph) {
@@ -262,7 +265,8 @@ public:
_stringSection = s;
}
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
virtual void doPreFlight() {}
@@ -336,15 +340,15 @@ SectionHeader<ELFT>::updateSection(Secti
}
template <class ELFT>
-void SectionHeader<ELFT>::write(ELFWriter *writer,
- llvm::FileOutputBuffer &buffer) {
+void SectionHeader<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
for (auto shi : _sectionInfo) {
memcpy(dest, shi, sizeof(Elf_Shdr));
dest += sizeof(Elf_Shdr);
}
- _stringSection->write(writer, buffer);
+ _stringSection->write(writer, layout, buffer);
}
} // end namespace elf
} // end namespace lld
Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,80 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
+//-------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_DYNAMIC_LIBRARY_WRITER_H
+#define HEXAGON_DYNAMIC_LIBRARY_WRITER_H
+
+#include "HexagonExecutableAtoms.h"
+#include "HexagonLinkingContext.h"
+#include "DynamicLibraryWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class HexagonTargetLayout;
+
+template <class ELFT>
+class HexagonDynamicLibraryWriter : public DynamicLibraryWriter<ELFT>,
+ public HexagonELFWriter<ELFT> {
+public:
+ HexagonDynamicLibraryWriter(HexagonLinkingContext &context,
+ HexagonTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues();
+
+ virtual error_code setELFHeader() {
+ DynamicLibraryWriter<ELFT>::setELFHeader();
+ HexagonELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+ return error_code::success();
+ }
+
+private:
+ void addDefaultAtoms() {
+ _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
+ }
+
+ HexagonLinkingContext &_hexagonLinkingContext;
+ HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+ std::unique_ptr<HexagonRuntimeFile<ELFT>> _hexagonRuntimeFile;
+};
+
+template <class ELFT>
+HexagonDynamicLibraryWriter<ELFT>::HexagonDynamicLibraryWriter(
+ HexagonLinkingContext &context, HexagonTargetLayout<ELFT> &layout)
+ : DynamicLibraryWriter<ELFT>(context, layout),
+ HexagonELFWriter<ELFT>(context, layout), _hexagonLinkingContext(context),
+ _hexagonTargetLayout(layout),
+ _hexagonRuntimeFile(new HexagonRuntimeFile<ELFT>(context)) {}
+
+template <class ELFT>
+bool HexagonDynamicLibraryWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+ // Add the default atoms as defined for hexagon
+ addDefaultAtoms();
+ result.push_back(std::move(_hexagonRuntimeFile));
+ return true;
+}
+
+template <class ELFT>
+void HexagonDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+ // Finalize the atom values that are part of the parent.
+ DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+ HexagonELFWriter<ELFT>::finalizeHexagonRuntimeAtomValues();
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // HEXAGON_DYNAMIC_LIBRARY_WRITER_H
Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,61 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h -------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HEXAGON_ELF_WRITERS_H
+#define HEXAGON_ELF_WRITERS_H
+
+#include "HexagonLinkingContext.h"
+#include "OutputELFWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class HexagonTargetLayout;
+
+template <typename ELFT> class HexagonELFWriter {
+public:
+ HexagonELFWriter(HexagonLinkingContext &context,
+ HexagonTargetLayout<ELFT> &targetLayout)
+ : _hexagonLinkingContext(context), _hexagonTargetLayout(targetLayout) {}
+
+protected:
+ bool setELFHeader(ELFHeader<ELFT> &elfHeader) {
+ elfHeader.e_ident(llvm::ELF::EI_VERSION, 1);
+ elfHeader.e_ident(llvm::ELF::EI_OSABI, 0);
+ elfHeader.e_version(1);
+ elfHeader.e_flags(0x3);
+ return true;
+ }
+
+ void finalizeHexagonRuntimeAtomValues() {
+ if (_hexagonLinkingContext.isDynamic()) {
+ auto gotAtomIter =
+ _hexagonTargetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ auto gotpltSection = _hexagonTargetLayout.findOutputSection(".got.plt");
+ if (gotpltSection)
+ (*gotAtomIter)->_virtualAddr = gotpltSection->virtualAddr();
+ else
+ (*gotAtomIter)->_virtualAddr = 0;
+ auto dynamicAtomIter = _hexagonTargetLayout.findAbsoluteAtom("_DYNAMIC");
+ auto dynamicSection = _hexagonTargetLayout.findOutputSection(".dynamic");
+ if (dynamicSection)
+ (*dynamicAtomIter)->_virtualAddr = dynamicSection->virtualAddr();
+ else
+ (*dynamicAtomIter)->_virtualAddr = 0;
+ }
+ }
+
+private:
+ HexagonLinkingContext &_hexagonLinkingContext LLVM_ATTRIBUTE_UNUSED;
+ HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+};
+
+} // elf
+} // lld
+#endif // HEXAGON_ELF_WRITERS_H
Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,86 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h -------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_EXECUTABLE_WRITER_H
+#define HEXAGON_EXECUTABLE_WRITER_H
+
+#include "HexagonExecutableAtoms.h"
+#include "HexagonLinkingContext.h"
+#include "HexagonELFWriters.h"
+#include "ExecutableWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class HexagonTargetLayout;
+
+template <class ELFT>
+class HexagonExecutableWriter : public ExecutableWriter<ELFT>,
+ public HexagonELFWriter<ELFT> {
+public:
+ HexagonExecutableWriter(HexagonLinkingContext &context,
+ HexagonTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues();
+
+ virtual error_code setELFHeader() {
+ ExecutableWriter<ELFT>::setELFHeader();
+ HexagonELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+ return error_code::success();
+ }
+
+private:
+ void addDefaultAtoms() {
+ _hexagonRuntimeFile->addAbsoluteAtom("_SDA_BASE_");
+ if (this->_context.isDynamic()) {
+ _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
+ }
+ }
+
+ HexagonLinkingContext &_hexagonLinkingContext;
+ HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+ std::unique_ptr<HexagonRuntimeFile<ELFT>> _hexagonRuntimeFile;
+};
+
+template <class ELFT>
+HexagonExecutableWriter<ELFT>::HexagonExecutableWriter(
+ HexagonLinkingContext &context, HexagonTargetLayout<ELFT> &layout)
+ : ExecutableWriter<ELFT>(context, layout),
+ HexagonELFWriter<ELFT>(context, layout), _hexagonLinkingContext(context),
+ _hexagonTargetLayout(layout),
+ _hexagonRuntimeFile(new HexagonRuntimeFile<ELFT>(context)) {}
+
+template <class ELFT>
+bool HexagonExecutableWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ ExecutableWriter<ELFT>::createImplicitFiles(result);
+ // Add the default atoms as defined for hexagon
+ addDefaultAtoms();
+ result.push_back(std::move(_hexagonRuntimeFile));
+ return true;
+}
+
+template <class ELFT>
+void HexagonExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
+ // Finalize the atom values that are part of the parent.
+ ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+ auto sdabaseAtomIter = _hexagonTargetLayout.findAbsoluteAtom("_SDA_BASE_");
+ (*sdabaseAtomIter)->_virtualAddr =
+ _hexagonTargetLayout.getSDataSection()->virtualAddr();
+ HexagonELFWriter<ELFT>::finalizeHexagonRuntimeAtomValues();
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // HEXAGON_EXECUTABLE_WRITER_H
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Sun Jan 26 19:21:02 2014
@@ -18,6 +18,8 @@
namespace lld {
namespace elf {
+typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
+
class HexagonLinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
HexagonLinkingContext(llvm::Triple triple);
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp Sun Jan 26 19:21:02 2014
@@ -264,19 +264,19 @@ error_code HexagonTargetRelocationHandle
break;
case R_HEX_GPREL16_0:
relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 0);
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 0);
break;
case R_HEX_GPREL16_1:
relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 1);
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 1);
break;
case R_HEX_GPREL16_2:
relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 2);
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 2);
break;
case R_HEX_GPREL16_3:
relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
- _targetLayout.getSDataSection()->virtualAddr(), 3);
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 3);
break;
case R_HEX_16_X:
case R_HEX_12_X:
@@ -296,45 +296,52 @@ error_code HexagonTargetRelocationHandle
break;
case R_HEX_GOTREL_32:
relocHexGOTREL_32(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGOTSymAddr());
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOTREL_LO16:
relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGOTSymAddr());
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOTREL_HI16:
relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGOTSymAddr(), 16);
+ _hexagonTargetLayout.getGOTSymAddr(), 16);
break;
case R_HEX_GOT_LO16:
- relocHexGOTLO16(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOTLO16(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOT_HI16:
- relocHexGOTHI16(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOTHI16(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOT_32:
- relocHexGOT32(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOT32(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOT_16:
- relocHexGOT16(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOT16(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOT_32_6_X:
- relocHexGOT32_6_X(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOT32_6_X(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOT_16_X:
- relocHexGOT16_X(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOT16_X(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOT_11_X:
- relocHexGOT11_X(location, targetVAddress, _targetHandler.getGOTSymAddr());
+ relocHexGOT11_X(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
break;
case R_HEX_GOTREL_32_6_X:
relocHexGOTRELSigned(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGOTSymAddr(), 6);
+ _hexagonTargetLayout.getGOTSymAddr(), 6);
break;
case R_HEX_GOTREL_16_X:
case R_HEX_GOTREL_11_X:
- relocHexGOTRELUnsigned(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGOTSymAddr());
+ relocHexGOTRELUnsigned(location, relocVAddress, targetVAddress,
+ ref.addend(), _hexagonTargetLayout.getGOTSymAddr());
break;
default : {
@@ -349,4 +356,4 @@ error_code HexagonTargetRelocationHandle
return error_code::success();
}
-
\ No newline at end of file
+
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h Sun Jan 26 19:21:02 2014
@@ -18,23 +18,21 @@ namespace elf {
class HexagonLinkingContext;
class HexagonTargetHandler;
-template <class HexagonELFType> class HexagonTargetLayout;
class HexagonTargetRelocationHandler LLVM_FINAL :
public TargetRelocationHandler<HexagonELFType> {
public:
- HexagonTargetRelocationHandler(
- const HexagonLinkingContext &context, const HexagonTargetHandler &tH,
- const HexagonTargetLayout<HexagonELFType> &layout)
- : _targetHandler(tH), _targetLayout(layout) {}
+ HexagonTargetRelocationHandler(HexagonLinkingContext &context,
+ HexagonTargetLayout<HexagonELFType> &layout)
+ : _hexagonLinkingContext(context), _hexagonTargetLayout(layout) {}
- virtual error_code
- applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const lld::AtomLayout &, const Reference &) const;
+ virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
+ const lld::AtomLayout &,
+ const Reference &) const;
private:
- const HexagonTargetHandler &_targetHandler;
- const HexagonTargetLayout<HexagonELFType> &_targetLayout;
+ HexagonLinkingContext &_hexagonLinkingContext LLVM_ATTRIBUTE_UNUSED;
+ HexagonTargetLayout<HexagonELFType> &_hexagonTargetLayout;
};
} // elf
} // lld
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h Sun Jan 26 19:21:02 2014
@@ -6,14 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_SECTION_CHUNKS_H
-#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_SECTION_CHUNKS_H
+#ifndef HEXAGON_SECTION_CHUNKS_H
+#define HEXAGON_SECTION_CHUNKS_H
#include "HexagonTargetHandler.h"
namespace lld {
namespace elf {
-typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
template <typename ELFT> class HexagonTargetLayout;
class HexagonLinkingContext;
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "HexagonExecutableWriter.h"
+#include "HexagonDynamicLibraryWriter.h"
#include "HexagonTargetHandler.h"
#include "HexagonLinkingContext.h"
@@ -17,11 +19,28 @@ using namespace llvm::ELF;
using llvm::makeArrayRef;
HexagonTargetHandler::HexagonTargetHandler(HexagonLinkingContext &context)
- : DefaultTargetHandler(context), _targetLayout(context),
- _relocationHandler(context, *this, _targetLayout),
- _hexagonRuntimeFile(new HexagonRuntimeFile<HexagonELFType>(context)) {}
-
-namespace {
+ : DefaultTargetHandler(context), _hexagonLinkingContext(context),
+ _hexagonRuntimeFile(new HexagonRuntimeFile<HexagonELFType>(context)),
+ _hexagonTargetLayout(new HexagonTargetLayout<HexagonELFType>(context)),
+ _hexagonRelocationHandler(new HexagonTargetRelocationHandler(
+ context, *_hexagonTargetLayout.get())) {}
+
+std::unique_ptr<Writer> HexagonTargetHandler::getWriter() {
+ switch (_hexagonLinkingContext.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return std::unique_ptr<Writer>(
+ new elf::HexagonExecutableWriter<HexagonELFType>(
+ _hexagonLinkingContext, *_hexagonTargetLayout.get()));
+ case llvm::ELF::ET_DYN:
+ return std::unique_ptr<Writer>(
+ new elf::HexagonDynamicLibraryWriter<HexagonELFType>(
+ _hexagonLinkingContext, *_hexagonTargetLayout.get()));
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
+ }
+}
using namespace llvm::ELF;
@@ -297,7 +316,6 @@ public:
return error_code::success();
}
};
-} // end anonymous namespace
void elf::HexagonLinkingContext::addPasses(PassManager &pm) {
if (isDynamic())
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_TARGET_HANDLER_H
-#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_TARGET_HANDLER_H
+#ifndef HEXAGON_TARGET_HANDLER_H
+#define HEXAGON_TARGET_HANDLER_H
#include "DefaultTargetHandler.h"
#include "HexagonExecutableAtoms.h"
@@ -25,14 +25,14 @@ class HexagonLinkingContext;
/// \brief TargetLayout for Hexagon
template <class HexagonELFType>
class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> {
-
public:
enum HexagonSectionOrder {
ORDER_SDATA = 205
};
HexagonTargetLayout(const HexagonLinkingContext &hti)
- : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr) {
+ : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr),
+ _gotSymAtom(nullptr), _cachedGotSymAtom(false) {
_sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti);
}
@@ -84,9 +84,22 @@ public:
return _sdataSection;
}
+ uint64_t getGOTSymAddr() {
+ if (!_cachedGotSymAtom) {
+ auto gotAtomIter = this->findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _gotSymAtom = (*gotAtomIter);
+ _cachedGotSymAtom = true;
+ }
+ if (_gotSymAtom)
+ return _gotSymAtom->_virtualAddr;
+ return 0;
+ }
+
private:
llvm::BumpPtrAllocator _alloc;
SDataSection<HexagonELFType> *_sdataSection;
+ AtomLayout *_gotSymAtom;
+ bool _cachedGotSymAtom;
};
/// \brief TargetHandler for Hexagon
@@ -97,64 +110,12 @@ public:
virtual void registerRelocationNames(Registry ®istry);
- bool doesOverrideELFHeader() { return true; }
-
- void setELFHeader(ELFHeader<HexagonELFType> *elfHeader) {
- elfHeader->e_ident(llvm::ELF::EI_VERSION, 1);
- elfHeader->e_ident(llvm::ELF::EI_OSABI, 0);
- elfHeader->e_version(1);
- elfHeader->e_flags(0x3);
- }
-
- virtual HexagonTargetLayout<HexagonELFType> &targetLayout() {
- return _targetLayout;
- }
-
virtual const HexagonTargetRelocationHandler &getRelocationHandler() const {
- return _relocationHandler;
- }
-
- void addDefaultAtoms() {
- _hexagonRuntimeFile->addAbsoluteAtom("_SDA_BASE_");
- if (_context.isDynamic()) {
- _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
- }
- }
-
- virtual bool
- createImplicitFiles(std::vector<std::unique_ptr<File> > &result) {
- // Add the default atoms as defined for hexagon
- addDefaultAtoms();
- result.push_back(std::move(_hexagonRuntimeFile));
- return true;
- }
-
- void finalizeSymbolValues() {
- auto sdabaseAtomIter = _targetLayout.findAbsoluteAtom("_SDA_BASE_");
- (*sdabaseAtomIter)->_virtualAddr =
- _targetLayout.getSDataSection()->virtualAddr();
- if (_context.isDynamic()) {
- auto gotAtomIter =
- _targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- _gotSymAtom = (*gotAtomIter);
- auto gotpltSection = _targetLayout.findOutputSection(".got.plt");
- if (gotpltSection)
- _gotSymAtom->_virtualAddr = gotpltSection->virtualAddr();
- else
- _gotSymAtom->_virtualAddr = 0;
- auto dynamicAtomIter = _targetLayout.findAbsoluteAtom("_DYNAMIC");
- auto dynamicSection = _targetLayout.findOutputSection(".dynamic");
- if (dynamicSection)
- (*dynamicAtomIter)->_virtualAddr = dynamicSection->virtualAddr();
- else
- (*dynamicAtomIter)->_virtualAddr = 0;
- }
+ return *(_hexagonRelocationHandler.get());
}
- uint64_t getGOTSymAddr() const {
- if (!_gotSymAtom) return 0;
- return _gotSymAtom->_virtualAddr;
+ virtual HexagonTargetLayout<HexagonELFType> &getTargetLayout() {
+ return *(_hexagonTargetLayout.get());
}
virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
@@ -165,13 +126,15 @@ public:
return std::unique_ptr<Reader>(new HexagonELFDSOReader(useShlibUndefines));
}
+ virtual std::unique_ptr<Writer> getWriter();
+
private:
+ llvm::BumpPtrAllocator _alloc;
static const Registry::KindStrings kindStrings[];
-
- HexagonTargetLayout<HexagonELFType> _targetLayout;
- HexagonTargetRelocationHandler _relocationHandler;
+ HexagonLinkingContext &_hexagonLinkingContext;
std::unique_ptr<HexagonRuntimeFile<HexagonELFType> > _hexagonRuntimeFile;
- AtomLayout *_gotSymAtom;
+ std::unique_ptr<HexagonTargetLayout<HexagonELFType>> _hexagonTargetLayout;
+ std::unique_ptr<HexagonTargetRelocationHandler> _hexagonRelocationHandler;
};
} // end namespace elf
} // end namespace lld
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,102 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h ---------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_DYNAMIC_LIBRARY_WRITER_H
+#define MIPS_DYNAMIC_LIBRARY_WRITER_H
+
+#include "DynamicLibraryWriter.h"
+#include "MipsELFWriters.h"
+#include "MipsLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class MipsTargetLayout;
+
+template <class ELFT>
+class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT>,
+ public MipsELFWriter<ELFT> {
+public:
+ MipsDynamicLibraryWriter(MipsLinkingContext &context,
+ MipsTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues();
+
+ virtual error_code setELFHeader() {
+ DynamicLibraryWriter<ELFT>::setELFHeader();
+ MipsELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+ return error_code::success();
+ }
+
+ LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
+
+ LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable();
+
+private:
+ void addDefaultAtoms() {
+ if (this->_context.isDynamic()) {
+ _mipsRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _mipsRuntimeFile->addAbsoluteAtom("_gp");
+ _mipsRuntimeFile->addAbsoluteAtom("_gp_disp");
+ }
+ }
+
+ std::unique_ptr<MipsRuntimeFile<ELFT>> _mipsRuntimeFile;
+ MipsLinkingContext &_mipsContext;
+ MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
+
+template <class ELFT>
+MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
+ MipsLinkingContext &context, MipsTargetLayout<ELFT> &layout)
+ : DynamicLibraryWriter<ELFT>(context, layout),
+ MipsELFWriter<ELFT>(context, layout),
+ _mipsRuntimeFile(new MipsRuntimeFile<ELFT>(context)),
+ _mipsContext(context), _mipsTargetLayout(layout) {}
+
+template <class ELFT>
+bool MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+ // Add the default atoms as defined for mips
+ addDefaultAtoms();
+ result.push_back(std::move(_mipsRuntimeFile));
+ return true;
+}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+ // Finalize the atom values that are part of the parent.
+ DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+ MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues();
+}
+
+/// \brief create dynamic table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
+ MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
+ return LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)(new (
+ this->_alloc) MipsDynamicTable(_mipsContext, _mipsTargetLayout));
+}
+
+/// \brief create dynamic symbol table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+ MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
+ return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)(new (
+ this->_alloc) MipsDynamicSymbolTable(_mipsContext, _mipsTargetLayout));
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // MIPS_DYNAMIC_LIBRARY_WRITER_H
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,75 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsELFWriters.h -------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MIPS_ELF_WRITERS_H
+#define MIPS_ELF_WRITERS_H
+
+#include "MipsLinkingContext.h"
+#include "OutputELFWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class MipsTargetLayout;
+
+template <typename ELFT> class MipsELFWriter {
+public:
+ MipsELFWriter(MipsLinkingContext &context,
+ MipsTargetLayout<ELFT> &targetLayout)
+ : _mipsLinkingContext(context), _mipsTargetLayout(targetLayout) {}
+
+protected:
+ bool setELFHeader(ELFHeader<ELFT> &elfHeader) {
+ elfHeader.e_version(1);
+ elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
+ elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
+ if (_mipsTargetLayout.findOutputSection(".got.plt"))
+ elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1);
+ else
+ elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
+
+ // FIXME (simon): Read elf flags from all inputs, check compatibility,
+ // merge them and write result here.
+ uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 |
+ llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2;
+ if (_mipsLinkingContext.getOutputELFType() == llvm::ELF::ET_DYN)
+ flags |= EF_MIPS_PIC;
+ elfHeader.e_flags(flags);
+ return true;
+ }
+
+ void finalizeMipsRuntimeAtomValues() {
+ if (_mipsLinkingContext.isDynamic()) {
+ auto gotSection = _mipsTargetLayout.findOutputSection(".got");
+ auto got = gotSection ? gotSection->virtualAddr() : 0;
+ auto gp = gotSection ? got + _mipsTargetLayout.getGPOffset() : 0;
+
+ auto gotAtomIter =
+ _mipsTargetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ assert(gotAtomIter != _mipsTargetLayout.absoluteAtoms().end());
+ (*gotAtomIter)->_virtualAddr = got;
+
+ auto gpAtomIter = _mipsTargetLayout.findAbsoluteAtom("_gp");
+ assert(gpAtomIter != _mipsTargetLayout.absoluteAtoms().end());
+ (*gpAtomIter)->_virtualAddr = gp;
+
+ AtomLayout *gpAtom = _mipsTargetLayout.getGP();
+ assert(gpAtom != nullptr);
+ gpAtom->_virtualAddr = gp;
+ }
+ }
+
+private:
+ MipsLinkingContext &_mipsLinkingContext LLVM_ATTRIBUTE_UNUSED;
+ MipsTargetLayout<ELFT> &_mipsTargetLayout;
+};
+
+} // elf
+} // lld
+#endif // MIPS_ELF_WRITERS_H
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,102 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h -------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_EXECUTABLE_WRITER_H
+#define MIPS_EXECUTABLE_WRITER_H
+
+#include "ExecutableWriter.h"
+#include "MipsELFWriters.h"
+#include "MipsLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class MipsTargetLayout;
+
+template <class ELFT>
+class MipsExecutableWriter : public ExecutableWriter<ELFT>,
+ public MipsELFWriter<ELFT> {
+public:
+ MipsExecutableWriter(MipsLinkingContext &context,
+ MipsTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues();
+
+ virtual error_code setELFHeader() {
+ ExecutableWriter<ELFT>::setELFHeader();
+ MipsELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+ return error_code::success();
+ }
+
+ LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
+
+ LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable();
+
+private:
+ void addDefaultAtoms() {
+ if (this->_context.isDynamic()) {
+ _mipsRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _mipsRuntimeFile->addAbsoluteAtom("_gp");
+ _mipsRuntimeFile->addAbsoluteAtom("_gp_disp");
+ }
+ }
+
+ std::unique_ptr<MipsRuntimeFile<ELFT>> _mipsRuntimeFile;
+ MipsLinkingContext &_mipsContext;
+ MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
+
+template <class ELFT>
+MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &context,
+ MipsTargetLayout<ELFT> &layout)
+ : ExecutableWriter<ELFT>(context, layout),
+ MipsELFWriter<ELFT>(context, layout),
+ _mipsRuntimeFile(new MipsRuntimeFile<ELFT>(context)),
+ _mipsContext(context), _mipsTargetLayout(layout) {}
+
+template <class ELFT>
+bool MipsExecutableWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ ExecutableWriter<ELFT>::createImplicitFiles(result);
+ // Add the default atoms as defined for mips
+ addDefaultAtoms();
+ result.push_back(std::move(_mipsRuntimeFile));
+ return true;
+}
+
+template <class ELFT>
+void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
+ // Finalize the atom values that are part of the parent.
+ ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+ MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues();
+}
+
+/// \brief create dynamic table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
+ MipsExecutableWriter<ELFT>::createDynamicTable() {
+ return LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)(new (
+ this->_alloc) MipsDynamicTable(_mipsContext, _mipsTargetLayout));
+}
+
+/// \brief create dynamic symbol table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+ MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
+ return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)(new (
+ this->_alloc) MipsDynamicSymbolTable(_mipsContext, _mipsTargetLayout));
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // MIPS_EXECUTABLE_WRITER_H
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Sun Jan 26 19:21:02 2014
@@ -19,17 +19,6 @@ MipsLinkingContext::MipsLinkingContext(l
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new MipsTargetHandler(*this))) {}
-MipsTargetLayout<Mips32ElELFType> &MipsLinkingContext::getTargetLayout() {
- auto &layout = getTargetHandler<Mips32ElELFType>().targetLayout();
- return static_cast<MipsTargetLayout<Mips32ElELFType> &>(layout);
-}
-
-const MipsTargetLayout<Mips32ElELFType> &
-MipsLinkingContext::getTargetLayout() const {
- auto &layout = getTargetHandler<Mips32ElELFType>().targetLayout();
- return static_cast<MipsTargetLayout<Mips32ElELFType> &>(layout);
-}
-
bool MipsLinkingContext::isLittleEndian() const {
return Mips32ElELFType::TargetEndianness == llvm::support::little;
}
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Sun Jan 26 19:21:02 2014
@@ -112,10 +112,6 @@ void relocLldLo16(uint8_t *location, uin
} // end anon namespace
-MipsTargetRelocationHandler::MipsTargetRelocationHandler(
- const MipsLinkingContext &context, const MipsTargetHandler &handler)
- : _targetHandler(handler) {}
-
MipsTargetRelocationHandler::~MipsTargetRelocationHandler() {
assert(_pairedRelocations.empty());
}
@@ -132,7 +128,7 @@ MipsTargetRelocationHandler::savePairedR
void MipsTargetRelocationHandler::applyPairedRelocations(
ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
- int64_t loAddend) const {
+ int64_t gpAddr, int64_t loAddend) const {
auto pi = _pairedRelocations.find(&atom);
if (pi == _pairedRelocations.end())
return;
@@ -150,13 +146,11 @@ void MipsTargetRelocationHandler::applyP
assert(ri->kindArch() == Reference::KindArch::Mips);
switch (ri->kindValue()) {
case R_MIPS_HI16:
- relocHi16(location, relocVAddress, targetVAddress, ahl,
- _targetHandler.getGPDispSymAddr(),
+ relocHi16(location, relocVAddress, targetVAddress, ahl, gpAddr,
ri->target()->name() == "_gp_disp");
break;
case R_MIPS_GOT16:
- relocGOT16(location, relocVAddress, targetVAddress, ahl,
- _targetHandler.getGPDispSymAddr());
+ relocGOT16(location, relocVAddress, targetVAddress, ahl, gpAddr);
break;
default:
llvm_unreachable("Unknown type of paired relocation.");
@@ -169,6 +163,9 @@ void MipsTargetRelocationHandler::applyP
error_code MipsTargetRelocationHandler::applyRelocation(
ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
const Reference &ref) const {
+ AtomLayout *gpAtom = _mipsTargetLayout.getGP();
+ uint64_t gpAddr = gpAtom ? gpAtom->_virtualAddr : 0;
+
uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
uint8_t *location = atomContent + ref.offsetInAtom();
uint64_t targetVAddress = writer.addressOfAtom(ref.target());
@@ -191,16 +188,14 @@ error_code MipsTargetRelocationHandler::
break;
case R_MIPS_LO16:
relocLo16(location, relocVAddress, targetVAddress, calcAHL(0, ref.addend()),
- _targetHandler.getGPDispSymAddr(),
- ref.target()->name() == "_gp_disp");
- applyPairedRelocations(writer, buf, atom, ref.addend());
+ gpAddr, ref.target()->name() == "_gp_disp");
+ applyPairedRelocations(writer, buf, atom, gpAddr, ref.addend());
break;
case R_MIPS_GOT16:
savePairedRelocation(atom, ref);
break;
case R_MIPS_CALL16:
- relocCall16(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGPDispSymAddr());
+ relocCall16(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
break;
case R_MIPS_JALR:
// We do not do JALR optimization now.
@@ -212,8 +207,7 @@ error_code MipsTargetRelocationHandler::
// Do nothing.
break;
case LLD_R_MIPS_GLOBAL_GOT16:
- relocGOT16(location, relocVAddress, targetVAddress, ref.addend(),
- _targetHandler.getGPDispSymAddr());
+ relocGOT16(location, relocVAddress, targetVAddress, ref.addend(), gpAddr);
break;
case LLD_R_MIPS_GLOBAL_26:
reloc26(location, relocVAddress, targetVAddress, false);
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h Sun Jan 26 19:21:02 2014
@@ -19,8 +19,9 @@ class MipsTargetHandler;
class MipsTargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<Mips32ElELFType> {
public:
- MipsTargetRelocationHandler(const MipsLinkingContext &context,
- const MipsTargetHandler &handler);
+ MipsTargetRelocationHandler(MipsLinkingContext &context,
+ MipsTargetLayout<Mips32ElELFType> &layout)
+ : _mipsLinkingContext(context), _mipsTargetLayout(layout) {}
~MipsTargetRelocationHandler();
@@ -29,8 +30,6 @@ public:
const Reference &) const;
private:
- const MipsTargetHandler &_targetHandler;
-
typedef std::vector<const Reference *> PairedRelocationsT;
typedef std::unordered_map<const lld::AtomLayout *, PairedRelocationsT>
PairedRelocationMapT;
@@ -40,8 +39,11 @@ private:
void savePairedRelocation(const lld::AtomLayout &atom,
const Reference &ref) const;
void applyPairedRelocations(ELFWriter &writer, llvm::FileOutputBuffer &buf,
- const lld::AtomLayout &atom,
+ const lld::AtomLayout &atom, int64_t gpAddr,
int64_t loAddend) const;
+
+ MipsLinkingContext &_mipsLinkingContext LLVM_ATTRIBUTE_UNUSED;
+ MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
};
} // elf
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -10,201 +10,35 @@
#include "ELFFile.h"
#include "MipsLinkingContext.h"
#include "MipsTargetHandler.h"
+#include "MipsExecutableWriter.h"
+#include "MipsDynamicLibraryWriter.h"
using namespace lld;
using namespace elf;
-namespace {
-
-class MipsDynamicSymbolTable : public DynamicSymbolTable<Mips32ElELFType> {
-public:
- MipsDynamicSymbolTable(const MipsLinkingContext &context)
- : DynamicSymbolTable<Mips32ElELFType>(
- context, ".dynsym",
- DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC_SYMBOLS),
- _layout(context.getTargetLayout()) {}
-
- virtual void sortSymbols() {
- std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
- [this](const SymbolEntry &A, const SymbolEntry &B) {
- if (A._symbol.getBinding() != STB_GLOBAL &&
- B._symbol.getBinding() != STB_GLOBAL)
- return A._symbol.getBinding() < B._symbol.getBinding();
-
- return _layout.getGOTSection().compare(A._atom, B._atom);
- });
- }
-
-private:
- const MipsTargetLayout<Mips32ElELFType> &_layout;
-};
-
-class MipsDynamicTable : public DynamicTable<Mips32ElELFType> {
-public:
- MipsDynamicTable(MipsLinkingContext &context)
- : DynamicTable<Mips32ElELFType>(
- context, ".dynamic", DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC),
- _layout(context.getTargetLayout()) {}
-
- virtual void createDefaultEntries() {
- DynamicTable<Mips32ElELFType>::createDefaultEntries();
-
- Elf_Dyn dyn;
-
- // Version id for the Runtime Linker Interface.
- dyn.d_un.d_val = 1;
- dyn.d_tag = DT_MIPS_RLD_VERSION;
- addEntry(dyn);
-
- // MIPS flags.
- dyn.d_un.d_val = RHF_NOTPOT;
- dyn.d_tag = DT_MIPS_FLAGS;
- addEntry(dyn);
-
- // The base address of the segment.
- dyn.d_un.d_ptr = 0;
- dyn.d_tag = DT_MIPS_BASE_ADDRESS;
- _dt_baseaddr = addEntry(dyn);
-
- // Number of local global offset table entries.
- dyn.d_un.d_val = 0;
- dyn.d_tag = DT_MIPS_LOCAL_GOTNO;
- _dt_localgot = addEntry(dyn);
-
- // Number of entries in the .dynsym section.
- dyn.d_un.d_val = 0;
- dyn.d_tag = DT_MIPS_SYMTABNO;
- _dt_symtabno = addEntry(dyn);
-
- // The index of the first dynamic symbol table entry that corresponds
- // to an entry in the global offset table.
- dyn.d_un.d_val = 0;
- dyn.d_tag = DT_MIPS_GOTSYM;
- _dt_gotsym = addEntry(dyn);
-
- // Address of the .got section.
- dyn.d_un.d_val = 0;
- dyn.d_tag = DT_PLTGOT;
- _dt_pltgot = addEntry(dyn);
- }
-
- virtual void updateDynamicTable() {
- DynamicTable<Mips32ElELFType>::updateDynamicTable();
-
- // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag.
- auto baseAddr = std::numeric_limits<uint64_t>::max();
- for (auto si : _layout.segments())
- if (si->segmentType() != llvm::ELF::PT_NULL)
- baseAddr = std::min(baseAddr, si->virtualAddr());
- _entries[_dt_baseaddr].d_un.d_val = baseAddr;
-
- auto &got = _layout.getGOTSection();
-
- _entries[_dt_symtabno].d_un.d_val = getSymbolTable()->size();
- _entries[_dt_gotsym].d_un.d_val =
- getSymbolTable()->size() - got.getGlobalCount();
- _entries[_dt_localgot].d_un.d_val = got.getLocalCount();
- _entries[_dt_pltgot].d_un.d_ptr =
- _layout.findOutputSection(".got")->virtualAddr();
- }
-
-private:
- MipsTargetLayout<Mips32ElELFType> &_layout;
-
- std::size_t _dt_symtabno;
- std::size_t _dt_localgot;
- std::size_t _dt_gotsym;
- std::size_t _dt_pltgot;
- std::size_t _dt_baseaddr;
-};
-}
+typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType;
MipsTargetHandler::MipsTargetHandler(MipsLinkingContext &context)
- : DefaultTargetHandler(context), _targetLayout(context),
- _relocationHandler(context, *this), _gpDispSymAtom(nullptr) {}
-
-uint64_t MipsTargetHandler::getGPDispSymAddr() const {
- return _gpDispSymAtom ? _gpDispSymAtom->_virtualAddr : 0;
-}
-
-bool MipsTargetHandler::doesOverrideELFHeader() { return true; }
-
-void MipsTargetHandler::setELFHeader(ELFHeader<Mips32ElELFType> *elfHeader) {
- elfHeader->e_version(1);
-
- elfHeader->e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
- elfHeader->e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
- if (_targetLayout.findOutputSection(".got.plt"))
- elfHeader->e_ident(llvm::ELF::EI_ABIVERSION, 1);
- else
- elfHeader->e_ident(llvm::ELF::EI_ABIVERSION, 0);
-
- // FIXME (simon): Read elf flags from all inputs, check compatibility,
- // merge them and write result here.
- uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 |
- llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2;
- if (_context.getOutputELFType() == llvm::ELF::ET_DYN)
- flags |= EF_MIPS_PIC;
- elfHeader->e_flags(flags);
-}
-
-MipsTargetLayout<Mips32ElELFType> &MipsTargetHandler::targetLayout() {
- return _targetLayout;
-}
-
-const MipsTargetRelocationHandler &
-MipsTargetHandler::getRelocationHandler() const {
- return _relocationHandler;
-}
-
-LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)
-MipsTargetHandler::createDynamicTable() {
- return LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)(
- new (_alloc) MipsDynamicTable(
- static_cast<MipsLinkingContext &>(_context)));
-}
-
-LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)
-MipsTargetHandler::createDynamicSymbolTable() {
- return LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)(
- new (_alloc) MipsDynamicSymbolTable(
- static_cast<MipsLinkingContext &>(_context)));
-}
-
-bool MipsTargetHandler::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- typedef CRuntimeFile<Mips32ElELFType> RFile;
- auto file = std::unique_ptr<RFile>(new RFile(_context, "MIPS runtime file"));
-
- if (_context.isDynamic()) {
- file->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- file->addAbsoluteAtom("_gp");
- file->addAbsoluteAtom("_gp_disp");
- }
- result.push_back(std::move(file));
- return true;
-}
-
-void MipsTargetHandler::finalizeSymbolValues() {
- DefaultTargetHandler<Mips32ElELFType>::finalizeSymbolValues();
-
- if (_context.isDynamic()) {
- auto gotSection = _targetLayout.findOutputSection(".got");
- auto got = gotSection ? gotSection->virtualAddr() : 0;
- auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
-
- auto gotAtomIter = _targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
- assert(gotAtomIter != _targetLayout.absoluteAtoms().end());
- (*gotAtomIter)->_virtualAddr = got;
-
- auto gpAtomIter = _targetLayout.findAbsoluteAtom("_gp");
- assert(gpAtomIter != _targetLayout.absoluteAtoms().end());
- (*gpAtomIter)->_virtualAddr = gp;
-
- auto gpDispAtomIter = _targetLayout.findAbsoluteAtom("_gp_disp");
- assert(gpDispAtomIter != _targetLayout.absoluteAtoms().end());
- _gpDispSymAtom = (*gpDispAtomIter);
- _gpDispSymAtom->_virtualAddr = gp;
+ : DefaultTargetHandler(context), _mipsLinkingContext(context),
+ _mipsRuntimeFile(new MipsRuntimeFile<Mips32ElELFType>(context)),
+ _mipsTargetLayout(new MipsTargetLayout<Mips32ElELFType>(context)),
+ _mipsRelocationHandler(
+ new MipsTargetRelocationHandler(context, *_mipsTargetLayout.get())) {}
+
+std::unique_ptr<Writer> MipsTargetHandler::getWriter() {
+ switch (_mipsLinkingContext.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return std::unique_ptr<Writer>(
+ new elf::MipsExecutableWriter<Mips32ElELFType>(
+ _mipsLinkingContext, *_mipsTargetLayout.get()));
+ case llvm::ELF::ET_DYN:
+ return std::unique_ptr<Writer>(
+ new elf::MipsDynamicLibraryWriter<Mips32ElELFType>(
+ _mipsLinkingContext, *_mipsTargetLayout.get()));
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
}
}
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -24,10 +24,8 @@ class MipsTargetLayout LLVM_FINAL : publ
public:
MipsTargetLayout(const MipsLinkingContext &ctx)
: TargetLayout<ELFType>(ctx),
- _gotSection(new (_alloc) MipsGOTSection<ELFType>(ctx)) {}
-
- /// \brief GP offset relative to .got section.
- uint64_t getGPOffset() const { return 0x7FF0; }
+ _gotSection(new (_alloc) MipsGOTSection<ELFType>(ctx)),
+ _cachedGP(false) {}
const MipsGOTSection<ELFType> &getGOTSection() const { return *_gotSection; }
@@ -41,39 +39,162 @@ public:
order);
}
+ /// \brief GP offset relative to .got section.
+ uint64_t getGPOffset() const { return 0x7FF0; }
+
+ /// \brief Get the cached value of the GP atom.
+ AtomLayout *getGP() {
+ if (!_cachedGP) {
+ auto gpAtomIter = this->findAbsoluteAtom("_gp_disp");
+ _gp = *(gpAtomIter);
+ _cachedGP = true;
+ }
+ return _gp;
+ }
+
private:
llvm::BumpPtrAllocator _alloc;
MipsGOTSection<ELFType> *_gotSection;
+ AtomLayout *_gp;
+ bool _cachedGP;
+};
+
+/// \brief Mips Runtime file.
+template <class ELFType> class MipsRuntimeFile : public CRuntimeFile<ELFType> {
+public:
+ MipsRuntimeFile(const MipsLinkingContext &context)
+ : CRuntimeFile<ELFType>(context, "Mips runtime file") {}
};
/// \brief TargetHandler for Mips
class MipsTargetHandler LLVM_FINAL
: public DefaultTargetHandler<Mips32ElELFType> {
public:
- MipsTargetHandler(MipsLinkingContext &targetInfo);
+ MipsTargetHandler(MipsLinkingContext &context);
+
+ virtual MipsTargetLayout<Mips32ElELFType> &getTargetLayout() {
+ return *(_mipsTargetLayout.get());
+ }
+
+ virtual const MipsTargetRelocationHandler &getRelocationHandler() const {
+ return *(_mipsRelocationHandler.get());
+ }
- uint64_t getGPDispSymAddr() const;
+ virtual std::unique_ptr<Writer> getWriter();
- virtual bool doesOverrideELFHeader();
- virtual void setELFHeader(ELFHeader<Mips32ElELFType> *elfHeader);
- virtual MipsTargetLayout<Mips32ElELFType> &targetLayout();
- virtual const MipsTargetRelocationHandler &getRelocationHandler() const;
- virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<Mips32ElELFType>)
- createDynamicTable();
- virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<Mips32ElELFType>)
- createDynamicSymbolTable();
- virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &result);
- virtual void finalizeSymbolValues();
virtual void registerRelocationNames(Registry ®istry);
private:
static const Registry::KindStrings kindStrings[];
- llvm::BumpPtrAllocator _alloc;
- MipsTargetLayout<Mips32ElELFType> _targetLayout;
- MipsTargetRelocationHandler _relocationHandler;
- AtomLayout *_gpDispSymAtom;
+ MipsLinkingContext &_mipsLinkingContext;
+ std::unique_ptr<MipsRuntimeFile<Mips32ElELFType>> _mipsRuntimeFile;
+ std::unique_ptr<MipsTargetLayout<Mips32ElELFType>> _mipsTargetLayout;
+ std::unique_ptr<MipsTargetRelocationHandler> _mipsRelocationHandler;
};
+class MipsDynamicSymbolTable : public DynamicSymbolTable<Mips32ElELFType> {
+public:
+ MipsDynamicSymbolTable(const MipsLinkingContext &context,
+ MipsTargetLayout<Mips32ElELFType> &layout)
+ : DynamicSymbolTable<Mips32ElELFType>(
+ context, layout, ".dynsym",
+ DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC_SYMBOLS),
+ _mipsTargetLayout(layout) {}
+
+ virtual void sortSymbols() {
+ std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
+ [this](const SymbolEntry &A, const SymbolEntry &B) {
+ if (A._symbol.getBinding() != STB_GLOBAL &&
+ B._symbol.getBinding() != STB_GLOBAL)
+ return A._symbol.getBinding() < B._symbol.getBinding();
+
+ return _mipsTargetLayout.getGOTSection().compare(A._atom, B._atom);
+ });
+ }
+
+private:
+ MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
+
+class MipsDynamicTable : public DynamicTable<Mips32ElELFType> {
+public:
+ MipsDynamicTable(MipsLinkingContext &context,
+ MipsTargetLayout<Mips32ElELFType> &layout)
+ : DynamicTable<Mips32ElELFType>(
+ context, layout, ".dynamic",
+ DefaultLayout<Mips32ElELFType>::ORDER_DYNAMIC),
+ _mipsTargetLayout(layout) {}
+
+ virtual void createDefaultEntries() {
+ DynamicTable<Mips32ElELFType>::createDefaultEntries();
+
+ Elf_Dyn dyn;
+
+ // Version id for the Runtime Linker Interface.
+ dyn.d_un.d_val = 1;
+ dyn.d_tag = DT_MIPS_RLD_VERSION;
+ addEntry(dyn);
+
+ // MIPS flags.
+ dyn.d_un.d_val = RHF_NOTPOT;
+ dyn.d_tag = DT_MIPS_FLAGS;
+ addEntry(dyn);
+
+ // The base address of the segment.
+ dyn.d_un.d_ptr = 0;
+ dyn.d_tag = DT_MIPS_BASE_ADDRESS;
+ _dt_baseaddr = addEntry(dyn);
+
+ // Number of local global offset table entries.
+ dyn.d_un.d_val = 0;
+ dyn.d_tag = DT_MIPS_LOCAL_GOTNO;
+ _dt_localgot = addEntry(dyn);
+
+ // Number of entries in the .dynsym section.
+ dyn.d_un.d_val = 0;
+ dyn.d_tag = DT_MIPS_SYMTABNO;
+ _dt_symtabno = addEntry(dyn);
+
+ // The index of the first dynamic symbol table entry that corresponds
+ // to an entry in the global offset table.
+ dyn.d_un.d_val = 0;
+ dyn.d_tag = DT_MIPS_GOTSYM;
+ _dt_gotsym = addEntry(dyn);
+
+ // Address of the .got section.
+ dyn.d_un.d_val = 0;
+ dyn.d_tag = DT_PLTGOT;
+ _dt_pltgot = addEntry(dyn);
+ }
+
+ virtual void updateDynamicTable() {
+ DynamicTable<Mips32ElELFType>::updateDynamicTable();
+
+ // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag.
+ auto baseAddr = std::numeric_limits<uint64_t>::max();
+ for (auto si : _mipsTargetLayout.segments())
+ if (si->segmentType() != llvm::ELF::PT_NULL)
+ baseAddr = std::min(baseAddr, si->virtualAddr());
+ _entries[_dt_baseaddr].d_un.d_val = baseAddr;
+
+ auto &got = _mipsTargetLayout.getGOTSection();
+
+ _entries[_dt_symtabno].d_un.d_val = getSymbolTable()->size();
+ _entries[_dt_gotsym].d_un.d_val =
+ getSymbolTable()->size() - got.getGlobalCount();
+ _entries[_dt_localgot].d_un.d_val = got.getLocalCount();
+ _entries[_dt_pltgot].d_un.d_ptr =
+ _mipsTargetLayout.findOutputSection(".got")->virtualAddr();
+ }
+
+private:
+ std::size_t _dt_symtabno;
+ std::size_t _dt_localgot;
+ std::size_t _dt_gotsym;
+ std::size_t _dt_pltgot;
+ std::size_t _dt_baseaddr;
+ MipsTargetLayout<Mips32ElELFType> &_mipsTargetLayout;
+};
} // end namespace elf
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Sun Jan 26 19:21:02 2014
@@ -26,6 +26,7 @@ using namespace llvm;
using namespace llvm::object;
template <class ELFT> class OutputELFWriter;
+template <class ELFT> class TargetLayout;
//===----------------------------------------------------------------------===//
// OutputELFWriter Class
@@ -41,7 +42,7 @@ public:
typedef Elf_Sym_Impl<ELFT> Elf_Sym;
typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
- OutputELFWriter(const ELFLinkingContext &context);
+ OutputELFWriter(const ELFLinkingContext &context, TargetLayout<ELFT> &layout);
protected:
// build the sections that need to be created
@@ -100,6 +101,13 @@ protected:
// This is a hook for creating default dynamic entries
virtual void createDefaultDynamicEntries() {}
+ /// \brief create dynamic table.
+ virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
+
+ /// \brief create dynamic symbol table.
+ virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+ createDynamicSymbolTable();
+
llvm::BumpPtrAllocator _alloc;
const ELFLinkingContext &_context;
@@ -107,7 +115,7 @@ protected:
typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
AtomToAddress _atomToAddressMap;
- TargetLayout<ELFT> *_layout;
+ TargetLayout<ELFT> &_layout;
LLD_UNIQUE_BUMP_PTR(ELFHeader<ELFT>) _elfHeader;
LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
@@ -129,29 +137,29 @@ protected:
// OutputELFWriter
//===----------------------------------------------------------------------===//
template <class ELFT>
-OutputELFWriter<ELFT>::OutputELFWriter(const ELFLinkingContext &context)
- : _context(context), _targetHandler(context.getTargetHandler<ELFT>()) {
- _layout = &_targetHandler.targetLayout();
-}
+OutputELFWriter<ELFT>::OutputELFWriter(const ELFLinkingContext &context,
+ TargetLayout<ELFT> &layout)
+ : _context(context), _targetHandler(context.getTargetHandler<ELFT>()),
+ _layout(layout) {}
template <class ELFT>
void OutputELFWriter<ELFT>::buildChunks(const File &file) {
ScopedTask task(getDefaultDomain(), "buildChunks");
for (const DefinedAtom *definedAtom : file.defined()) {
- _layout->addAtom(definedAtom);
+ _layout.addAtom(definedAtom);
}
for (const AbsoluteAtom *absoluteAtom : file.absolute())
- _layout->addAtom(absoluteAtom);
+ _layout.addAtom(absoluteAtom);
}
template <class ELFT>
void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) {
ScopedTask task(getDefaultDomain(), "buildStaticSymbolTable");
- for (auto sec : _layout->sections())
+ for (auto sec : _layout.sections())
if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
for (const auto &atom : section->atoms())
_symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
- for (auto &atom : _layout->absoluteAtoms())
+ for (auto &atom : _layout.absoluteAtoms())
_symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
for (const UndefinedAtom *a : file.undefined())
_symtab->addSymbol(a, ELF::SHN_UNDEF);
@@ -160,7 +168,7 @@ void OutputELFWriter<ELFT>::buildStaticS
template <class ELFT>
void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
- for (auto sec : this->_layout->sections())
+ for (auto sec : this->_layout.sections())
if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
for (const auto &atom : section->atoms()) {
const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
@@ -208,17 +216,17 @@ void OutputELFWriter<ELFT>::buildDynamic
template <class ELFT>
void OutputELFWriter<ELFT>::buildAtomToAddressMap(const File &file) {
ScopedTask task(getDefaultDomain(), "buildAtomToAddressMap");
- int64_t totalAbsAtoms = _layout->absoluteAtoms().size();
+ int64_t totalAbsAtoms = _layout.absoluteAtoms().size();
int64_t totalUndefinedAtoms = file.undefined().size();
int64_t totalDefinedAtoms = 0;
- for (auto sec : _layout->sections())
+ for (auto sec : _layout.sections())
if (auto section = dyn_cast<AtomSection<ELFT> >(sec)) {
totalDefinedAtoms += section->atoms().size();
for (const auto &atom : section->atoms())
_atomToAddressMap[atom->_atom] = atom->_virtualAddr;
}
// build the atomToAddressMap that contains absolute symbols too
- for (auto &atom : _layout->absoluteAtoms())
+ for (auto &atom : _layout.absoluteAtoms())
_atomToAddressMap[atom->_atom] = atom->_virtualAddr;
// Set the total number of atoms in the symbol table, so that appropriate
@@ -230,7 +238,7 @@ void OutputELFWriter<ELFT>::buildAtomToA
template<class ELFT>
void OutputELFWriter<ELFT>::buildSectionHeaderTable() {
ScopedTask task(getDefaultDomain(), "buildSectionHeaderTable");
- for (auto mergedSec : _layout->mergedSections()) {
+ for (auto mergedSec : _layout.mergedSections()) {
if (mergedSec->kind() != Chunk<ELFT>::Kind::ELFSection &&
mergedSec->kind() != Chunk<ELFT>::Kind::AtomSection)
continue;
@@ -242,15 +250,15 @@ void OutputELFWriter<ELFT>::buildSection
template<class ELFT>
void OutputELFWriter<ELFT>::assignSectionsWithNoSegments() {
ScopedTask task(getDefaultDomain(), "assignSectionsWithNoSegments");
- for (auto mergedSec : _layout->mergedSections()) {
+ for (auto mergedSec : _layout.mergedSections()) {
if (mergedSec->kind() != Chunk<ELFT>::Kind::ELFSection &&
mergedSec->kind() != Chunk<ELFT>::Kind::AtomSection)
continue;
if (!mergedSec->hasSegment())
_shdrtab->appendSection(mergedSec);
}
- _layout->assignOffsetsForMiscSections();
- for (auto sec : _layout->sections())
+ _layout.assignOffsetsForMiscSections();
+ for (auto sec : _layout.sections())
if (auto section = dyn_cast<Section<ELFT>>(sec))
if (!DefaultLayout<ELFT>::hasOutputSegment(section))
_shdrtab->updateSection(section);
@@ -258,17 +266,15 @@ void OutputELFWriter<ELFT>::assignSectio
template <class ELFT>
bool OutputELFWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File> > &result) {
- // Add all input Files that are defined by the target
- _targetHandler.createImplicitFiles(result);
+ std::vector<std::unique_ptr<File>> &) {
return true;
}
template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
_elfHeader.reset(new (_alloc) ELFHeader<ELFT>(_context));
_programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_context));
- _layout->setHeader(_elfHeader.get());
- _layout->setProgramHeader(_programHeader.get());
+ _layout.setHeader(_elfHeader.get());
+ _layout.setProgramHeader(_programHeader.get());
_symtab.reset(new (_alloc) SymbolTable<ELFT>(
_context, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
@@ -278,50 +284,67 @@ template <class ELFT> void OutputELFWrit
_context, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
_shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
_context, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
- _layout->addSection(_symtab.get());
- _layout->addSection(_strtab.get());
- _layout->addSection(_shstrtab.get());
+ _layout.addSection(_symtab.get());
+ _layout.addSection(_strtab.get());
+ _layout.addSection(_shstrtab.get());
_shdrtab->setStringSection(_shstrtab.get());
_symtab->setStringSection(_strtab.get());
- _layout->addSection(_shdrtab.get());
+ _layout.addSection(_shdrtab.get());
- for (auto sec : _layout->sections()) {
+ for (auto sec : _layout.sections()) {
if (sec->name() != ".eh_frame")
continue;
_ehFrameHeader.reset(new (_alloc) EHFrameHeader<ELFT>(
- _context, ".eh_frame_hdr", DefaultLayout<ELFT>::ORDER_EH_FRAMEHDR));
- _layout->addSection(_ehFrameHeader.get());
+ _context, ".eh_frame_hdr", _layout,
+ DefaultLayout<ELFT>::ORDER_EH_FRAMEHDR));
+ _layout.addSection(_ehFrameHeader.get());
break;
}
if (_context.isDynamic()) {
- _dynamicTable = std::move(_targetHandler.createDynamicTable());
+ _dynamicTable = std::move(createDynamicTable());
_dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
_context, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS, true));
- _dynamicSymbolTable = std::move(_targetHandler.createDynamicSymbolTable());
+ _dynamicSymbolTable = std::move(createDynamicSymbolTable());
_hashTable.reset(new (_alloc) HashSection<ELFT>(
_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());
_hashTable->setSymbolTable(_dynamicSymbolTable.get());
- _layout->addSection(_dynamicTable.get());
- _layout->addSection(_dynamicStringTable.get());
- _layout->addSection(_dynamicSymbolTable.get());
- _layout->addSection(_hashTable.get());
+ _layout.addSection(_dynamicTable.get());
+ _layout.addSection(_dynamicStringTable.get());
+ _layout.addSection(_dynamicSymbolTable.get());
+ _layout.addSection(_hashTable.get());
_dynamicSymbolTable->setStringSection(_dynamicStringTable.get());
_dynamicTable->setSymbolTable(_dynamicSymbolTable.get());
_dynamicTable->setHashTable(_hashTable.get());
- if (_layout->hasDynamicRelocationTable())
- _layout->getDynamicRelocationTable()
- ->setSymbolTable(_dynamicSymbolTable.get());
- if (_layout->hasPLTRelocationTable())
- _layout->getPLTRelocationTable()->setSymbolTable(
+ if (_layout.hasDynamicRelocationTable())
+ _layout.getDynamicRelocationTable()->setSymbolTable(
+ _dynamicSymbolTable.get());
+ if (_layout.hasPLTRelocationTable())
+ _layout.getPLTRelocationTable()->setSymbolTable(
_dynamicSymbolTable.get());
}
+}
- // give a chance for the target to add sections
- _targetHandler.createDefaultSections();
+/// \brief create dynamic table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
+ OutputELFWriter<ELFT>::createDynamicTable() {
+ return LLD_UNIQUE_BUMP_PTR(
+ DynamicTable<ELFT>)(new (_alloc) DynamicTable<ELFT>(
+ this->_context, _layout, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
+}
+
+/// \brief create dynamic symbol table
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
+ OutputELFWriter<ELFT>::createDynamicSymbolTable() {
+ return LLD_UNIQUE_BUMP_PTR(
+ DynamicSymbolTable<ELFT>)(new (_alloc) DynamicSymbolTable<ELFT>(
+ this->_context, _layout, ".dynsym",
+ DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
}
template <class ELFT>
@@ -334,7 +357,7 @@ error_code OutputELFWriter<ELFT>::buildO
createDefaultSections();
// Set the Layout
- _layout->assignSectionsToSegments();
+ _layout.assignSectionsToSegments();
// Create the dynamic table entries
if (_context.isDynamic()) {
@@ -344,10 +367,10 @@ error_code OutputELFWriter<ELFT>::buildO
// Call the preFlight callbacks to modify the sections and the atoms
// contained in them, in anyway the targets may want
- _layout->doPreFlight();
+ _layout.doPreFlight();
- _layout->assignFileOffsets();
- _layout->assignVirtualAddress();
+ _layout.assignFileOffsets();
+ _layout.assignVirtualAddress();
// Finalize the default value of symbols that the linker adds
finalizeDefaultAtomValues();
@@ -359,7 +382,7 @@ error_code OutputELFWriter<ELFT>::buildO
buildStaticSymbolTable(file);
// Finalize the layout by calling the finalize() functions
- _layout->finalize();
+ _layout.finalize();
// build Section Header table
buildSectionHeaderTable();
@@ -393,7 +416,7 @@ template <class ELFT> error_code OutputE
_elfHeader->e_shnum(_shdrtab->numHeaders());
_elfHeader->e_shstrndx(_shstrtab->ordinal());
uint64_t virtualAddr = 0;
- _layout->findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
+ _layout.findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
_elfHeader->e_entry(virtualAddr);
return error_code::success();
@@ -420,11 +443,11 @@ error_code OutputELFWriter<ELFT>::writeO
// HACK: We have to write out the header and program header here even though
// they are a member of a segment because only sections are written in the
// following loop.
- _elfHeader->write(this, *buffer);
- _programHeader->write(this, *buffer);
+ _elfHeader->write(this, _layout, *buffer);
+ _programHeader->write(this, _layout, *buffer);
- for (auto section : _layout->sections())
- section->write(this, *buffer);
+ for (auto section : _layout.sections())
+ section->write(this, _layout, *buffer);
writeTask.end();
ScopedTask commitTask(getDefaultDomain(), "ELF Writer commit to disk");
Added: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFFile.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,38 @@
+//===- lib/ReaderWriter/ELF/PPCELFFile.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_PPC_ELF_FILE_H
+#define LLD_READER_WRITER_ELF_PPC_ELF_FILE_H
+
+#include "ELFReader.h"
+
+namespace lld {
+namespace elf {
+
+class PPCLinkingContext;
+
+template <class ELFT> class PPCELFFile : public ELFFile<ELFT> {
+public:
+ PPCELFFile(StringRef name) : ELFFile<ELFT>(name) {}
+
+ PPCELFFile(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
+ TargetHandlerBase *handler, error_code &ec)
+ : ELFFile<ELFT>(std::move(mb), atomizeStrings, handler, ec) {}
+};
+
+template <class ELFT> class PPCDynamicFile : public DynamicFile<ELFT> {
+public:
+ PPCDynamicFile(const PPCLinkingContext &context, StringRef name)
+ : DynamicFile<ELFT>(context, name) {}
+};
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_PPC_ELF_FILE_H
Added: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCELFReader.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,81 @@
+//===- lib/ReaderWriter/ELF/PPCELFReader.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_PPC_ELF_READER_H
+#define LLD_READER_WRITER_PPC_ELF_READER_H
+
+#include "ELFReader.h"
+#include "PPCELFFile.h"
+
+namespace lld {
+namespace elf {
+
+struct PPCDynamicFileCreateELFTraits {
+ typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
+
+ template <class ELFT>
+ static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+ bool useUndefines) {
+ return lld::elf::PPCDynamicFile<ELFT>::create(std::move(mb), useUndefines);
+ }
+};
+
+struct PPCELFFileCreateELFTraits {
+ typedef llvm::ErrorOr<std::unique_ptr<lld::File>> result_type;
+
+ template <class ELFT>
+ static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+ bool atomizeStrings) {
+ return lld::elf::PPCELFFile<ELFT>::create(std::move(mb), atomizeStrings);
+ }
+};
+
+class PPCELFObjectReader : public ELFObjectReader {
+public:
+ PPCELFObjectReader(bool atomizeStrings) : ELFObjectReader(atomizeStrings) {}
+
+ virtual error_code
+ parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+ std::vector<std::unique_ptr<File>> &result) const {
+ error_code ec;
+ std::size_t maxAlignment =
+ 1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
+ auto f = createELF<PPCELFFileCreateELFTraits>(
+ llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
+ _atomizeStrings);
+ if (!f)
+ return f;
+ result.push_back(std::move(*f));
+ return error_code::success();
+ }
+};
+
+class PPCELFDSOReader : public ELFDSOReader {
+public:
+ PPCELFDSOReader(bool useUndefines) : ELFDSOReader(useUndefines) {}
+
+ virtual error_code
+ parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+ std::vector<std::unique_ptr<File>> &result) const {
+ std::size_t maxAlignment =
+ 1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
+ auto f = createELF<PPCDynamicFileCreateELFTraits>(
+ llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
+ _useUndefines);
+ if (!f)
+ return f;
+ result.push_back(std::move(*f));
+ return error_code::success();
+ }
+};
+
+} // namespace elf
+} // namespace lld
+
+#endif // LLD_READER_WRITER_ELF_READER_H
Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -63,15 +63,32 @@ error_code PPCTargetRelocationHandler::a
return error_code::success();
}
-PPCTargetHandler::PPCTargetHandler(PPCLinkingContext &targetInfo)
- : DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
- _targetLayout(targetInfo) {}
+PPCTargetHandler::PPCTargetHandler(PPCLinkingContext &context)
+ : DefaultTargetHandler(context), _ppcLinkingContext(context),
+ _ppcTargetLayout(new PPCTargetLayout<PPCELFType>(context)),
+ _ppcRelocationHandler(
+ new PPCTargetRelocationHandler(context, *_ppcTargetLayout.get())) {}
void PPCTargetHandler::registerRelocationNames(Registry ®istry) {
registry.addKindTable(Reference::KindNamespace::ELF,
Reference::KindArch::PowerPC, kindStrings);
}
+std::unique_ptr<Writer> PPCTargetHandler::getWriter() {
+ switch (_ppcLinkingContext.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return std::unique_ptr<Writer>(new elf::ExecutableWriter<PPCELFType>(
+ _ppcLinkingContext, *_ppcTargetLayout.get()));
+ case llvm::ELF::ET_DYN:
+ return std::unique_ptr<Writer>(new elf::DynamicLibraryWriter<PPCELFType>(
+ _ppcLinkingContext, *_ppcTargetLayout.get()));
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
+ }
+}
+
const Registry::KindStrings PPCTargetHandler::kindStrings[] = {
LLD_KIND_STRING_ENTRY(R_PPC_NONE),
LLD_KIND_STRING_ENTRY(R_PPC_ADDR32),
Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h Sun Jan 26 19:21:02 2014
@@ -18,35 +18,49 @@ namespace elf {
typedef llvm::object::ELFType<llvm::support::big, 2, false> PPCELFType;
class PPCLinkingContext;
+template <class ELFT> class PPCTargetLayout : public TargetLayout<ELFT> {
+public:
+ PPCTargetLayout(PPCLinkingContext &context) : TargetLayout<ELFT>(context) {}
+};
+
class PPCTargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<PPCELFType> {
public:
- PPCTargetRelocationHandler(const PPCLinkingContext &context) {}
+ PPCTargetRelocationHandler(PPCLinkingContext &context,
+ PPCTargetLayout<PPCELFType> &layout)
+ : _ppcContext(context), _ppcTargetLayout(layout) {}
virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
const Reference &) const;
+protected:
+ PPCLinkingContext &_ppcContext;
+ PPCTargetLayout<PPCELFType> &_ppcTargetLayout;
};
class PPCTargetHandler LLVM_FINAL
: public DefaultTargetHandler<PPCELFType> {
public:
- PPCTargetHandler(PPCLinkingContext &targetInfo);
+ PPCTargetHandler(PPCLinkingContext &context);
- virtual void registerRelocationNames(Registry ®istry);
+ virtual PPCTargetLayout<PPCELFType> &getTargetLayout() {
+ return *(_ppcTargetLayout.get());
+ }
- virtual TargetLayout<PPCELFType> &targetLayout() { return _targetLayout; }
+ virtual void registerRelocationNames(Registry ®istry);
virtual const PPCTargetRelocationHandler &getRelocationHandler() const {
- return _relocationHandler;
+ return *(_ppcRelocationHandler.get());
}
+ virtual std::unique_ptr<Writer> getWriter();
+
private:
static const Registry::KindStrings kindStrings[];
-
- PPCTargetRelocationHandler _relocationHandler;
- TargetLayout<PPCELFType> _targetLayout;
+ PPCLinkingContext &_ppcLinkingContext;
+ std::unique_ptr<PPCTargetLayout<PPCELFType>> _ppcTargetLayout;
+ std::unique_ptr<PPCTargetRelocationHandler> _ppcRelocationHandler;
};
} // end namespace elf
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Sun Jan 26 19:21:02 2014
@@ -234,7 +234,8 @@ public:
range<atom_iter> atoms() { return _atoms; }
- virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
static bool classof(const Chunk<ELFT> *c) {
return c->kind() == Chunk<ELFT>::Kind::AtomSection;
@@ -359,7 +360,7 @@ template <class ELFT> StringRef Section<
/// \brief Write the section and the atom contents to the buffer
template <class ELFT>
-void AtomSection<ELFT>::write(ELFWriter *writer,
+void AtomSection<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
parallel_for_each(_atoms.begin(), _atoms.end(), [&](lld::AtomLayout * ai) {
@@ -524,7 +525,8 @@ public:
uint64_t addString(StringRef symname);
- virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
inline void setNumEntries(int64_t numEntries) {
_stringMap.resize(numEntries);
@@ -583,7 +585,7 @@ template <class ELFT> uint64_t StringTab
}
template <class ELFT>
-void StringTable<ELFT>::write(ELFWriter *writer,
+void StringTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &,
llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
@@ -649,7 +651,8 @@ public:
virtual void finalize(bool sort = true);
- virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
void setStringSection(StringTable<ELFT> *s) { _stringSection = s; }
@@ -842,7 +845,7 @@ template <class ELFT> void SymbolTable<E
}
template <class ELFT>
-void SymbolTable<ELFT>::write(ELFWriter *writer,
+void SymbolTable<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &,
llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
@@ -856,9 +859,10 @@ template <class ELFT> class HashSection;
template <class ELFT> class DynamicSymbolTable : public SymbolTable<ELFT> {
public:
- DynamicSymbolTable(const ELFLinkingContext &context, const char *str,
- int32_t order)
- : SymbolTable<ELFT>(context, str, order), _hashTable(nullptr) {
+ DynamicSymbolTable(const ELFLinkingContext &context,
+ TargetLayout<ELFT> &layout, const char *str, int32_t order)
+ : SymbolTable<ELFT>(context, str, order), _hashTable(nullptr),
+ _layout(layout) {
this->_type = SHT_DYNSYM;
this->_flags = SHF_ALLOC;
this->_msize = this->_fsize;
@@ -894,8 +898,9 @@ public:
SymbolTable<ELFT>::finalize(false);
}
-private:
+protected:
HashSection<ELFT> *_hashTable;
+ TargetLayout<ELFT> &_layout;
};
template <class ELFT> class RelocationTable : public Section<ELFT> {
@@ -951,8 +956,10 @@ public:
this->_parent->setLink(this->_link);
}
- virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
- uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
+ uint8_t *chunkBuffer = buffer.getBufferStart();
+ uint8_t *dest = chunkBuffer + this->fileOffset();
for (const auto &rel : _relocs) {
if (this->_context.isRelaOutputFormat())
writeRela(writer, *reinterpret_cast<Elf_Rela *>(dest), *rel.first,
@@ -1007,8 +1014,9 @@ public:
typedef llvm::object::Elf_Dyn_Impl<ELFT> Elf_Dyn;
typedef std::vector<Elf_Dyn> EntriesT;
- DynamicTable(const ELFLinkingContext &context, StringRef str, int32_t order)
- : Section<ELFT>(context, str) {
+ DynamicTable(const ELFLinkingContext &context, TargetLayout<ELFT> &layout,
+ StringRef str, int32_t order)
+ : Section<ELFT>(context, str), _layout(layout) {
this->setOrder(order);
this->_entSize = sizeof(Elf_Dyn);
this->_align2 = llvm::alignOf<Elf_Dyn>();
@@ -1017,7 +1025,6 @@ public:
this->_msize = sizeof(Elf_Dyn);
this->_type = SHT_DYNAMIC;
this->_flags = SHF_ALLOC;
- _layout = &context.getTargetHandler<ELFT>().targetLayout();
}
range<typename EntriesT::iterator> entries() { return _entries; }
@@ -1030,7 +1037,8 @@ public:
return _entries.size() - 1;
}
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
// Add the null entry.
@@ -1061,7 +1069,7 @@ public:
_dt_fini_array = addEntry(dyn);
dyn.d_tag = DT_FINI_ARRAYSZ;
_dt_fini_arraysz = addEntry(dyn);
- if (_layout->hasDynamicRelocationTable()) {
+ if (_layout.hasDynamicRelocationTable()) {
dyn.d_tag = isRela ? DT_RELA : DT_REL;
_dt_rela = addEntry(dyn);
dyn.d_tag = isRela ? DT_RELASZ : DT_RELSZ;
@@ -1069,7 +1077,7 @@ public:
dyn.d_tag = isRela ? DT_RELAENT : DT_RELENT;
_dt_relaent = addEntry(dyn);
}
- if (_layout->hasPLTRelocationTable()) {
+ if (_layout.hasPLTRelocationTable()) {
dyn.d_tag = DT_PLTRELSZ;
_dt_pltrelsz = addEntry(dyn);
dyn.d_tag = DT_PLTGOT;
@@ -1111,30 +1119,28 @@ public:
_entries[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr();
_entries[_dt_strsz].d_un.d_val = dynamicStringTable->memSize();
_entries[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize();
- auto finiArray = _layout->findOutputSection(".fini_array");
+ auto finiArray = _layout.findOutputSection(".fini_array");
if (finiArray) {
_entries[_dt_fini_array].d_un.d_val = finiArray->virtualAddr();
_entries[_dt_fini_arraysz].d_un.d_val = finiArray->memSize();
}
- if (_layout->hasDynamicRelocationTable()) {
- auto relaTbl = _layout->getDynamicRelocationTable();
+ if (_layout.hasDynamicRelocationTable()) {
+ auto relaTbl = _layout.getDynamicRelocationTable();
_entries[_dt_rela].d_un.d_val = relaTbl->virtualAddr();
_entries[_dt_relasz].d_un.d_val = relaTbl->memSize();
_entries[_dt_relaent].d_un.d_val = relaTbl->getEntSize();
}
- if (_layout->hasPLTRelocationTable()) {
- auto relaTbl = _layout->getPLTRelocationTable();
+ if (_layout.hasPLTRelocationTable()) {
+ auto relaTbl = _layout.getPLTRelocationTable();
_entries[_dt_jmprel].d_un.d_val = relaTbl->virtualAddr();
_entries[_dt_pltrelsz].d_un.d_val = relaTbl->memSize();
- auto gotplt = _layout->findOutputSection(".got.plt");
+ auto gotplt = _layout.findOutputSection(".got.plt");
_entries[_dt_pltgot].d_un.d_val = gotplt->virtualAddr();
}
}
protected:
EntriesT _entries;
-
-private:
std::size_t _dt_hash;
std::size_t _dt_strtab;
std::size_t _dt_symtab;
@@ -1149,7 +1155,7 @@ private:
std::size_t _dt_jmprel;
std::size_t _dt_fini_array;
std::size_t _dt_fini_arraysz;
- TargetLayout<ELFT> *_layout;
+ TargetLayout<ELFT> &_layout;
DynamicSymbolTable<ELFT> *_dynamicSymbolTable;
HashSection<ELFT> *_hashTable;
};
@@ -1168,7 +1174,8 @@ public:
this->_flags = SHF_ALLOC;
}
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
std::memcpy(dest, _interp.data(), _interp.size());
@@ -1280,7 +1287,8 @@ public:
this->_parent->setLink(this->_link);
}
- virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
uint32_t bucketChainCounts[2];
@@ -1311,8 +1319,9 @@ private:
template <class ELFT> class EHFrameHeader : public Section<ELFT> {
public:
- EHFrameHeader(const ELFLinkingContext &context, StringRef name, int32_t order)
- : Section<ELFT>(context, name) {
+ EHFrameHeader(const ELFLinkingContext &context, StringRef name,
+ TargetLayout<ELFT> &layout, int32_t order)
+ : Section<ELFT>(context, name), _layout(layout) {
this->setOrder(order);
this->_entSize = 0;
this->_type = SHT_PROGBITS;
@@ -1332,13 +1341,11 @@ public:
}
virtual void finalize() LLVM_OVERRIDE {
- MergedSections<ELFT> *s = this->_context.template getTargetHandler<ELFT>()
- .targetLayout()
- .findOutputSection(".eh_frame");
+ MergedSections<ELFT> *s = _layout.findOutputSection(".eh_frame");
_ehFrameAddr = s ? s->virtualAddr() : 0;
}
- virtual void write(ELFWriter *writer,
+ virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
llvm::FileOutputBuffer &buffer) LLVM_OVERRIDE {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
@@ -1353,6 +1360,7 @@ public:
private:
uint64_t _ehFrameAddr;
+ TargetLayout<ELFT> &_layout;
};
} // end namespace elf
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Sun Jan 26 19:21:02 2014
@@ -159,7 +159,8 @@ public:
void assignVirtualAddress(uint64_t &addr);
// Write the Segment
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer);
int64_t flags() const;
@@ -582,10 +583,11 @@ template <class ELFT> void Segment<ELFT>
// Write the Segment
template <class ELFT>
-void Segment<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+void Segment<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
for (auto slice : slices())
for (auto section : slice->sections())
- section->write(writer, buffer);
+ section->write(writer, layout, buffer);
}
template<class ELFT>
Modified: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h Sun Jan 26 19:21:02 2014
@@ -42,63 +42,38 @@ template <class ELFT> class TargetLayout
template <class ELFT> class TargetRelocationHandler {
public:
- virtual error_code
- applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const lld::AtomLayout &, const Reference &) const = 0;
+ virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
+ const lld::AtomLayout &,
+ const Reference &) const = 0;
virtual ~TargetRelocationHandler() {}
};
-/// \brief An interface to override functions that are provided by the
-/// the default ELF Layout
+/// \brief TargetHandler contains all the information responsible to handle a
+/// a particular target on ELF. A target might wish to override implementation
+/// of creating atoms and how the atoms are written to the output file.
template <class ELFT> class TargetHandler : public TargetHandlerBase {
public:
+ /// Constructor
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
- /// that target
- virtual bool doesOverrideELFHeader() = 0;
-
- /// Set the ELF Header information
- virtual void setELFHeader(ELFHeader<ELFT> *elfHeader) = 0;
-
- /// TargetLayout
- virtual TargetLayout<ELFT> &targetLayout() = 0;
+ /// The layout determined completely by the Target.
+ virtual TargetLayout<ELFT> &getTargetLayout() = 0;
+ /// Determine how relocations need to be applied.
virtual const TargetRelocationHandler<ELFT> &getRelocationHandler() const = 0;
- /// Create a set of Default target sections that a target might needj
- virtual void createDefaultSections() = 0;
-
- /// \brief Add a section to the current Layout
- virtual void addSection(Section<ELFT> *section) = 0;
-
- /// \brief add new symbol file
- virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) = 0;
-
- /// \brief Finalize the symbol values
- virtual void finalizeSymbolValues() = 0;
-
- /// \brief allocate Commons, some architectures may move small common
- /// symbols over to small data, this would also be used
- virtual void allocateCommons() = 0;
-
- /// \brief create dynamic table
- virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() = 0;
-
- /// \brief create dynamic symbol table
- virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
- createDynamicSymbolTable() = 0;
-
+ /// How does the target deal with reading input files.
virtual std::unique_ptr<Reader> getObjReader(bool) = 0;
+ /// How does the target deal with reading dynamic libraries.
virtual std::unique_ptr<Reader> getDSOReader(bool) = 0;
+ /// How does the target deal with writing ELF output.
virtual std::unique_ptr<Writer> getWriter() = 0;
-protected:
+private:
ELFLinkingContext &_context;
};
} // end namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -31,6 +31,21 @@ static int relocPC32(uint8_t *location,
return 0;
}
+std::unique_ptr<Writer> X86TargetHandler::getWriter() {
+ switch (_x86LinkingContext.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return std::unique_ptr<Writer>(new elf::ExecutableWriter<X86ELFType>(
+ _x86LinkingContext, *_x86TargetLayout.get()));
+ case llvm::ELF::ET_DYN:
+ return std::unique_ptr<Writer>(new elf::DynamicLibraryWriter<X86ELFType>(
+ _x86LinkingContext, *_x86TargetLayout.get()));
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
+ }
+}
+
const Registry::KindStrings X86TargetHandler::kindStrings[] = {
LLD_KIND_STRING_ENTRY(R_386_NONE),
LLD_KIND_STRING_ENTRY(R_386_32),
@@ -111,6 +126,8 @@ error_code X86TargetRelocationHandler::a
return error_code::success();
}
-X86TargetHandler::X86TargetHandler(X86LinkingContext &targetInfo)
- : DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
- _targetLayout(targetInfo) {}
+X86TargetHandler::X86TargetHandler(X86LinkingContext &context)
+ : DefaultTargetHandler(context), _x86LinkingContext(context),
+ _x86TargetLayout(new X86TargetLayout<X86ELFType>(context)),
+ _x86RelocationHandler(
+ new X86TargetRelocationHandler(context, *_x86TargetLayout.get())) {}
Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h Sun Jan 26 19:21:02 2014
@@ -21,16 +21,27 @@ namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 2, false> X86ELFType;
class X86LinkingContext;
+template <class ELFT> class X86TargetLayout : public TargetLayout<ELFT> {
+public:
+ X86TargetLayout(X86LinkingContext &context) : TargetLayout<ELFT>(context) {}
+};
+
class X86TargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<X86ELFType> {
public:
- X86TargetRelocationHandler(const X86LinkingContext &context) {}
+ X86TargetRelocationHandler(X86LinkingContext &context,
+ X86TargetLayout<X86ELFType> &layout)
+ : _x86Context(context), _x86TargetLayout(layout) {}
virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
const Reference &) const;
static const Registry::KindStrings kindStrings[];
+
+protected:
+ X86LinkingContext &_x86Context;
+ X86TargetLayout<X86ELFType> &_x86TargetLayout;
};
class X86TargetHandler LLVM_FINAL
@@ -38,19 +49,23 @@ class X86TargetHandler LLVM_FINAL
public:
X86TargetHandler(X86LinkingContext &context);
- virtual void registerRelocationNames(Registry ®istry);
+ virtual X86TargetLayout<X86ELFType> &getTargetLayout() {
+ return *(_x86TargetLayout.get());
+ }
- virtual TargetLayout<X86ELFType> &targetLayout() { return _targetLayout; }
+ virtual void registerRelocationNames(Registry ®istry);
virtual const X86TargetRelocationHandler &getRelocationHandler() const {
- return _relocationHandler;
+ return *(_x86RelocationHandler.get());
}
-private:
- static const Registry::KindStrings kindStrings[];
+ virtual std::unique_ptr<Writer> getWriter();
- X86TargetRelocationHandler _relocationHandler;
- TargetLayout<X86ELFType> _targetLayout;
+protected:
+ static const Registry::KindStrings kindStrings[];
+ X86LinkingContext &_x86LinkingContext;
+ std::unique_ptr<X86TargetLayout<X86ELFType>> _x86TargetLayout;
+ std::unique_ptr<X86TargetRelocationHandler> _x86RelocationHandler;
};
} // end namespace elf
} // end namespace lld
Added: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,70 @@
+//===- lib/ReaderWriter/ELF/X86/X86_64DynamicLibraryWriter.h
+//-----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_64_DYNAMIC_LIBRARY_WRITER_H
+#define X86_64_DYNAMIC_LIBRARY_WRITER_H
+
+#include "DynamicLibraryWriter.h"
+#include "X86_64LinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+class X86_64DynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
+public:
+ X86_64DynamicLibraryWriter(X86_64LinkingContext &context,
+ X86_64TargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues() {
+ return DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+ }
+
+ virtual void addDefaultAtoms() {
+ return DynamicLibraryWriter<ELFT>::addDefaultAtoms();
+ }
+
+private:
+ class GOTFile : public SimpleFile {
+ public:
+ GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
+ llvm::BumpPtrAllocator _alloc;
+ };
+
+ std::unique_ptr<GOTFile> _gotFile;
+ X86_64LinkingContext &_context;
+ X86_64TargetLayout<ELFT> &_x86_64Layout;
+};
+
+template <class ELFT>
+X86_64DynamicLibraryWriter<ELFT>::X86_64DynamicLibraryWriter(
+ X86_64LinkingContext &context, X86_64TargetLayout<ELFT> &layout)
+ : DynamicLibraryWriter<ELFT>(context, layout),
+ _gotFile(new GOTFile(context)), _context(context), _x86_64Layout(layout) {
+}
+
+template <class ELFT>
+bool X86_64DynamicLibraryWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+ _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
+ _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
+ _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
+ result.push_back(std::move(_gotFile));
+ return true;
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif
Added: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h?rev=200177&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h Sun Jan 26 19:21:02 2014
@@ -0,0 +1,70 @@
+//===- lib/ReaderWriter/ELF/X86/X86_64ExecutableWriter.h
+//-----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_64_EXECUTABLE_WRITER_H
+#define X86_64_EXECUTABLE_WRITER_H
+
+#include "ExecutableWriter.h"
+#include "X86_64LinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+class X86_64ExecutableWriter : public ExecutableWriter<ELFT> {
+public:
+ X86_64ExecutableWriter(X86_64LinkingContext &context,
+ X86_64TargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues() {
+ return ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+ }
+
+ virtual void addDefaultAtoms() {
+ return ExecutableWriter<ELFT>::addDefaultAtoms();
+ }
+
+private:
+ class GOTFile : public SimpleFile {
+ public:
+ GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
+ llvm::BumpPtrAllocator _alloc;
+ };
+
+ std::unique_ptr<GOTFile> _gotFile;
+ X86_64LinkingContext &_context;
+ X86_64TargetLayout<ELFT> &_x86_64Layout;
+};
+
+template <class ELFT>
+X86_64ExecutableWriter<ELFT>::X86_64ExecutableWriter(
+ X86_64LinkingContext &context, X86_64TargetLayout<ELFT> &layout)
+ : ExecutableWriter<ELFT>(context, layout), _gotFile(new GOTFile(context)),
+ _context(context), _x86_64Layout(layout) {}
+
+template <class ELFT>
+bool X86_64ExecutableWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ ExecutableWriter<ELFT>::createImplicitFiles(result);
+ _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
+ _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
+ if (_context.isDynamic())
+ _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
+ result.push_back(std::move(_gotFile));
+ return true;
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif
Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp Sun Jan 26 19:21:02 2014
@@ -90,8 +90,7 @@ error_code X86_64TargetRelocationHandler
case R_X86_64_TPOFF64:
case R_X86_64_DTPOFF32:
case R_X86_64_TPOFF32: {
- _tlsSize =
- _context.getTargetHandler<X86_64ELFType>().targetLayout().getTLSSize();
+ _tlsSize = _x86_64Layout.getTLSSize();
if (ref.kindValue() == R_X86_64_TPOFF32 ||
ref.kindValue() == R_X86_64_DTPOFF32) {
int32_t result = (int32_t)(targetVAddress - _tlsSize);
@@ -115,8 +114,8 @@ error_code X86_64TargetRelocationHandler
for (const Reference *r : *target) {
if (r->kindValue() == R_X86_64_JUMP_SLOT) {
uint32_t index;
- if (!_context.getTargetHandler<X86_64ELFType>().targetLayout()
- .getPLTRelocationTable()->getRelocationIndex(*r, index))
+ if (!_x86_64Layout.getPLTRelocationTable()->getRelocationIndex(*r,
+ index))
llvm_unreachable("Relocation doesn't exist");
reloc32(location, 0, index, 0);
break;
Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h Sun Jan 26 19:21:02 2014
@@ -8,8 +8,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_RELOCATION_HANDLER_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_RELOCATION_HANDLER_H
+#ifndef X86_64_RELOCATION_HANDLER_H
+#define X86_64_RELOCATION_HANDLER_H
#include "X86_64TargetHandler.h"
@@ -18,11 +18,14 @@ namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
class X86_64LinkingContext;
+template <class ELFT> class X86_64TargetLayout;
+
class X86_64TargetRelocationHandler LLVM_FINAL
: public TargetRelocationHandler<X86_64ELFType> {
public:
- X86_64TargetRelocationHandler(const X86_64LinkingContext &context)
- : _tlsSize(0), _context(context) {}
+ X86_64TargetRelocationHandler(const X86_64LinkingContext &context,
+ X86_64TargetLayout<X86_64ELFType> &layout)
+ : _tlsSize(0), _context(context), _x86_64Layout(layout) {}
virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &,
@@ -35,10 +38,11 @@ public:
private:
// Cached size of the TLS segment.
mutable uint64_t _tlsSize;
- const X86_64LinkingContext &_context;
+ const X86_64LinkingContext &_context LLVM_ATTRIBUTE_UNUSED;
+ X86_64TargetLayout<X86_64ELFType> &_x86_64Layout;
};
} // end namespace elf
} // end namespace lld
-#endif
+#endif // X86_64_RELOCATION_HANDLER_H
Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Sun Jan 26 19:21:02 2014
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "Atoms.h"
+#include "X86_64ExecutableWriter.h"
+#include "X86_64DynamicLibraryWriter.h"
#include "X86_64TargetHandler.h"
#include "X86_64LinkingContext.h"
@@ -15,24 +17,32 @@ using namespace lld;
using namespace elf;
X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &context)
- : DefaultTargetHandler(context), _gotFile(new GOTFile(context)),
- _relocationHandler(context), _targetLayout(context) {}
-
-bool X86_64TargetHandler::createImplicitFiles(
- std::vector<std::unique_ptr<File> > &result) {
- _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
- _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
- if (_context.isDynamic())
- _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
- result.push_back(std::move(_gotFile));
- return true;
-}
+ : DefaultTargetHandler(context), _context(context),
+ _x86_64TargetLayout(new X86_64TargetLayout<X86_64ELFType>(context)),
+ _x86_64RelocationHandler(new X86_64TargetRelocationHandler(
+ context, *_x86_64TargetLayout.get())) {}
void X86_64TargetHandler::registerRelocationNames(Registry ®istry) {
registry.addKindTable(Reference::KindNamespace::ELF,
Reference::KindArch::x86_64, kindStrings);
}
+std::unique_ptr<Writer> X86_64TargetHandler::getWriter() {
+ switch (this->_context.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return std::unique_ptr<Writer>(new X86_64ExecutableWriter<X86_64ELFType>(
+ _context, *_x86_64TargetLayout.get()));
+ case llvm::ELF::ET_DYN:
+ return std::unique_ptr<Writer>(
+ new X86_64DynamicLibraryWriter<X86_64ELFType>(
+ _context, *_x86_64TargetLayout.get()));
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
+ }
+}
+
const Registry::KindStrings X86_64TargetHandler::kindStrings[] = {
LLD_KIND_STRING_ENTRY(R_X86_64_NONE),
LLD_KIND_STRING_ENTRY(R_X86_64_64),
Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h Sun Jan 26 19:21:02 2014
@@ -22,35 +22,36 @@ namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
class X86_64LinkingContext;
+template <class ELFT> class X86_64TargetLayout : public TargetLayout<ELFT> {
+public:
+ X86_64TargetLayout(X86_64LinkingContext &context)
+ : TargetLayout<ELFT>(context) {}
+};
+
class X86_64TargetHandler LLVM_FINAL
: public DefaultTargetHandler<X86_64ELFType> {
public:
- X86_64TargetHandler(X86_64LinkingContext &targetInfo);
-
- virtual void registerRelocationNames(Registry ®istry);
+ X86_64TargetHandler(X86_64LinkingContext &context);
- virtual TargetLayout<X86_64ELFType> &targetLayout() {
- return _targetLayout;
+ virtual X86_64TargetLayout<X86_64ELFType> &getTargetLayout() {
+ return *(_x86_64TargetLayout.get());
}
+ virtual void registerRelocationNames(Registry ®istry);
+
virtual const X86_64TargetRelocationHandler &getRelocationHandler() const {
- return _relocationHandler;
+ return *(_x86_64RelocationHandler.get());
}
- virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
+ virtual std::unique_ptr<Writer> getWriter();
private:
- class GOTFile : public SimpleFile {
- public:
- GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
- llvm::BumpPtrAllocator _alloc;
- };
-
static const Registry::KindStrings kindStrings[];
- std::unique_ptr<GOTFile> _gotFile;
- X86_64TargetRelocationHandler _relocationHandler;
- TargetLayout<X86_64ELFType> _targetLayout;
+ X86_64LinkingContext &_context;
+ std::unique_ptr<X86_64TargetLayout<X86_64ELFType>> _x86_64TargetLayout;
+ std::unique_ptr<X86_64TargetRelocationHandler> _x86_64RelocationHandler;
};
+
} // end namespace elf
} // end namespace lld
Modified: lld/trunk/test/elf/Hexagon/dynlib-syms.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Hexagon/dynlib-syms.test?rev=200177&r1=200176&r2=200177&view=diff
==============================================================================
--- lld/trunk/test/elf/Hexagon/dynlib-syms.test (original)
+++ lld/trunk/test/elf/Hexagon/dynlib-syms.test Sun Jan 26 19:21:02 2014
@@ -5,4 +5,3 @@ RUN: FileCheck -check-prefix=CHECKSYMS %
CHECKSYMS: 0000028c A _DYNAMIC
CHECKSYMS: 00001008 A _GLOBAL_OFFSET_TABLE_
-CHECKSYMS: 00002000 A _SDA_BASE_
More information about the llvm-commits
mailing list