blob: 2318cd8ebef5f7129123a7910572445caf803190 [file] [log] [blame]
Nick Kledzikabb69812012-05-31 22:34:00 +00001//===- lib/ReaderWriter/ELF/WriterELF.cpp ---------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Michael J. Spencer43ecac52013-01-29 19:53:41 +000010#include "lld/ReaderWriter/Writer.h"
Michael J. Spencer64afcb42013-01-23 01:18:43 +000011
Michael J. Spencere68f9032013-01-29 22:03:39 +000012#include "DefaultLayout.h"
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000013#include "ExecutableAtoms.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000014
Michael J. Spencer43ecac52013-01-29 19:53:41 +000015#include "lld/ReaderWriter/ELFTargetInfo.h"
16
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000017using namespace llvm;
18using namespace llvm::object;
Nick Kledzikabb69812012-05-31 22:34:00 +000019namespace lld {
20namespace elf {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000021template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000022class ExecutableWriter;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000023
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000024//===----------------------------------------------------------------------===//
Michael J. Spencere68f9032013-01-29 22:03:39 +000025// ExecutableWriter Class
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000026//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000027template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000028class ExecutableWriter : public ELFWriter {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000029public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000030 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
31 typedef Elf_Sym_Impl<ELFT> Elf_Sym;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000032
Michael J. Spencere68f9032013-01-29 22:03:39 +000033 ExecutableWriter(const ELFTargetInfo &ti);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000034
35private:
Michael J. Spencera2c97272013-01-04 21:09:21 +000036 // build the sections that need to be created
Michael J. Spencere68f9032013-01-29 22:03:39 +000037 void buildChunks(const File &file);
38 virtual error_code writeFile(const File &File, StringRef path);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000039 void buildAtomToAddressMap();
40 void buildSymbolTable ();
41 void buildSectionHeaderTable();
42 void assignSectionsWithNoSegments();
Michael J. Spencere68f9032013-01-29 22:03:39 +000043 void addAbsoluteUndefinedSymbols(const File &File);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000044 void addDefaultAtoms();
45 void addFiles(InputFiles&);
46 void finalizeDefaultAtomValues();
Shankar Easwaran495d38b2012-12-27 02:26:30 +000047
Michael J. Spencera2c97272013-01-04 21:09:21 +000048 uint64_t addressOfAtom(const Atom *atom) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000049 return _atomToAddressMap[atom];
50 }
51
52 KindHandler *kindHandler() { return _referenceKindHandler.get(); }
53
54 void createDefaultSections();
55
Michael J. Spencer64afcb42013-01-23 01:18:43 +000056 const ELFTargetInfo &_targetInfo;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000057
58 typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
59 std::unique_ptr<KindHandler> _referenceKindHandler;
60 AtomToAddress _atomToAddressMap;
61 llvm::BumpPtrAllocator _chunkAllocate;
Michael J. Spencere68f9032013-01-29 22:03:39 +000062 DefaultLayout<ELFT> *_layout;
63 Header<ELFT> *_Header;
64 ProgramHeader<ELFT> *_programHeader;
65 SymbolTable<ELFT> * _symtab;
66 StringTable<ELFT> *_strtab;
67 StringTable<ELFT> *_shstrtab;
68 SectionHeader<ELFT> *_shdrtab;
69 CRuntimeFile<ELFT> _runtimeFile;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000070};
71
72//===----------------------------------------------------------------------===//
Michael J. Spencere68f9032013-01-29 22:03:39 +000073// ExecutableWriter
Shankar Easwaran495d38b2012-12-27 02:26:30 +000074//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000075template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000076ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
Michael J. Spencer64afcb42013-01-23 01:18:43 +000077 : _targetInfo(ti)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000078 , _referenceKindHandler(KindHandler::makeHandler(
Michael J. Spencer64afcb42013-01-23 01:18:43 +000079 ti.getTriple().getArch(), ti.isLittleEndian()))
80 , _runtimeFile(ti) {
Michael J. Spencere68f9032013-01-29 22:03:39 +000081 _layout = new DefaultLayout<ELFT>(ti);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000082}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000083
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000084template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000085void ExecutableWriter<ELFT>::buildChunks(const File &file){
Shankar Easwaran495d38b2012-12-27 02:26:30 +000086 for (const DefinedAtom *definedAtom : file.defined() ) {
87 _layout->addAtom(definedAtom);
88 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000089 /// Add all the absolute atoms to the layout
90 for (const AbsoluteAtom *absoluteAtom : file.absolute()) {
91 _layout->addAtom(absoluteAtom);
92 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +000093}
94
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000095template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000096void ExecutableWriter<ELFT>::buildSymbolTable () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +000097 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000098 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +000099 for (const auto &atom : section->atoms())
100 _symtab->addSymbol(atom._atom, section->ordinal(), atom._virtualAddr);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000101}
102
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000103template<class ELFT>
104void
Michael J. Spencere68f9032013-01-29 22:03:39 +0000105ExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const File &file) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000106 // add all the absolute symbols that the layout contains to the output symbol
107 // table
108 for (auto &atom : _layout->absoluteAtoms())
109 _symtab->addSymbol(atom.absoluteAtom(), ELF::SHN_ABS, atom.value());
110 for (const UndefinedAtom *a : file.undefined())
111 _symtab->addSymbol(a, ELF::SHN_UNDEF);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000112}
113
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000114template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000115void ExecutableWriter<ELFT>::buildAtomToAddressMap () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000116 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000117 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000118 for (const auto &atom : section->atoms())
119 _atomToAddressMap[atom._atom] = atom._virtualAddr;
120 // build the atomToAddressMap that contains absolute symbols too
121 for (auto &atom : _layout->absoluteAtoms())
122 _atomToAddressMap[atom.absoluteAtom()] = atom.value();
Sid Manningdd110202012-09-25 18:22:09 +0000123}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000124
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000125template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000126void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000127 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000128 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000129 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000130 if (mergedSec->hasSegment())
131 _shdrtab->appendSection(mergedSec);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000132 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000133}
134
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000135template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000136void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000137 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000138 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000139 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000140 if (!mergedSec->hasSegment())
141 _shdrtab->appendSection(mergedSec);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000142 }
143 _layout->assignOffsetsForMiscSections();
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000144 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000145 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencere68f9032013-01-29 22:03:39 +0000146 if (!DefaultLayout<ELFT>::hasOutputSegment(section))
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000147 _shdrtab->updateSection(section);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000148}
149
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000150/// \brief Add absolute symbols by default. These are linker added
151/// absolute symbols
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000152template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000153void ExecutableWriter<ELFT>::addDefaultAtoms() {
Michael J. Spencer990ec2b2013-01-28 04:15:44 +0000154 _runtimeFile.addUndefinedAtom(_targetInfo.getEntry());
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000155 _runtimeFile.addAbsoluteAtom("__bss_start");
156 _runtimeFile.addAbsoluteAtom("__bss_end");
157 _runtimeFile.addAbsoluteAtom("_end");
158 _runtimeFile.addAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000159 _runtimeFile.addAbsoluteAtom("__init_array_start");
160 _runtimeFile.addAbsoluteAtom("__init_array_end");
Michael J. Spencer289dced2013-01-29 16:38:03 +0000161 _runtimeFile.addAbsoluteAtom("__rela_iplt_start");
162 _runtimeFile.addAbsoluteAtom("__rela_iplt_end");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000163}
164
165/// \brief Hook in lld to add CRuntime file
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000166template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000167void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000168 addDefaultAtoms();
169 inputFiles.prependFile(_runtimeFile);
170}
171
172/// Finalize the value of all the absolute symbols that we
173/// created
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000174template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000175void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
Michael J. Spencer289dced2013-01-29 16:38:03 +0000176 auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
177 auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
178 auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
179 auto endAtomIter = _layout->findAbsoluteAtom("end");
180 auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
181 auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
182 auto realIpltStartIter = _layout->findAbsoluteAtom("__rela_iplt_start");
183 auto realIpltEndIter = _layout->findAbsoluteAtom("__rela_iplt_end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000184
Michael J. Spencere68f9032013-01-29 22:03:39 +0000185 auto startEnd = [&](typename DefaultLayout<ELFT>::AbsoluteAtomIterT start,
186 typename DefaultLayout<ELFT>::AbsoluteAtomIterT end,
Michael J. Spencer289dced2013-01-29 16:38:03 +0000187 StringRef sec) -> void {
188 auto section = _layout->findOutputSection(sec);
189 if (section) {
190 start->setValue(section->virtualAddr());
191 end->setValue(section->virtualAddr() + section->memSize());
192 } else {
193 start->setValue(0);
194 end->setValue(0);
195 }
196 };
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000197
Michael J. Spencer289dced2013-01-29 16:38:03 +0000198 startEnd(initArrayStartIter, initArrayEndIter, ".init_array");
199 startEnd(realIpltStartIter, realIpltEndIter, ".rela.plt");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000200
Michael J. Spencer289dced2013-01-29 16:38:03 +0000201 assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
202 bssEndAtomIter == _layout->absoluteAtoms().end() ||
203 underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
204 endAtomIter == _layout->absoluteAtoms().end()) &&
205 "Unable to find the absolute atoms that have been added by lld");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000206
Michael J. Spencer289dced2013-01-29 16:38:03 +0000207 auto phe = _programHeader->findProgramHeader(
208 llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000209
Michael J. Spencer289dced2013-01-29 16:38:03 +0000210 assert(!(phe == _programHeader->end()) &&
211 "Can't find a data segment in the program header!");
212
213 bssStartAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_filesz);
214 bssEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
215 underScoreEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
216 endAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000217}
218
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000219template<class ELFT>
220error_code
Michael J. Spencere68f9032013-01-29 22:03:39 +0000221ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000222 buildChunks(file);
223 // Create the default sections like the symbol table, string table, and the
224 // section string table
225 createDefaultSections();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000226
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000227 // Set the Layout
228 _layout->assignSectionsToSegments();
229 _layout->assignFileOffsets();
230 _layout->assignVirtualAddress();
231
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000232 // Finalize the default value of symbols that the linker adds
233 finalizeDefaultAtomValues();
234
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000235 // Build the Atom To Address map for applying relocations
236 buildAtomToAddressMap();
237
238 // Create symbol table and section string table
239 buildSymbolTable();
240
241 // add other symbols
242 addAbsoluteUndefinedSymbols(file);
243
244 // Finalize the layout by calling the finalize() functions
245 _layout->finalize();
246
247 // build Section Header table
248 buildSectionHeaderTable();
249
250 // assign Offsets and virtual addresses
251 // for sections with no segments
252 assignSectionsWithNoSegments();
253
254 uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000255
256 OwningPtr<FileOutputBuffer> buffer;
257 error_code ec = FileOutputBuffer::create(path,
258 totalSize, buffer,
259 FileOutputBuffer::F_executable);
260 if (ec)
261 return ec;
262
Michael J. Spencere68f9032013-01-29 22:03:39 +0000263 _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000264 : ELF::ELFCLASS32);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000265 _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000266 ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000267 _Header->e_ident(ELF::EI_VERSION, 1);
268 _Header->e_ident(ELF::EI_OSABI, 0);
269 _Header->e_type(_targetInfo.getOutputType());
270 _Header->e_machine(_targetInfo.getOutputMachine());
271 _Header->e_version(1);
272 _Header->e_entry(0ULL);
273 _Header->e_phoff(_programHeader->fileOffset());
274 _Header->e_shoff(_shdrtab->fileOffset());
275 _Header->e_phentsize(_programHeader->entsize());
276 _Header->e_phnum(_programHeader->numHeaders());
277 _Header->e_shentsize(_shdrtab->entsize());
278 _Header->e_shnum(_shdrtab->numHeaders());
279 _Header->e_shstrndx(_shstrtab->ordinal());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000280 uint64_t virtualAddr = 0;
Michael J. Spencer990ec2b2013-01-28 04:15:44 +0000281 _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000282 _Header->e_entry(virtualAddr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000283
284 // HACK: We have to write out the header and program header here even though
285 // they are a member of a segment because only sections are written in the
286 // following loop.
Michael J. Spencere68f9032013-01-29 22:03:39 +0000287 _Header->write(this, *buffer);
Michael J. Spenceradfb7eb2013-01-29 01:00:21 +0000288 _programHeader->write(this, *buffer);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000289
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000290 for (auto section : _layout->sections())
Michael J. Spenceradfb7eb2013-01-29 01:00:21 +0000291 section->write(this, *buffer);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000292
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000293 return buffer->commit();
294}
Nick Kledzikabb69812012-05-31 22:34:00 +0000295
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000296template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000297void ExecutableWriter<ELFT>::createDefaultSections() {
298 _Header = new Header<ELFT>(_targetInfo);
299 _programHeader = new ProgramHeader<ELFT>(_targetInfo);
300 _layout->setHeader(_Header);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000301 _layout->setProgramHeader(_programHeader);
302
Michael J. Spencere68f9032013-01-29 22:03:39 +0000303 _symtab = new SymbolTable<
304 ELFT>(_targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE);
305 _strtab = new StringTable<
306 ELFT>(_targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE);
307 _shstrtab = new StringTable<ELFT>(
308 _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS);
309 _shdrtab = new SectionHeader<
310 ELFT>(_targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000311 _layout->addSection(_symtab);
312 _layout->addSection(_strtab);
313 _layout->addSection(_shstrtab);
314 _shdrtab->setStringSection(_shstrtab);
315 _symtab->setStringSection(_strtab);
316 _layout->addSection(_shdrtab);
Sid Manningdd110202012-09-25 18:22:09 +0000317}
Nick Kledzikabb69812012-05-31 22:34:00 +0000318} // namespace elf
319
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000320std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000321 using llvm::object::ELFType;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000322 // Set the default layout to be the static executable layout
Michael J. Spencera2c97272013-01-04 21:09:21 +0000323 // We would set the layout to a dynamic executable layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000324 // if we came across any shared libraries in the process
Michael J. Spencera2c97272013-01-04 21:09:21 +0000325
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000326 if (!TI.is64Bits() && TI.isLittleEndian())
327 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000328 elf::ExecutableWriter<ELFType<support::little, 4, false>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000329 else if (TI.is64Bits() && TI.isLittleEndian())
330 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000331 elf::ExecutableWriter<ELFType<support::little, 8, true>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000332 else if (!TI.is64Bits() && !TI.isLittleEndian())
333 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000334 elf::ExecutableWriter<ELFType<support::big, 4, false>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000335 else if (TI.is64Bits() && !TI.isLittleEndian())
336 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000337 elf::ExecutableWriter<ELFType<support::big, 8, true>>(TI));
Nick Kledzikabb69812012-05-31 22:34:00 +0000338
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000339 llvm_unreachable("Invalid Options!");
Nick Kledzikabb69812012-05-31 22:34:00 +0000340}
Nick Kledzikabb69812012-05-31 22:34:00 +0000341} // namespace lld