blob: d9be025c5cab002e8db91d89af6a68ce1f672724 [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
Shankar Easwaran6d9921f2013-01-21 20:09:55 +000010#include "DefaultELFLayout.h"
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000011#include "ExecutableAtoms.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000012
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000013using namespace llvm;
14using namespace llvm::object;
Nick Kledzikabb69812012-05-31 22:34:00 +000015namespace lld {
16namespace elf {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000017template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +000018class ELFExecutableWriter;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000019
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000020//===----------------------------------------------------------------------===//
Shankar Easwaran495d38b2012-12-27 02:26:30 +000021// ELFExecutableWriter Class
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000022//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000023template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +000024class ELFExecutableWriter : public ELFWriter {
25public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000026 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
27 typedef Elf_Sym_Impl<ELFT> Elf_Sym;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000028
29 ELFExecutableWriter(const WriterOptionsELF &options);
30
31private:
Michael J. Spencera2c97272013-01-04 21:09:21 +000032 // build the sections that need to be created
Shankar Easwaran495d38b2012-12-27 02:26:30 +000033 void buildChunks(const lld::File &file);
34 virtual error_code writeFile(const lld::File &File, StringRef path);
35 void buildAtomToAddressMap();
36 void buildSymbolTable ();
37 void buildSectionHeaderTable();
38 void assignSectionsWithNoSegments();
39 void addAbsoluteUndefinedSymbols(const lld::File &File);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000040 void addDefaultAtoms();
41 void addFiles(InputFiles&);
42 void finalizeDefaultAtomValues();
Shankar Easwaran495d38b2012-12-27 02:26:30 +000043
Michael J. Spencera2c97272013-01-04 21:09:21 +000044 uint64_t addressOfAtom(const Atom *atom) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000045 return _atomToAddressMap[atom];
46 }
47
48 KindHandler *kindHandler() { return _referenceKindHandler.get(); }
49
50 void createDefaultSections();
51
52 const WriterOptionsELF &_options;
53
54 typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
55 std::unique_ptr<KindHandler> _referenceKindHandler;
56 AtomToAddress _atomToAddressMap;
57 llvm::BumpPtrAllocator _chunkAllocate;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000058 DefaultELFLayout<ELFT> *_layout;
59 ELFHeader<ELFT> *_elfHeader;
60 ELFProgramHeader<ELFT> *_programHeader;
61 ELFSymbolTable<ELFT> * _symtab;
62 ELFStringTable<ELFT> *_strtab;
63 ELFStringTable<ELFT> *_shstrtab;
64 ELFSectionHeader<ELFT> *_shdrtab;
65 CRuntimeFile<ELFT> _runtimeFile;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000066};
67
68//===----------------------------------------------------------------------===//
69// ELFExecutableWriter
70//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000071template<class ELFT>
72ELFExecutableWriter<ELFT>::ELFExecutableWriter(const WriterOptionsELF &options)
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000073 : _options(options)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000074 , _referenceKindHandler(KindHandler::makeHandler(
75 _options.machine(), (endianness)ELFT::TargetEndianness))
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000076 , _runtimeFile(options) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000077 _layout =new DefaultELFLayout<ELFT>(options);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000078}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000079
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000080template<class ELFT>
81void ELFExecutableWriter<ELFT>::buildChunks(const lld::File &file){
Shankar Easwaran495d38b2012-12-27 02:26:30 +000082 for (const DefinedAtom *definedAtom : file.defined() ) {
83 _layout->addAtom(definedAtom);
84 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000085 /// Add all the absolute atoms to the layout
86 for (const AbsoluteAtom *absoluteAtom : file.absolute()) {
87 _layout->addAtom(absoluteAtom);
88 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +000089}
90
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000091template<class ELFT>
92void ELFExecutableWriter<ELFT>::buildSymbolTable () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +000093 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000094 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +000095 for (const auto &atom : section->atoms())
96 _symtab->addSymbol(atom._atom, section->ordinal(), atom._virtualAddr);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000097}
98
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000099template<class ELFT>
100void
101ELFExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const lld::File &file) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000102 // add all the absolute symbols that the layout contains to the output symbol
103 // table
104 for (auto &atom : _layout->absoluteAtoms())
105 _symtab->addSymbol(atom.absoluteAtom(), ELF::SHN_ABS, atom.value());
106 for (const UndefinedAtom *a : file.undefined())
107 _symtab->addSymbol(a, ELF::SHN_UNDEF);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000108}
109
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000110template<class ELFT>
111void ELFExecutableWriter<ELFT>::buildAtomToAddressMap () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000112 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000113 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000114 for (const auto &atom : section->atoms())
115 _atomToAddressMap[atom._atom] = atom._virtualAddr;
116 // build the atomToAddressMap that contains absolute symbols too
117 for (auto &atom : _layout->absoluteAtoms())
118 _atomToAddressMap[atom.absoluteAtom()] = atom.value();
Sid Manningdd110202012-09-25 18:22:09 +0000119}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000120
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000121template<class ELFT>
122void ELFExecutableWriter<ELFT>::buildSectionHeaderTable() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000123 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000124 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000125 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000126 if (mergedSec->hasSegment())
127 _shdrtab->appendSection(mergedSec);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000128 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000129}
130
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000131template<class ELFT>
132void ELFExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000133 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000134 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000135 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000136 if (!mergedSec->hasSegment())
137 _shdrtab->appendSection(mergedSec);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000138 }
139 _layout->assignOffsetsForMiscSections();
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000140 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000141 if (auto section = dyn_cast<Section<ELFT>>(sec))
142 if (!DefaultELFLayout<ELFT>::hasOutputSegment(section))
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000143 _shdrtab->updateSection(section);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000144}
145
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000146/// \brief Add absolute symbols by default. These are linker added
147/// absolute symbols
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000148template<class ELFT>
149void ELFExecutableWriter<ELFT>::addDefaultAtoms() {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000150 _runtimeFile.addUndefinedAtom("_start");
151 _runtimeFile.addAbsoluteAtom("__bss_start");
152 _runtimeFile.addAbsoluteAtom("__bss_end");
153 _runtimeFile.addAbsoluteAtom("_end");
154 _runtimeFile.addAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000155 _runtimeFile.addAbsoluteAtom("__init_array_start");
156 _runtimeFile.addAbsoluteAtom("__init_array_end");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000157}
158
159/// \brief Hook in lld to add CRuntime file
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000160template<class ELFT>
161void ELFExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000162 addDefaultAtoms();
163 inputFiles.prependFile(_runtimeFile);
164}
165
166/// Finalize the value of all the absolute symbols that we
167/// created
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000168template<class ELFT>
169void ELFExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000170 auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
171 auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
172 auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
173 auto endAtomIter = _layout->findAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000174 auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
175 auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
176
177 auto section = _layout->findOutputSection(".init_array");
178 if (section) {
179 initArrayStartIter->setValue(section->virtualAddr());
180 initArrayEndIter->setValue(section->virtualAddr() +
181 section->memSize());
182 } else {
183 initArrayStartIter->setValue(0);
184 initArrayEndIter->setValue(0);
185 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000186
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000187 assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
188 bssEndAtomIter == _layout->absoluteAtoms().end() ||
189 underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
190 endAtomIter == _layout->absoluteAtoms().end()) &&
Shankar Easwaran37c52822013-01-10 18:16:10 +0000191 "Unable to find the absolute atoms that have been added by lld");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000192
193 auto phe = _programHeader->findProgramHeader(
194 llvm::ELF::PT_LOAD,
195 llvm::ELF::PF_W,
196 llvm::ELF::PF_X);
197
Shankar Easwaran37c52822013-01-10 18:16:10 +0000198 assert(!(phe == _programHeader->end()) &&
199 "Can't find a data segment in the program header!");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000200
201 bssStartAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_filesz);
202 bssEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
203 underScoreEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
204 endAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
205}
206
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000207template<class ELFT>
208error_code
209ELFExecutableWriter<ELFT>::writeFile(const lld::File &file, StringRef path) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000210 buildChunks(file);
211 // Create the default sections like the symbol table, string table, and the
212 // section string table
213 createDefaultSections();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000214
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000215 // Set the Layout
216 _layout->assignSectionsToSegments();
217 _layout->assignFileOffsets();
218 _layout->assignVirtualAddress();
219
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000220 // Finalize the default value of symbols that the linker adds
221 finalizeDefaultAtomValues();
222
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000223 // Build the Atom To Address map for applying relocations
224 buildAtomToAddressMap();
225
226 // Create symbol table and section string table
227 buildSymbolTable();
228
229 // add other symbols
230 addAbsoluteUndefinedSymbols(file);
231
232 // Finalize the layout by calling the finalize() functions
233 _layout->finalize();
234
235 // build Section Header table
236 buildSectionHeaderTable();
237
238 // assign Offsets and virtual addresses
239 // for sections with no segments
240 assignSectionsWithNoSegments();
241
242 uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000243
244 OwningPtr<FileOutputBuffer> buffer;
245 error_code ec = FileOutputBuffer::create(path,
246 totalSize, buffer,
247 FileOutputBuffer::F_executable);
248 if (ec)
249 return ec;
250
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000251 _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64
252 : ELF::ELFCLASS32));
Michael J. Spencera2c97272013-01-04 21:09:21 +0000253 _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000254 ? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB);
255 _elfHeader->e_ident(ELF::EI_VERSION, 1);
256 _elfHeader->e_ident(ELF::EI_OSABI, 0);
257 _elfHeader->e_type(_options.type());
258 _elfHeader->e_machine(_options.machine());
259 _elfHeader->e_version(1);
260 _elfHeader->e_entry(0ULL);
261 _elfHeader->e_phoff(_programHeader->fileOffset());
262 _elfHeader->e_shoff(_shdrtab->fileOffset());
263 _elfHeader->e_phentsize(_programHeader->entsize());
264 _elfHeader->e_phnum(_programHeader->numHeaders());
265 _elfHeader->e_shentsize(_shdrtab->entsize());
266 _elfHeader->e_shnum(_shdrtab->numHeaders());
267 _elfHeader->e_shstrndx(_shstrtab->ordinal());
268 uint64_t virtualAddr = 0;
269 _layout->findAtomAddrByName("_start", virtualAddr);
270 _elfHeader->e_entry(virtualAddr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000271
272 // HACK: We have to write out the header and program header here even though
273 // they are a member of a segment because only sections are written in the
274 // following loop.
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000275 _elfHeader->write(this, buffer);
276 _programHeader->write(this, buffer);
277
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000278 for (auto section : _layout->sections())
279 section->write(this, buffer);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000280
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000281 return buffer->commit();
282}
Nick Kledzikabb69812012-05-31 22:34:00 +0000283
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000284template<class ELFT>
285void ELFExecutableWriter<ELFT>::createDefaultSections() {
286 _elfHeader = new ELFHeader<ELFT>();
287 _programHeader = new ELFProgramHeader<ELFT>();
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000288 _layout->setELFHeader(_elfHeader);
289 _layout->setProgramHeader(_programHeader);
290
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000291 _symtab = new ELFSymbolTable<ELFT>(
292 ".symtab", DefaultELFLayout<ELFT>::ORDER_SYMBOL_TABLE);
293 _strtab = new ELFStringTable<ELFT>(
294 ".strtab", DefaultELFLayout<ELFT>::ORDER_STRING_TABLE);
295 _shstrtab = new ELFStringTable<ELFT>(
296 ".shstrtab", DefaultELFLayout<ELFT>::ORDER_SECTION_STRINGS);
297 _shdrtab = new ELFSectionHeader<ELFT>(
298 DefaultELFLayout<ELFT>::ORDER_SECTION_HEADERS);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000299 _layout->addSection(_symtab);
300 _layout->addSection(_strtab);
301 _layout->addSection(_shstrtab);
302 _shdrtab->setStringSection(_shstrtab);
303 _symtab->setStringSection(_strtab);
304 _layout->addSection(_shdrtab);
Sid Manningdd110202012-09-25 18:22:09 +0000305}
Nick Kledzikabb69812012-05-31 22:34:00 +0000306} // namespace elf
307
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000308Writer *createWriterELF(const WriterOptionsELF &options) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000309 using llvm::object::ELFType;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000310 // Set the default layout to be the static executable layout
Michael J. Spencera2c97272013-01-04 21:09:21 +0000311 // We would set the layout to a dynamic executable layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000312 // if we came across any shared libraries in the process
Michael J. Spencera2c97272013-01-04 21:09:21 +0000313
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000314 if (!options.is64Bit() && options.endianness() == llvm::support::little)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000315 return
316 new elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(options);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000317 else if (options.is64Bit() && options.endianness() == llvm::support::little)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000318 return
319 new elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(options);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000320 else if (!options.is64Bit() && options.endianness() == llvm::support::big)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000321 return
322 new elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(options);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000323 else if (options.is64Bit() && options.endianness() == llvm::support::big)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000324 return
325 new elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(options);
Nick Kledzikabb69812012-05-31 22:34:00 +0000326
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000327 llvm_unreachable("Invalid Options!");
Nick Kledzikabb69812012-05-31 22:34:00 +0000328}
Nick Kledzikabb69812012-05-31 22:34:00 +0000329} // namespace lld