blob: cb7fddeee77c83cd73db6739a1c7d7ebecb875e3 [file] [log] [blame]
Petr Hosek05a04cb2017-08-01 00:33:58 +00001//===- Object.cpp -----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "Object.h"
10#include "llvm-objcopy.h"
11
12using namespace llvm;
13using namespace object;
14using namespace ELF;
15
16template <class ELFT> void Segment::writeHeader(FileOutputBuffer &Out) const {
17 typedef typename ELFT::Ehdr Elf_Ehdr;
18 typedef typename ELFT::Phdr Elf_Phdr;
19
20 uint8_t *Buf = Out.getBufferStart();
21 Buf += sizeof(Elf_Ehdr) + Index * sizeof(Elf_Phdr);
22 Elf_Phdr &Phdr = *reinterpret_cast<Elf_Phdr *>(Buf);
23 Phdr.p_type = Type;
24 Phdr.p_flags = Flags;
25 Phdr.p_offset = Offset;
26 Phdr.p_vaddr = VAddr;
27 Phdr.p_paddr = PAddr;
28 Phdr.p_filesz = FileSize;
29 Phdr.p_memsz = MemSize;
30 Phdr.p_align = Align;
31}
32
33void Segment::finalize() {
34 auto FirstSec = firstSection();
35 if (FirstSec) {
36 // It is possible for a gap to be at the begining of a segment. Because of
37 // this we need to compute the new offset based on how large this gap was
38 // in the source file. Section layout should have already ensured that this
39 // space is not used for something else.
40 uint64_t OriginalOffset = Offset;
41 Offset = FirstSec->Offset - (FirstSec->OriginalOffset - OriginalOffset);
42 }
43}
44
Petr Hosekc4df10e2017-08-04 21:09:26 +000045void Segment::writeSegment(FileOutputBuffer &Out) const {
46 uint8_t *Buf = Out.getBufferStart() + Offset;
47 // We want to maintain segments' interstitial data and contents exactly.
48 // This lets us just copy segments directly.
49 std::copy(std::begin(Contents), std::end(Contents), Buf);
50}
51
Jake Ehrlichf5a43772017-09-25 20:37:28 +000052void SectionBase::initialize(SectionTableRef SecTable) {}
Petr Hosek05a04cb2017-08-01 00:33:58 +000053void SectionBase::finalize() {}
54
55template <class ELFT>
56void SectionBase::writeHeader(FileOutputBuffer &Out) const {
57 uint8_t *Buf = Out.getBufferStart();
58 Buf += HeaderOffset;
59 typename ELFT::Shdr &Shdr = *reinterpret_cast<typename ELFT::Shdr *>(Buf);
60 Shdr.sh_name = NameIndex;
61 Shdr.sh_type = Type;
62 Shdr.sh_flags = Flags;
63 Shdr.sh_addr = Addr;
64 Shdr.sh_offset = Offset;
65 Shdr.sh_size = Size;
66 Shdr.sh_link = Link;
67 Shdr.sh_info = Info;
68 Shdr.sh_addralign = Align;
69 Shdr.sh_entsize = EntrySize;
70}
71
72void Section::writeSection(FileOutputBuffer &Out) const {
73 if (Type == SHT_NOBITS)
74 return;
75 uint8_t *Buf = Out.getBufferStart() + Offset;
76 std::copy(std::begin(Contents), std::end(Contents), Buf);
77}
78
79void StringTableSection::addString(StringRef Name) {
80 StrTabBuilder.add(Name);
81 Size = StrTabBuilder.getSize();
82}
83
84uint32_t StringTableSection::findIndex(StringRef Name) const {
85 return StrTabBuilder.getOffset(Name);
86}
87
88void StringTableSection::finalize() { StrTabBuilder.finalize(); }
89
90void StringTableSection::writeSection(FileOutputBuffer &Out) const {
91 StrTabBuilder.write(Out.getBufferStart() + Offset);
92}
93
Petr Hosekc1135772017-09-13 03:04:50 +000094static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine) {
Petr Hosekec2b3fc2017-09-07 23:02:50 +000095 switch (Index) {
96 case SHN_ABS:
97 case SHN_COMMON:
Petr Hosekec2b3fc2017-09-07 23:02:50 +000098 return true;
Petr Hosekec2b3fc2017-09-07 23:02:50 +000099 }
Petr Hosekc1135772017-09-13 03:04:50 +0000100 if (Machine == EM_HEXAGON) {
101 switch (Index) {
102 case SHN_HEXAGON_SCOMMON:
103 case SHN_HEXAGON_SCOMMON_2:
104 case SHN_HEXAGON_SCOMMON_4:
105 case SHN_HEXAGON_SCOMMON_8:
106 return true;
107 }
108 }
109 return false;
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000110}
111
112uint16_t Symbol::getShndx() const {
113 if (DefinedIn != nullptr) {
114 return DefinedIn->Index;
115 }
116 switch (ShndxType) {
117 // This means that we don't have a defined section but we do need to
118 // output a legitimate section index.
119 case SYMBOL_SIMPLE_INDEX:
120 return SHN_UNDEF;
121 case SYMBOL_ABS:
122 case SYMBOL_COMMON:
123 case SYMBOL_HEXAGON_SCOMMON:
124 case SYMBOL_HEXAGON_SCOMMON_2:
125 case SYMBOL_HEXAGON_SCOMMON_4:
126 case SYMBOL_HEXAGON_SCOMMON_8:
127 return static_cast<uint16_t>(ShndxType);
128 }
129 llvm_unreachable("Symbol with invalid ShndxType encountered");
130}
131
Petr Hosek79cee9e2017-08-29 02:12:03 +0000132void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
133 SectionBase *DefinedIn, uint64_t Value,
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000134 uint16_t Shndx, uint64_t Sz) {
Petr Hosek79cee9e2017-08-29 02:12:03 +0000135 Symbol Sym;
136 Sym.Name = Name;
137 Sym.Binding = Bind;
138 Sym.Type = Type;
139 Sym.DefinedIn = DefinedIn;
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000140 if (DefinedIn == nullptr) {
Petr Hosekc1135772017-09-13 03:04:50 +0000141 if (Shndx >= SHN_LORESERVE)
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000142 Sym.ShndxType = static_cast<SymbolShndxType>(Shndx);
143 else
144 Sym.ShndxType = SYMBOL_SIMPLE_INDEX;
145 }
Petr Hosek79cee9e2017-08-29 02:12:03 +0000146 Sym.Value = Value;
147 Sym.Size = Sz;
148 Sym.Index = Symbols.size();
149 Symbols.emplace_back(llvm::make_unique<Symbol>(Sym));
150 Size += this->EntrySize;
151}
152
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000153void SymbolTableSection::initialize(SectionTableRef SecTable) {
154 Size = 0;
155 setStrTab(SecTable.getSectionOfType<StringTableSection>(
156 Link,
157 "Symbol table has link index of " + Twine(Link) +
158 " which is not a valid index",
159 "Symbol table has link index of " + Twine(Link) +
160 " which is not a string table"));
161}
162
Petr Hosek79cee9e2017-08-29 02:12:03 +0000163void SymbolTableSection::finalize() {
164 // Make sure SymbolNames is finalized before getting name indexes.
165 SymbolNames->finalize();
166
167 uint32_t MaxLocalIndex = 0;
168 for (auto &Sym : Symbols) {
169 Sym->NameIndex = SymbolNames->findIndex(Sym->Name);
170 if (Sym->Binding == STB_LOCAL)
171 MaxLocalIndex = std::max(MaxLocalIndex, Sym->Index);
172 }
173 // Now we need to set the Link and Info fields.
174 Link = SymbolNames->Index;
175 Info = MaxLocalIndex + 1;
176}
177
178void SymbolTableSection::addSymbolNames() {
179 // Add all of our strings to SymbolNames so that SymbolNames has the right
180 // size before layout is decided.
181 for (auto &Sym : Symbols)
182 SymbolNames->addString(Sym->Name);
183}
184
185const Symbol *SymbolTableSection::getSymbolByIndex(uint32_t Index) const {
186 if (Symbols.size() <= Index)
187 error("Invalid symbol index: " + Twine(Index));
188 return Symbols[Index].get();
189}
190
191template <class ELFT>
192void SymbolTableSectionImpl<ELFT>::writeSection(
193 llvm::FileOutputBuffer &Out) const {
194 uint8_t *Buf = Out.getBufferStart();
195 Buf += Offset;
196 typename ELFT::Sym *Sym = reinterpret_cast<typename ELFT::Sym *>(Buf);
197 // Loop though symbols setting each entry of the symbol table.
198 for (auto &Symbol : Symbols) {
199 Sym->st_name = Symbol->NameIndex;
200 Sym->st_value = Symbol->Value;
201 Sym->st_size = Symbol->Size;
202 Sym->setBinding(Symbol->Binding);
203 Sym->setType(Symbol->Type);
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000204 Sym->st_shndx = Symbol->getShndx();
Petr Hosek79cee9e2017-08-29 02:12:03 +0000205 ++Sym;
206 }
207}
208
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000209template <class SymTabType>
210void RelocationSectionBase<SymTabType>::initialize(SectionTableRef SecTable) {
211 setSymTab(SecTable.getSectionOfType<SymTabType>(
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000212 Link,
213 "Link field value " + Twine(Link) + " in section " + Name + " is invalid",
214 "Link field value " + Twine(Link) + " in section " + Name +
215 " is not a symbol table"));
216
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000217 if (Info != SHN_UNDEF)
218 setSection(SecTable.getSection(Info,
219 "Info field value " + Twine(Info) +
220 " in section " + Name + " is invalid"));
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000221}
222
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000223template <class SymTabType> void RelocationSectionBase<SymTabType>::finalize() {
Petr Hosekd7df9b22017-09-06 23:41:02 +0000224 this->Link = Symbols->Index;
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000225 if (SecToApplyRel != nullptr)
226 this->Info = SecToApplyRel->Index;
Petr Hosekd7df9b22017-09-06 23:41:02 +0000227}
228
229template <class ELFT>
230void setAddend(Elf_Rel_Impl<ELFT, false> &Rel, uint64_t Addend) {}
231
232template <class ELFT>
233void setAddend(Elf_Rel_Impl<ELFT, true> &Rela, uint64_t Addend) {
234 Rela.r_addend = Addend;
235}
236
237template <class ELFT>
238template <class T>
239void RelocationSection<ELFT>::writeRel(T *Buf) const {
240 for (const auto &Reloc : Relocations) {
241 Buf->r_offset = Reloc.Offset;
242 setAddend(*Buf, Reloc.Addend);
243 Buf->setSymbolAndType(Reloc.RelocSymbol->Index, Reloc.Type, false);
244 ++Buf;
245 }
246}
247
248template <class ELFT>
249void RelocationSection<ELFT>::writeSection(llvm::FileOutputBuffer &Out) const {
250 uint8_t *Buf = Out.getBufferStart() + Offset;
251 if (Type == SHT_REL)
252 writeRel(reinterpret_cast<Elf_Rel *>(Buf));
253 else
254 writeRel(reinterpret_cast<Elf_Rela *>(Buf));
255}
256
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000257void DynamicRelocationSection::writeSection(llvm::FileOutputBuffer &Out) const {
258 std::copy(std::begin(Contents), std::end(Contents),
259 Out.getBufferStart() + Offset);
260}
261
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000262bool SectionWithStrTab::classof(const SectionBase *S) {
263 return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S);
264}
265
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000266void SectionWithStrTab::initialize(SectionTableRef SecTable) {
267 setStrTab(SecTable.getSectionOfType<StringTableSection>(
268 Link,
269 "Link field value " + Twine(Link) + " in section " + Name + " is invalid",
270 "Link field value " + Twine(Link) + " in section " + Name +
271 " is not a string table"));
272}
273
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000274void SectionWithStrTab::finalize() { this->Link = StrTab->Index; }
275
Petr Hosek05a04cb2017-08-01 00:33:58 +0000276// Returns true IFF a section is wholly inside the range of a segment
277static bool sectionWithinSegment(const SectionBase &Section,
278 const Segment &Segment) {
279 // If a section is empty it should be treated like it has a size of 1. This is
280 // to clarify the case when an empty section lies on a boundary between two
281 // segments and ensures that the section "belongs" to the second segment and
282 // not the first.
283 uint64_t SecSize = Section.Size ? Section.Size : 1;
284 return Segment.Offset <= Section.OriginalOffset &&
285 Segment.Offset + Segment.FileSize >= Section.OriginalOffset + SecSize;
286}
287
Jake Ehrlichd246b0a2017-09-19 21:37:35 +0000288// Returns true IFF a segment's original offset is inside of another segment's
289// range.
290static bool segmentOverlapsSegment(const Segment &Child,
291 const Segment &Parent) {
292
293 return Parent.OriginalOffset <= Child.OriginalOffset &&
294 Parent.OriginalOffset + Parent.FileSize > Child.OriginalOffset;
295}
296
Petr Hosek05a04cb2017-08-01 00:33:58 +0000297template <class ELFT>
298void Object<ELFT>::readProgramHeaders(const ELFFile<ELFT> &ElfFile) {
299 uint32_t Index = 0;
300 for (const auto &Phdr : unwrapOrError(ElfFile.program_headers())) {
Petr Hosekc4df10e2017-08-04 21:09:26 +0000301 ArrayRef<uint8_t> Data{ElfFile.base() + Phdr.p_offset,
302 (size_t)Phdr.p_filesz};
303 Segments.emplace_back(llvm::make_unique<Segment>(Data));
Petr Hosek05a04cb2017-08-01 00:33:58 +0000304 Segment &Seg = *Segments.back();
305 Seg.Type = Phdr.p_type;
306 Seg.Flags = Phdr.p_flags;
Petr Hosek3f383832017-08-26 01:32:20 +0000307 Seg.OriginalOffset = Phdr.p_offset;
Petr Hosek05a04cb2017-08-01 00:33:58 +0000308 Seg.Offset = Phdr.p_offset;
309 Seg.VAddr = Phdr.p_vaddr;
310 Seg.PAddr = Phdr.p_paddr;
311 Seg.FileSize = Phdr.p_filesz;
312 Seg.MemSize = Phdr.p_memsz;
313 Seg.Align = Phdr.p_align;
314 Seg.Index = Index++;
315 for (auto &Section : Sections) {
316 if (sectionWithinSegment(*Section, Seg)) {
317 Seg.addSection(&*Section);
318 if (!Section->ParentSegment ||
319 Section->ParentSegment->Offset > Seg.Offset) {
320 Section->ParentSegment = &Seg;
321 }
322 }
323 }
324 }
Jake Ehrlichd246b0a2017-09-19 21:37:35 +0000325 // Now we do an O(n^2) loop through the segments in order to match up
326 // segments.
327 for (auto &Child : Segments) {
328 for (auto &Parent : Segments) {
329 // Every segment will overlap with itself but we don't want a segment to
330 // be it's own parent so we avoid that situation.
331 if (&Child != &Parent && segmentOverlapsSegment(*Child, *Parent)) {
332 // We want a canonical "most parental" segment but this requires
333 // inspecting the ParentSegment.
334 if (Child->ParentSegment != nullptr) {
335 if (Child->ParentSegment->OriginalOffset > Parent->OriginalOffset) {
336 Child->ParentSegment = Parent.get();
337 } else if (Child->ParentSegment->Index > Parent->Index) {
338 // They must have equal OriginalOffsets so we need to disambiguate.
339 // To decide which is the parent we'll choose the one with the
340 // higher index.
341 Child->ParentSegment = Parent.get();
342 }
343 } else {
344 Child->ParentSegment = Parent.get();
345 }
346 }
347 }
348 }
Petr Hosek05a04cb2017-08-01 00:33:58 +0000349}
350
351template <class ELFT>
Petr Hosek79cee9e2017-08-29 02:12:03 +0000352void Object<ELFT>::initSymbolTable(const llvm::object::ELFFile<ELFT> &ElfFile,
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000353 SymbolTableSection *SymTab,
354 SectionTableRef SecTable) {
Petr Hosek79cee9e2017-08-29 02:12:03 +0000355
356 const Elf_Shdr &Shdr = *unwrapOrError(ElfFile.getSection(SymTab->Index));
357 StringRef StrTabData = unwrapOrError(ElfFile.getStringTableForSymtab(Shdr));
358
359 for (const auto &Sym : unwrapOrError(ElfFile.symbols(&Shdr))) {
360 SectionBase *DefSection = nullptr;
361 StringRef Name = unwrapOrError(Sym.getName(StrTabData));
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000362
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000363 if (Sym.st_shndx >= SHN_LORESERVE) {
Petr Hosekc1135772017-09-13 03:04:50 +0000364 if (!isValidReservedSectionIndex(Sym.st_shndx, Machine)) {
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000365 error(
366 "Symbol '" + Name +
367 "' has unsupported value greater than or equal to SHN_LORESERVE: " +
368 Twine(Sym.st_shndx));
369 }
370 } else if (Sym.st_shndx != SHN_UNDEF) {
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000371 DefSection = SecTable.getSection(
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000372 Sym.st_shndx,
373 "Symbol '" + Name + "' is defined in invalid section with index " +
Petr Hosek79cee9e2017-08-29 02:12:03 +0000374 Twine(Sym.st_shndx));
Petr Hosek79cee9e2017-08-29 02:12:03 +0000375 }
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000376
Petr Hosek79cee9e2017-08-29 02:12:03 +0000377 SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
Petr Hosekec2b3fc2017-09-07 23:02:50 +0000378 Sym.getValue(), Sym.st_shndx, Sym.st_size);
Petr Hosek79cee9e2017-08-29 02:12:03 +0000379 }
380}
381
382template <class ELFT>
Petr Hosekd7df9b22017-09-06 23:41:02 +0000383static void getAddend(uint64_t &ToSet, const Elf_Rel_Impl<ELFT, false> &Rel) {}
384
385template <class ELFT>
386static void getAddend(uint64_t &ToSet, const Elf_Rel_Impl<ELFT, true> &Rela) {
387 ToSet = Rela.r_addend;
388}
389
390template <class ELFT, class T>
391void initRelocations(RelocationSection<ELFT> *Relocs,
392 SymbolTableSection *SymbolTable, T RelRange) {
393 for (const auto &Rel : RelRange) {
394 Relocation ToAdd;
395 ToAdd.Offset = Rel.r_offset;
396 getAddend(ToAdd.Addend, Rel);
397 ToAdd.Type = Rel.getType(false);
398 ToAdd.RelocSymbol = SymbolTable->getSymbolByIndex(Rel.getSymbol(false));
399 Relocs->addRelocation(ToAdd);
400 }
401}
402
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000403SectionBase *SectionTableRef::getSection(uint16_t Index, Twine ErrMsg) {
404 if (Index == SHN_UNDEF || Index > Sections.size())
405 error(ErrMsg);
406 return Sections[Index - 1].get();
407}
408
409template <class T>
410T *SectionTableRef::getSectionOfType(uint16_t Index, Twine IndexErrMsg,
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000411 Twine TypeErrMsg) {
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000412 if (T *Sec = llvm::dyn_cast<T>(getSection(Index, IndexErrMsg)))
413 return Sec;
414 error(TypeErrMsg);
415}
416
Petr Hosekd7df9b22017-09-06 23:41:02 +0000417template <class ELFT>
Petr Hosek05a04cb2017-08-01 00:33:58 +0000418std::unique_ptr<SectionBase>
419Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
420 const Elf_Shdr &Shdr) {
421 ArrayRef<uint8_t> Data;
422 switch (Shdr.sh_type) {
Petr Hosekd7df9b22017-09-06 23:41:02 +0000423 case SHT_REL:
424 case SHT_RELA:
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000425 if (Shdr.sh_flags & SHF_ALLOC) {
426 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
427 return llvm::make_unique<DynamicRelocationSection>(Data);
428 }
Petr Hosekd7df9b22017-09-06 23:41:02 +0000429 return llvm::make_unique<RelocationSection<ELFT>>();
Petr Hosek05a04cb2017-08-01 00:33:58 +0000430 case SHT_STRTAB:
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000431 // If a string table is allocated we don't want to mess with it. That would
432 // mean altering the memory image. There are no special link types or
433 // anything so we can just use a Section.
434 if (Shdr.sh_flags & SHF_ALLOC) {
435 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
436 return llvm::make_unique<Section>(Data);
437 }
Petr Hosek05a04cb2017-08-01 00:33:58 +0000438 return llvm::make_unique<StringTableSection>();
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000439 case SHT_HASH:
440 case SHT_GNU_HASH:
441 // Hash tables should refer to SHT_DYNSYM which we're not going to change.
442 // Because of this we don't need to mess with the hash tables either.
443 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
444 return llvm::make_unique<Section>(Data);
445 case SHT_DYNSYM:
446 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
447 return llvm::make_unique<DynamicSymbolTableSection>(Data);
448 case SHT_DYNAMIC:
449 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
450 return llvm::make_unique<DynamicSection>(Data);
Petr Hosek79cee9e2017-08-29 02:12:03 +0000451 case SHT_SYMTAB: {
452 auto SymTab = llvm::make_unique<SymbolTableSectionImpl<ELFT>>();
453 SymbolTable = SymTab.get();
454 return std::move(SymTab);
455 }
Petr Hosek05a04cb2017-08-01 00:33:58 +0000456 case SHT_NOBITS:
457 return llvm::make_unique<Section>(Data);
458 default:
459 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
460 return llvm::make_unique<Section>(Data);
Petr Hosekc4df10e2017-08-04 21:09:26 +0000461 }
Petr Hosek05a04cb2017-08-01 00:33:58 +0000462}
463
464template <class ELFT>
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000465SectionTableRef Object<ELFT>::readSectionHeaders(const ELFFile<ELFT> &ElfFile) {
Petr Hosek05a04cb2017-08-01 00:33:58 +0000466 uint32_t Index = 0;
467 for (const auto &Shdr : unwrapOrError(ElfFile.sections())) {
468 if (Index == 0) {
469 ++Index;
470 continue;
471 }
472 SecPtr Sec = makeSection(ElfFile, Shdr);
473 Sec->Name = unwrapOrError(ElfFile.getSectionName(&Shdr));
474 Sec->Type = Shdr.sh_type;
475 Sec->Flags = Shdr.sh_flags;
476 Sec->Addr = Shdr.sh_addr;
477 Sec->Offset = Shdr.sh_offset;
478 Sec->OriginalOffset = Shdr.sh_offset;
479 Sec->Size = Shdr.sh_size;
480 Sec->Link = Shdr.sh_link;
481 Sec->Info = Shdr.sh_info;
482 Sec->Align = Shdr.sh_addralign;
483 Sec->EntrySize = Shdr.sh_entsize;
484 Sec->Index = Index++;
485 Sections.push_back(std::move(Sec));
486 }
Petr Hosek79cee9e2017-08-29 02:12:03 +0000487
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000488 SectionTableRef SecTable(Sections);
489
Petr Hosek79cee9e2017-08-29 02:12:03 +0000490 // Now that all of the sections have been added we can fill out some extra
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000491 // details about symbol tables. We need the symbol table filled out before
492 // any relocations.
493 if (SymbolTable) {
494 SymbolTable->initialize(SecTable);
495 initSymbolTable(ElfFile, SymbolTable, SecTable);
496 }
Petr Hosekd7df9b22017-09-06 23:41:02 +0000497
498 // Now that all sections and symbols have been added we can add
499 // relocations that reference symbols and set the link and info fields for
500 // relocation sections.
501 for (auto &Section : Sections) {
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000502 if (Section.get() == SymbolTable)
503 continue;
504 Section->initialize(SecTable);
Petr Hosekd7df9b22017-09-06 23:41:02 +0000505 if (auto RelSec = dyn_cast<RelocationSection<ELFT>>(Section.get())) {
Petr Hosekd7df9b22017-09-06 23:41:02 +0000506 auto Shdr = unwrapOrError(ElfFile.sections()).begin() + RelSec->Index;
507 if (RelSec->Type == SHT_REL)
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000508 initRelocations(RelSec, SymbolTable, unwrapOrError(ElfFile.rels(Shdr)));
Petr Hosekd7df9b22017-09-06 23:41:02 +0000509 else
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000510 initRelocations(RelSec, SymbolTable,
511 unwrapOrError(ElfFile.relas(Shdr)));
Petr Hosekd7df9b22017-09-06 23:41:02 +0000512 }
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000513
514 if (auto Sec = dyn_cast<SectionWithStrTab>(Section.get())) {
Jake Ehrlich9f1a3902017-09-26 18:02:25 +0000515 Sec->setStrTab(SecTable.getSectionOfType<StringTableSection>(
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000516 Sec->Link,
517 "Link field value " + Twine(Sec->Link) + " in section " + Sec->Name +
518 " is invalid",
519 "Link field value " + Twine(Sec->Link) + " in section " + Sec->Name +
520 " is not a string table"));
521 }
Petr Hosekd7df9b22017-09-06 23:41:02 +0000522 }
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000523
524 return SecTable;
Petr Hosek05a04cb2017-08-01 00:33:58 +0000525}
526
Petr Hosek05a04cb2017-08-01 00:33:58 +0000527template <class ELFT> Object<ELFT>::Object(const ELFObjectFile<ELFT> &Obj) {
528 const auto &ElfFile = *Obj.getELFFile();
529 const auto &Ehdr = *ElfFile.getHeader();
530
531 std::copy(Ehdr.e_ident, Ehdr.e_ident + 16, Ident);
532 Type = Ehdr.e_type;
533 Machine = Ehdr.e_machine;
534 Version = Ehdr.e_version;
535 Entry = Ehdr.e_entry;
536 Flags = Ehdr.e_flags;
537
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000538 SectionTableRef SecTable = readSectionHeaders(ElfFile);
Petr Hosek05a04cb2017-08-01 00:33:58 +0000539 readProgramHeaders(ElfFile);
540
Jake Ehrlichf5a43772017-09-25 20:37:28 +0000541 SectionNames = SecTable.getSectionOfType<StringTableSection>(
Jake Ehrliche5d424b2017-09-20 17:11:58 +0000542 Ehdr.e_shstrndx,
543 "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) + " in elf header " +
544 " is invalid",
545 "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) + " in elf header " +
546 " is not a string table");
Petr Hosek05a04cb2017-08-01 00:33:58 +0000547}
548
Petr Hosek05a04cb2017-08-01 00:33:58 +0000549template <class ELFT>
550void Object<ELFT>::writeHeader(FileOutputBuffer &Out) const {
551 uint8_t *Buf = Out.getBufferStart();
552 Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf);
553 std::copy(Ident, Ident + 16, Ehdr.e_ident);
554 Ehdr.e_type = Type;
555 Ehdr.e_machine = Machine;
556 Ehdr.e_version = Version;
557 Ehdr.e_entry = Entry;
558 Ehdr.e_phoff = sizeof(Elf_Ehdr);
559 Ehdr.e_shoff = SHOffset;
560 Ehdr.e_flags = Flags;
561 Ehdr.e_ehsize = sizeof(Elf_Ehdr);
562 Ehdr.e_phentsize = sizeof(Elf_Phdr);
563 Ehdr.e_phnum = Segments.size();
564 Ehdr.e_shentsize = sizeof(Elf_Shdr);
565 Ehdr.e_shnum = Sections.size() + 1;
566 Ehdr.e_shstrndx = SectionNames->Index;
567}
568
569template <class ELFT>
570void Object<ELFT>::writeProgramHeaders(FileOutputBuffer &Out) const {
571 for (auto &Phdr : Segments)
572 Phdr->template writeHeader<ELFT>(Out);
573}
574
575template <class ELFT>
576void Object<ELFT>::writeSectionHeaders(FileOutputBuffer &Out) const {
577 uint8_t *Buf = Out.getBufferStart() + SHOffset;
578 // This reference serves to write the dummy section header at the begining
Jake Ehrlich425ec9f2017-09-15 22:04:09 +0000579 // of the file. It is not used for anything else
Petr Hosek05a04cb2017-08-01 00:33:58 +0000580 Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(Buf);
581 Shdr.sh_name = 0;
582 Shdr.sh_type = SHT_NULL;
583 Shdr.sh_flags = 0;
584 Shdr.sh_addr = 0;
585 Shdr.sh_offset = 0;
586 Shdr.sh_size = 0;
587 Shdr.sh_link = 0;
588 Shdr.sh_info = 0;
589 Shdr.sh_addralign = 0;
590 Shdr.sh_entsize = 0;
591
592 for (auto &Section : Sections)
593 Section->template writeHeader<ELFT>(Out);
594}
595
596template <class ELFT>
597void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const {
598 for (auto &Section : Sections)
599 Section->writeSection(Out);
600}
601
Petr Hosekc4df10e2017-08-04 21:09:26 +0000602template <class ELFT> void ELFObject<ELFT>::sortSections() {
603 // Put all sections in offset order. Maintain the ordering as closely as
604 // possible while meeting that demand however.
605 auto CompareSections = [](const SecPtr &A, const SecPtr &B) {
606 return A->OriginalOffset < B->OriginalOffset;
607 };
608 std::stable_sort(std::begin(this->Sections), std::end(this->Sections),
609 CompareSections);
610}
611
612template <class ELFT> void ELFObject<ELFT>::assignOffsets() {
Jake Ehrlichd246b0a2017-09-19 21:37:35 +0000613 // We need a temporary list of segments that has a special order to it
614 // so that we know that anytime ->ParentSegment is set that segment has
615 // already had it's offset properly set.
616 std::vector<Segment *> OrderedSegments;
617 for (auto &Segment : this->Segments)
618 OrderedSegments.push_back(Segment.get());
619 auto CompareSegments = [](const Segment *A, const Segment *B) {
620 // Any segment without a parent segment should come before a segment
621 // that has a parent segment.
622 if (A->OriginalOffset < B->OriginalOffset)
623 return true;
624 if (A->OriginalOffset > B->OriginalOffset)
625 return false;
626 return A->Index < B->Index;
627 };
628 std::stable_sort(std::begin(OrderedSegments), std::end(OrderedSegments),
629 CompareSegments);
Petr Hosek3f383832017-08-26 01:32:20 +0000630 // The size of ELF + program headers will not change so it is ok to assume
631 // that the first offset of the first segment is a good place to start
632 // outputting sections. This covers both the standard case and the PT_PHDR
633 // case.
634 uint64_t Offset;
Jake Ehrlichd246b0a2017-09-19 21:37:35 +0000635 if (!OrderedSegments.empty()) {
636 Offset = OrderedSegments[0]->Offset;
Petr Hosek3f383832017-08-26 01:32:20 +0000637 } else {
638 Offset = sizeof(Elf_Ehdr);
Petr Hosekc4df10e2017-08-04 21:09:26 +0000639 }
Petr Hosek3f383832017-08-26 01:32:20 +0000640 // The only way a segment should move is if a section was between two
641 // segments and that section was removed. If that section isn't in a segment
642 // then it's acceptable, but not ideal, to simply move it to after the
643 // segments. So we can simply layout segments one after the other accounting
644 // for alignment.
Jake Ehrlichd246b0a2017-09-19 21:37:35 +0000645 for (auto &Segment : OrderedSegments) {
646 // We assume that segments have been ordered by OriginalOffset and Index
647 // such that a parent segment will always come before a child segment in
648 // OrderedSegments. This means that the Offset of the ParentSegment should
649 // already be set and we can set our offset relative to it.
650 if (Segment->ParentSegment != nullptr) {
651 auto Parent = Segment->ParentSegment;
652 Segment->Offset =
653 Parent->Offset + Segment->OriginalOffset - Parent->OriginalOffset;
654 } else {
655 Offset = alignTo(Offset, Segment->Align == 0 ? 1 : Segment->Align);
656 Segment->Offset = Offset;
657 Offset += Segment->FileSize;
658 }
Petr Hosek3f383832017-08-26 01:32:20 +0000659 }
660 // Now the offset of every segment has been set we can assign the offsets
661 // of each section. For sections that are covered by a segment we should use
662 // the segment's original offset and the section's original offset to compute
663 // the offset from the start of the segment. Using the offset from the start
664 // of the segment we can assign a new offset to the section. For sections not
665 // covered by segments we can just bump Offset to the next valid location.
666 uint32_t Index = 1;
667 for (auto &Section : this->Sections) {
668 Section->Index = Index++;
669 if (Section->ParentSegment != nullptr) {
670 auto Segment = Section->ParentSegment;
671 Section->Offset =
672 Segment->Offset + (Section->OriginalOffset - Segment->OriginalOffset);
673 } else {
674 Offset = alignTo(Offset, Section->Offset);
675 Section->Offset = Offset;
676 if (Section->Type != SHT_NOBITS)
677 Offset += Section->Size;
678 }
679 }
680
Petr Hosekc4df10e2017-08-04 21:09:26 +0000681 Offset = alignTo(Offset, sizeof(typename ELFT::Addr));
682 this->SHOffset = Offset;
683}
684
685template <class ELFT> size_t ELFObject<ELFT>::totalSize() const {
686 // We already have the section header offset so we can calculate the total
687 // size by just adding up the size of each section header.
688 return this->SHOffset + this->Sections.size() * sizeof(Elf_Shdr) +
689 sizeof(Elf_Shdr);
690}
691
692template <class ELFT> void ELFObject<ELFT>::write(FileOutputBuffer &Out) const {
693 this->writeHeader(Out);
694 this->writeProgramHeaders(Out);
695 this->writeSectionData(Out);
696 this->writeSectionHeaders(Out);
697}
698
699template <class ELFT> void ELFObject<ELFT>::finalize() {
Petr Hosek79cee9e2017-08-29 02:12:03 +0000700 // Make sure we add the names of all the sections.
Petr Hosekc4df10e2017-08-04 21:09:26 +0000701 for (const auto &Section : this->Sections) {
702 this->SectionNames->addString(Section->Name);
703 }
Petr Hosek79cee9e2017-08-29 02:12:03 +0000704 // Make sure we add the names of all the symbols.
705 this->SymbolTable->addSymbolNames();
Petr Hosekc4df10e2017-08-04 21:09:26 +0000706
707 sortSections();
708 assignOffsets();
709
710 // Finalize SectionNames first so that we can assign name indexes.
711 this->SectionNames->finalize();
712 // Finally now that all offsets and indexes have been set we can finalize any
713 // remaining issues.
714 uint64_t Offset = this->SHOffset + sizeof(Elf_Shdr);
715 for (auto &Section : this->Sections) {
716 Section->HeaderOffset = Offset;
717 Offset += sizeof(Elf_Shdr);
718 Section->NameIndex = this->SectionNames->findIndex(Section->Name);
719 Section->finalize();
720 }
721
722 for (auto &Segment : this->Segments)
723 Segment->finalize();
724}
725
726template <class ELFT> size_t BinaryObject<ELFT>::totalSize() const {
727 return TotalSize;
728}
729
730template <class ELFT>
731void BinaryObject<ELFT>::write(FileOutputBuffer &Out) const {
732 for (auto &Segment : this->Segments) {
Petr Hosekd53951d2017-08-04 23:18:18 +0000733 // GNU objcopy does not output segments that do not cover a section. Such
734 // segments can sometimes be produced by LLD due to how LLD handles PT_PHDR.
735 if (Segment->Type == llvm::ELF::PT_LOAD &&
736 Segment->firstSection() != nullptr) {
Petr Hosekc4df10e2017-08-04 21:09:26 +0000737 Segment->writeSegment(Out);
738 }
739 }
740}
741
742template <class ELFT> void BinaryObject<ELFT>::finalize() {
743 for (auto &Segment : this->Segments)
744 Segment->finalize();
745
746 // Put all segments in offset order.
747 auto CompareSegments = [](const SegPtr &A, const SegPtr &B) {
748 return A->Offset < B->Offset;
749 };
750 std::sort(std::begin(this->Segments), std::end(this->Segments),
751 CompareSegments);
752
753 uint64_t Offset = 0;
754 for (auto &Segment : this->Segments) {
Petr Hosekd53951d2017-08-04 23:18:18 +0000755 if (Segment->Type == llvm::ELF::PT_LOAD &&
756 Segment->firstSection() != nullptr) {
Petr Hosekc4df10e2017-08-04 21:09:26 +0000757 Offset = alignTo(Offset, Segment->Align);
758 Segment->Offset = Offset;
759 Offset += Segment->FileSize;
760 }
761 }
762 TotalSize = Offset;
Petr Hosek05a04cb2017-08-01 00:33:58 +0000763}
764
Petr Hosek35fdbd52017-08-01 05:31:50 +0000765template class Object<ELF64LE>;
766template class Object<ELF64BE>;
767template class Object<ELF32LE>;
768template class Object<ELF32BE>;
Petr Hosekc4df10e2017-08-04 21:09:26 +0000769
770template class ELFObject<ELF64LE>;
771template class ELFObject<ELF64BE>;
772template class ELFObject<ELF32LE>;
773template class ELFObject<ELF32BE>;
774
775template class BinaryObject<ELF64LE>;
776template class BinaryObject<ELF64BE>;
777template class BinaryObject<ELF32LE>;
778template class BinaryObject<ELF32BE>;