diff options
| author | Denis Protivensky <dprotivensky@accesssoftek.com> | 2015-05-21 11:16:40 +0000 |
|---|---|---|
| committer | Denis Protivensky <dprotivensky@accesssoftek.com> | 2015-05-21 11:16:40 +0000 |
| commit | ad52e44e989b2e6c447632901c03a3313d643180 (patch) | |
| tree | a36e75aa346cc397c2486b314d4aeff7acb4099c /lld/lib/ReaderWriter/ELF/ARM | |
| parent | bea5bd18eb16b32c2bf2f8e244eb5dd7c0fe0931 (diff) | |
| download | bcm5719-llvm-ad52e44e989b2e6c447632901c03a3313d643180.tar.gz bcm5719-llvm-ad52e44e989b2e6c447632901c03a3313d643180.zip | |
[ARM] Move out common Writer functionality to ARMELFWriter
llvm-svn: 237891
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/ARM')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h | 6 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.cpp | 18 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h | 120 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h | 84 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h | 3 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/CMakeLists.txt | 1 |
6 files changed, 149 insertions, 83 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h b/lld/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h index 1f75eb8c4cb..40eadacba79 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMDynamicLibraryWriter.h @@ -10,13 +10,15 @@ #define LLD_READER_WRITER_ELF_ARM_ARM_DYNAMIC_LIBRARY_WRITER_H #include "DynamicLibraryWriter.h" +#include "ARMELFWriters.h" #include "ARMLinkingContext.h" #include "ARMTargetHandler.h" namespace lld { namespace elf { -class ARMDynamicLibraryWriter : public DynamicLibraryWriter<ELF32LE> { +class ARMDynamicLibraryWriter + : public ARMELFWriter<DynamicLibraryWriter<ELF32LE>> { public: ARMDynamicLibraryWriter(ARMLinkingContext &ctx, ARMTargetLayout &layout); @@ -27,7 +29,7 @@ protected: ARMDynamicLibraryWriter::ARMDynamicLibraryWriter(ARMLinkingContext &ctx, ARMTargetLayout &layout) - : DynamicLibraryWriter(ctx, layout) {} + : ARMELFWriter(ctx, layout) {} void ARMDynamicLibraryWriter::createImplicitFiles( std::vector<std::unique_ptr<File>> &result) { diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.cpp b/lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.cpp new file mode 100644 index 00000000000..cf9333ce68a --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.cpp @@ -0,0 +1,18 @@ +//===- lib/ReaderWriter/ELF/ARM/ARMELFWriters.cpp -------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ARMELFWriters.h" +#include "ARMExecutableWriter.h" +#include "ARMDynamicLibraryWriter.h" + +using namespace lld; +using namespace elf; + +template class ARMELFWriter<ExecutableWriter<ELF32LE>>; +template class ARMELFWriter<DynamicLibraryWriter<ELF32LE>>; diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h b/lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h new file mode 100644 index 00000000000..a842ebe5303 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMELFWriters.h @@ -0,0 +1,120 @@ +//===- lib/ReaderWriter/ELF/ARM/ARMELFWriters.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_ARM_ARM_ELF_WRITERS_H +#define LLD_READER_WRITER_ELF_ARM_ARM_ELF_WRITERS_H + +#include "ARMLinkingContext.h" +#include "ARMSymbolTable.h" +#include "llvm/Support/ELF.h" + +namespace lld { +namespace elf { + +template <class WriterT> class ARMELFWriter : public WriterT { +public: + ARMELFWriter(ARMLinkingContext &ctx, TargetLayout<ELF32LE> &layout); + + void finalizeDefaultAtomValues() override; + + /// \brief Create symbol table. + unique_bump_ptr<SymbolTable<ELF32LE>> createSymbolTable() override; + + // Setup the ELF header. + std::error_code setELFHeader() override; + +protected: + static const char *gotSymbol; + static const char *dynamicSymbol; + +private: + ARMLinkingContext &_ctx; + TargetLayout<ELF32LE> &_armLayout; +}; + +template <class WriterT> +const char *ARMELFWriter<WriterT>::gotSymbol = "_GLOBAL_OFFSET_TABLE_"; +template <class WriterT> +const char *ARMELFWriter<WriterT>::dynamicSymbol = "_DYNAMIC"; + +template <class WriterT> +ARMELFWriter<WriterT>::ARMELFWriter(ARMLinkingContext &ctx, + TargetLayout<ELF32LE> &layout) + : WriterT(ctx, layout), _ctx(ctx), _armLayout(layout) {} + +template <class WriterT> +void ARMELFWriter<WriterT>::finalizeDefaultAtomValues() { + // Finalize the atom values that are part of the parent. + WriterT::finalizeDefaultAtomValues(); + + if (auto *gotAtom = _armLayout.findAbsoluteAtom(gotSymbol)) { + if (auto gotpltSection = _armLayout.findOutputSection(".got.plt")) + gotAtom->_virtualAddr = gotpltSection->virtualAddr(); + else if (auto gotSection = _armLayout.findOutputSection(".got")) + gotAtom->_virtualAddr = gotSection->virtualAddr(); + else + gotAtom->_virtualAddr = 0; + } + + if (auto *dynamicAtom = _armLayout.findAbsoluteAtom(dynamicSymbol)) { + if (auto dynamicSection = _armLayout.findOutputSection(".dynamic")) + dynamicAtom->_virtualAddr = dynamicSection->virtualAddr(); + else + dynamicAtom->_virtualAddr = 0; + } + + // Set required by gcc libc __ehdr_start symbol with pointer to ELF header + if (auto ehdr = _armLayout.findAbsoluteAtom("__ehdr_start")) + ehdr->_virtualAddr = this->_elfHeader->virtualAddr(); + + // Set required by gcc libc symbols __exidx_start/__exidx_end + this->updateScopeAtomValues("exidx", ".ARM.exidx"); +} + +template <class WriterT> +unique_bump_ptr<SymbolTable<ELF32LE>> +ARMELFWriter<WriterT>::createSymbolTable() { + return unique_bump_ptr<SymbolTable<ELF32LE>>(new (this->_alloc) + ARMSymbolTable(_ctx)); +} + +template <class WriterT> std::error_code ARMELFWriter<WriterT>::setELFHeader() { + if (std::error_code ec = WriterT::setELFHeader()) + return ec; + + // Set ARM-specific flags. + this->_elfHeader->e_flags(llvm::ELF::EF_ARM_EABI_VER5 | + llvm::ELF::EF_ARM_VFP_FLOAT); + + StringRef entryName = _ctx.entrySymbolName(); + if (const AtomLayout *al = _armLayout.findAtomLayoutByName(entryName)) { + if (const auto *ea = dyn_cast<DefinedAtom>(al->_atom)) { + switch (ea->codeModel()) { + case DefinedAtom::codeNA: + if (al->_virtualAddr & 0x3) { + llvm::report_fatal_error( + "Two least bits must be zero for ARM entry point"); + } + break; + case DefinedAtom::codeARMThumb: + // Fixup entry point for Thumb code. + this->_elfHeader->e_entry(al->_virtualAddr | 0x1); + break; + default: + llvm_unreachable("Wrong code model of entry point atom"); + } + } + } + + return std::error_code(); +} + +} // namespace elf +} // namespace lld + +#endif // LLD_READER_WRITER_ELF_ARM_ARM_ELF_WRITERS_H diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h index 50d4754885d..0f5c89d15cb 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h @@ -10,20 +10,14 @@ #define LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H #include "ExecutableWriter.h" +#include "ARMELFWriters.h" #include "ARMLinkingContext.h" #include "ARMTargetHandler.h" -#include "ARMSymbolTable.h" -#include "llvm/Support/ELF.h" - -namespace { -const char *gotSymbol = "_GLOBAL_OFFSET_TABLE_"; -const char *dynamicSymbol = "_DYNAMIC"; -} namespace lld { namespace elf { -class ARMExecutableWriter : public ExecutableWriter<ELF32LE> { +class ARMExecutableWriter : public ARMELFWriter<ExecutableWriter<ELF32LE>> { public: ARMExecutableWriter(ARMLinkingContext &ctx, ARMTargetLayout &layout); @@ -31,17 +25,9 @@ protected: // Add any runtime files and their atoms to the output void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; - void finalizeDefaultAtomValues() override; - - /// \brief Create symbol table. - unique_bump_ptr<SymbolTable<ELF32LE>> createSymbolTable() override; - void processUndefinedSymbol(StringRef symName, RuntimeFile<ELF32LE> &file) const override; - // Setup the ELF header. - std::error_code setELFHeader() override; - private: ARMLinkingContext &_ctx; ARMTargetLayout &_armLayout; @@ -49,7 +35,7 @@ private: ARMExecutableWriter::ARMExecutableWriter(ARMLinkingContext &ctx, ARMTargetLayout &layout) - : ExecutableWriter(ctx, layout), _ctx(ctx), _armLayout(layout) {} + : ARMELFWriter(ctx, layout), _ctx(ctx), _armLayout(layout) {} void ARMExecutableWriter::createImplicitFiles( std::vector<std::unique_ptr<File>> &result) { @@ -63,39 +49,6 @@ void ARMExecutableWriter::createImplicitFiles( } } -void ARMExecutableWriter::finalizeDefaultAtomValues() { - // Finalize the atom values that are part of the parent. - ExecutableWriter::finalizeDefaultAtomValues(); - AtomLayout *gotAtom = _armLayout.findAbsoluteAtom(gotSymbol); - if (gotAtom) { - if (auto gotpltSection = _armLayout.findOutputSection(".got.plt")) - gotAtom->_virtualAddr = gotpltSection->virtualAddr(); - else if (auto gotSection = _armLayout.findOutputSection(".got")) - gotAtom->_virtualAddr = gotSection->virtualAddr(); - else - gotAtom->_virtualAddr = 0; - } - - if (auto *dynamicAtom = _armLayout.findAbsoluteAtom(dynamicSymbol)) { - if (auto dynamicSection = _armLayout.findOutputSection(".dynamic")) - dynamicAtom->_virtualAddr = dynamicSection->virtualAddr(); - else - dynamicAtom->_virtualAddr = 0; - } - - // Set required by gcc libc __ehdr_start symbol with pointer to ELF header - if (auto ehdr = _armLayout.findAbsoluteAtom("__ehdr_start")) - ehdr->_virtualAddr = _elfHeader->virtualAddr(); - - // Set required by gcc libc symbols __exidx_start/__exidx_end - updateScopeAtomValues("exidx", ".ARM.exidx"); -} - -unique_bump_ptr<SymbolTable<ELF32LE>> ARMExecutableWriter::createSymbolTable() { - return unique_bump_ptr<SymbolTable<ELF32LE>>(new (_alloc) - ARMSymbolTable(_ctx)); -} - void ARMExecutableWriter::processUndefinedSymbol( StringRef symName, RuntimeFile<ELF32LE> &file) const { if (symName == gotSymbol) { @@ -108,37 +61,6 @@ void ARMExecutableWriter::processUndefinedSymbol( } } -std::error_code ARMExecutableWriter::setELFHeader() { - if (std::error_code ec = ExecutableWriter::setELFHeader()) - return ec; - - // Set ARM-specific flags. - _elfHeader->e_flags(llvm::ELF::EF_ARM_EABI_VER5 | - llvm::ELF::EF_ARM_VFP_FLOAT); - - StringRef entryName = _ctx.entrySymbolName(); - if (const AtomLayout *al = _armLayout.findAtomLayoutByName(entryName)) { - if (const auto *ea = dyn_cast<DefinedAtom>(al->_atom)) { - switch (ea->codeModel()) { - case DefinedAtom::codeNA: - if (al->_virtualAddr & 0x3) { - llvm::report_fatal_error( - "Two least bits must be zero for ARM entry point"); - } - break; - case DefinedAtom::codeARMThumb: - // Fixup entry point for Thumb code. - _elfHeader->e_entry(al->_virtualAddr | 0x1); - break; - default: - llvm_unreachable("Wrong code model of entry point atom"); - } - } - } - - return std::error_code(); -} - } // namespace elf } // namespace lld diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h b/lld/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h index 43586bf31d5..832efbabdea 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMSymbolTable.h @@ -10,6 +10,9 @@ #ifndef LLD_READER_WRITER_ELF_ARM_ARM_SYMBOL_TABLE_H #define LLD_READER_WRITER_ELF_ARM_ARM_SYMBOL_TABLE_H +#include "SectionChunks.h" +#include "TargetLayout.h" + namespace lld { namespace elf { diff --git a/lld/lib/ReaderWriter/ELF/ARM/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/ARM/CMakeLists.txt index 2ccf9eb6266..2b8656db164 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/ARM/CMakeLists.txt @@ -3,6 +3,7 @@ add_llvm_library(lldARMELFTarget ARMTargetHandler.cpp ARMRelocationHandler.cpp ARMRelocationPass.cpp + ARMELFWriters.cpp LINK_LIBS lldELF lldReaderWriter |

