blob: 73bb6bb61034600a96c01670571289f228088407 [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. Spencer64afcb42013-01-23 01:18:43 +000010#include "lld/ReaderWriter/ELFTargetInfo.h"
11
Shankar Easwaran6d9921f2013-01-21 20:09:55 +000012#include "DefaultELFLayout.h"
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000013#include "ExecutableAtoms.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000014
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000015using namespace llvm;
16using namespace llvm::object;
Nick Kledzikabb69812012-05-31 22:34:00 +000017namespace lld {
18namespace elf {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000019template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +000020class ELFExecutableWriter;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000021
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000022//===----------------------------------------------------------------------===//
Shankar Easwaran495d38b2012-12-27 02:26:30 +000023// ELFExecutableWriter Class
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000024//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000025template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +000026class ELFExecutableWriter : public ELFWriter {
27public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000028 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
29 typedef Elf_Sym_Impl<ELFT> Elf_Sym;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000030
Michael J. Spencer64afcb42013-01-23 01:18:43 +000031 ELFExecutableWriter(const ELFTargetInfo &ti);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000032
33private:
Michael J. Spencera2c97272013-01-04 21:09:21 +000034 // build the sections that need to be created
Shankar Easwaran495d38b2012-12-27 02:26:30 +000035 void buildChunks(const lld::File &file);
36 virtual error_code writeFile(const lld::File &File, StringRef path);
37 void buildAtomToAddressMap();
38 void buildSymbolTable ();
39 void buildSectionHeaderTable();
40 void assignSectionsWithNoSegments();
41 void addAbsoluteUndefinedSymbols(const lld::File &File);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000042 void addDefaultAtoms();
43 void addFiles(InputFiles&);
44 void finalizeDefaultAtomValues();
Shankar Easwaran495d38b2012-12-27 02:26:30 +000045
Michael J. Spencera2c97272013-01-04 21:09:21 +000046 uint64_t addressOfAtom(const Atom *atom) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +000047 return _atomToAddressMap[atom];
48 }
49
50 KindHandler *kindHandler() { return _referenceKindHandler.get(); }
51
52 void createDefaultSections();
53
Michael J. Spencer64afcb42013-01-23 01:18:43 +000054 const ELFTargetInfo &_targetInfo;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000055
56 typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
57 std::unique_ptr<KindHandler> _referenceKindHandler;
58 AtomToAddress _atomToAddressMap;
59 llvm::BumpPtrAllocator _chunkAllocate;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000060 DefaultELFLayout<ELFT> *_layout;
61 ELFHeader<ELFT> *_elfHeader;
62 ELFProgramHeader<ELFT> *_programHeader;
63 ELFSymbolTable<ELFT> * _symtab;
64 ELFStringTable<ELFT> *_strtab;
65 ELFStringTable<ELFT> *_shstrtab;
66 ELFSectionHeader<ELFT> *_shdrtab;
67 CRuntimeFile<ELFT> _runtimeFile;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000068};
69
70//===----------------------------------------------------------------------===//
71// ELFExecutableWriter
72//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000073template<class ELFT>
Michael J. Spencer64afcb42013-01-23 01:18:43 +000074ELFExecutableWriter<ELFT>::ELFExecutableWriter(const ELFTargetInfo &ti)
75 : _targetInfo(ti)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000076 , _referenceKindHandler(KindHandler::makeHandler(
Michael J. Spencer64afcb42013-01-23 01:18:43 +000077 ti.getTriple().getArch(), ti.isLittleEndian()))
78 , _runtimeFile(ti) {
79 _layout = new DefaultELFLayout<ELFT>(ti);
Shankar Easwaran495d38b2012-12-27 02:26:30 +000080}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000081
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000082template<class ELFT>
83void ELFExecutableWriter<ELFT>::buildChunks(const lld::File &file){
Shankar Easwaran495d38b2012-12-27 02:26:30 +000084 for (const DefinedAtom *definedAtom : file.defined() ) {
85 _layout->addAtom(definedAtom);
86 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000087 /// Add all the absolute atoms to the layout
88 for (const AbsoluteAtom *absoluteAtom : file.absolute()) {
89 _layout->addAtom(absoluteAtom);
90 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +000091}
92
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000093template<class ELFT>
94void ELFExecutableWriter<ELFT>::buildSymbolTable () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +000095 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000096 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +000097 for (const auto &atom : section->atoms())
98 _symtab->addSymbol(atom._atom, section->ordinal(), atom._virtualAddr);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000099}
100
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000101template<class ELFT>
102void
103ELFExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const lld::File &file) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000104 // add all the absolute symbols that the layout contains to the output symbol
105 // table
106 for (auto &atom : _layout->absoluteAtoms())
107 _symtab->addSymbol(atom.absoluteAtom(), ELF::SHN_ABS, atom.value());
108 for (const UndefinedAtom *a : file.undefined())
109 _symtab->addSymbol(a, ELF::SHN_UNDEF);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000110}
111
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000112template<class ELFT>
113void ELFExecutableWriter<ELFT>::buildAtomToAddressMap () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000114 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000115 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000116 for (const auto &atom : section->atoms())
117 _atomToAddressMap[atom._atom] = atom._virtualAddr;
118 // build the atomToAddressMap that contains absolute symbols too
119 for (auto &atom : _layout->absoluteAtoms())
120 _atomToAddressMap[atom.absoluteAtom()] = atom.value();
Sid Manningdd110202012-09-25 18:22:09 +0000121}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000122
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000123template<class ELFT>
124void ELFExecutableWriter<ELFT>::buildSectionHeaderTable() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000125 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000126 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000127 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000128 if (mergedSec->hasSegment())
129 _shdrtab->appendSection(mergedSec);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000130 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000131}
132
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000133template<class ELFT>
134void ELFExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000135 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000136 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000137 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000138 if (!mergedSec->hasSegment())
139 _shdrtab->appendSection(mergedSec);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000140 }
141 _layout->assignOffsetsForMiscSections();
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000142 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000143 if (auto section = dyn_cast<Section<ELFT>>(sec))
144 if (!DefaultELFLayout<ELFT>::hasOutputSegment(section))
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000145 _shdrtab->updateSection(section);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000146}
147
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000148/// \brief Add absolute symbols by default. These are linker added
149/// absolute symbols
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000150template<class ELFT>
151void ELFExecutableWriter<ELFT>::addDefaultAtoms() {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000152 _runtimeFile.addUndefinedAtom("_start");
153 _runtimeFile.addAbsoluteAtom("__bss_start");
154 _runtimeFile.addAbsoluteAtom("__bss_end");
155 _runtimeFile.addAbsoluteAtom("_end");
156 _runtimeFile.addAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000157 _runtimeFile.addAbsoluteAtom("__init_array_start");
158 _runtimeFile.addAbsoluteAtom("__init_array_end");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000159}
160
161/// \brief Hook in lld to add CRuntime file
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000162template<class ELFT>
163void ELFExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000164 addDefaultAtoms();
165 inputFiles.prependFile(_runtimeFile);
166}
167
168/// Finalize the value of all the absolute symbols that we
169/// created
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000170template<class ELFT>
171void ELFExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000172 auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
173 auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
174 auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
175 auto endAtomIter = _layout->findAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +0000176 auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
177 auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
178
179 auto section = _layout->findOutputSection(".init_array");
180 if (section) {
181 initArrayStartIter->setValue(section->virtualAddr());
182 initArrayEndIter->setValue(section->virtualAddr() +
183 section->memSize());
184 } else {
185 initArrayStartIter->setValue(0);
186 initArrayEndIter->setValue(0);
187 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000188
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000189 assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
190 bssEndAtomIter == _layout->absoluteAtoms().end() ||
191 underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
192 endAtomIter == _layout->absoluteAtoms().end()) &&
Shankar Easwaran37c52822013-01-10 18:16:10 +0000193 "Unable to find the absolute atoms that have been added by lld");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000194
195 auto phe = _programHeader->findProgramHeader(
196 llvm::ELF::PT_LOAD,
197 llvm::ELF::PF_W,
198 llvm::ELF::PF_X);
199
Shankar Easwaran37c52822013-01-10 18:16:10 +0000200 assert(!(phe == _programHeader->end()) &&
201 "Can't find a data segment in the program header!");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000202
203 bssStartAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_filesz);
204 bssEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
205 underScoreEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
206 endAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
207}
208
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000209template<class ELFT>
210error_code
211ELFExecutableWriter<ELFT>::writeFile(const lld::File &file, StringRef path) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000212 buildChunks(file);
213 // Create the default sections like the symbol table, string table, and the
214 // section string table
215 createDefaultSections();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000216
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000217 // Set the Layout
218 _layout->assignSectionsToSegments();
219 _layout->assignFileOffsets();
220 _layout->assignVirtualAddress();
221
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000222 // Finalize the default value of symbols that the linker adds
223 finalizeDefaultAtomValues();
224
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000225 // Build the Atom To Address map for applying relocations
226 buildAtomToAddressMap();
227
228 // Create symbol table and section string table
229 buildSymbolTable();
230
231 // add other symbols
232 addAbsoluteUndefinedSymbols(file);
233
234 // Finalize the layout by calling the finalize() functions
235 _layout->finalize();
236
237 // build Section Header table
238 buildSectionHeaderTable();
239
240 // assign Offsets and virtual addresses
241 // for sections with no segments
242 assignSectionsWithNoSegments();
243
244 uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000245
246 OwningPtr<FileOutputBuffer> buffer;
247 error_code ec = FileOutputBuffer::create(path,
248 totalSize, buffer,
249 FileOutputBuffer::F_executable);
250 if (ec)
251 return ec;
252
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000253 _elfHeader->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
254 : ELF::ELFCLASS32);
255 _elfHeader->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
256 ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000257 _elfHeader->e_ident(ELF::EI_VERSION, 1);
258 _elfHeader->e_ident(ELF::EI_OSABI, 0);
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000259 _elfHeader->e_type(_targetInfo.getOutputType());
260 _elfHeader->e_machine(_targetInfo.getOutputMachine());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000261 _elfHeader->e_version(1);
262 _elfHeader->e_entry(0ULL);
263 _elfHeader->e_phoff(_programHeader->fileOffset());
264 _elfHeader->e_shoff(_shdrtab->fileOffset());
265 _elfHeader->e_phentsize(_programHeader->entsize());
266 _elfHeader->e_phnum(_programHeader->numHeaders());
267 _elfHeader->e_shentsize(_shdrtab->entsize());
268 _elfHeader->e_shnum(_shdrtab->numHeaders());
269 _elfHeader->e_shstrndx(_shstrtab->ordinal());
270 uint64_t virtualAddr = 0;
271 _layout->findAtomAddrByName("_start", virtualAddr);
272 _elfHeader->e_entry(virtualAddr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000273
274 // HACK: We have to write out the header and program header here even though
275 // they are a member of a segment because only sections are written in the
276 // following loop.
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000277 _elfHeader->write(this, buffer);
278 _programHeader->write(this, buffer);
279
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000280 for (auto section : _layout->sections())
281 section->write(this, buffer);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000282
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000283 return buffer->commit();
284}
Nick Kledzikabb69812012-05-31 22:34:00 +0000285
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000286template<class ELFT>
287void ELFExecutableWriter<ELFT>::createDefaultSections() {
288 _elfHeader = new ELFHeader<ELFT>();
289 _programHeader = new ELFProgramHeader<ELFT>();
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000290 _layout->setELFHeader(_elfHeader);
291 _layout->setProgramHeader(_programHeader);
292
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000293 _symtab = new ELFSymbolTable<ELFT>(
294 ".symtab", DefaultELFLayout<ELFT>::ORDER_SYMBOL_TABLE);
295 _strtab = new ELFStringTable<ELFT>(
296 ".strtab", DefaultELFLayout<ELFT>::ORDER_STRING_TABLE);
297 _shstrtab = new ELFStringTable<ELFT>(
298 ".shstrtab", DefaultELFLayout<ELFT>::ORDER_SECTION_STRINGS);
299 _shdrtab = new ELFSectionHeader<ELFT>(
300 DefaultELFLayout<ELFT>::ORDER_SECTION_HEADERS);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000301 _layout->addSection(_symtab);
302 _layout->addSection(_strtab);
303 _layout->addSection(_shstrtab);
304 _shdrtab->setStringSection(_shstrtab);
305 _symtab->setStringSection(_strtab);
306 _layout->addSection(_shdrtab);
Sid Manningdd110202012-09-25 18:22:09 +0000307}
Nick Kledzikabb69812012-05-31 22:34:00 +0000308} // namespace elf
309
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000310std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000311 using llvm::object::ELFType;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000312 // Set the default layout to be the static executable layout
Michael J. Spencera2c97272013-01-04 21:09:21 +0000313 // We would set the layout to a dynamic executable layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000314 // if we came across any shared libraries in the process
Michael J. Spencera2c97272013-01-04 21:09:21 +0000315
Michael J. Spencer64afcb42013-01-23 01:18:43 +0000316 if (!TI.is64Bits() && TI.isLittleEndian())
317 return std::unique_ptr<Writer>(new
318 elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(TI));
319 else if (TI.is64Bits() && TI.isLittleEndian())
320 return std::unique_ptr<Writer>(new
321 elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(TI));
322 else if (!TI.is64Bits() && !TI.isLittleEndian())
323 return std::unique_ptr<Writer>(new
324 elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(TI));
325 else if (TI.is64Bits() && !TI.isLittleEndian())
326 return std::unique_ptr<Writer>(new
327 elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(TI));
Nick Kledzikabb69812012-05-31 22:34:00 +0000328
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000329 llvm_unreachable("Invalid Options!");
Nick Kledzikabb69812012-05-31 22:34:00 +0000330}
Nick Kledzikabb69812012-05-31 22:34:00 +0000331} // namespace lld