blob: 4c2ab1257867cabed9a0637f954459983c3a38cf [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 Easwarana6f00fe2013-01-30 07:11:43 +000013#include "TargetLayout.h"
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000014#include "ExecutableAtoms.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000015
Michael J. Spencer43ecac52013-01-29 19:53:41 +000016#include "lld/ReaderWriter/ELFTargetInfo.h"
17
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000018using namespace llvm;
19using namespace llvm::object;
Nick Kledzikabb69812012-05-31 22:34:00 +000020namespace lld {
21namespace elf {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000022template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000023class ExecutableWriter;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000024
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000025//===----------------------------------------------------------------------===//
Michael J. Spencere68f9032013-01-29 22:03:39 +000026// ExecutableWriter Class
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000027//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000028template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000029class ExecutableWriter : public ELFWriter {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000030public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000031 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
32 typedef Elf_Sym_Impl<ELFT> Elf_Sym;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000033
Michael J. Spencere68f9032013-01-29 22:03:39 +000034 ExecutableWriter(const ELFTargetInfo &ti);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000035
36private:
Michael J. Spencera2c97272013-01-04 21:09:21 +000037 // build the sections that need to be created
Michael J. Spencere68f9032013-01-29 22:03:39 +000038 void buildChunks(const File &file);
39 virtual error_code writeFile(const File &File, StringRef path);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000040 void buildAtomToAddressMap();
41 void buildSymbolTable ();
42 void buildSectionHeaderTable();
43 void assignSectionsWithNoSegments();
Michael J. Spencere68f9032013-01-29 22:03:39 +000044 void addAbsoluteUndefinedSymbols(const File &File);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000045 void addDefaultAtoms();
46 void addFiles(InputFiles&);
47 void finalizeDefaultAtomValues();
Shankar Easwaran495d38b2012-12-27 02:26:30 +000048
Michael J. Spencera2c97272013-01-04 21:09:21 +000049 uint64_t addressOfAtom(const Atom *atom) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000050 return _atomToAddressMap[atom];
51 }
52
Shankar Easwaran495d38b2012-12-27 02:26:30 +000053 void createDefaultSections();
54
Michael J. Spencer64afcb42013-01-23 01:18:43 +000055 const ELFTargetInfo &_targetInfo;
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000056 TargetHandler<ELFT> &_targetHandler;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000057
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000058 typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000059 AtomToAddress _atomToAddressMap;
60 llvm::BumpPtrAllocator _chunkAllocate;
Shankar Easwaran396e4c02013-01-30 07:19:57 +000061 TargetLayout<ELFT> *_layout;
Michael J. Spencere68f9032013-01-29 22:03:39 +000062 Header<ELFT> *_Header;
63 ProgramHeader<ELFT> *_programHeader;
64 SymbolTable<ELFT> * _symtab;
65 StringTable<ELFT> *_strtab;
66 StringTable<ELFT> *_shstrtab;
67 SectionHeader<ELFT> *_shdrtab;
68 CRuntimeFile<ELFT> _runtimeFile;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000069};
70
71//===----------------------------------------------------------------------===//
Michael J. Spencere68f9032013-01-29 22:03:39 +000072// ExecutableWriter
Shankar Easwaran495d38b2012-12-27 02:26:30 +000073//===----------------------------------------------------------------------===//
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000074template <class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000075ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000076 : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000077 _runtimeFile(ti) {
Michael J. Spencer901fd6a2013-01-30 20:05:27 +000078 _layout = &_targetHandler.targetLayout();
Shankar Easwaran495d38b2012-12-27 02:26:30 +000079}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000080
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000081template <class ELFT>
82void ExecutableWriter<ELFT>::buildChunks(const File &file) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000083 for (const DefinedAtom *definedAtom : file.defined() ) {
84 _layout->addAtom(definedAtom);
85 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000086 /// Add all the absolute atoms to the layout
87 for (const AbsoluteAtom *absoluteAtom : file.absolute()) {
88 _layout->addAtom(absoluteAtom);
89 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +000090}
91
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000092template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000093void ExecutableWriter<ELFT>::buildSymbolTable () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +000094 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000095 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +000096 for (const auto &atom : section->atoms())
Michael J. Spencer42606572013-01-30 01:25:06 +000097 _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000098}
99
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000100template<class ELFT>
101void
Michael J. Spencere68f9032013-01-29 22:03:39 +0000102ExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const File &file) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000103 // add all the absolute symbols that the layout contains to the output symbol
104 // table
105 for (auto &atom : _layout->absoluteAtoms())
Michael J. Spencer42606572013-01-30 01:25:06 +0000106 _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000107 for (const UndefinedAtom *a : file.undefined())
108 _symtab->addSymbol(a, ELF::SHN_UNDEF);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000109}
110
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000111template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000112void ExecutableWriter<ELFT>::buildAtomToAddressMap () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000113 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000114 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000115 for (const auto &atom : section->atoms())
Michael J. Spencer42606572013-01-30 01:25:06 +0000116 _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000117 // build the atomToAddressMap that contains absolute symbols too
118 for (auto &atom : _layout->absoluteAtoms())
Michael J. Spencer42606572013-01-30 01:25:06 +0000119 _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
Sid Manningdd110202012-09-25 18:22:09 +0000120}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000121
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000122template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000123void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000124 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000125 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000126 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000127 if (mergedSec->hasSegment())
128 _shdrtab->appendSection(mergedSec);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000129 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000130}
131
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000132template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000133void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000134 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000135 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000136 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000137 if (!mergedSec->hasSegment())
138 _shdrtab->appendSection(mergedSec);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000139 }
140 _layout->assignOffsetsForMiscSections();
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000141 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000142 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencere68f9032013-01-29 22:03:39 +0000143 if (!DefaultLayout<ELFT>::hasOutputSegment(section))
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000144 _shdrtab->updateSection(section);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000145}
146
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000147/// \brief Add absolute symbols by default. These are linker added
148/// absolute symbols
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000149template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000150void ExecutableWriter<ELFT>::addDefaultAtoms() {
Michael J. Spencer990ec2b2013-01-28 04:15:44 +0000151 _runtimeFile.addUndefinedAtom(_targetInfo.getEntry());
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000152 _runtimeFile.addAbsoluteAtom("__bss_start");
153 _runtimeFile.addAbsoluteAtom("__bss_end");
154 _runtimeFile.addAbsoluteAtom("_end");
155 _runtimeFile.addAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000156 _runtimeFile.addAbsoluteAtom("__init_array_start");
157 _runtimeFile.addAbsoluteAtom("__init_array_end");
Michael J. Spencer289dced2013-01-29 16:38:03 +0000158 _runtimeFile.addAbsoluteAtom("__rela_iplt_start");
159 _runtimeFile.addAbsoluteAtom("__rela_iplt_end");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000160}
161
162/// \brief Hook in lld to add CRuntime file
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000163template <class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000164void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000165 addDefaultAtoms();
166 inputFiles.prependFile(_runtimeFile);
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000167 // Give a chance for the target to add atoms
168 _targetHandler.addFiles(inputFiles);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000169}
170
171/// Finalize the value of all the absolute symbols that we
172/// created
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000173template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000174void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
Michael J. Spencer289dced2013-01-29 16:38:03 +0000175 auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
176 auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
177 auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
178 auto endAtomIter = _layout->findAbsoluteAtom("end");
179 auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
180 auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
181 auto realIpltStartIter = _layout->findAbsoluteAtom("__rela_iplt_start");
182 auto realIpltEndIter = _layout->findAbsoluteAtom("__rela_iplt_end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000183
Michael J. Spencere68f9032013-01-29 22:03:39 +0000184 auto startEnd = [&](typename DefaultLayout<ELFT>::AbsoluteAtomIterT start,
185 typename DefaultLayout<ELFT>::AbsoluteAtomIterT end,
Michael J. Spencer289dced2013-01-29 16:38:03 +0000186 StringRef sec) -> void {
187 auto section = _layout->findOutputSection(sec);
188 if (section) {
Michael J. Spencer42606572013-01-30 01:25:06 +0000189 (*start)->_virtualAddr = section->virtualAddr();
190 (*end)->_virtualAddr = section->virtualAddr() + section->memSize();
Michael J. Spencer289dced2013-01-29 16:38:03 +0000191 } else {
Michael J. Spencer42606572013-01-30 01:25:06 +0000192 (*start)->_virtualAddr = 0;
193 (*end)->_virtualAddr = 0;
Michael J. Spencer289dced2013-01-29 16:38:03 +0000194 }
195 };
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000196
Michael J. Spencer289dced2013-01-29 16:38:03 +0000197 startEnd(initArrayStartIter, initArrayEndIter, ".init_array");
198 startEnd(realIpltStartIter, realIpltEndIter, ".rela.plt");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000199
Michael J. Spencer289dced2013-01-29 16:38:03 +0000200 assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
201 bssEndAtomIter == _layout->absoluteAtoms().end() ||
202 underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
203 endAtomIter == _layout->absoluteAtoms().end()) &&
204 "Unable to find the absolute atoms that have been added by lld");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000205
Michael J. Spencer289dced2013-01-29 16:38:03 +0000206 auto phe = _programHeader->findProgramHeader(
207 llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000208
Michael J. Spencer289dced2013-01-29 16:38:03 +0000209 assert(!(phe == _programHeader->end()) &&
210 "Can't find a data segment in the program header!");
211
Michael J. Spencer42606572013-01-30 01:25:06 +0000212 (*bssStartAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_filesz;
213 (*bssEndAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
214 (*underScoreEndAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
215 (*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000216}
217
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000218template<class ELFT>
219error_code
Michael J. Spencere68f9032013-01-29 22:03:39 +0000220ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000221 buildChunks(file);
222 // Create the default sections like the symbol table, string table, and the
223 // section string table
224 createDefaultSections();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000225
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000226 // Set the Layout
227 _layout->assignSectionsToSegments();
228 _layout->assignFileOffsets();
229 _layout->assignVirtualAddress();
230
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000231 // Finalize the default value of symbols that the linker adds
232 finalizeDefaultAtomValues();
233
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000234 // Build the Atom To Address map for applying relocations
235 buildAtomToAddressMap();
236
237 // Create symbol table and section string table
238 buildSymbolTable();
239
240 // add other symbols
241 addAbsoluteUndefinedSymbols(file);
242
243 // Finalize the layout by calling the finalize() functions
244 _layout->finalize();
245
246 // build Section Header table
247 buildSectionHeaderTable();
248
249 // assign Offsets and virtual addresses
250 // for sections with no segments
251 assignSectionsWithNoSegments();
252
253 uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000254
255 OwningPtr<FileOutputBuffer> buffer;
256 error_code ec = FileOutputBuffer::create(path,
257 totalSize, buffer,
258 FileOutputBuffer::F_executable);
259 if (ec)
260 return ec;
261
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000262 _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
263 ELF::ELFCLASS32);
264 _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
265 ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000266 _Header->e_type(_targetInfo.getOutputType());
267 _Header->e_machine(_targetInfo.getOutputMachine());
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000268
269 if (!_targetHandler.doesOverrideHeader()) {
270 _Header->e_ident(ELF::EI_VERSION, 1);
271 _Header->e_ident(ELF::EI_OSABI, 0);
272 _Header->e_version(1);
273 } else {
274 // override the contents of the ELF Header
275 _targetHandler.setHeaderInfo(_Header);
276 }
Michael J. Spencere68f9032013-01-29 22:03:39 +0000277 _Header->e_phoff(_programHeader->fileOffset());
278 _Header->e_shoff(_shdrtab->fileOffset());
279 _Header->e_phentsize(_programHeader->entsize());
280 _Header->e_phnum(_programHeader->numHeaders());
281 _Header->e_shentsize(_shdrtab->entsize());
282 _Header->e_shnum(_shdrtab->numHeaders());
283 _Header->e_shstrndx(_shstrtab->ordinal());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000284 uint64_t virtualAddr = 0;
Michael J. Spencer990ec2b2013-01-28 04:15:44 +0000285 _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000286 _Header->e_entry(virtualAddr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000287
288 // HACK: We have to write out the header and program header here even though
289 // they are a member of a segment because only sections are written in the
290 // following loop.
Michael J. Spencere68f9032013-01-29 22:03:39 +0000291 _Header->write(this, *buffer);
Michael J. Spenceradfb7eb2013-01-29 01:00:21 +0000292 _programHeader->write(this, *buffer);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000293
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000294 for (auto section : _layout->sections())
Michael J. Spenceradfb7eb2013-01-29 01:00:21 +0000295 section->write(this, *buffer);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000296
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000297 return buffer->commit();
298}
Nick Kledzikabb69812012-05-31 22:34:00 +0000299
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000300template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000301void ExecutableWriter<ELFT>::createDefaultSections() {
302 _Header = new Header<ELFT>(_targetInfo);
303 _programHeader = new ProgramHeader<ELFT>(_targetInfo);
304 _layout->setHeader(_Header);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000305 _layout->setProgramHeader(_programHeader);
306
Michael J. Spencere68f9032013-01-29 22:03:39 +0000307 _symtab = new SymbolTable<
308 ELFT>(_targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE);
309 _strtab = new StringTable<
310 ELFT>(_targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE);
311 _shstrtab = new StringTable<ELFT>(
312 _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS);
313 _shdrtab = new SectionHeader<
314 ELFT>(_targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000315 _layout->addSection(_symtab);
316 _layout->addSection(_strtab);
317 _layout->addSection(_shstrtab);
318 _shdrtab->setStringSection(_shstrtab);
319 _symtab->setStringSection(_strtab);
320 _layout->addSection(_shdrtab);
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000321
322 // give a chance for the target to add sections
323 _targetHandler.createDefaultSections();
Sid Manningdd110202012-09-25 18:22:09 +0000324}
Nick Kledzikabb69812012-05-31 22:34:00 +0000325} // namespace elf
326
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000327std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000328 using llvm::object::ELFType;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000329 // Set the default layout to be the static executable layout
Michael J. Spencera2c97272013-01-04 21:09:21 +0000330 // We would set the layout to a dynamic executable layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000331 // if we came across any shared libraries in the process
Michael J. Spencera2c97272013-01-04 21:09:21 +0000332
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000333 if (!TI.is64Bits() && TI.isLittleEndian())
334 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000335 elf::ExecutableWriter<ELFType<support::little, 4, false>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000336 else if (TI.is64Bits() && TI.isLittleEndian())
337 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000338 elf::ExecutableWriter<ELFType<support::little, 8, true>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000339 else if (!TI.is64Bits() && !TI.isLittleEndian())
340 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000341 elf::ExecutableWriter<ELFType<support::big, 4, false>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000342 else if (TI.is64Bits() && !TI.isLittleEndian())
343 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000344 elf::ExecutableWriter<ELFType<support::big, 8, true>>(TI));
Nick Kledzikabb69812012-05-31 22:34:00 +0000345
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000346 llvm_unreachable("Invalid Options!");
Nick Kledzikabb69812012-05-31 22:34:00 +0000347}
Nick Kledzikabb69812012-05-31 22:34:00 +0000348} // namespace lld