blob: 7738171d4e81fcf4788a808a61f3919c621c394a [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
Petr Hosek05a04cb2017-08-01 00:33:58 +000052void SectionBase::finalize() {}
53
54template <class ELFT>
55void SectionBase::writeHeader(FileOutputBuffer &Out) const {
56 uint8_t *Buf = Out.getBufferStart();
57 Buf += HeaderOffset;
58 typename ELFT::Shdr &Shdr = *reinterpret_cast<typename ELFT::Shdr *>(Buf);
59 Shdr.sh_name = NameIndex;
60 Shdr.sh_type = Type;
61 Shdr.sh_flags = Flags;
62 Shdr.sh_addr = Addr;
63 Shdr.sh_offset = Offset;
64 Shdr.sh_size = Size;
65 Shdr.sh_link = Link;
66 Shdr.sh_info = Info;
67 Shdr.sh_addralign = Align;
68 Shdr.sh_entsize = EntrySize;
69}
70
71void Section::writeSection(FileOutputBuffer &Out) const {
72 if (Type == SHT_NOBITS)
73 return;
74 uint8_t *Buf = Out.getBufferStart() + Offset;
75 std::copy(std::begin(Contents), std::end(Contents), Buf);
76}
77
78void StringTableSection::addString(StringRef Name) {
79 StrTabBuilder.add(Name);
80 Size = StrTabBuilder.getSize();
81}
82
83uint32_t StringTableSection::findIndex(StringRef Name) const {
84 return StrTabBuilder.getOffset(Name);
85}
86
87void StringTableSection::finalize() { StrTabBuilder.finalize(); }
88
89void StringTableSection::writeSection(FileOutputBuffer &Out) const {
90 StrTabBuilder.write(Out.getBufferStart() + Offset);
91}
92
Petr Hosek79cee9e2017-08-29 02:12:03 +000093void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
94 SectionBase *DefinedIn, uint64_t Value,
95 uint64_t Sz) {
96 Symbol Sym;
97 Sym.Name = Name;
98 Sym.Binding = Bind;
99 Sym.Type = Type;
100 Sym.DefinedIn = DefinedIn;
101 Sym.Value = Value;
102 Sym.Size = Sz;
103 Sym.Index = Symbols.size();
104 Symbols.emplace_back(llvm::make_unique<Symbol>(Sym));
105 Size += this->EntrySize;
106}
107
108void SymbolTableSection::finalize() {
109 // Make sure SymbolNames is finalized before getting name indexes.
110 SymbolNames->finalize();
111
112 uint32_t MaxLocalIndex = 0;
113 for (auto &Sym : Symbols) {
114 Sym->NameIndex = SymbolNames->findIndex(Sym->Name);
115 if (Sym->Binding == STB_LOCAL)
116 MaxLocalIndex = std::max(MaxLocalIndex, Sym->Index);
117 }
118 // Now we need to set the Link and Info fields.
119 Link = SymbolNames->Index;
120 Info = MaxLocalIndex + 1;
121}
122
123void SymbolTableSection::addSymbolNames() {
124 // Add all of our strings to SymbolNames so that SymbolNames has the right
125 // size before layout is decided.
126 for (auto &Sym : Symbols)
127 SymbolNames->addString(Sym->Name);
128}
129
130const Symbol *SymbolTableSection::getSymbolByIndex(uint32_t Index) const {
131 if (Symbols.size() <= Index)
132 error("Invalid symbol index: " + Twine(Index));
133 return Symbols[Index].get();
134}
135
136template <class ELFT>
137void SymbolTableSectionImpl<ELFT>::writeSection(
138 llvm::FileOutputBuffer &Out) const {
139 uint8_t *Buf = Out.getBufferStart();
140 Buf += Offset;
141 typename ELFT::Sym *Sym = reinterpret_cast<typename ELFT::Sym *>(Buf);
142 // Loop though symbols setting each entry of the symbol table.
143 for (auto &Symbol : Symbols) {
144 Sym->st_name = Symbol->NameIndex;
145 Sym->st_value = Symbol->Value;
146 Sym->st_size = Symbol->Size;
147 Sym->setBinding(Symbol->Binding);
148 Sym->setType(Symbol->Type);
149 if (Symbol->DefinedIn)
150 Sym->st_shndx = Symbol->DefinedIn->Index;
151 else
152 Sym->st_shndx = SHN_UNDEF;
153 ++Sym;
154 }
155}
156
Petr Hosek05a04cb2017-08-01 00:33:58 +0000157// Returns true IFF a section is wholly inside the range of a segment
158static bool sectionWithinSegment(const SectionBase &Section,
159 const Segment &Segment) {
160 // If a section is empty it should be treated like it has a size of 1. This is
161 // to clarify the case when an empty section lies on a boundary between two
162 // segments and ensures that the section "belongs" to the second segment and
163 // not the first.
164 uint64_t SecSize = Section.Size ? Section.Size : 1;
165 return Segment.Offset <= Section.OriginalOffset &&
166 Segment.Offset + Segment.FileSize >= Section.OriginalOffset + SecSize;
167}
168
169template <class ELFT>
170void Object<ELFT>::readProgramHeaders(const ELFFile<ELFT> &ElfFile) {
171 uint32_t Index = 0;
172 for (const auto &Phdr : unwrapOrError(ElfFile.program_headers())) {
Petr Hosekc4df10e2017-08-04 21:09:26 +0000173 ArrayRef<uint8_t> Data{ElfFile.base() + Phdr.p_offset,
174 (size_t)Phdr.p_filesz};
175 Segments.emplace_back(llvm::make_unique<Segment>(Data));
Petr Hosek05a04cb2017-08-01 00:33:58 +0000176 Segment &Seg = *Segments.back();
177 Seg.Type = Phdr.p_type;
178 Seg.Flags = Phdr.p_flags;
Petr Hosek3f383832017-08-26 01:32:20 +0000179 Seg.OriginalOffset = Phdr.p_offset;
Petr Hosek05a04cb2017-08-01 00:33:58 +0000180 Seg.Offset = Phdr.p_offset;
181 Seg.VAddr = Phdr.p_vaddr;
182 Seg.PAddr = Phdr.p_paddr;
183 Seg.FileSize = Phdr.p_filesz;
184 Seg.MemSize = Phdr.p_memsz;
185 Seg.Align = Phdr.p_align;
186 Seg.Index = Index++;
187 for (auto &Section : Sections) {
188 if (sectionWithinSegment(*Section, Seg)) {
189 Seg.addSection(&*Section);
190 if (!Section->ParentSegment ||
191 Section->ParentSegment->Offset > Seg.Offset) {
192 Section->ParentSegment = &Seg;
193 }
194 }
195 }
196 }
197}
198
199template <class ELFT>
Petr Hosek79cee9e2017-08-29 02:12:03 +0000200void Object<ELFT>::initSymbolTable(const llvm::object::ELFFile<ELFT> &ElfFile,
201 SymbolTableSection *SymTab) {
202
203 SymTab->Size = 0;
204 if (SymbolTable->Link - 1 >= Sections.size())
205 error("Symbol table has link index of " + Twine(SymbolTable->Link) +
206 " which is not a valid index");
207
208 if (auto StrTab =
209 dyn_cast<StringTableSection>(Sections[SymbolTable->Link - 1].get()))
210 SymTab->setStrTab(StrTab);
211 else
212 error("Symbol table has link index of " + Twine(SymbolTable->Link) +
213 "which is not a string table");
214
215 const Elf_Shdr &Shdr = *unwrapOrError(ElfFile.getSection(SymTab->Index));
216 StringRef StrTabData = unwrapOrError(ElfFile.getStringTableForSymtab(Shdr));
217
218 for (const auto &Sym : unwrapOrError(ElfFile.symbols(&Shdr))) {
219 SectionBase *DefSection = nullptr;
220 StringRef Name = unwrapOrError(Sym.getName(StrTabData));
221 if (Sym.st_shndx != SHN_UNDEF) {
222 if (Sym.st_shndx >= Sections.size())
223 error("Symbol '" + Name +
224 "' is defined in invalid section with index " +
225 Twine(Sym.st_shndx));
226 DefSection = Sections[Sym.st_shndx - 1].get();
227 }
228 SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
229 Sym.getValue(), Sym.st_size);
230 }
231}
232
233template <class ELFT>
Petr Hosek05a04cb2017-08-01 00:33:58 +0000234std::unique_ptr<SectionBase>
235Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
236 const Elf_Shdr &Shdr) {
237 ArrayRef<uint8_t> Data;
238 switch (Shdr.sh_type) {
239 case SHT_STRTAB:
240 return llvm::make_unique<StringTableSection>();
Petr Hosek79cee9e2017-08-29 02:12:03 +0000241 case SHT_SYMTAB: {
242 auto SymTab = llvm::make_unique<SymbolTableSectionImpl<ELFT>>();
243 SymbolTable = SymTab.get();
244 return std::move(SymTab);
245 }
Petr Hosek05a04cb2017-08-01 00:33:58 +0000246 case SHT_NOBITS:
247 return llvm::make_unique<Section>(Data);
248 default:
249 Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
250 return llvm::make_unique<Section>(Data);
Petr Hosekc4df10e2017-08-04 21:09:26 +0000251 }
Petr Hosek05a04cb2017-08-01 00:33:58 +0000252}
253
254template <class ELFT>
255void Object<ELFT>::readSectionHeaders(const ELFFile<ELFT> &ElfFile) {
256 uint32_t Index = 0;
257 for (const auto &Shdr : unwrapOrError(ElfFile.sections())) {
258 if (Index == 0) {
259 ++Index;
260 continue;
261 }
262 SecPtr Sec = makeSection(ElfFile, Shdr);
263 Sec->Name = unwrapOrError(ElfFile.getSectionName(&Shdr));
264 Sec->Type = Shdr.sh_type;
265 Sec->Flags = Shdr.sh_flags;
266 Sec->Addr = Shdr.sh_addr;
267 Sec->Offset = Shdr.sh_offset;
268 Sec->OriginalOffset = Shdr.sh_offset;
269 Sec->Size = Shdr.sh_size;
270 Sec->Link = Shdr.sh_link;
271 Sec->Info = Shdr.sh_info;
272 Sec->Align = Shdr.sh_addralign;
273 Sec->EntrySize = Shdr.sh_entsize;
274 Sec->Index = Index++;
275 Sections.push_back(std::move(Sec));
276 }
Petr Hosek79cee9e2017-08-29 02:12:03 +0000277
278 // Now that all of the sections have been added we can fill out some extra
279 // details about symbol tables.
280 if (SymbolTable)
281 initSymbolTable(ElfFile, SymbolTable);
Petr Hosek05a04cb2017-08-01 00:33:58 +0000282}
283
Petr Hosek05a04cb2017-08-01 00:33:58 +0000284template <class ELFT> Object<ELFT>::Object(const ELFObjectFile<ELFT> &Obj) {
285 const auto &ElfFile = *Obj.getELFFile();
286 const auto &Ehdr = *ElfFile.getHeader();
287
288 std::copy(Ehdr.e_ident, Ehdr.e_ident + 16, Ident);
289 Type = Ehdr.e_type;
290 Machine = Ehdr.e_machine;
291 Version = Ehdr.e_version;
292 Entry = Ehdr.e_entry;
293 Flags = Ehdr.e_flags;
294
295 readSectionHeaders(ElfFile);
296 readProgramHeaders(ElfFile);
297
298 SectionNames =
299 dyn_cast<StringTableSection>(Sections[Ehdr.e_shstrndx - 1].get());
300}
301
Petr Hosek05a04cb2017-08-01 00:33:58 +0000302template <class ELFT>
303void Object<ELFT>::writeHeader(FileOutputBuffer &Out) const {
304 uint8_t *Buf = Out.getBufferStart();
305 Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf);
306 std::copy(Ident, Ident + 16, Ehdr.e_ident);
307 Ehdr.e_type = Type;
308 Ehdr.e_machine = Machine;
309 Ehdr.e_version = Version;
310 Ehdr.e_entry = Entry;
311 Ehdr.e_phoff = sizeof(Elf_Ehdr);
312 Ehdr.e_shoff = SHOffset;
313 Ehdr.e_flags = Flags;
314 Ehdr.e_ehsize = sizeof(Elf_Ehdr);
315 Ehdr.e_phentsize = sizeof(Elf_Phdr);
316 Ehdr.e_phnum = Segments.size();
317 Ehdr.e_shentsize = sizeof(Elf_Shdr);
318 Ehdr.e_shnum = Sections.size() + 1;
319 Ehdr.e_shstrndx = SectionNames->Index;
320}
321
322template <class ELFT>
323void Object<ELFT>::writeProgramHeaders(FileOutputBuffer &Out) const {
324 for (auto &Phdr : Segments)
325 Phdr->template writeHeader<ELFT>(Out);
326}
327
328template <class ELFT>
329void Object<ELFT>::writeSectionHeaders(FileOutputBuffer &Out) const {
330 uint8_t *Buf = Out.getBufferStart() + SHOffset;
331 // This reference serves to write the dummy section header at the begining
332 // of the file.
333 Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(Buf);
334 Shdr.sh_name = 0;
335 Shdr.sh_type = SHT_NULL;
336 Shdr.sh_flags = 0;
337 Shdr.sh_addr = 0;
338 Shdr.sh_offset = 0;
339 Shdr.sh_size = 0;
340 Shdr.sh_link = 0;
341 Shdr.sh_info = 0;
342 Shdr.sh_addralign = 0;
343 Shdr.sh_entsize = 0;
344
345 for (auto &Section : Sections)
346 Section->template writeHeader<ELFT>(Out);
347}
348
349template <class ELFT>
350void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const {
351 for (auto &Section : Sections)
352 Section->writeSection(Out);
353}
354
Petr Hosekc4df10e2017-08-04 21:09:26 +0000355template <class ELFT> void ELFObject<ELFT>::sortSections() {
356 // Put all sections in offset order. Maintain the ordering as closely as
357 // possible while meeting that demand however.
358 auto CompareSections = [](const SecPtr &A, const SecPtr &B) {
359 return A->OriginalOffset < B->OriginalOffset;
360 };
361 std::stable_sort(std::begin(this->Sections), std::end(this->Sections),
362 CompareSections);
363}
364
365template <class ELFT> void ELFObject<ELFT>::assignOffsets() {
Petr Hosek3f383832017-08-26 01:32:20 +0000366 // The size of ELF + program headers will not change so it is ok to assume
367 // that the first offset of the first segment is a good place to start
368 // outputting sections. This covers both the standard case and the PT_PHDR
369 // case.
370 uint64_t Offset;
371 if (!this->Segments.empty()) {
372 Offset = this->Segments[0]->Offset;
373 } else {
374 Offset = sizeof(Elf_Ehdr);
Petr Hosekc4df10e2017-08-04 21:09:26 +0000375 }
Petr Hosek3f383832017-08-26 01:32:20 +0000376 // The only way a segment should move is if a section was between two
377 // segments and that section was removed. If that section isn't in a segment
378 // then it's acceptable, but not ideal, to simply move it to after the
379 // segments. So we can simply layout segments one after the other accounting
380 // for alignment.
381 for (auto &Segment : this->Segments) {
382 Offset = alignTo(Offset, Segment->Align);
383 Segment->Offset = Offset;
384 Offset += Segment->FileSize;
385 }
386 // Now the offset of every segment has been set we can assign the offsets
387 // of each section. For sections that are covered by a segment we should use
388 // the segment's original offset and the section's original offset to compute
389 // the offset from the start of the segment. Using the offset from the start
390 // of the segment we can assign a new offset to the section. For sections not
391 // covered by segments we can just bump Offset to the next valid location.
392 uint32_t Index = 1;
393 for (auto &Section : this->Sections) {
394 Section->Index = Index++;
395 if (Section->ParentSegment != nullptr) {
396 auto Segment = Section->ParentSegment;
397 Section->Offset =
398 Segment->Offset + (Section->OriginalOffset - Segment->OriginalOffset);
399 } else {
400 Offset = alignTo(Offset, Section->Offset);
401 Section->Offset = Offset;
402 if (Section->Type != SHT_NOBITS)
403 Offset += Section->Size;
404 }
405 }
406
Petr Hosekc4df10e2017-08-04 21:09:26 +0000407 Offset = alignTo(Offset, sizeof(typename ELFT::Addr));
408 this->SHOffset = Offset;
409}
410
411template <class ELFT> size_t ELFObject<ELFT>::totalSize() const {
412 // We already have the section header offset so we can calculate the total
413 // size by just adding up the size of each section header.
414 return this->SHOffset + this->Sections.size() * sizeof(Elf_Shdr) +
415 sizeof(Elf_Shdr);
416}
417
418template <class ELFT> void ELFObject<ELFT>::write(FileOutputBuffer &Out) const {
419 this->writeHeader(Out);
420 this->writeProgramHeaders(Out);
421 this->writeSectionData(Out);
422 this->writeSectionHeaders(Out);
423}
424
425template <class ELFT> void ELFObject<ELFT>::finalize() {
Petr Hosek79cee9e2017-08-29 02:12:03 +0000426 // Make sure we add the names of all the sections.
Petr Hosekc4df10e2017-08-04 21:09:26 +0000427 for (const auto &Section : this->Sections) {
428 this->SectionNames->addString(Section->Name);
429 }
Petr Hosek79cee9e2017-08-29 02:12:03 +0000430 // Make sure we add the names of all the symbols.
431 this->SymbolTable->addSymbolNames();
Petr Hosekc4df10e2017-08-04 21:09:26 +0000432
433 sortSections();
434 assignOffsets();
435
436 // Finalize SectionNames first so that we can assign name indexes.
437 this->SectionNames->finalize();
438 // Finally now that all offsets and indexes have been set we can finalize any
439 // remaining issues.
440 uint64_t Offset = this->SHOffset + sizeof(Elf_Shdr);
441 for (auto &Section : this->Sections) {
442 Section->HeaderOffset = Offset;
443 Offset += sizeof(Elf_Shdr);
444 Section->NameIndex = this->SectionNames->findIndex(Section->Name);
445 Section->finalize();
446 }
447
448 for (auto &Segment : this->Segments)
449 Segment->finalize();
450}
451
452template <class ELFT> size_t BinaryObject<ELFT>::totalSize() const {
453 return TotalSize;
454}
455
456template <class ELFT>
457void BinaryObject<ELFT>::write(FileOutputBuffer &Out) const {
458 for (auto &Segment : this->Segments) {
Petr Hosekd53951d2017-08-04 23:18:18 +0000459 // GNU objcopy does not output segments that do not cover a section. Such
460 // segments can sometimes be produced by LLD due to how LLD handles PT_PHDR.
461 if (Segment->Type == llvm::ELF::PT_LOAD &&
462 Segment->firstSection() != nullptr) {
Petr Hosekc4df10e2017-08-04 21:09:26 +0000463 Segment->writeSegment(Out);
464 }
465 }
466}
467
468template <class ELFT> void BinaryObject<ELFT>::finalize() {
469 for (auto &Segment : this->Segments)
470 Segment->finalize();
471
472 // Put all segments in offset order.
473 auto CompareSegments = [](const SegPtr &A, const SegPtr &B) {
474 return A->Offset < B->Offset;
475 };
476 std::sort(std::begin(this->Segments), std::end(this->Segments),
477 CompareSegments);
478
479 uint64_t Offset = 0;
480 for (auto &Segment : this->Segments) {
Petr Hosekd53951d2017-08-04 23:18:18 +0000481 if (Segment->Type == llvm::ELF::PT_LOAD &&
482 Segment->firstSection() != nullptr) {
Petr Hosekc4df10e2017-08-04 21:09:26 +0000483 Offset = alignTo(Offset, Segment->Align);
484 Segment->Offset = Offset;
485 Offset += Segment->FileSize;
486 }
487 }
488 TotalSize = Offset;
Petr Hosek05a04cb2017-08-01 00:33:58 +0000489}
490
Petr Hosek35fdbd52017-08-01 05:31:50 +0000491template class Object<ELF64LE>;
492template class Object<ELF64BE>;
493template class Object<ELF32LE>;
494template class Object<ELF32BE>;
Petr Hosekc4df10e2017-08-04 21:09:26 +0000495
496template class ELFObject<ELF64LE>;
497template class ELFObject<ELF64BE>;
498template class ELFObject<ELF32LE>;
499template class ELFObject<ELF32BE>;
500
501template class BinaryObject<ELF64LE>;
502template class BinaryObject<ELF64BE>;
503template class BinaryObject<ELF32LE>;
504template class BinaryObject<ELF32BE>;