blob: b5d3b4d3324efa8aaa968d2af300699a8a155a9c [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();
Michael J. Spencer942dbcc2013-02-23 01:02:31 +000041 void buildStaticSymbolTable(const File &file);
42 void buildDynamicSymbolTable(const File &file);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000043 void buildSectionHeaderTable();
44 void assignSectionsWithNoSegments();
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. Spencercadb0822013-02-19 21:04:30 +000055 llvm::BumpPtrAllocator _alloc;
56
Michael J. Spencer64afcb42013-01-23 01:18:43 +000057 const ELFTargetInfo &_targetInfo;
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000058 TargetHandler<ELFT> &_targetHandler;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000059
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000060 typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000061 AtomToAddress _atomToAddressMap;
Shankar Easwaran396e4c02013-01-30 07:19:57 +000062 TargetLayout<ELFT> *_layout;
Michael J. Spencercadb0822013-02-19 21:04:30 +000063 LLD_UNIQUE_BUMP_PTR(Header<ELFT>) _Header;
64 LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
65 LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
66 LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _strtab;
67 LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _shstrtab;
68 LLD_UNIQUE_BUMP_PTR(SectionHeader<ELFT>) _shdrtab;
Michael J. Spencerb71ce652013-02-20 19:46:12 +000069 /// \name Dynamic sections.
70 /// @{
71 LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) _dynamicTable;
Michael J. Spencer942dbcc2013-02-23 01:02:31 +000072 LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) _dynamicSymbolTable;
73 LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable;
Michael J. Spencere4c0e372013-02-20 20:13:47 +000074 LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection;
Michael J. Spencer34072112013-02-23 19:46:18 +000075 LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
Michael J. Spencerb71ce652013-02-20 19:46:12 +000076 /// @}
Michael J. Spencere68f9032013-01-29 22:03:39 +000077 CRuntimeFile<ELFT> _runtimeFile;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000078};
79
80//===----------------------------------------------------------------------===//
Michael J. Spencere68f9032013-01-29 22:03:39 +000081// ExecutableWriter
Shankar Easwaran495d38b2012-12-27 02:26:30 +000082//===----------------------------------------------------------------------===//
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000083template <class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +000084ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000085 : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000086 _runtimeFile(ti) {
Michael J. Spencer901fd6a2013-01-30 20:05:27 +000087 _layout = &_targetHandler.targetLayout();
Shankar Easwaran495d38b2012-12-27 02:26:30 +000088}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000089
Shankar Easwarana6f00fe2013-01-30 07:11:43 +000090template <class ELFT>
91void ExecutableWriter<ELFT>::buildChunks(const File &file) {
Shankar Easwarandb74ffb2013-02-24 03:09:10 +000092 for (const DefinedAtom *definedAtom : file.defined()) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000093 _layout->addAtom(definedAtom);
Shankar Easwarandb74ffb2013-02-24 03:09:10 +000094 }
Michael J. Spencer942dbcc2013-02-23 01:02:31 +000095 for (const AbsoluteAtom *absoluteAtom : file.absolute())
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000096 _layout->addAtom(absoluteAtom);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000097}
98
Michael J. Spencer942dbcc2013-02-23 01:02:31 +000099template <class ELFT>
100void ExecutableWriter<ELFT>::buildStaticSymbolTable(const File &file) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000101 for (auto sec : _layout->sections())
Michael J. Spencerdb188472013-02-14 20:24:38 +0000102 if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000103 for (const auto &atom : section->atoms())
Michael J. Spencer42606572013-01-30 01:25:06 +0000104 _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000105 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. Spencer942dbcc2013-02-23 01:02:31 +0000111template <class ELFT>
112void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
113 for (const auto sla : file.sharedLibrary()) {
114 _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
115 }
116}
117
118template <class ELFT> void ExecutableWriter<ELFT>::buildAtomToAddressMap() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000119 for (auto sec : _layout->sections())
Michael J. Spencerdb188472013-02-14 20:24:38 +0000120 if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000121 for (const auto &atom : section->atoms())
Michael J. Spencer42606572013-01-30 01:25:06 +0000122 _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000123 // build the atomToAddressMap that contains absolute symbols too
124 for (auto &atom : _layout->absoluteAtoms())
Michael J. Spencer42606572013-01-30 01:25:06 +0000125 _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
Sid Manningdd110202012-09-25 18:22:09 +0000126}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000127
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000128template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000129void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000130 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerdb188472013-02-14 20:24:38 +0000131 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
132 mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000133 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000134 if (mergedSec->hasSegment())
135 _shdrtab->appendSection(mergedSec);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000136 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000137}
138
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000139template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000140void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000141 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerdb188472013-02-14 20:24:38 +0000142 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
143 mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000144 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000145 if (!mergedSec->hasSegment())
146 _shdrtab->appendSection(mergedSec);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000147 }
148 _layout->assignOffsetsForMiscSections();
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000149 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000150 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencere68f9032013-01-29 22:03:39 +0000151 if (!DefaultLayout<ELFT>::hasOutputSegment(section))
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000152 _shdrtab->updateSection(section);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000153}
154
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000155/// \brief Add absolute symbols by default. These are linker added
156/// absolute symbols
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000157template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000158void ExecutableWriter<ELFT>::addDefaultAtoms() {
Michael J. Spencer990ec2b2013-01-28 04:15:44 +0000159 _runtimeFile.addUndefinedAtom(_targetInfo.getEntry());
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000160 _runtimeFile.addAbsoluteAtom("__bss_start");
161 _runtimeFile.addAbsoluteAtom("__bss_end");
162 _runtimeFile.addAbsoluteAtom("_end");
163 _runtimeFile.addAbsoluteAtom("end");
Michael J. Spencerc8803d22013-02-01 05:36:00 +0000164 _runtimeFile.addAbsoluteAtom("__preinit_array_start");
165 _runtimeFile.addAbsoluteAtom("__preinit_array_end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000166 _runtimeFile.addAbsoluteAtom("__init_array_start");
167 _runtimeFile.addAbsoluteAtom("__init_array_end");
Michael J. Spencer289dced2013-01-29 16:38:03 +0000168 _runtimeFile.addAbsoluteAtom("__rela_iplt_start");
169 _runtimeFile.addAbsoluteAtom("__rela_iplt_end");
Michael J. Spencerc8803d22013-02-01 05:36:00 +0000170 _runtimeFile.addAbsoluteAtom("__fini_array_start");
171 _runtimeFile.addAbsoluteAtom("__fini_array_end");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000172}
173
174/// \brief Hook in lld to add CRuntime file
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000175template <class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000176void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000177 addDefaultAtoms();
178 inputFiles.prependFile(_runtimeFile);
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000179 // Give a chance for the target to add atoms
180 _targetHandler.addFiles(inputFiles);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000181}
182
183/// Finalize the value of all the absolute symbols that we
184/// created
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000185template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000186void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
Michael J. Spencer289dced2013-01-29 16:38:03 +0000187 auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
188 auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
189 auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
190 auto endAtomIter = _layout->findAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000191
Michael J. Spencerc8803d22013-02-01 05:36:00 +0000192 auto startEnd = [&](StringRef sym, StringRef sec) -> void {
193 // TODO: This looks like a good place to use Twine...
194 std::string start("__"), end("__");
195 start += sym;
196 start += "_start";
197 end += sym;
198 end += "_end";
199 auto s = _layout->findAbsoluteAtom(start);
200 auto e = _layout->findAbsoluteAtom(end);
Michael J. Spencer289dced2013-01-29 16:38:03 +0000201 auto section = _layout->findOutputSection(sec);
202 if (section) {
Michael J. Spencerc8803d22013-02-01 05:36:00 +0000203 (*s)->_virtualAddr = section->virtualAddr();
204 (*e)->_virtualAddr = section->virtualAddr() + section->memSize();
Michael J. Spencer289dced2013-01-29 16:38:03 +0000205 } else {
Michael J. Spencerc8803d22013-02-01 05:36:00 +0000206 (*s)->_virtualAddr = 0;
207 (*e)->_virtualAddr = 0;
Michael J. Spencer289dced2013-01-29 16:38:03 +0000208 }
209 };
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000210
Michael J. Spencerc8803d22013-02-01 05:36:00 +0000211 startEnd("preinit_array", ".preinit_array");
212 startEnd("init_array", ".init_array");
213 startEnd("rela_iplt", ".rela.plt");
214 startEnd("fini_array", ".fini_array");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000215
Michael J. Spencer289dced2013-01-29 16:38:03 +0000216 assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
217 bssEndAtomIter == _layout->absoluteAtoms().end() ||
218 underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
219 endAtomIter == _layout->absoluteAtoms().end()) &&
220 "Unable to find the absolute atoms that have been added by lld");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000221
Michael J. Spencer289dced2013-01-29 16:38:03 +0000222 auto phe = _programHeader->findProgramHeader(
223 llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000224
Michael J. Spencer289dced2013-01-29 16:38:03 +0000225 assert(!(phe == _programHeader->end()) &&
226 "Can't find a data segment in the program header!");
227
Michael J. Spencer42606572013-01-30 01:25:06 +0000228 (*bssStartAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_filesz;
229 (*bssEndAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
230 (*underScoreEndAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
231 (*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000232}
233
Shankar Easwaran8c55c012013-02-22 18:01:08 +0000234template <class ELFT>
235error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000236 buildChunks(file);
Shankar Easwaran873c9ff2013-02-22 17:18:53 +0000237
Shankar Easwaran8c55c012013-02-22 18:01:08 +0000238 // Call the preFlight callbacks to modify the sections and the atoms
239 // contained in them, in anyway the targets may want
240 _layout->doPreFlight();
241
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000242 // Create the default sections like the symbol table, string table, and the
243 // section string table
244 createDefaultSections();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000245
Michael J. Spencer942dbcc2013-02-23 01:02:31 +0000246 if (_targetInfo.isDynamic())
247 buildDynamicSymbolTable(file);
248
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000249 // Set the Layout
250 _layout->assignSectionsToSegments();
251 _layout->assignFileOffsets();
252 _layout->assignVirtualAddress();
253
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000254 // Finalize the default value of symbols that the linker adds
255 finalizeDefaultAtomValues();
256
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000257 // Build the Atom To Address map for applying relocations
258 buildAtomToAddressMap();
259
260 // Create symbol table and section string table
Michael J. Spencer942dbcc2013-02-23 01:02:31 +0000261 buildStaticSymbolTable(file);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000262
263 // Finalize the layout by calling the finalize() functions
264 _layout->finalize();
265
266 // build Section Header table
267 buildSectionHeaderTable();
268
269 // assign Offsets and virtual addresses
270 // for sections with no segments
271 assignSectionsWithNoSegments();
272
273 uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000274
275 OwningPtr<FileOutputBuffer> buffer;
276 error_code ec = FileOutputBuffer::create(path,
277 totalSize, buffer,
278 FileOutputBuffer::F_executable);
279 if (ec)
280 return ec;
281
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000282 _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
283 ELF::ELFCLASS32);
284 _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
285 ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000286 _Header->e_type(_targetInfo.getOutputType());
287 _Header->e_machine(_targetInfo.getOutputMachine());
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000288
289 if (!_targetHandler.doesOverrideHeader()) {
290 _Header->e_ident(ELF::EI_VERSION, 1);
291 _Header->e_ident(ELF::EI_OSABI, 0);
292 _Header->e_version(1);
293 } else {
294 // override the contents of the ELF Header
Michael J. Spencercadb0822013-02-19 21:04:30 +0000295 _targetHandler.setHeaderInfo(_Header.get());
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000296 }
Michael J. Spencere68f9032013-01-29 22:03:39 +0000297 _Header->e_phoff(_programHeader->fileOffset());
298 _Header->e_shoff(_shdrtab->fileOffset());
299 _Header->e_phentsize(_programHeader->entsize());
300 _Header->e_phnum(_programHeader->numHeaders());
301 _Header->e_shentsize(_shdrtab->entsize());
302 _Header->e_shnum(_shdrtab->numHeaders());
303 _Header->e_shstrndx(_shstrtab->ordinal());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000304 uint64_t virtualAddr = 0;
Michael J. Spencer990ec2b2013-01-28 04:15:44 +0000305 _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
Michael J. Spencere68f9032013-01-29 22:03:39 +0000306 _Header->e_entry(virtualAddr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000307
308 // HACK: We have to write out the header and program header here even though
309 // they are a member of a segment because only sections are written in the
310 // following loop.
Michael J. Spencere68f9032013-01-29 22:03:39 +0000311 _Header->write(this, *buffer);
Michael J. Spenceradfb7eb2013-01-29 01:00:21 +0000312 _programHeader->write(this, *buffer);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000313
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000314 for (auto section : _layout->sections())
Michael J. Spenceradfb7eb2013-01-29 01:00:21 +0000315 section->write(this, *buffer);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000316
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000317 return buffer->commit();
318}
Nick Kledzikabb69812012-05-31 22:34:00 +0000319
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000320template<class ELFT>
Michael J. Spencere68f9032013-01-29 22:03:39 +0000321void ExecutableWriter<ELFT>::createDefaultSections() {
Michael J. Spencercadb0822013-02-19 21:04:30 +0000322 _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
323 _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
324 _layout->setHeader(_Header.get());
325 _layout->setProgramHeader(_programHeader.get());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000326
Michael J. Spencercadb0822013-02-19 21:04:30 +0000327 _symtab.reset(new (_alloc) SymbolTable<ELFT>(
328 _targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
329 _strtab.reset(new (_alloc) StringTable<ELFT>(
330 _targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
331 _shstrtab.reset(new (_alloc) StringTable<ELFT>(
332 _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
333 _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
334 _targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
335 _layout->addSection(_symtab.get());
336 _layout->addSection(_strtab.get());
337 _layout->addSection(_shstrtab.get());
338 _shdrtab->setStringSection(_shstrtab.get());
339 _symtab->setStringSection(_strtab.get());
340 _layout->addSection(_shdrtab.get());
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000341
Michael J. Spencerb71ce652013-02-20 19:46:12 +0000342 if (_targetInfo.isDynamic()) {
343 _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>(
344 _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC));
Michael J. Spencer942dbcc2013-02-23 01:02:31 +0000345 _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>(
346 _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS,
347 true));
348 _dynamicSymbolTable.reset(new (_alloc) DynamicSymbolTable<ELFT>(
349 _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
Michael J. Spencere4c0e372013-02-20 20:13:47 +0000350 _interpSection.reset(new (_alloc) InterpSection<ELFT>(
351 _targetInfo, ".interp", DefaultLayout<ELFT>::ORDER_INTERP,
352 _targetInfo.getInterpreter()));
Michael J. Spencer34072112013-02-23 19:46:18 +0000353 _hashTable.reset(new (_alloc) HashSection<ELFT>(
354 _targetInfo, ".hash", DefaultLayout<ELFT>::ORDER_HASH));
Michael J. Spencerb71ce652013-02-20 19:46:12 +0000355 _layout->addSection(_dynamicTable.get());
Michael J. Spencer942dbcc2013-02-23 01:02:31 +0000356 _layout->addSection(_dynamicStringTable.get());
357 _layout->addSection(_dynamicSymbolTable.get());
Michael J. Spencere4c0e372013-02-20 20:13:47 +0000358 _layout->addSection(_interpSection.get());
Michael J. Spencer34072112013-02-23 19:46:18 +0000359 _layout->addSection(_hashTable.get());
Michael J. Spencer942dbcc2013-02-23 01:02:31 +0000360 _dynamicSymbolTable->setStringSection(_dynamicStringTable.get());
Michael J. Spencerb71ce652013-02-20 19:46:12 +0000361 }
362
Shankar Easwarana6f00fe2013-01-30 07:11:43 +0000363 // give a chance for the target to add sections
364 _targetHandler.createDefaultSections();
Sid Manningdd110202012-09-25 18:22:09 +0000365}
Nick Kledzikabb69812012-05-31 22:34:00 +0000366} // namespace elf
367
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000368std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000369 using llvm::object::ELFType;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000370 // Set the default layout to be the static executable layout
Michael J. Spencera2c97272013-01-04 21:09:21 +0000371 // We would set the layout to a dynamic executable layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000372 // if we came across any shared libraries in the process
Michael J. Spencera2c97272013-01-04 21:09:21 +0000373
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000374 if (!TI.is64Bits() && TI.isLittleEndian())
375 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000376 elf::ExecutableWriter<ELFType<support::little, 4, false>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000377 else if (TI.is64Bits() && TI.isLittleEndian())
378 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000379 elf::ExecutableWriter<ELFType<support::little, 8, true>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000380 else if (!TI.is64Bits() && !TI.isLittleEndian())
381 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000382 elf::ExecutableWriter<ELFType<support::big, 4, false>>(TI));
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000383 else if (TI.is64Bits() && !TI.isLittleEndian())
384 return std::unique_ptr<Writer>(new
Michael J. Spencere68f9032013-01-29 22:03:39 +0000385 elf::ExecutableWriter<ELFType<support::big, 8, true>>(TI));
Nick Kledzikabb69812012-05-31 22:34:00 +0000386
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000387 llvm_unreachable("Invalid Options!");
Nick Kledzikabb69812012-05-31 22:34:00 +0000388}
Nick Kledzikabb69812012-05-31 22:34:00 +0000389} // namespace lld