blob: 78f669030e35379ee5dde3eed6566e2fab83d2b2 [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
10#include "lld/ReaderWriter/WriterELF.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000011#include "ReferenceKinds.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000012
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000013#include "lld/Core/DefinedAtom.h"
14#include "lld/Core/File.h"
15#include "lld/Core/InputFiles.h"
Michael J. Spencerbb78a042013-01-15 06:55:37 +000016#include "lld/Core/range.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000017#include "lld/Core/Reference.h"
18#include "lld/Core/SharedLibraryAtom.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000019#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/DenseMap.h"
Shankar Easwaran495d38b2012-12-27 02:26:30 +000021#include "llvm/ADT/Hashing.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000022#include "llvm/ADT/OwningPtr.h"
23#include "llvm/ADT/SmallVector.h"
Shankar Easwaran495d38b2012-12-27 02:26:30 +000024#include "llvm/ADT/StringExtras.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000025#include "llvm/ADT/StringMap.h"
26#include "llvm/ADT/StringRef.h"
Shankar Easwaran495d38b2012-12-27 02:26:30 +000027#include "llvm/ADT/StringSwitch.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000028#include "llvm/Object/ELF.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000029#include "llvm/Support/Allocator.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000030#include "llvm/Support/Debug.h"
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000031#include "llvm/Support/ELF.h"
32#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/FileOutputBuffer.h"
34#include "llvm/Support/Format.h"
35#include "llvm/Support/MathExtras.h"
36#include "llvm/Support/raw_ostream.h"
37#include "llvm/Support/system_error.h"
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +000038#include "ExecutableAtoms.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000039
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000040#include <map>
Shankar Easwaran495d38b2012-12-27 02:26:30 +000041#include <unordered_map>
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000042#include <tuple>
43#include <vector>
Nick Kledzikabb69812012-05-31 22:34:00 +000044
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000045using namespace llvm;
46using namespace llvm::object;
Nick Kledzikabb69812012-05-31 22:34:00 +000047namespace lld {
48namespace elf {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000049template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +000050class ELFExecutableWriter;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000051
Shankar Easwaran495d38b2012-12-27 02:26:30 +000052/// \brief The ELFWriter class is a base class for the linker to write
53/// various kinds of ELF files.
54class ELFWriter : public Writer {
Michael J. Spencera2c97272013-01-04 21:09:21 +000055public:
56 ELFWriter() { }
Shankar Easwaran495d38b2012-12-27 02:26:30 +000057
Michael J. Spencera2c97272013-01-04 21:09:21 +000058public:
59 /// \brief builds the chunks that needs to be written to the output
60 /// ELF file
61 virtual void buildChunks(const lld::File &file) = 0;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000062
Michael J. Spencera2c97272013-01-04 21:09:21 +000063 /// \brief Writes the chunks into the output file specified by path
64 virtual error_code writeFile(const lld::File &File, StringRef path) = 0;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000065
Michael J. Spencer37568522013-01-11 22:39:56 +000066 /// \brief Get the virtual address of \p atom after layout.
Michael J. Spencera2c97272013-01-04 21:09:21 +000067 virtual uint64_t addressOfAtom(const Atom *atom) = 0;
Shankar Easwaran495d38b2012-12-27 02:26:30 +000068
Michael J. Spencera2c97272013-01-04 21:09:21 +000069 /// \brief Return the processing function to apply Relocations
70 virtual KindHandler *kindHandler() = 0;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000071};
72
Shankar Easwaran495d38b2012-12-27 02:26:30 +000073/// \brief A chunk is a contiguous region of space
Michael J. Spencerb03f6c42013-01-15 07:53:22 +000074template<class ELFT>
Hemant Kulkarni927bbc22012-09-14 16:11:34 +000075class Chunk {
76public:
Shankar Easwaran495d38b2012-12-27 02:26:30 +000077
78 /// \brief Describes the type of Chunk
79 enum Kind {
80 K_ELFHeader, // ELF Header
81 K_ELFProgramHeader, // Program Header
82 K_ELFSegment, // Segment
83 K_ELFSection, // Section
84 K_ELFSectionHeader // Section header
Hemant Kulkarni87dbac02012-11-13 21:34:45 +000085 };
Michael J. Spencera2c97272013-01-04 21:09:21 +000086 Chunk(StringRef name, Kind kind)
Shankar Easwaran495d38b2012-12-27 02:26:30 +000087 : _name(name)
88 , _kind(kind)
89 , _fsize(0)
90 , _msize(0)
91 , _align2(0)
92 , _order(0)
93 , _ordinal(1)
94 , _start(0)
95 , _fileoffset(0) {}
96 virtual ~Chunk() {}
Michael J. Spencera2c97272013-01-04 21:09:21 +000097 // Does the chunk occupy disk space
Shankar Easwaran495d38b2012-12-27 02:26:30 +000098 virtual bool occupiesNoDiskSpace() const {
Michael J. Spencera2c97272013-01-04 21:09:21 +000099 return false;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000100 }
101 // The name of the chunk
102 StringRef name() const { return _name; }
103 // Kind of chunk
104 Kind kind() const { return _kind; }
105 uint64_t fileSize() const { return _fsize; }
106 uint64_t align2() const { return _align2; }
107 void appendAtom() const;
108
109 // The ordinal value of the chunk
110 uint64_t ordinal() const { return _ordinal;}
111 void setOrdinal(uint64_t newVal) { _ordinal = newVal;}
112 // The order in which the chunk would appear in the output file
113 uint64_t order() const { return _order; }
114 void setOrder(uint32_t order) { _order = order; }
115 // Output file offset of the chunk
116 uint64_t fileOffset() const { return _fileoffset; }
117 void setFileOffset(uint64_t offset) { _fileoffset = offset; }
118 // Output start address of the chunk
119 void setVAddr(uint64_t start) { _start = start; }
120 uint64_t virtualAddr() const { return _start; }
121 // Does the chunk occupy memory during execution ?
122 uint64_t memSize() const { return _msize; }
123 void setMemSize(uint64_t msize) { _msize = msize; }
Michael J. Spencera2c97272013-01-04 21:09:21 +0000124 // Writer the chunk
125 virtual void write(ELFWriter *writer,
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000126 OwningPtr<FileOutputBuffer> &buffer) = 0;
127 // Finalize the chunk before writing
128 virtual void finalize() = 0;
129
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000130protected:
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000131 StringRef _name;
132 Kind _kind;
133 uint64_t _fsize;
134 uint64_t _msize;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000135 uint64_t _align2;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000136 uint32_t _order;
Hemant Kulkarni08e410292012-10-01 23:53:20 +0000137 uint64_t _ordinal;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000138 uint64_t _start;
139 uint64_t _fileoffset;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000140};
141
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000142/// \brief The ELFLayoutOptions encapsulates the options used by all Layouts
143/// Examples of the ELFLayoutOptions would be a script that would be used
Michael J. Spencera2c97272013-01-04 21:09:21 +0000144/// to drive the layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000145class ELFLayoutOptions {
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000146public:
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000147 ELFLayoutOptions() { }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000148
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000149 ELFLayoutOptions(StringRef &linker_script) : _script(linker_script)
150 {}
Hemant Kulkarni87dbac02012-11-13 21:34:45 +0000151
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000152 /// parse the linker script
153 error_code parseLinkerScript();
Hemant Kulkarni736f7fb2012-11-21 21:07:36 +0000154
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000155 /// Is the current section present in the linker script
156 bool isSectionPresent();
157
Hemant Kulkarni08e410292012-10-01 23:53:20 +0000158private:
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000159 StringRef _script;
Hemant Kulkarni08e410292012-10-01 23:53:20 +0000160};
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000161
Michael J. Spencera2c97272013-01-04 21:09:21 +0000162/// \brief The ELFLayout is an abstract class for managing the final layout for
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000163/// the kind of binaries(Shared Libraries / Relocatables / Executables 0
Michael J. Spencera2c97272013-01-04 21:09:21 +0000164/// Each architecture (Hexagon, PowerPC, MIPS) would have a concrete
165/// subclass derived from ELFLayout for generating each binary thats
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000166// needed by the lld linker
167class ELFLayout {
168public:
169 typedef uint32_t SectionOrder;
170 typedef uint32_t SegmentType;
171 typedef uint32_t Flags;
172
173public:
174 /// Return the order the section would appear in the output file
175 virtual SectionOrder getSectionOrder
176 (const StringRef name,
177 int32_t contentType,
178 int32_t contentPerm) = 0;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000179 /// append the Atom to the layout and create appropriate sections
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000180 virtual error_code addAtom(const Atom *atom) = 0;
181 /// find the Atom Address in the current layout
182 virtual bool findAtomAddrByName(const StringRef name, uint64_t &addr) = 0;
183 /// associates a section to a segment
184 virtual void assignSectionsToSegments() = 0;
185 /// associates a virtual address to the segment, section, and the atom
186 virtual void assignVirtualAddress() = 0;
187 /// associates a file offset to the segment, section and the atom
188 virtual void assignFileOffsets() = 0;
189
190public:
191 ELFLayout() {}
Michael J. Spencera2c97272013-01-04 21:09:21 +0000192 ELFLayout(WriterOptionsELF &writerOptions,
193 ELFLayoutOptions &layoutOptions)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000194 : _writerOptions(writerOptions)
195 , _layoutOptions(layoutOptions) {}
196 virtual ~ELFLayout() { }
197
198private:
199 WriterOptionsELF _writerOptions;
200 ELFLayoutOptions _layoutOptions;
201};
202
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000203struct AtomLayout {
204 AtomLayout(const Atom *a, uint64_t fileOff, uint64_t virAddr)
205 : _atom(a), _fileOffset(fileOff), _virtualAddr(virAddr) {}
206
207 AtomLayout()
208 : _atom(nullptr), _fileOffset(0), _virtualAddr(0) {}
209
210 const Atom *_atom;
211 uint64_t _fileOffset;
212 uint64_t _virtualAddr;
213};
214
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000215/// \brief A section contains a set of atoms that have similiar properties
216/// The atoms that have similiar properties are merged to form a section
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000217template<class ELFT>
218class Section : public Chunk<ELFT> {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000219public:
Michael J. Spencera2c97272013-01-04 21:09:21 +0000220 // The Kind of section that the object represents
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000221 enum SectionKind {
222 K_Default,
223 K_SymbolTable,
224 K_StringTable,
225 };
226 // Create a section object, the section is set to the default type if the
227 // caller doesnot set it
Michael J. Spencera2c97272013-01-04 21:09:21 +0000228 Section(const StringRef sectionName,
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000229 const int32_t contentType,
230 const int32_t contentPermissions,
231 const int32_t order,
Michael J. Spencera2c97272013-01-04 21:09:21 +0000232 const SectionKind kind = K_Default)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000233 : Chunk<ELFT>(sectionName, Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000234 , _contentType(contentType)
235 , _contentPermissions(contentPermissions)
236 , _sectionKind(kind)
237 , _entSize(0)
238 , _shInfo(0)
239 , _link(0) {
240 this->setOrder(order);
241 }
242
243 /// return the section kind
244 SectionKind sectionKind() const {
245 return _sectionKind;
246 }
247
248 /// Align the offset to the required modulus defined by the atom alignment
249 uint64_t alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign) {
250 uint64_t requiredModulus = atomAlign.modulus;
251 uint64_t align2 = 1u << atomAlign.powerOf2;
252 uint64_t currentModulus = (offset % align2);
253 uint64_t retOffset = offset;
254 if (currentModulus != requiredModulus) {
255 if (requiredModulus > currentModulus)
256 retOffset += requiredModulus - currentModulus;
257 else
258 retOffset += align2 + requiredModulus - currentModulus;
259 }
260 return retOffset;
261 }
262
Michael J. Spencera2c97272013-01-04 21:09:21 +0000263 // \brief Append an atom to a Section. The atom gets pushed into a vector
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000264 // contains the atom, the atom file offset, the atom virtual address
265 // the atom file offset is aligned appropriately as set by the Reader
266 void appendAtom(const Atom *atom) {
267 Atom::Definition atomType = atom->definition();
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000268 const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
269
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000270 DefinedAtom::Alignment atomAlign = definedAtom->alignment();
271 uint64_t align2 = 1u << atomAlign.powerOf2;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000272 // Align the atom to the required modulus/ align the file offset and the
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000273 // memory offset seperately this is required so that BSS symbols are handled
274 // properly as the BSS symbols only occupy memory size and not file size
275 uint64_t fOffset = alignOffset(this->fileSize(), atomAlign);
276 uint64_t mOffset = alignOffset(this->memSize(), atomAlign);
277 switch (atomType) {
278 case Atom::definitionRegular:
279 switch(definedAtom->contentType()) {
280 case DefinedAtom::typeCode:
281 case DefinedAtom::typeData:
Michael J. Spencer8de83642013-01-07 08:00:42 +0000282 case DefinedAtom::typeConstant:
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000283 _atoms.push_back(AtomLayout(atom, fOffset, 0));
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000284 this->_fsize = fOffset + definedAtom->size();
285 this->_msize = mOffset + definedAtom->size();
286 break;
287 case DefinedAtom::typeZeroFill:
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000288 _atoms.push_back(AtomLayout(atom, mOffset, 0));
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000289 this->_msize = mOffset + definedAtom->size();
290 break;
291 default:
292 this->_fsize = fOffset + definedAtom->size();
293 this->_msize = mOffset + definedAtom->size();
294 break;
295 }
296 break;
297 default:
298 llvm_unreachable("Expecting only definedAtoms being passed here");
299 break;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000300 }
301 // Set the section alignment to the largest alignment
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000302 // std::max doesnot support uint64_t
Michael J. Spencera2c97272013-01-04 21:09:21 +0000303 if (this->_align2 < align2)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000304 this->_align2 = align2;
305 }
306
Michael J. Spencera2c97272013-01-04 21:09:21 +0000307 /// \brief Set the virtual address of each Atom in the Section. This
308 /// routine gets called after the linker fixes up the virtual address
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000309 /// of the section
310 void assignVirtualAddress(uint64_t &addr) {
311 for (auto &ai : _atoms) {
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000312 ai._virtualAddr = addr + ai._fileOffset;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000313 }
314 addr += this->memSize();
315 }
316
Michael J. Spencera2c97272013-01-04 21:09:21 +0000317 /// \brief Set the file offset of each Atom in the section. This routine
318 /// gets called after the linker fixes up the section offset
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000319 void assignOffsets(uint64_t offset) {
320 for (auto &ai : _atoms) {
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000321 ai._fileOffset = offset + ai._fileOffset;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000322 }
323 }
324
Michael J. Spencera2c97272013-01-04 21:09:21 +0000325 /// \brief Find the Atom address given a name, this is needed to to properly
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000326 /// apply relocation. The section class calls this to find the atom address
327 /// to fix the relocation
328 bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
329 for (auto ai : _atoms) {
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000330 if (ai._atom->name() == name) {
331 addr = ai._virtualAddr;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000332 return true;
333 }
334 }
335 return false;
336 }
337
338 /// \brief Does the Atom occupy any disk space
339 bool occupiesNoDiskSpace() const {
340 return _contentType == DefinedAtom::typeZeroFill;
341 }
342
Michael J. Spencera2c97272013-01-04 21:09:21 +0000343 /// \brief The permission of the section is the most permissive permission
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000344 /// of all atoms that the section contains
345 void setContentPermissions(int32_t perm) {
346 _contentPermissions = std::max(perm, _contentPermissions);
347 }
348
349 /// \brief Get the section flags, defined by the permissions of the section
350 int64_t flags() {
351 switch (_contentPermissions) {
352 case DefinedAtom::perm___:
353 return 0;
354
355 case DefinedAtom::permR__:
356 return llvm::ELF::SHF_ALLOC;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000357
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000358 case DefinedAtom::permR_X:
359 return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000360
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000361 case DefinedAtom::permRW_:
362 case DefinedAtom::permRW_L:
363 return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000364
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000365 case DefinedAtom::permRWX:
Michael J. Spencera2c97272013-01-04 21:09:21 +0000366 return llvm::ELF::SHF_ALLOC |
367 llvm::ELF::SHF_WRITE |
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000368 llvm::ELF::SHF_EXECINSTR;
369
370 default:
371 break;
372 }
373 return llvm::ELF::SHF_ALLOC;
374 }
375
376 /// \brief Return the raw flags, we need this to sort segments
377 int64_t atomflags() const {
378 return _contentPermissions;
379 }
380
Michael J. Spencera2c97272013-01-04 21:09:21 +0000381 /// \brief Return the section type, the returned value is recorded in the
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000382 /// sh_type field of the Section Header
383 int type() {
384 switch (_contentType) {
385 case DefinedAtom::typeCode:
386 case DefinedAtom::typeData:
387 case DefinedAtom::typeConstant:
388 return llvm::ELF::SHT_PROGBITS;
389
390 case DefinedAtom::typeZeroFill:
391 return llvm::ELF::SHT_NOBITS;
392
393 // Case to handle section types
394 // Symtab, String Table ...
395 default:
396 return _contentType;
397 }
398 }
399
Michael J. Spencera2c97272013-01-04 21:09:21 +0000400 /// \brief Returns the section link field, the returned value is
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000401 /// recorded in the sh_link field of the Section Header
402 int link() const {
403 return _link;
404 }
405
406 void setLink(int32_t link) {
407 _link = link;
408 }
409
Michael J. Spencera2c97272013-01-04 21:09:21 +0000410 /// \brief Returns the section entsize field, the returned value is
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000411 /// recorded in the sh_entsize field of the Section Header
412 int entsize() const {
413 return _entSize;
414 }
415
Michael J. Spencera2c97272013-01-04 21:09:21 +0000416 /// \brief Returns the shinfo field, the returned value is
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000417 /// recorded in the sh_info field of the Section Header
Michael J. Spencera2c97272013-01-04 21:09:21 +0000418 int shinfo() const {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000419 return _shInfo;
420 }
421
422 /// \brief Records the segmentType, that this section belongs to
423 void setSegment(const ELFLayout::SegmentType segmentType) {
424 _segmentType = segmentType;
425 }
426
427 /// \brief convert the segment type to a String for diagnostics
428 /// and printing purposes
429 StringRef segmentKindToStr() const {
430 switch(_segmentType) {
431 case llvm::ELF::PT_INTERP:
432 return "INTERP";
433 case llvm::ELF::PT_LOAD:
434 return "LOAD";
435 case llvm::ELF::PT_GNU_EH_FRAME:
436 return "EH_FRAME";
437 case llvm::ELF::PT_NOTE:
438 return "NOTE";
439 case llvm::ELF::PT_DYNAMIC:
440 return "DYNAMIC";
441 case llvm::ELF::PT_GNU_RELRO:
442 return "RELRO";
443 case llvm::ELF::PT_NULL:
444 return "NULL";
445 default:
446 return "UNKNOWN";
447 }
448 }
449
450 /// \brief for LLVM style RTTI information
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000451 static inline bool classof(const Chunk<ELFT> *c) {
452 return c->kind() == Chunk<ELFT>::K_ELFSection;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000453 }
454
455 /// \brief Finalize the section contents before writing
456 void finalize() { }
457
Michael J. Spencera2c97272013-01-04 21:09:21 +0000458 /// \brief Write the section and the atom contents to the buffer
459 void write(ELFWriter *writer,
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000460 OwningPtr<FileOutputBuffer> &buffer) {
461 uint8_t *chunkBuffer = buffer->getBufferStart();
462 for (auto &ai : _atoms) {
Michael J. Spencer7fe77f82013-01-15 06:55:11 +0000463 const DefinedAtom *definedAtom = cast<DefinedAtom>(ai._atom);
Michael J. Spencer8de83642013-01-07 08:00:42 +0000464 if (definedAtom->contentType() == DefinedAtom::typeZeroFill)
465 continue;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000466 // Copy raw content of atom to file buffer.
467 ArrayRef<uint8_t> content = definedAtom->rawContent();
468 uint64_t contentSize = content.size();
469 if (contentSize == 0)
470 continue;
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000471 uint8_t *atomContent = chunkBuffer + ai._fileOffset;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000472 std::copy_n(content.data(), contentSize, atomContent);
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000473 for (const auto ref : *definedAtom) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000474 uint32_t offset = ref->offsetInAtom();
475 uint64_t targetAddress = 0;
Michael J. Spencerbbe4b982013-01-11 21:38:36 +0000476 assert(ref->target() != nullptr && "Found the target to be NULL");
477 targetAddress = writer->addressOfAtom(ref->target());
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000478 uint64_t fixupAddress = writer->addressOfAtom(ai._atom) + offset;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000479 // apply the relocation
Michael J. Spencera2c97272013-01-04 21:09:21 +0000480 writer->kindHandler()->applyFixup(ref->kind(),
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000481 ref->addend(),
482 &atomContent[offset],
483 fixupAddress,
484 targetAddress);
485 }
486 }
487 }
488
489 /// Atom Iterators
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000490 typedef typename std::vector<AtomLayout>::iterator atom_iter;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000491
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000492 range<atom_iter> atoms() { return _atoms; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000493
494protected:
495 int32_t _contentType;
496 int32_t _contentPermissions;
Michael J. Spencer4ffbd602013-01-11 22:39:44 +0000497 SectionKind _sectionKind;
498 std::vector<AtomLayout> _atoms;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000499 ELFLayout::SegmentType _segmentType;
500 int64_t _entSize;
501 int64_t _shInfo;
502 int64_t _link;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000503};
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000504
Michael J. Spencera2c97272013-01-04 21:09:21 +0000505/// \brief A MergedSections represents a set of sections grouped by the same
506/// name. The output file that gets written by the linker has sections grouped
507/// by similiar names
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000508template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000509class MergedSections {
510public:
Michael J. Spencera2c97272013-01-04 21:09:21 +0000511 MergedSections(StringRef name)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000512 : _name(name)
513 ,_hasSegment(false)
514 ,_ordinal(0)
515 ,_flags(0)
516 ,_size(0)
517 ,_memSize(0)
518 ,_fileOffset(0)
519 ,_virtualAddr(0)
520 ,_shInfo(0)
521 ,_entSize(0)
522 ,_link(0)
523 ,_align2(0)
524 ,_kind(0)
525 ,_type(0) { }
Michael J. Spencera2c97272013-01-04 21:09:21 +0000526
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000527 // Set the MergedSections is associated with a segment
528 void setHasSegment() { _hasSegment = true; }
529
Michael J. Spencera2c97272013-01-04 21:09:21 +0000530 /// Sets the ordinal
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000531 void setOrdinal(uint64_t ordinal) {
532 _ordinal = ordinal;
533 }
534
Michael J. Spencera2c97272013-01-04 21:09:21 +0000535 /// Sets the Memory size
536 void setMemSize(uint64_t memsz) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000537 _memSize = memsz;
538 }
539
540 /// Sets the size fo the merged Section
541 void setSize(uint64_t fsiz) {
542 _size = fsiz;
543 }
544
Michael J. Spencera2c97272013-01-04 21:09:21 +0000545 // The offset of the first section contained in the merged section is
546 // contained here
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000547 void setFileOffset(uint64_t foffset) {
548 _fileOffset = foffset;
549 }
550
551 // Sets the starting address of the section
552 void setAddr(uint64_t addr) {
553 _virtualAddr = addr;
554 }
555
556 // Appends a section into the list of sections that are part of this Merged
557 // Section
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000558 void appendSection(Chunk<ELFT> *c) {
Michael J. Spencera2c97272013-01-04 21:09:21 +0000559 if (c->align2() > _align2)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000560 _align2 = c->align2();
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000561 if (const auto section = dyn_cast<Section<ELFT>>(c)) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000562 _link = section->link();
563 _shInfo = section->shinfo();
564 _entSize = section->entsize();
565 _type = section->type();
566 if (_flags < section->flags())
567 _flags = section->flags();
568 }
569 _kind = c->kind();
570 _sections.push_back(c);
571 }
572
573 // Iterators
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000574 typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000575
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000576 range<ChunkIter> sections() { return _sections; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000577
578 // The below functions returns the properties of the MergeSection
579 bool hasSegment() const { return _hasSegment; }
580
581 StringRef name() const { return _name; }
582
583 int64_t shinfo() const { return _shInfo; }
584
585 uint64_t align2() const { return _align2; }
586
587 int64_t link() const { return _link; }
588
589 int64_t type() const { return _type; }
590
591 uint64_t virtualAddr() const { return _virtualAddr; }
592
593 int64_t ordinal() const { return _ordinal; }
594
595 int64_t kind() const { return _kind; }
596
597 uint64_t fileSize() const { return _size; }
598
599 int64_t entsize() const { return _entSize; }
600
601 uint64_t fileOffset() const { return _fileOffset; }
602
603 int64_t flags() const { return _flags; }
604
605 uint64_t memSize() { return _memSize; }
606
607private:
608 StringRef _name;
609 bool _hasSegment;
610 uint64_t _ordinal;
611 int64_t _flags;
612 uint64_t _size;
613 uint64_t _memSize;
614 uint64_t _fileOffset;
615 uint64_t _virtualAddr;
616 int64_t _shInfo;
617 int64_t _entSize;
618 int64_t _link;
619 uint64_t _align2;
620 int64_t _kind;
621 int64_t _type;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000622 std::vector<Chunk<ELFT> *> _sections;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000623};
624
Michael J. Spencera2c97272013-01-04 21:09:21 +0000625/// \brief A segment can be divided into segment slices
626/// depending on how the segments can be split
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000627template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000628class SegmentSlice {
629public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000630 typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000631
632 SegmentSlice() { }
633
634 /// Set the segment slice so that it begins at the offset specified
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000635 /// by file offset and set the start of the slice to be s and the end
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000636 /// of the slice to be e
637 void set(uint64_t fileoffset, int32_t s, int e) {
638 _startSection = s;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000639 _endSection = e + 1;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000640 _offset = fileoffset;
641 }
642
643 // Set the segment slice start and end iterators. This is used to walk through
644 // the sections that are part of the Segment slice
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000645 void setSections(range<SectionIter> sections) {
646 _sections = sections;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000647 }
648
649 // Return the fileOffset of the slice
650 uint64_t fileOffset() const { return _offset; }
651
652 // Return the size of the slice
653 uint64_t fileSize() const { return _size; }
654
655 // Return the start of the slice
656 int32_t startSection() const { return _startSection; }
657
658 // Return the start address of the slice
659 uint64_t virtualAddr() const { return _addr; }
660
661 // Return the memory size of the slice
662 uint64_t memSize() const { return _memSize; }
663
664 // Return the alignment of the slice
665 uint64_t align2() const { return _align2; }
666
667 void setSize(uint64_t sz) { _size = sz; }
668
669 void setMemSize(uint64_t memsz) { _memSize = memsz; }
670
671 void setVAddr(uint64_t addr) { _addr = addr; }
672
673 void setAlign(uint64_t align) { _align2 = align; }
674
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000675 static bool compare_slices(SegmentSlice<ELFT> *a, SegmentSlice<ELFT> *b) {
676 return a->startSection() < b->startSection();
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000677 }
678
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000679 range<SectionIter> sections() {
680 return _sections;
681 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000682
683private:
684 int32_t _startSection;
685 int32_t _endSection;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000686 range<SectionIter> _sections;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000687 uint64_t _addr;
688 uint64_t _offset;
689 uint64_t _size;
690 uint64_t _align2;
691 uint64_t _memSize;
692};
693
694/// \brief A segment contains a set of sections, that have similiar properties
695// the sections are already seperated based on different flags and properties
696// the segment is just a way to concatenate sections to segments
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000697template<class ELFT>
698class Segment : public Chunk<ELFT> {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000699public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000700 typedef typename std::vector<SegmentSlice<ELFT> *>::iterator SliceIter;
701 typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000702
703 Segment(const StringRef name,
704 const ELFLayout::SegmentType type,
705 const WriterOptionsELF &options)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000706 : Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment)
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000707 , _segmentType(type)
708 , _flags(0)
709 , _atomflags(0)
710 , _options(options) {
711 this->_align2 = 0;
712 this->_fsize = 0;
713 }
714
715 /// append a section to a segment
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000716 void append(Section<ELFT> *section) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000717 _sections.push_back(section);
718 if (_flags < section->flags())
719 _flags = section->flags();
720 if (_atomflags < section->atomflags())
721 _atomflags = section->atomflags();
722 if (this->_align2 < section->align2())
723 this->_align2 = section->align2();
724 }
725
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000726 /// Prepend a generic chunk to the segment.
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000727 void prepend(Chunk<ELFT> *c) {
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000728 _sections.insert(_sections.begin(), c);
729 }
730
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000731 /// Sort segments depending on the property
732 /// If we have a Program Header segment, it should appear first
733 /// If we have a INTERP segment, that should appear after the Program Header
734 /// All Loadable segments appear next in this order
735 /// All Read Write Execute segments follow
736 /// All Read Execute segments appear next
737 /// All Read only segments appear first
Michael J. Spencera2c97272013-01-04 21:09:21 +0000738 /// All Write execute segments follow
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000739 static bool compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb) {
Michael J. Spencera2c97272013-01-04 21:09:21 +0000740 if (sega->atomflags() < segb->atomflags())
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000741 return false;
742 return true;
743 }
744
745 /// \brief Start assigning file offset to the segment chunks The fileoffset
746 /// needs to be page at the start of the segment and in addition the
747 /// fileoffset needs to be aligned to the max section alignment within the
748 /// segment. This is required so that the ELF property p_poffset % p_align =
749 /// p_vaddr mod p_align holds true.
750 /// The algorithm starts off by assigning the startOffset thats passed in as
751 /// parameter to the first section in the segment, if the difference between
752 /// the newly computed offset is greater than a page, then we create a segment
Michael J. Spencera2c97272013-01-04 21:09:21 +0000753 /// slice, as it would be a waste of virtual memory just to be filled with
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000754 /// zeroes
755 void assignOffsets(uint64_t startOffset) {
756 int startSection = 0;
757 int currSection = 0;
758 SectionIter startSectionIter, endSectionIter;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000759 // slice align is set to the max alignment of the chunks that are
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000760 // contained in the slice
761 uint64_t sliceAlign = 0;
762 // Current slice size
763 uint64_t curSliceSize = 0;
764 // Current Slice File Offset
765 uint64_t curSliceFileOffset = 0;
766
767 startSectionIter = _sections.begin();
768 endSectionIter = _sections.end();
769 startSection = 0;
770 bool isFirstSection = true;
771 for (auto si = _sections.begin(); si != _sections.end(); ++si) {
772 if (isFirstSection) {
773 // align the startOffset to the section alignment
Michael J. Spencera2c97272013-01-04 21:09:21 +0000774 uint64_t newOffset =
775 llvm::RoundUpToAlignment(startOffset, (*si)->align2());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000776 curSliceFileOffset = newOffset;
777 sliceAlign = (*si)->align2();
778 this->setFileOffset(startOffset);
779 (*si)->setFileOffset(newOffset);
780 curSliceSize = (*si)->fileSize();
781 isFirstSection = false;
782 } else {
783 uint64_t curOffset = curSliceFileOffset + curSliceSize;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000784 uint64_t newOffset =
785 llvm::RoundUpToAlignment(curOffset, (*si)->align2());
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000786 SegmentSlice<ELFT> *slice = nullptr;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000787 // If the newOffset computed is more than a page away, lets create
788 // a seperate segment, so that memory is not used up while running
789 if ((newOffset - curOffset) > _options.pageSize()) {
790 // TODO: use std::find here
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000791 for (auto s : slices()) {
792 if (s->startSection() == startSection) {
793 slice = s;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000794 break;
795 }
796 }
797 if (!slice) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000798 slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
799 SegmentSlice<ELFT>();
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000800 _segmentSlices.push_back(slice);
801 }
802 slice->set(curSliceFileOffset, startSection, currSection);
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000803 slice->setSections(make_range(startSectionIter, endSectionIter));
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000804 slice->setSize(curSliceSize);
805 slice->setAlign(sliceAlign);
Michael J. Spencera2c97272013-01-04 21:09:21 +0000806 uint64_t newPageOffset =
807 llvm::RoundUpToAlignment(curOffset, _options.pageSize());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000808 newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2());
809 curSliceFileOffset = newOffset;
810 startSectionIter = endSectionIter;
811 startSection = currSection;
812 (*si)->setFileOffset(curSliceFileOffset);
813 curSliceSize = newOffset - curSliceFileOffset + (*si)->fileSize();
814 sliceAlign = (*si)->align2();
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +0000815 } else {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000816 if (sliceAlign < (*si)->align2())
817 sliceAlign = (*si)->align2();
818 (*si)->setFileOffset(newOffset);
819 curSliceSize = newOffset - curSliceFileOffset + (*si)->fileSize();
820 }
821 }
822 currSection++;
823 endSectionIter = si;
824 }
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000825 SegmentSlice<ELFT> *slice = nullptr;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000826 for (auto s : slices()) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000827 // TODO: add std::find
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000828 if (s->startSection() == startSection) {
829 slice = s;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000830 break;
831 }
832 }
833 if (!slice) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000834 slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
835 SegmentSlice<ELFT>();
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000836 _segmentSlices.push_back(slice);
837 }
838 slice->set(curSliceFileOffset, startSection, currSection);
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000839 slice->setSections(make_range(startSectionIter, _sections.end()));
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000840 slice->setSize(curSliceSize);
841 slice->setAlign(sliceAlign);
842 this->_fsize = curSliceFileOffset - startOffset + curSliceSize;
Michael J. Spencera2c97272013-01-04 21:09:21 +0000843 std::stable_sort(slices_begin(), slices_end(),
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000844 SegmentSlice<ELFT>::compare_slices);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000845 }
846
847 /// \brief Assign virtual addresses to the slices
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000848 void assignVirtualAddress(uint64_t &addr) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000849 for (auto slice : slices()) {
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000850 // Align to a page
851 addr = llvm::RoundUpToAlignment(addr, _options.pageSize());
852 // Align to the slice alignment
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000853 addr = llvm::RoundUpToAlignment(addr, slice->align2());
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000854
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000855 bool virtualAddressSet = false;
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000856 for (auto section : slice->sections()) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000857 // Align the section address
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000858 addr = llvm::RoundUpToAlignment(addr, section->align2());
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000859 if (!virtualAddressSet) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000860 slice->setVAddr(addr);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000861 virtualAddressSet = true;
862 }
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000863 section->setVAddr(addr);
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000864 if (auto s = dyn_cast<Section<ELFT>>(section))
Michael J. Spencer00b702c2013-01-07 07:59:46 +0000865 s->assignVirtualAddress(addr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +0000866 else
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000867 addr += section->memSize();
868 section->setMemSize(addr - section->virtualAddr());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000869 }
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000870 slice->setMemSize(addr - slice->virtualAddr());
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000871 }
872 }
873
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000874 range<SliceIter> slices() { return _segmentSlices; }
875
876 // These two accessors are still needed for a call to std::stable_sort.
877 // Consider adding wrappers for two iterator algorithms.
878 SliceIter slices_begin() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000879 return _segmentSlices.begin();
880 }
881
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000882 SliceIter slices_end() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000883 return _segmentSlices.end();
884 }
885
Michael J. Spencera2c97272013-01-04 21:09:21 +0000886 // Write the Segment
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000887 void write(ELFWriter *writer, OwningPtr<FileOutputBuffer> &buffer) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +0000888 for (auto slice : slices())
889 for (auto section : slice->sections())
890 section->write(writer, buffer);
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000891 }
892
893 // Finalize the segment, before we want to write to the output file
894 void finalize() { }
895
Michael J. Spencera2c97272013-01-04 21:09:21 +0000896 // For LLVM RTTI
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000897 static inline bool classof(const Chunk<ELFT> *c) {
898 return c->kind() == Chunk<ELFT>::K_ELFSegment;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000899 }
900
901 // Getters
902 int32_t sectionCount() const {
903 return _sections.size();
904 }
905
906 ELFLayout::SegmentType segmentType() { return _segmentType; }
907
908 int pageSize() const { return _options.pageSize(); }
909
910 int64_t atomflags() const { return _atomflags; }
911
912 int64_t flags() const {
913 int64_t fl = 0;
914 if (_flags & llvm::ELF::SHF_ALLOC)
915 fl |= llvm::ELF::PF_R;
916 if (_flags & llvm::ELF::SHF_WRITE)
917 fl |= llvm::ELF::PF_W;
918 if (_flags & llvm::ELF::SHF_EXECINSTR)
919 fl |= llvm::ELF::PF_X;
920 return fl;
921 }
922
923 int64_t numSlices() const {
924 return _segmentSlices.size();
925 }
926
927private:
Michael J. Spencer00b702c2013-01-07 07:59:46 +0000928 /// \brief Section or some other chunk type.
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000929 std::vector<Chunk<ELFT> *> _sections;
930 std::vector<SegmentSlice<ELFT> *> _segmentSlices;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000931 ELFLayout::SegmentType _segmentType;
932 int64_t _flags;
933 int64_t _atomflags;
934 const WriterOptionsELF _options;
935 llvm::BumpPtrAllocator _segmentAllocate;
936};
937
938/// \brief The class represents the ELF String Table
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000939template<class ELFT>
940class ELFStringTable : public Section<ELFT> {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000941public:
Michael J. Spencera2c97272013-01-04 21:09:21 +0000942 ELFStringTable(const char *str, int32_t order)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000943 : Section<ELFT>(
Michael J. Spencera2c97272013-01-04 21:09:21 +0000944 str,
945 llvm::ELF::SHT_STRTAB,
946 DefinedAtom::perm___,
947 order,
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000948 Section<ELFT>::K_StringTable) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000949 // the string table has a NULL entry for which
950 // add an empty string
951 _strings.push_back("");
952 this->_fsize = 1;
953 this->_align2 = 1;
954 this->setOrder(order);
955 }
956
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000957 static inline bool classof(const Chunk<ELFT> *c) {
958 return c->kind() == Section<ELFT>::K_StringTable;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000959 }
960
961 uint64_t addString(const StringRef symname) {
962 _strings.push_back(symname);
963 uint64_t offset = this->_fsize;
964 this->_fsize += symname.size() + 1;
965 return offset;
966 }
967
Michael J. Spencera2c97272013-01-04 21:09:21 +0000968 void write(ELFWriter *writer,
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000969 OwningPtr<FileOutputBuffer> &buffer) {
970 uint8_t *chunkBuffer = buffer->getBufferStart();
971 uint8_t *dest = chunkBuffer + this->fileOffset();
972 for (auto si : _strings) {
973 memcpy(dest, si.data(), si.size());
974 dest += si.size();
975 memcpy(dest, "", 1);
976 dest += 1;
977 }
978 }
979
980 void finalize() { }
981
982private:
983 std::vector<StringRef> _strings;
984};
985
Michael J. Spencera2c97272013-01-04 21:09:21 +0000986/// \brief The ELFSymbolTable class represents the symbol table in a ELF file
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000987template<class ELFT>
988class ELFSymbolTable : public Section<ELFT> {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000989public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000990 typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000991
Michael J. Spencera2c97272013-01-04 21:09:21 +0000992 ELFSymbolTable(const char *str, int32_t order)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000993 : Section<ELFT>(
Michael J. Spencera2c97272013-01-04 21:09:21 +0000994 str,
995 llvm::ELF::SHT_SYMTAB,
996 0,
997 order,
Michael J. Spencerb03f6c42013-01-15 07:53:22 +0000998 Section<ELFT>::K_SymbolTable) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +0000999 this->setOrder(order);
1000 Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
Michael J. Spencera2c97272013-01-04 21:09:21 +00001001 memset((void *)symbol, 0, sizeof(Elf_Sym));
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001002 _symbolTable.push_back(symbol);
1003 this->_entSize = sizeof(Elf_Sym);
1004 this->_fsize = sizeof(Elf_Sym);
1005 this->_align2 = sizeof(void *);
1006 }
1007
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001008 static inline bool classof(const Chunk<ELFT> *c) {
1009 return c->kind() == Section<ELFT>::K_SymbolTable;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001010 }
1011
1012 void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0) {
1013 Elf_Sym *symbol = new(_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
1014 unsigned char binding = 0, type = 0;
1015 symbol->st_name = _stringSection->addString(atom->name());
1016 symbol->st_size = 0;
1017 symbol->st_shndx = sectionIndex;
1018 symbol->st_value = 0;
1019 symbol->st_other = ELF::STV_DEFAULT;
Michael J. Spencer7fe77f82013-01-15 06:55:11 +00001020 if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom)){
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001021 symbol->st_size = da->size();
1022 lld::DefinedAtom::ContentType ct;
1023 switch (ct = da->contentType()){
1024 case DefinedAtom::typeCode:
1025 symbol->st_value = addr;
1026 type = ELF::STT_FUNC;
1027 break;
1028 case DefinedAtom::typeData:
Michael J. Spencer8de83642013-01-07 08:00:42 +00001029 case DefinedAtom::typeConstant:
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001030 symbol->st_value = addr;
1031 type = ELF::STT_OBJECT;
1032 break;
1033 case DefinedAtom::typeZeroFill:
Michael J. Spencer28c65942013-01-07 07:05:52 +00001034 type = ELF::STT_OBJECT;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001035 symbol->st_value = addr;
1036 break;
1037 default:
1038 type = ELF::STT_NOTYPE;
1039 }
Michael J. Spencera2c97272013-01-04 21:09:21 +00001040 if (da->scope() == DefinedAtom::scopeTranslationUnit)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001041 binding = ELF::STB_LOCAL;
1042 else
1043 binding = ELF::STB_GLOBAL;
Michael J. Spencer7fe77f82013-01-15 06:55:11 +00001044 } else if (const AbsoluteAtom *aa = dyn_cast<const AbsoluteAtom>(atom)){
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001045 type = ELF::STT_OBJECT;
1046 symbol->st_shndx = ELF::SHN_ABS;
1047 switch (aa->scope()) {
1048 case AbsoluteAtom::scopeLinkageUnit:
1049 symbol->st_other = ELF::STV_HIDDEN;
1050 binding = ELF::STB_LOCAL;
1051 break;
1052 case AbsoluteAtom::scopeTranslationUnit:
1053 binding = ELF::STB_LOCAL;
1054 break;
1055 case AbsoluteAtom::scopeGlobal:
1056 binding = ELF::STB_GLOBAL;
1057 break;
1058 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001059 symbol->st_value = addr;
1060 } else {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001061 symbol->st_value = 0;
1062 type = ELF::STT_NOTYPE;
1063 binding = ELF::STB_WEAK;
1064 }
1065 symbol->setBindingAndType(binding, type);
1066 _symbolTable.push_back(symbol);
1067 this->_fsize += sizeof(Elf_Sym);
1068 }
1069
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001070 void setStringSection(ELFStringTable<ELFT> *s) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001071 _stringSection = s;
1072 }
1073
1074 void finalize() {
1075 // sh_info should be one greater than last symbol with STB_LOCAL binding
1076 // we sort the symbol table to keep all local symbols at the beginning
1077 std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
1078 [](const Elf_Sym *A, const Elf_Sym *B) {
1079 return A->getBinding() < B->getBinding();
Michael J. Spencera2c97272013-01-04 21:09:21 +00001080 });
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001081 uint16_t shInfo = 0;
1082 for (auto i : _symbolTable) {
1083 if (i->getBinding() != ELF::STB_LOCAL)
1084 break;
1085 shInfo++;
1086 }
1087 this->_shInfo = shInfo;
1088 this->setLink(_stringSection->ordinal());
1089 }
1090
Michael J. Spencera2c97272013-01-04 21:09:21 +00001091 void write(ELFWriter *writer,
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001092 OwningPtr<FileOutputBuffer> &buffer) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001093 uint8_t *chunkBuffer = buffer->getBufferStart();
1094 uint8_t *dest = chunkBuffer + this->fileOffset();
1095 for (auto sti : _symbolTable) {
1096 memcpy(dest, sti, sizeof(Elf_Sym));
1097 dest += sizeof(Elf_Sym);
1098 }
1099 }
1100
1101private:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001102 ELFStringTable<ELFT> *_stringSection;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001103 std::vector<Elf_Sym*> _symbolTable;
1104 llvm::BumpPtrAllocator _symbolAllocate;
1105 int64_t _link;
1106};
1107
1108/// \brief An ELFHeader represents the Elf[32/64]_Ehdr structure at the
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001109/// start of an ELF executable file.
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001110template<class ELFT>
1111class ELFHeader : public Chunk<ELFT> {
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001112public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001113 typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001114
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001115 ELFHeader()
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001116 : Chunk<ELFT>("elfhdr", Chunk<ELFT>::K_ELFHeader) {
1117 this->_align2 = ELFT::Is64Bits ? 8 : 4;
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001118 this->_fsize = sizeof(Elf_Ehdr);
1119 this->_msize = sizeof(Elf_Ehdr);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001120 memset(_eh.e_ident, 0, llvm::ELF::EI_NIDENT);
1121 e_ident(ELF::EI_MAG0, 0x7f);
1122 e_ident(ELF::EI_MAG1, 'E');
1123 e_ident(ELF::EI_MAG2, 'L');
1124 e_ident(ELF::EI_MAG3, 'F');
1125 e_ehsize(sizeof(Elf_Ehdr));
1126 e_flags(2);
1127 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001128 void e_ident(int I, unsigned char C) { _eh.e_ident[I] = C; }
1129 void e_type(uint16_t type) { _eh.e_type = type; }
1130 void e_machine(uint16_t machine) { _eh.e_machine = machine; }
1131 void e_version(uint32_t version) { _eh.e_version = version; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001132 void e_entry(int64_t entry) { _eh.e_entry = entry; }
1133 void e_phoff(int64_t phoff) { _eh.e_phoff = phoff; }
1134 void e_shoff(int64_t shoff) { _eh.e_shoff = shoff; }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001135 void e_flags(uint32_t flags) { _eh.e_flags = flags; }
1136 void e_ehsize(uint16_t ehsize) { _eh.e_ehsize = ehsize; }
1137 void e_phentsize(uint16_t phentsize) { _eh.e_phentsize = phentsize; }
1138 void e_phnum(uint16_t phnum) { _eh.e_phnum = phnum; }
1139 void e_shentsize(uint16_t shentsize) { _eh.e_shentsize = shentsize; }
1140 void e_shnum(uint16_t shnum) { _eh.e_shnum = shnum; }
1141 void e_shstrndx(uint16_t shstrndx) { _eh.e_shstrndx = shstrndx; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001142 uint64_t fileSize() { return sizeof (Elf_Ehdr); }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001143
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001144 static inline bool classof(const Chunk<ELFT> *c) {
1145 return c->Kind() == Chunk<ELFT>::K_ELFHeader;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001146 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001147
Michael J. Spencera2c97272013-01-04 21:09:21 +00001148 void write(ELFWriter *writer,
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001149 OwningPtr<FileOutputBuffer> &buffer) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001150 uint8_t *chunkBuffer = buffer->getBufferStart();
1151 uint8_t *atomContent = chunkBuffer + this->fileOffset();
1152 memcpy(atomContent, &_eh, fileSize());
1153 }
1154
1155 void finalize() { }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001156
1157private:
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001158 Elf_Ehdr _eh;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001159};
1160
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001161/// \brief An ELFProgramHeader represents the Elf[32/64]_Phdr structure at the
1162/// start of an ELF executable file.
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001163template<class ELFT>
1164class ELFProgramHeader : public Chunk<ELFT> {
Hemant Kulkarni08e410292012-10-01 23:53:20 +00001165public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001166 typedef Elf_Phdr_Impl<ELFT> Elf_Phdr;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001167 typedef typename std::vector<Elf_Phdr *>::iterator PhIterT;
1168
1169 /// \brief Find a program header entry, given the type of entry that
1170 /// we are looking for
1171 class FindPhdr {
1172 public:
1173 FindPhdr(uint64_t type, uint64_t flags, uint64_t flagsClear)
1174 : _type(type)
1175 , _flags(flags)
1176 , _flagsClear(flagsClear)
1177 {}
1178
Shankar Easwaran37c52822013-01-10 18:16:10 +00001179 bool operator()(const Elf_Phdr *j) const {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001180 return ((j->p_type == _type) &&
1181 ((j->p_flags & _flags) == _flags) &&
1182 (!(j->p_flags & _flagsClear)));
1183 }
1184 private:
1185 uint64_t _type;
1186 uint64_t _flags;
1187 uint64_t _flagsClear;
1188 };
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001189
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001190 ELFProgramHeader()
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001191 : Chunk<ELFT>("elfphdr", Chunk<ELFT>::K_ELFProgramHeader) {
1192 this->_align2 = ELFT::Is64Bits ? 8 : 4;
Reid Klecknere974bd12013-01-05 02:21:42 +00001193 resetProgramHeaders();
1194 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001195
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001196 bool addSegment(Segment<ELFT> *segment) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001197 Elf_Phdr *phdr = nullptr;
1198 bool ret = false;
1199
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001200 for (auto slice : segment->slices()) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001201 if (_phi == _ph.end()) {
1202 phdr = new(_allocator.Allocate<Elf_Phdr>()) Elf_Phdr;
1203 _ph.push_back(phdr);
1204 _phi = _ph.end();
1205 ret = true;
1206 } else {
1207 phdr = (*_phi);
1208 ++_phi;
1209 }
1210 phdr->p_type = segment->segmentType();
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001211 phdr->p_offset = slice->fileOffset();
1212 phdr->p_vaddr = slice->virtualAddr();
1213 phdr->p_paddr = slice->virtualAddr();
1214 phdr->p_filesz = slice->fileSize();
1215 phdr->p_memsz = slice->memSize();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001216 phdr->p_flags = segment->flags();
Michael J. Spencera2c97272013-01-04 21:09:21 +00001217 phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ?
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001218 segment->pageSize() : slice->align2();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001219 }
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001220
1221 this->_fsize = fileSize();
1222 this->_msize = this->_fsize;
1223
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001224 return ret;
1225 }
1226
1227 void resetProgramHeaders() {
Michael J. Spencera2c97272013-01-04 21:09:21 +00001228 _phi = _ph.begin();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001229 }
1230
Michael J. Spencera2c97272013-01-04 21:09:21 +00001231 uint64_t fileSize() {
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001232 return sizeof(Elf_Phdr) * _ph.size();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001233 }
1234
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001235 static inline bool classof(const Chunk<ELFT> *c) {
1236 return c->Kind() == Chunk<ELFT>::K_ELFProgramHeader;
Michael J. Spencera2c97272013-01-04 21:09:21 +00001237 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001238
Michael J. Spencera2c97272013-01-04 21:09:21 +00001239 void write(ELFWriter *writer,
1240 OwningPtr<FileOutputBuffer> &buffer) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001241 uint8_t *chunkBuffer = buffer->getBufferStart();
1242 uint8_t *dest = chunkBuffer + this->fileOffset();
1243 for (auto phi : _ph) {
1244 memcpy(dest, phi, sizeof(Elf_Phdr));
1245 dest += sizeof(Elf_Phdr);
1246 }
1247 }
1248
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001249 /// \brief find a program header entry in the list of program headers
1250 PhIterT findProgramHeader(uint64_t type, uint64_t flags, uint64_t flagClear) {
1251 return std::find_if(_ph.begin(), _ph.end(),
1252 FindPhdr(type, flags, flagClear));
1253 }
1254
1255 PhIterT begin() {
1256 return _ph.begin();
1257 }
1258
1259 PhIterT end() {
1260 return _ph.end();
1261 }
1262
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001263 void finalize() { }
1264
Michael J. Spencera2c97272013-01-04 21:09:21 +00001265 int64_t entsize() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001266 return sizeof(Elf_Phdr);
1267 }
1268
1269 int64_t numHeaders() {
1270 return _ph.size();
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001271 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001272
1273private:
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001274 std::vector<Elf_Phdr *> _ph;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001275 PhIterT _phi;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001276 llvm::BumpPtrAllocator _allocator;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001277};
1278
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001279/// \brief An ELFSectionHeader represents the Elf[32/64]_Shdr structure
1280/// at the end of the file
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001281template<class ELFT>
1282class ELFSectionHeader : public Chunk<ELFT> {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001283public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001284 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001285
Michael J. Spencera2c97272013-01-04 21:09:21 +00001286 ELFSectionHeader(int32_t order)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001287 : Chunk<ELFT>("shdr", Chunk<ELFT>::K_ELFSectionHeader) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001288 this->_fsize = 0;
1289 this->_align2 = 8;
1290 this->setOrder(order);
1291 // The first element in the list is always NULL
1292 Elf_Shdr *nullshdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr;
1293 ::memset(nullshdr, 0, sizeof (Elf_Shdr));
1294 _sectionInfo.push_back(nullshdr);
1295 this->_fsize += sizeof (Elf_Shdr);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001296 }
1297
Michael J. Spencera2c97272013-01-04 21:09:21 +00001298 uint16_t fileSize() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001299 return sizeof(Elf_Shdr) * _sectionInfo.size();
Hemant Kulkarni08e410292012-10-01 23:53:20 +00001300 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001301
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001302 void appendSection(MergedSections<ELFT> *section) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001303 Elf_Shdr *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr;
1304 shdr->sh_name = _stringSection->addString(section->name());
1305 shdr->sh_type = section->type();
1306 shdr->sh_flags = section->flags();
1307 shdr->sh_offset = section->fileOffset();
1308 shdr->sh_addr = section->virtualAddr();
1309 shdr->sh_size = section->memSize();
1310 shdr->sh_link = section->link();
1311 shdr->sh_info = section->shinfo();
1312 shdr->sh_addralign = section->align2();
1313 shdr->sh_entsize = section->entsize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001314 _sectionInfo.push_back(shdr);
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001315 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001316
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001317 void updateSection(Section<ELFT> *section) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001318 Elf_Shdr *shdr = _sectionInfo[section->ordinal()];
1319 shdr->sh_type = section->type();
1320 shdr->sh_flags = section->flags();
1321 shdr->sh_offset = section->fileOffset();
1322 shdr->sh_addr = section->virtualAddr();
1323 shdr->sh_size = section->fileSize();
1324 shdr->sh_link = section->link();
1325 shdr->sh_info = section->shinfo();
1326 shdr->sh_addralign = section->align2();
1327 shdr->sh_entsize = section->entsize();
1328 }
1329
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001330 static inline bool classof(const Chunk<ELFT> *c) {
1331 return c->getChunkKind() == Chunk<ELFT>::K_ELFSectionHeader;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001332 }
1333
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001334 void setStringSection(ELFStringTable<ELFT> *s) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001335 _stringSection = s;
1336 }
1337
Michael J. Spencera2c97272013-01-04 21:09:21 +00001338 void write(ELFWriter *writer,
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001339 OwningPtr<FileOutputBuffer> &buffer) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001340 uint8_t *chunkBuffer = buffer->getBufferStart();
1341 uint8_t *dest = chunkBuffer + this->fileOffset();
1342 for (auto shi : _sectionInfo) {
1343 memcpy(dest, shi, sizeof(Elf_Shdr));
1344 dest += sizeof(Elf_Shdr);
1345 }
1346 _stringSection->write(writer, buffer);
1347 }
1348
1349 void finalize() { }
1350
Michael J. Spencera2c97272013-01-04 21:09:21 +00001351 int64_t entsize() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001352 return sizeof(Elf_Shdr);
1353 }
1354
1355 int64_t numHeaders() {
1356 return _sectionInfo.size();
1357 }
1358
1359private:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001360 ELFStringTable<ELFT> *_stringSection;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001361 std::vector<Elf_Shdr*> _sectionInfo;
1362 llvm::BumpPtrAllocator _sectionAllocate;
1363};
1364
Michael J. Spencera2c97272013-01-04 21:09:21 +00001365/// \brief The DefaultELFLayout class is used by the Writer to arrange
1366/// sections and segments in the order determined by the target ELF
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001367/// format. The writer creates a single instance of the DefaultELFLayout
Michael J. Spencera2c97272013-01-04 21:09:21 +00001368/// class
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001369template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001370class DefaultELFLayout : public ELFLayout {
1371public:
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001372
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001373 // The order in which the sections appear in the output file
Michael J. Spencera2c97272013-01-04 21:09:21 +00001374 // If its determined, that the layout needs to change
1375 // just changing the order of enumerations would essentially
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001376 // change the layout in the output file
1377 enum DefaultSectionOrder {
1378 ORDER_NOT_DEFINED = 0,
1379 ORDER_INTERP,
1380 ORDER_NOTE,
1381 ORDER_HASH,
1382 ORDER_DYNAMIC_SYMBOLS,
1383 ORDER_DYNAMIC_STRINGS,
1384 ORDER_INIT,
1385 ORDER_TEXT,
1386 ORDER_PLT,
1387 ORDER_FINI,
1388 ORDER_RODATA,
1389 ORDER_EH_FRAME,
1390 ORDER_EH_FRAMEHDR,
1391 ORDER_CTORS,
1392 ORDER_DTORS,
Michael J. Spencerecd5f402013-01-10 22:41:42 +00001393 ORDER_INIT_ARRAY,
1394 ORDER_FINI_ARRAY,
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001395 ORDER_DYNAMIC,
1396 ORDER_GOT,
1397 ORDER_GOT_PLT,
1398 ORDER_DATA,
1399 ORDER_BSS,
1400 ORDER_OTHER,
1401 ORDER_SECTION_STRINGS,
1402 ORDER_SYMBOL_TABLE,
1403 ORDER_STRING_TABLE,
1404 ORDER_SECTION_HEADERS
1405 };
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001406
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001407public:
1408
1409 // The Key used for creating Sections
Michael J. Spencera2c97272013-01-04 21:09:21 +00001410 // The sections are created using
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001411 // SectionName, [contentType, contentPermissions]
Michael J. Spencera2c97272013-01-04 21:09:21 +00001412 typedef std::pair<StringRef,
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001413 std::pair<int32_t, int32_t>> Key;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001414 typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001415 // The key used for Segments
Michael J. Spencera2c97272013-01-04 21:09:21 +00001416 // The segments are created using
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001417 // SegmentName, Segment flags
1418 typedef std::pair<StringRef, int64_t> SegmentKey;
1419 // Merged Sections contain the map of Sectionnames to a vector of sections,
1420 // that have been merged to form a single section
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001421 typedef std::map<StringRef, MergedSections<ELFT> *> MergedSectionMapT;
1422 typedef typename std::vector<MergedSections<ELFT> *>::iterator
1423 MergedSectionIter;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001424
1425 // HashKey for the Section
1426 class HashKey {
1427 public:
1428 int64_t operator() (const Key &k) const {
1429 // k.first = section Name
1430 // k.second = [contentType, Permissions]
1431 return llvm::hash_combine(k.first, k.second.first, k.second.second);
1432 }
1433 };
1434
1435 // HashKey for the Segment
1436 class SegmentHashKey {
1437 public:
1438 int64_t operator() (const SegmentKey &k) const {
1439 // k.first = SegmentName
1440 // k.second = SegmentFlags
1441 return llvm::hash_combine(k.first, k.second);
1442 }
1443 };
1444
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001445 typedef std::unordered_map<Key, Section<ELFT>*, HashKey> SectionMapT;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001446 typedef std::unordered_map<SegmentKey,
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001447 Segment<ELFT>*,
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001448 SegmentHashKey> SegmentMapT;
1449
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001450 /// \brief All absolute atoms are created in the ELF Layout by using
1451 /// an AbsoluteAtomPair. Contains a pair of AbsoluteAtom and the
1452 /// value which is the address of the absolute atom
1453 class AbsoluteAtomPair {
1454 public:
1455 AbsoluteAtomPair(const AbsoluteAtom *a, int64_t value)
1456 : _absoluteAtom(a)
1457 , _value(value) { }
1458
1459 const AbsoluteAtom *absoluteAtom() { return _absoluteAtom; }
1460 int64_t value() const { return _value; }
1461 void setValue(int64_t val) { _value = val; }
1462
1463 private:
1464 const AbsoluteAtom *_absoluteAtom;
1465 int64_t _value;
1466 };
1467
1468 /// \brief find a absolute atom pair given a absolute atom name
1469 struct FindByName {
Nick Kledzik343ecbd2013-01-14 22:10:22 +00001470 const std::string _name;
Shankar Easwaranf6dc0822013-01-15 03:02:33 +00001471 FindByName(StringRef name) : _name(name) {}
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001472 bool operator()(AbsoluteAtomPair& j) {
Nick Kledzik343ecbd2013-01-14 22:10:22 +00001473 return j.absoluteAtom()->name() == _name;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001474 }
1475 };
1476
1477 typedef typename std::vector<AbsoluteAtomPair>::iterator AbsoluteAtomIterT;
1478
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001479 DefaultELFLayout(const WriterOptionsELF &options):_options(options) { }
1480
1481 /// \brief Return the section order for a input section
1482 virtual SectionOrder getSectionOrder
1483 (const StringRef name,
1484 int32_t contentType,
1485 int32_t contentPermissions) {
1486 switch (contentType) {
1487 case DefinedAtom::typeCode:
1488 return llvm::StringSwitch<Reference::Kind>(name)
1489 .StartsWith(".eh_frame_hdr", ORDER_EH_FRAMEHDR)
1490 .StartsWith(".eh_frame", ORDER_EH_FRAME)
1491 .StartsWith(".init", ORDER_INIT)
1492 .StartsWith(".fini", ORDER_FINI)
1493 .StartsWith(".hash", ORDER_HASH)
1494 .Default(ORDER_TEXT);
1495
1496 case DefinedAtom::typeConstant:
Michael J. Spencera2c97272013-01-04 21:09:21 +00001497 return ORDER_RODATA;
1498
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001499 case DefinedAtom::typeData:
Michael J. Spencerecd5f402013-01-10 22:41:42 +00001500 return llvm::StringSwitch<Reference::Kind>(name)
1501 .StartsWith(".init_array", ORDER_INIT_ARRAY)
1502 .Default(ORDER_DATA);
Michael J. Spencera2c97272013-01-04 21:09:21 +00001503
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001504 case DefinedAtom::typeZeroFill:
1505 return ORDER_BSS;
1506
1507 default:
1508 // If we get passed in a section push it to OTHER
Michael J. Spencera2c97272013-01-04 21:09:21 +00001509 if (contentPermissions == DefinedAtom::perm___)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001510 return ORDER_OTHER;
Michael J. Spencera2c97272013-01-04 21:09:21 +00001511
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001512 return ORDER_NOT_DEFINED;
1513 }
1514 }
1515
1516 /// \brief This maps the input sections to the output section names
1517 StringRef getSectionName(const StringRef name,
1518 const int32_t contentType) {
Michael J. Spencera2c97272013-01-04 21:09:21 +00001519 if (contentType == DefinedAtom::typeZeroFill)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001520 return ".bss";
Michael J. Spencera2c97272013-01-04 21:09:21 +00001521 if (name.startswith(".text"))
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001522 return ".text";
Michael J. Spencera2c97272013-01-04 21:09:21 +00001523 if (name.startswith(".rodata"))
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001524 return ".rodata";
1525 return name;
1526 }
1527
1528 /// \brief Gets the segment for a output section
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001529 virtual ELFLayout::SegmentType getSegmentType(Section<ELFT> *section) const {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001530 switch(section->order()) {
1531 case ORDER_INTERP:
1532 return llvm::ELF::PT_INTERP;
1533
1534 case ORDER_TEXT:
1535 case ORDER_HASH:
1536 case ORDER_DYNAMIC_SYMBOLS:
1537 case ORDER_DYNAMIC_STRINGS:
1538 case ORDER_INIT:
1539 case ORDER_PLT:
1540 case ORDER_FINI:
1541 case ORDER_RODATA:
1542 case ORDER_EH_FRAME:
1543 case ORDER_EH_FRAMEHDR:
1544 return llvm::ELF::PT_LOAD;
1545
1546 case ORDER_NOTE:
1547 return llvm::ELF::PT_NOTE;
1548
1549 case ORDER_DYNAMIC:
1550 return llvm::ELF::PT_DYNAMIC;
1551
1552 case ORDER_CTORS:
1553 case ORDER_DTORS:
1554 case ORDER_GOT:
1555 return llvm::ELF::PT_GNU_RELRO;
1556
1557 case ORDER_GOT_PLT:
1558 case ORDER_DATA:
1559 case ORDER_BSS:
Michael J. Spencerecd5f402013-01-10 22:41:42 +00001560 case ORDER_INIT_ARRAY:
1561 case ORDER_FINI_ARRAY:
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001562 return llvm::ELF::PT_LOAD;
1563
1564 default:
1565 return llvm::ELF::PT_NULL;
1566 }
1567 }
1568
1569 /// \brief Returns true/false depending on whether the section has a Output
1570 // segment or not
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001571 static bool hasOutputSegment(Section<ELFT> *section) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001572 switch(section->order()) {
1573 case ORDER_INTERP:
1574 case ORDER_HASH:
1575 case ORDER_DYNAMIC_SYMBOLS:
1576 case ORDER_DYNAMIC_STRINGS:
1577 case ORDER_INIT:
1578 case ORDER_PLT:
1579 case ORDER_TEXT:
1580 case ORDER_FINI:
1581 case ORDER_RODATA:
1582 case ORDER_EH_FRAME:
1583 case ORDER_EH_FRAMEHDR:
1584 case ORDER_NOTE:
1585 case ORDER_DYNAMIC:
1586 case ORDER_CTORS:
1587 case ORDER_DTORS:
1588 case ORDER_GOT:
1589 case ORDER_GOT_PLT:
1590 case ORDER_DATA:
Michael J. Spencerecd5f402013-01-10 22:41:42 +00001591 case ORDER_INIT_ARRAY:
1592 case ORDER_FINI_ARRAY:
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001593 case ORDER_BSS:
1594 return true;
1595
1596 default:
1597 return false;
1598 }
1599 }
1600
1601 // Adds an atom to the section
1602 virtual error_code addAtom(const Atom *atom) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001603 if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
1604 const StringRef sectionName =
1605 getSectionName(definedAtom->customSectionName(),
1606 definedAtom->contentType());
1607 const lld::DefinedAtom::ContentPermissions permissions =
1608 definedAtom->permissions();
1609 const lld::DefinedAtom::ContentType contentType =
1610 definedAtom->contentType();
1611 const Key key(sectionName, std::make_pair(contentType, permissions));
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001612 const std::pair<Key, Section<ELFT> *>currentSection(key, nullptr);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001613 std::pair<typename SectionMapT::iterator, bool>
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001614 sectionInsert(_sectionMap.insert(currentSection));
1615 Section<ELFT> *section;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001616 // the section is already in the map
1617 if (!sectionInsert.second) {
1618 section = sectionInsert.first->second;
1619 section->setContentPermissions(permissions);
1620 } else {
1621 SectionOrder section_order = getSectionOrder(sectionName,
1622 contentType,
1623 permissions);
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001624 section = new (_allocator.Allocate<Section<ELFT>>()) Section<ELFT>(
1625 sectionName, contentType, permissions, section_order);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001626 sectionInsert.first->second = section;
1627 section->setOrder(section_order);
1628 _sections.push_back(section);
1629 }
1630 section->appendAtom(atom);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001631 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001632 // Absolute atoms are not part of any section, they are global for the whole
1633 // link
1634 else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) {
1635 _absoluteAtoms.push_back(AbsoluteAtomPair(absoluteAtom,
1636 absoluteAtom->value()));
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001637 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001638 else
1639 llvm_unreachable("Only absolute / defined atoms can be added here");
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001640 return error_code::success();
1641 }
1642
Shankar Easwaranb1d09c02013-01-11 18:56:11 +00001643 /// \brief Find an output Section given a section name.
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001644 MergedSections<ELFT> *findOutputSection(StringRef name) {
Shankar Easwaranb1d09c02013-01-11 18:56:11 +00001645 auto iter = _mergedSectionMap.find(name);
1646 if (iter == _mergedSectionMap.end())
1647 return nullptr;
1648 return iter->second;
Michael J. Spencerecd5f402013-01-10 22:41:42 +00001649 }
1650
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001651 /// \brief find a absolute atom given a name
1652 AbsoluteAtomIterT findAbsoluteAtom(const StringRef name) {
1653 return std::find_if(_absoluteAtoms.begin(), _absoluteAtoms.end(),
1654 FindByName(name));
1655 }
1656
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001657 range<AbsoluteAtomIterT> absoluteAtoms() { return _absoluteAtoms; }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001658
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001659 // Merge sections with the same name into a MergedSections
1660 void mergeSimiliarSections() {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001661 MergedSections<ELFT> *mergedSection;
Michael J. Spencera2c97272013-01-04 21:09:21 +00001662
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001663 for (auto &si : _sections) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001664 const std::pair<StringRef, MergedSections<ELFT> *>
Michael J. Spencera2c97272013-01-04 21:09:21 +00001665 currentMergedSections(si->name(), nullptr);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001666 std::pair<typename MergedSectionMapT::iterator, bool>
1667 mergedSectionInsert
1668 (_mergedSectionMap.insert(currentMergedSections));
1669 if (!mergedSectionInsert.second) {
1670 mergedSection = mergedSectionInsert.first->second;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001671 } else {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001672 mergedSection = new (_allocator.Allocate<MergedSections<ELFT>>())
1673 MergedSections<ELFT>(si->name());
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001674 _mergedSections.push_back(mergedSection);
1675 mergedSectionInsert.first->second = mergedSection;
1676 }
1677 mergedSection->appendSection(si);
1678 }
1679 }
1680
1681 void assignSectionsToSegments() {
1682 // sort the sections by their order as defined by the layout
1683 std::stable_sort(_sections.begin(), _sections.end(),
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001684 [](Chunk<ELFT> *A, Chunk<ELFT> *B) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001685 return A->order() < B->order();
1686 });
1687 // Merge all sections
1688 mergeSimiliarSections();
1689 // Set the ordinal after sorting the sections
1690 int ordinal = 1;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001691 for (auto msi : _mergedSections) {
1692 msi->setOrdinal(ordinal);
1693 for (auto ai : msi->sections()) {
1694 ai->setOrdinal(ordinal);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001695 }
1696 ++ordinal;
1697 }
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001698 for (auto msi : _mergedSections) {
1699 for (auto ai : msi->sections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001700 if (auto section = dyn_cast<Section<ELFT>>(ai)) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001701 if (!hasOutputSegment(section))
1702 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001703 msi->setHasSegment();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001704 section->setSegment(getSegmentType(section));
1705 const StringRef segmentName = section->segmentKindToStr();
1706 // Use the flags of the merged Section for the segment
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001707 const SegmentKey key(segmentName, msi->flags());
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001708 const std::pair<SegmentKey, Segment<ELFT> *>
Michael J. Spencera2c97272013-01-04 21:09:21 +00001709 currentSegment(key, nullptr);
1710 std::pair<typename SegmentMapT::iterator, bool>
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001711 segmentInsert(_segmentMap.insert(currentSegment));
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001712 Segment<ELFT> *segment;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001713 if (!segmentInsert.second) {
1714 segment = segmentInsert.first->second;
1715 } else {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001716 segment = new (_allocator.Allocate<Segment<ELFT>>()) Segment<ELFT>(
1717 segmentName, getSegmentType(section), _options);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001718 segmentInsert.first->second = segment;
1719 _segments.push_back(segment);
1720 }
1721 segment->append(section);
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001722 }
1723 }
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001724 }
1725 }
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001726
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001727 void addSection(Chunk<ELFT> *c) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001728 _sections.push_back(c);
1729 }
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001730
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001731 void assignFileOffsets() {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001732 std::sort(_segments.begin(), _segments.end(),
1733 Segment<ELFT>::compareSegments);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001734 int ordinal = 0;
1735 // Compute the number of segments that might be needed, so that the
1736 // size of the program header can be computed
1737 uint64_t offset = 0;
1738 for (auto si : _segments) {
1739 si->setOrdinal(++ordinal);
1740 si->assignOffsets(offset);
1741 offset += si->fileSize();
1742 }
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001743 }
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001744
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001745 void setELFHeader(ELFHeader<ELFT> *e) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001746 _elfHeader = e;
1747 }
Hemant Kulkarni87dbac02012-11-13 21:34:45 +00001748
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001749 void setProgramHeader(ELFProgramHeader<ELFT> *p) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001750 _programHeader = p;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001751 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001752
1753 void assignVirtualAddress() {
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001754 if (_segments.empty())
1755 return;
1756
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001757 uint64_t virtualAddress = _options.baseAddress();
1758
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001759 // HACK: This is a super dirty hack. The elf header and program header are
1760 // not part of a section, but we need them to be loaded at the base address
1761 // so that AT_PHDR is set correctly by the loader and so they are accessible
1762 // at runtime. To do this we simply prepend them to the first Segment and
1763 // let the layout logic take care of it.
1764 _segments[0]->prepend(_programHeader);
1765 _segments[0]->prepend(_elfHeader);
1766
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001767 bool newSegmentHeaderAdded = true;
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001768 while (true) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001769 for (auto si : _segments) {
1770 newSegmentHeaderAdded = _programHeader->addSegment(si);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001771 }
Michael J. Spencera2c97272013-01-04 21:09:21 +00001772 if (!newSegmentHeaderAdded)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001773 break;
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001774 uint64_t fileoffset = 0;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001775 uint64_t address = virtualAddress;
1776 // Fix the offsets after adding the program header
1777 for (auto &si : _segments) {
1778 // Align the segment to a page boundary
1779 fileoffset = llvm::RoundUpToAlignment(fileoffset, _options.pageSize());
1780 si->assignOffsets(fileoffset);
1781 fileoffset = si->fileOffset() + si->fileSize();
1782 }
1783 // start assigning virtual addresses
1784 for (auto si = _segments.begin(); si != _segments.end(); ++si) {
1785 (*si)->setVAddr(virtualAddress);
1786 // The first segment has the virtualAddress set to the base address as
1787 // we have added the file header and the program header dont align the
Michael J. Spencera2c97272013-01-04 21:09:21 +00001788 // first segment to the pagesize
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00001789 (*si)->assignVirtualAddress(address);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001790 (*si)->setMemSize(address - virtualAddress);
1791 virtualAddress = llvm::RoundUpToAlignment(address, _options.pageSize());
1792 }
1793 _programHeader->resetProgramHeaders();
1794 }
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001795 Section<ELFT> *section;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001796 // Fix the offsets of all the atoms within a section
1797 for (auto &si : _sections) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001798 section = dyn_cast<Section<ELFT>>(si);
1799 if (section && DefaultELFLayout<ELFT>::hasOutputSegment(section))
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001800 section->assignOffsets(section->fileOffset());
1801 }
1802 // Set the size of the merged Sections
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001803 for (auto msi : _mergedSections) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001804 uint64_t sectionfileoffset = 0;
1805 uint64_t startFileOffset = 0;
1806 uint64_t sectionsize = 0;
1807 bool isFirstSection = true;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001808 for (auto si : msi->sections()) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001809 if (isFirstSection) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001810 startFileOffset = si->fileOffset();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001811 isFirstSection = false;
1812 }
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001813 sectionfileoffset = si->fileOffset();
1814 sectionsize = si->fileSize();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001815 }
1816 sectionsize = (sectionfileoffset - startFileOffset) + sectionsize;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001817 msi->setFileOffset(startFileOffset);
1818 msi->setSize(sectionsize);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001819 }
1820 // Set the virtual addr of the merged Sections
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001821 for (auto msi : _mergedSections) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001822 uint64_t sectionstartaddr = 0;
1823 uint64_t startaddr = 0;
1824 uint64_t sectionsize = 0;
1825 bool isFirstSection = true;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001826 for (auto si : msi->sections()) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001827 if (isFirstSection) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001828 startaddr = si->virtualAddr();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001829 isFirstSection = false;
1830 }
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001831 sectionstartaddr = si->virtualAddr();
1832 sectionsize = si->memSize();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001833 }
1834 sectionsize = (sectionstartaddr - startaddr) + sectionsize;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001835 msi->setMemSize(sectionsize);
1836 msi->setAddr(startaddr);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001837 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001838 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001839
1840 void assignOffsetsForMiscSections() {
1841 uint64_t fileoffset = 0;
1842 uint64_t size = 0;
1843 for (auto si : _segments) {
1844 fileoffset = si->fileOffset();
1845 size = si->fileSize();
1846 }
1847 fileoffset = fileoffset + size;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001848 Section<ELFT> *section;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001849 for (auto si : _sections) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001850 section = dyn_cast<Section<ELFT>>(si);
1851 if (section && DefaultELFLayout<ELFT>::hasOutputSegment(section))
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001852 continue;
1853 fileoffset = llvm::RoundUpToAlignment(fileoffset, si->align2());
1854 si->setFileOffset(fileoffset);
1855 si->setVAddr(0);
1856 fileoffset += si->fileSize();
1857 }
Hemant Kulkarni08e410292012-10-01 23:53:20 +00001858 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001859
1860 void finalize() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001861 for (auto &si : _sections)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001862 si->finalize();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001863 }
1864
1865 bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001866 for (auto sec : _sections)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001867 if (auto section = dyn_cast<Section<ELFT>>(sec))
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001868 if (section->findAtomAddrByName(name, addr))
1869 return true;
Michael J. Spencera2c97272013-01-04 21:09:21 +00001870 return false;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001871 }
1872
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001873 range<MergedSectionIter> mergedSections() { return _mergedSections; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001874
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001875 range<ChunkIter> sections() { return _sections; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001876
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001877 range<ChunkIter> segments() { return _segments; }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001878
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001879 ELFHeader<ELFT> *elfHeader() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001880 return _elfHeader;
1881 }
1882
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001883 ELFProgramHeader<ELFT> *elfProgramHeader() {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001884 return _programHeader;
Hemant Kulkarni08e410292012-10-01 23:53:20 +00001885 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001886
1887private:
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001888 SectionMapT _sectionMap;
1889 MergedSectionMapT _mergedSectionMap;
1890 SegmentMapT _segmentMap;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001891 std::vector<Chunk<ELFT> *> _sections;
1892 std::vector<Segment<ELFT> *> _segments;
1893 std::vector<MergedSections<ELFT> *> _mergedSections;
1894 ELFHeader<ELFT> *_elfHeader;
1895 ELFProgramHeader<ELFT> *_programHeader;
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001896 std::vector<AbsoluteAtomPair> _absoluteAtoms;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001897 llvm::BumpPtrAllocator _allocator;
1898 const WriterOptionsELF &_options;
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001899};
1900
1901//===----------------------------------------------------------------------===//
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001902// ELFExecutableWriter Class
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001903//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001904template<class ELFT>
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001905class ELFExecutableWriter : public ELFWriter {
1906public:
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001907 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
1908 typedef Elf_Sym_Impl<ELFT> Elf_Sym;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001909
1910 ELFExecutableWriter(const WriterOptionsELF &options);
1911
1912private:
Michael J. Spencera2c97272013-01-04 21:09:21 +00001913 // build the sections that need to be created
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001914 void buildChunks(const lld::File &file);
1915 virtual error_code writeFile(const lld::File &File, StringRef path);
1916 void buildAtomToAddressMap();
1917 void buildSymbolTable ();
1918 void buildSectionHeaderTable();
1919 void assignSectionsWithNoSegments();
1920 void addAbsoluteUndefinedSymbols(const lld::File &File);
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001921 void addDefaultAtoms();
1922 void addFiles(InputFiles&);
1923 void finalizeDefaultAtomValues();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001924
Michael J. Spencera2c97272013-01-04 21:09:21 +00001925 uint64_t addressOfAtom(const Atom *atom) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001926 return _atomToAddressMap[atom];
1927 }
1928
1929 KindHandler *kindHandler() { return _referenceKindHandler.get(); }
1930
1931 void createDefaultSections();
1932
1933 const WriterOptionsELF &_options;
1934
1935 typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
1936 std::unique_ptr<KindHandler> _referenceKindHandler;
1937 AtomToAddress _atomToAddressMap;
1938 llvm::BumpPtrAllocator _chunkAllocate;
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001939 DefaultELFLayout<ELFT> *_layout;
1940 ELFHeader<ELFT> *_elfHeader;
1941 ELFProgramHeader<ELFT> *_programHeader;
1942 ELFSymbolTable<ELFT> * _symtab;
1943 ELFStringTable<ELFT> *_strtab;
1944 ELFStringTable<ELFT> *_shstrtab;
1945 ELFSectionHeader<ELFT> *_shdrtab;
1946 CRuntimeFile<ELFT> _runtimeFile;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001947};
1948
1949//===----------------------------------------------------------------------===//
1950// ELFExecutableWriter
1951//===----------------------------------------------------------------------===//
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001952template<class ELFT>
1953ELFExecutableWriter<ELFT>::ELFExecutableWriter(const WriterOptionsELF &options)
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001954 : _options(options)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001955 , _referenceKindHandler(KindHandler::makeHandler(
1956 _options.machine(), (endianness)ELFT::TargetEndianness))
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001957 , _runtimeFile(options) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001958 _layout =new DefaultELFLayout<ELFT>(options);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001959}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001960
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001961template<class ELFT>
1962void ELFExecutableWriter<ELFT>::buildChunks(const lld::File &file){
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001963 for (const DefinedAtom *definedAtom : file.defined() ) {
1964 _layout->addAtom(definedAtom);
1965 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00001966 /// Add all the absolute atoms to the layout
1967 for (const AbsoluteAtom *absoluteAtom : file.absolute()) {
1968 _layout->addAtom(absoluteAtom);
1969 }
Shankar Easwaran495d38b2012-12-27 02:26:30 +00001970}
1971
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001972template<class ELFT>
1973void ELFExecutableWriter<ELFT>::buildSymbolTable () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001974 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001975 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001976 for (const auto &atom : section->atoms())
1977 _symtab->addSymbol(atom._atom, section->ordinal(), atom._virtualAddr);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001978}
1979
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001980template<class ELFT>
1981void
1982ELFExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const lld::File &file) {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001983 // add all the absolute symbols that the layout contains to the output symbol
1984 // table
1985 for (auto &atom : _layout->absoluteAtoms())
1986 _symtab->addSymbol(atom.absoluteAtom(), ELF::SHN_ABS, atom.value());
1987 for (const UndefinedAtom *a : file.undefined())
1988 _symtab->addSymbol(a, ELF::SHN_UNDEF);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00001989}
1990
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001991template<class ELFT>
1992void ELFExecutableWriter<ELFT>::buildAtomToAddressMap () {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001993 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00001994 if (auto section = dyn_cast<Section<ELFT>>(sec))
Michael J. Spencerbb78a042013-01-15 06:55:37 +00001995 for (const auto &atom : section->atoms())
1996 _atomToAddressMap[atom._atom] = atom._virtualAddr;
1997 // build the atomToAddressMap that contains absolute symbols too
1998 for (auto &atom : _layout->absoluteAtoms())
1999 _atomToAddressMap[atom.absoluteAtom()] = atom.value();
Sid Manningdd110202012-09-25 18:22:09 +00002000}
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002001
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002002template<class ELFT>
2003void ELFExecutableWriter<ELFT>::buildSectionHeaderTable() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002004 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002005 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002006 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002007 if (mergedSec->hasSegment())
2008 _shdrtab->appendSection(mergedSec);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002009 }
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002010}
2011
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002012template<class ELFT>
2013void ELFExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002014 for (auto mergedSec : _layout->mergedSections()) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002015 if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002016 continue;
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002017 if (!mergedSec->hasSegment())
2018 _shdrtab->appendSection(mergedSec);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002019 }
2020 _layout->assignOffsetsForMiscSections();
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002021 for (auto sec : _layout->sections())
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002022 if (auto section = dyn_cast<Section<ELFT>>(sec))
2023 if (!DefaultELFLayout<ELFT>::hasOutputSegment(section))
Michael J. Spencer7fe77f82013-01-15 06:55:11 +00002024 _shdrtab->updateSection(section);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002025}
2026
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002027/// \brief Add absolute symbols by default. These are linker added
2028/// absolute symbols
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002029template<class ELFT>
2030void ELFExecutableWriter<ELFT>::addDefaultAtoms() {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002031 _runtimeFile.addUndefinedAtom("_start");
2032 _runtimeFile.addAbsoluteAtom("__bss_start");
2033 _runtimeFile.addAbsoluteAtom("__bss_end");
2034 _runtimeFile.addAbsoluteAtom("_end");
2035 _runtimeFile.addAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +00002036 _runtimeFile.addAbsoluteAtom("__init_array_start");
2037 _runtimeFile.addAbsoluteAtom("__init_array_end");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002038}
2039
2040/// \brief Hook in lld to add CRuntime file
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002041template<class ELFT>
2042void ELFExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002043 addDefaultAtoms();
2044 inputFiles.prependFile(_runtimeFile);
2045}
2046
2047/// Finalize the value of all the absolute symbols that we
2048/// created
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002049template<class ELFT>
2050void ELFExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002051 auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
2052 auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
2053 auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
2054 auto endAtomIter = _layout->findAbsoluteAtom("end");
Michael J. Spencerecd5f402013-01-10 22:41:42 +00002055 auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
2056 auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
2057
2058 auto section = _layout->findOutputSection(".init_array");
2059 if (section) {
2060 initArrayStartIter->setValue(section->virtualAddr());
2061 initArrayEndIter->setValue(section->virtualAddr() +
2062 section->memSize());
2063 } else {
2064 initArrayStartIter->setValue(0);
2065 initArrayEndIter->setValue(0);
2066 }
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002067
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002068 assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
2069 bssEndAtomIter == _layout->absoluteAtoms().end() ||
2070 underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
2071 endAtomIter == _layout->absoluteAtoms().end()) &&
Shankar Easwaran37c52822013-01-10 18:16:10 +00002072 "Unable to find the absolute atoms that have been added by lld");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002073
2074 auto phe = _programHeader->findProgramHeader(
2075 llvm::ELF::PT_LOAD,
2076 llvm::ELF::PF_W,
2077 llvm::ELF::PF_X);
2078
Shankar Easwaran37c52822013-01-10 18:16:10 +00002079 assert(!(phe == _programHeader->end()) &&
2080 "Can't find a data segment in the program header!");
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002081
2082 bssStartAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_filesz);
2083 bssEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
2084 underScoreEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
2085 endAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
2086}
2087
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002088template<class ELFT>
2089error_code
2090ELFExecutableWriter<ELFT>::writeFile(const lld::File &file, StringRef path) {
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002091 buildChunks(file);
2092 // Create the default sections like the symbol table, string table, and the
2093 // section string table
2094 createDefaultSections();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002095
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002096 // Set the Layout
2097 _layout->assignSectionsToSegments();
2098 _layout->assignFileOffsets();
2099 _layout->assignVirtualAddress();
2100
Shankar Easwaran2ca8e7d2013-01-10 03:16:27 +00002101 // Finalize the default value of symbols that the linker adds
2102 finalizeDefaultAtomValues();
2103
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002104 // Build the Atom To Address map for applying relocations
2105 buildAtomToAddressMap();
2106
2107 // Create symbol table and section string table
2108 buildSymbolTable();
2109
2110 // add other symbols
2111 addAbsoluteUndefinedSymbols(file);
2112
2113 // Finalize the layout by calling the finalize() functions
2114 _layout->finalize();
2115
2116 // build Section Header table
2117 buildSectionHeaderTable();
2118
2119 // assign Offsets and virtual addresses
2120 // for sections with no segments
2121 assignSectionsWithNoSegments();
2122
2123 uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002124
2125 OwningPtr<FileOutputBuffer> buffer;
2126 error_code ec = FileOutputBuffer::create(path,
2127 totalSize, buffer,
2128 FileOutputBuffer::F_executable);
2129 if (ec)
2130 return ec;
2131
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002132 _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64
2133 : ELF::ELFCLASS32));
Michael J. Spencera2c97272013-01-04 21:09:21 +00002134 _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002135 ? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB);
2136 _elfHeader->e_ident(ELF::EI_VERSION, 1);
2137 _elfHeader->e_ident(ELF::EI_OSABI, 0);
2138 _elfHeader->e_type(_options.type());
2139 _elfHeader->e_machine(_options.machine());
2140 _elfHeader->e_version(1);
2141 _elfHeader->e_entry(0ULL);
2142 _elfHeader->e_phoff(_programHeader->fileOffset());
2143 _elfHeader->e_shoff(_shdrtab->fileOffset());
2144 _elfHeader->e_phentsize(_programHeader->entsize());
2145 _elfHeader->e_phnum(_programHeader->numHeaders());
2146 _elfHeader->e_shentsize(_shdrtab->entsize());
2147 _elfHeader->e_shnum(_shdrtab->numHeaders());
2148 _elfHeader->e_shstrndx(_shstrtab->ordinal());
2149 uint64_t virtualAddr = 0;
2150 _layout->findAtomAddrByName("_start", virtualAddr);
2151 _elfHeader->e_entry(virtualAddr);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00002152
2153 // HACK: We have to write out the header and program header here even though
2154 // they are a member of a segment because only sections are written in the
2155 // following loop.
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002156 _elfHeader->write(this, buffer);
2157 _programHeader->write(this, buffer);
2158
Michael J. Spencerbb78a042013-01-15 06:55:37 +00002159 for (auto section : _layout->sections())
2160 section->write(this, buffer);
Michael J. Spencer1ac382f02013-01-07 08:00:04 +00002161
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002162 return buffer->commit();
2163}
Nick Kledzikabb69812012-05-31 22:34:00 +00002164
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002165template<class ELFT>
2166void ELFExecutableWriter<ELFT>::createDefaultSections() {
2167 _elfHeader = new ELFHeader<ELFT>();
2168 _programHeader = new ELFProgramHeader<ELFT>();
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002169 _layout->setELFHeader(_elfHeader);
2170 _layout->setProgramHeader(_programHeader);
2171
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002172 _symtab = new ELFSymbolTable<ELFT>(
2173 ".symtab", DefaultELFLayout<ELFT>::ORDER_SYMBOL_TABLE);
2174 _strtab = new ELFStringTable<ELFT>(
2175 ".strtab", DefaultELFLayout<ELFT>::ORDER_STRING_TABLE);
2176 _shstrtab = new ELFStringTable<ELFT>(
2177 ".shstrtab", DefaultELFLayout<ELFT>::ORDER_SECTION_STRINGS);
2178 _shdrtab = new ELFSectionHeader<ELFT>(
2179 DefaultELFLayout<ELFT>::ORDER_SECTION_HEADERS);
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002180 _layout->addSection(_symtab);
2181 _layout->addSection(_strtab);
2182 _layout->addSection(_shstrtab);
2183 _shdrtab->setStringSection(_shstrtab);
2184 _symtab->setStringSection(_strtab);
2185 _layout->addSection(_shdrtab);
Sid Manningdd110202012-09-25 18:22:09 +00002186}
Nick Kledzikabb69812012-05-31 22:34:00 +00002187} // namespace elf
2188
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002189Writer *createWriterELF(const WriterOptionsELF &options) {
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002190 using llvm::object::ELFType;
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002191 // Set the default layout to be the static executable layout
Michael J. Spencera2c97272013-01-04 21:09:21 +00002192 // We would set the layout to a dynamic executable layout
Shankar Easwaran495d38b2012-12-27 02:26:30 +00002193 // if we came across any shared libraries in the process
Michael J. Spencera2c97272013-01-04 21:09:21 +00002194
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002195 if (!options.is64Bit() && options.endianness() == llvm::support::little)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002196 return
2197 new elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(options);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002198 else if (options.is64Bit() && options.endianness() == llvm::support::little)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002199 return
2200 new elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(options);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002201 else if (!options.is64Bit() && options.endianness() == llvm::support::big)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002202 return
2203 new elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(options);
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002204 else if (options.is64Bit() && options.endianness() == llvm::support::big)
Michael J. Spencerb03f6c42013-01-15 07:53:22 +00002205 return
2206 new elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(options);
Nick Kledzikabb69812012-05-31 22:34:00 +00002207
Hemant Kulkarni927bbc22012-09-14 16:11:34 +00002208 llvm_unreachable("Invalid Options!");
Nick Kledzikabb69812012-05-31 22:34:00 +00002209}
Nick Kledzikabb69812012-05-31 22:34:00 +00002210} // namespace lld