1 //===--------- lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h -------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 #ifndef LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H
10 #define LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H
12 #include "ExecutableWriter.h"
13 #include "ARMLinkingContext.h"
14 #include "ARMTargetHandler.h"
15 #include "ARMSymbolTable.h"
18 const char *gotSymbol = "_GLOBAL_OFFSET_TABLE_";
25 class ARMExecutableWriter : public ExecutableWriter<ELFT> {
27 ARMExecutableWriter(ARMLinkingContext &context,
28 ARMTargetLayout<ELFT> &layout);
31 // Add any runtime files and their atoms to the output
32 bool createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
34 void finalizeDefaultAtomValues() override;
36 void addDefaultAtoms() override {
37 ExecutableWriter<ELFT>::addDefaultAtoms();
40 /// \brief Create symbol table.
41 unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
43 void processUndefinedSymbol(StringRef symName,
44 RuntimeFile<ELFT> &file) const override;
46 // Setup the ELF header.
47 std::error_code setELFHeader() override;
50 ARMLinkingContext &_context;
51 ARMTargetLayout<ELFT> &_armLayout;
55 ARMExecutableWriter<ELFT>::ARMExecutableWriter(ARMLinkingContext &context,
56 ARMTargetLayout<ELFT> &layout)
57 : ExecutableWriter<ELFT>(context, layout), _context(context),
61 bool ARMExecutableWriter<ELFT>::createImplicitFiles(
62 std::vector<std::unique_ptr<File>> &result) {
63 ExecutableWriter<ELFT>::createImplicitFiles(result);
68 void ARMExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
69 // Finalize the atom values that are part of the parent.
70 ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
71 auto gotAtomIter = _armLayout.findAbsoluteAtom(gotSymbol);
72 if (gotAtomIter != _armLayout.absoluteAtoms().end()) {
73 auto *gotAtom = *gotAtomIter;
74 if (auto gotpltSection = _armLayout.findOutputSection(".got.plt"))
75 gotAtom->_virtualAddr = gotpltSection->virtualAddr();
76 else if (auto gotSection = _armLayout.findOutputSection(".got"))
77 gotAtom->_virtualAddr = gotSection->virtualAddr();
79 gotAtom->_virtualAddr = 0;
81 // TODO: resolve addresses of __exidx_start/_end atoms
85 unique_bump_ptr<SymbolTable<ELFT>>
86 ARMExecutableWriter<ELFT>::createSymbolTable() {
87 return unique_bump_ptr<SymbolTable<ELFT>>(
88 new (this->_alloc) ARMSymbolTable<ELFT>(this->_context));
92 void ARMExecutableWriter<ELFT>::processUndefinedSymbol(
93 StringRef symName, RuntimeFile<ELFT> &file) const {
94 if (symName == gotSymbol) {
95 file.addAbsoluteAtom(gotSymbol);
96 } else if (symName.startswith("__exidx")) {
97 file.addAbsoluteAtom("__exidx_start");
98 file.addAbsoluteAtom("__exidx_end");
102 template <class ELFT>
103 std::error_code ARMExecutableWriter<ELFT>::setELFHeader() {
104 if (std::error_code ec = ExecutableWriter<ELFT>::setELFHeader())
107 // Fixup entry point for Thumb code.
108 StringRef entryName = _context.entrySymbolName();
109 if (const AtomLayout *al = _armLayout.findAtomLayoutByName(entryName)) {
110 const auto *ea = dyn_cast<DefinedAtom>(al->_atom);
111 if (ea && ea->codeModel() == DefinedAtom::codeARMThumb)
112 this->_elfHeader->e_entry(al->_virtualAddr | 0x1);
115 return std::error_code();
121 #endif // LLD_READER_WRITER_ELF_ARM_ARM_EXECUTABLE_WRITER_H