1 //===- Object.cpp ---------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "llvm-objcopy.h"
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/ADT/iterator_range.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/Object/ELFObjectFile.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/FileOutputBuffer.h"
29 using namespace object
;
32 template <class ELFT
> void Segment::writeHeader(FileOutputBuffer
&Out
) const {
33 using Elf_Ehdr
= typename
ELFT::Ehdr
;
34 using Elf_Phdr
= typename
ELFT::Phdr
;
36 uint8_t *Buf
= Out
.getBufferStart();
37 Buf
+= sizeof(Elf_Ehdr
) + Index
* sizeof(Elf_Phdr
);
38 Elf_Phdr
&Phdr
= *reinterpret_cast<Elf_Phdr
*>(Buf
);
41 Phdr
.p_offset
= Offset
;
44 Phdr
.p_filesz
= FileSize
;
45 Phdr
.p_memsz
= MemSize
;
49 void Segment::writeSegment(FileOutputBuffer
&Out
) const {
50 uint8_t *Buf
= Out
.getBufferStart() + Offset
;
51 // We want to maintain segments' interstitial data and contents exactly.
52 // This lets us just copy segments directly.
53 std::copy(std::begin(Contents
), std::end(Contents
), Buf
);
56 void SectionBase::removeSectionReferences(const SectionBase
*Sec
) {}
57 void SectionBase::initialize(SectionTableRef SecTable
) {}
58 void SectionBase::finalize() {}
61 void SectionBase::writeHeader(FileOutputBuffer
&Out
) const {
62 uint8_t *Buf
= Out
.getBufferStart();
64 typename
ELFT::Shdr
&Shdr
= *reinterpret_cast<typename
ELFT::Shdr
*>(Buf
);
65 Shdr
.sh_name
= NameIndex
;
67 Shdr
.sh_flags
= Flags
;
69 Shdr
.sh_offset
= Offset
;
73 Shdr
.sh_addralign
= Align
;
74 Shdr
.sh_entsize
= EntrySize
;
77 void Section::writeSection(FileOutputBuffer
&Out
) const {
78 if (Type
== SHT_NOBITS
)
80 uint8_t *Buf
= Out
.getBufferStart() + Offset
;
81 std::copy(std::begin(Contents
), std::end(Contents
), Buf
);
84 void StringTableSection::addString(StringRef Name
) {
85 StrTabBuilder
.add(Name
);
86 Size
= StrTabBuilder
.getSize();
89 uint32_t StringTableSection::findIndex(StringRef Name
) const {
90 return StrTabBuilder
.getOffset(Name
);
93 void StringTableSection::finalize() { StrTabBuilder
.finalize(); }
95 void StringTableSection::writeSection(FileOutputBuffer
&Out
) const {
96 StrTabBuilder
.write(Out
.getBufferStart() + Offset
);
99 static bool isValidReservedSectionIndex(uint16_t Index
, uint16_t Machine
) {
105 if (Machine
== EM_HEXAGON
) {
107 case SHN_HEXAGON_SCOMMON
:
108 case SHN_HEXAGON_SCOMMON_2
:
109 case SHN_HEXAGON_SCOMMON_4
:
110 case SHN_HEXAGON_SCOMMON_8
:
117 uint16_t Symbol::getShndx() const {
118 if (DefinedIn
!= nullptr) {
119 return DefinedIn
->Index
;
122 // This means that we don't have a defined section but we do need to
123 // output a legitimate section index.
124 case SYMBOL_SIMPLE_INDEX
:
128 case SYMBOL_HEXAGON_SCOMMON
:
129 case SYMBOL_HEXAGON_SCOMMON_2
:
130 case SYMBOL_HEXAGON_SCOMMON_4
:
131 case SYMBOL_HEXAGON_SCOMMON_8
:
132 return static_cast<uint16_t>(ShndxType
);
134 llvm_unreachable("Symbol with invalid ShndxType encountered");
137 void SymbolTableSection::addSymbol(StringRef Name
, uint8_t Bind
, uint8_t Type
,
138 SectionBase
*DefinedIn
, uint64_t Value
,
139 uint16_t Shndx
, uint64_t Sz
) {
144 Sym
.DefinedIn
= DefinedIn
;
145 if (DefinedIn
== nullptr) {
146 if (Shndx
>= SHN_LORESERVE
)
147 Sym
.ShndxType
= static_cast<SymbolShndxType
>(Shndx
);
149 Sym
.ShndxType
= SYMBOL_SIMPLE_INDEX
;
153 Sym
.Index
= Symbols
.size();
154 Symbols
.emplace_back(llvm::make_unique
<Symbol
>(Sym
));
155 Size
+= this->EntrySize
;
158 void SymbolTableSection::removeSectionReferences(const SectionBase
*Sec
) {
159 if (SymbolNames
== Sec
) {
160 error("String table " + SymbolNames
->Name
+
161 " cannot be removed because it is referenced by the symbol table " +
165 std::remove_if(std::begin(Symbols
), std::end(Symbols
),
166 [=](const SymPtr
&Sym
) { return Sym
->DefinedIn
== Sec
; });
167 Size
-= (std::end(Symbols
) - Iter
) * this->EntrySize
;
168 Symbols
.erase(Iter
, std::end(Symbols
));
171 void SymbolTableSection::initialize(SectionTableRef SecTable
) {
173 setStrTab(SecTable
.getSectionOfType
<StringTableSection
>(
175 "Symbol table has link index of " + Twine(Link
) +
176 " which is not a valid index",
177 "Symbol table has link index of " + Twine(Link
) +
178 " which is not a string table"));
181 void SymbolTableSection::finalize() {
182 // Make sure SymbolNames is finalized before getting name indexes.
183 SymbolNames
->finalize();
185 uint32_t MaxLocalIndex
= 0;
186 for (auto &Sym
: Symbols
) {
187 Sym
->NameIndex
= SymbolNames
->findIndex(Sym
->Name
);
188 if (Sym
->Binding
== STB_LOCAL
)
189 MaxLocalIndex
= std::max(MaxLocalIndex
, Sym
->Index
);
191 // Now we need to set the Link and Info fields.
192 Link
= SymbolNames
->Index
;
193 Info
= MaxLocalIndex
+ 1;
196 void SymbolTableSection::addSymbolNames() {
197 // Add all of our strings to SymbolNames so that SymbolNames has the right
198 // size before layout is decided.
199 for (auto &Sym
: Symbols
)
200 SymbolNames
->addString(Sym
->Name
);
203 const Symbol
*SymbolTableSection::getSymbolByIndex(uint32_t Index
) const {
204 if (Symbols
.size() <= Index
)
205 error("Invalid symbol index: " + Twine(Index
));
206 return Symbols
[Index
].get();
209 template <class ELFT
>
210 void SymbolTableSectionImpl
<ELFT
>::writeSection(FileOutputBuffer
&Out
) const {
211 uint8_t *Buf
= Out
.getBufferStart();
213 typename
ELFT::Sym
*Sym
= reinterpret_cast<typename
ELFT::Sym
*>(Buf
);
214 // Loop though symbols setting each entry of the symbol table.
215 for (auto &Symbol
: Symbols
) {
216 Sym
->st_name
= Symbol
->NameIndex
;
217 Sym
->st_value
= Symbol
->Value
;
218 Sym
->st_size
= Symbol
->Size
;
219 Sym
->setBinding(Symbol
->Binding
);
220 Sym
->setType(Symbol
->Type
);
221 Sym
->st_shndx
= Symbol
->getShndx();
226 template <class SymTabType
>
227 void RelocSectionWithSymtabBase
<SymTabType
>::removeSectionReferences(
228 const SectionBase
*Sec
) {
229 if (Symbols
== Sec
) {
230 error("Symbol table " + Symbols
->Name
+
231 " cannot be removed because it is "
232 "referenced by the relocation "
238 template <class SymTabType
>
239 void RelocSectionWithSymtabBase
<SymTabType
>::initialize(
240 SectionTableRef SecTable
) {
241 setSymTab(SecTable
.getSectionOfType
<SymTabType
>(
243 "Link field value " + Twine(Link
) + " in section " + Name
+ " is invalid",
244 "Link field value " + Twine(Link
) + " in section " + Name
+
245 " is not a symbol table"));
247 if (Info
!= SHN_UNDEF
)
248 setSection(SecTable
.getSection(Info
, "Info field value " + Twine(Info
) +
249 " in section " + Name
+
255 template <class SymTabType
>
256 void RelocSectionWithSymtabBase
<SymTabType
>::finalize() {
257 this->Link
= Symbols
->Index
;
258 if (SecToApplyRel
!= nullptr)
259 this->Info
= SecToApplyRel
->Index
;
262 template <class ELFT
>
263 void setAddend(Elf_Rel_Impl
<ELFT
, false> &Rel
, uint64_t Addend
) {}
265 template <class ELFT
>
266 void setAddend(Elf_Rel_Impl
<ELFT
, true> &Rela
, uint64_t Addend
) {
267 Rela
.r_addend
= Addend
;
270 template <class ELFT
>
272 void RelocationSection
<ELFT
>::writeRel(T
*Buf
) const {
273 for (const auto &Reloc
: Relocations
) {
274 Buf
->r_offset
= Reloc
.Offset
;
275 setAddend(*Buf
, Reloc
.Addend
);
276 Buf
->setSymbolAndType(Reloc
.RelocSymbol
->Index
, Reloc
.Type
, false);
281 template <class ELFT
>
282 void RelocationSection
<ELFT
>::writeSection(FileOutputBuffer
&Out
) const {
283 uint8_t *Buf
= Out
.getBufferStart() + Offset
;
285 writeRel(reinterpret_cast<Elf_Rel
*>(Buf
));
287 writeRel(reinterpret_cast<Elf_Rela
*>(Buf
));
290 void DynamicRelocationSection::writeSection(FileOutputBuffer
&Out
) const {
291 std::copy(std::begin(Contents
), std::end(Contents
),
292 Out
.getBufferStart() + Offset
);
295 void SectionWithStrTab::removeSectionReferences(const SectionBase
*Sec
) {
297 error("String table " + StrTab
->Name
+
298 " cannot be removed because it is "
299 "referenced by the section " +
304 bool SectionWithStrTab::classof(const SectionBase
*S
) {
305 return isa
<DynamicSymbolTableSection
>(S
) || isa
<DynamicSection
>(S
);
308 void SectionWithStrTab::initialize(SectionTableRef SecTable
) {
310 SecTable
.getSection(Link
, "Link field value " + Twine(Link
) +
311 " in section " + Name
+ " is invalid");
312 if (StrTab
->Type
!= SHT_STRTAB
) {
313 error("Link field value " + Twine(Link
) + " in section " + Name
+
314 " is not a string table");
319 void SectionWithStrTab::finalize() { this->Link
= StrTab
->Index
; }
321 // Returns true IFF a section is wholly inside the range of a segment
322 static bool sectionWithinSegment(const SectionBase
&Section
,
323 const Segment
&Segment
) {
324 // If a section is empty it should be treated like it has a size of 1. This is
325 // to clarify the case when an empty section lies on a boundary between two
326 // segments and ensures that the section "belongs" to the second segment and
328 uint64_t SecSize
= Section
.Size
? Section
.Size
: 1;
329 return Segment
.Offset
<= Section
.OriginalOffset
&&
330 Segment
.Offset
+ Segment
.FileSize
>= Section
.OriginalOffset
+ SecSize
;
333 // Returns true IFF a segment's original offset is inside of another segment's
335 static bool segmentOverlapsSegment(const Segment
&Child
,
336 const Segment
&Parent
) {
338 return Parent
.OriginalOffset
<= Child
.OriginalOffset
&&
339 Parent
.OriginalOffset
+ Parent
.FileSize
> Child
.OriginalOffset
;
342 static bool compareSegments(const Segment
*A
, const Segment
*B
) {
343 // Any segment without a parent segment should come before a segment
344 // that has a parent segment.
345 if (A
->OriginalOffset
< B
->OriginalOffset
)
347 if (A
->OriginalOffset
> B
->OriginalOffset
)
349 return A
->Index
< B
->Index
;
352 template <class ELFT
>
353 void Object
<ELFT
>::readProgramHeaders(const ELFFile
<ELFT
> &ElfFile
) {
355 for (const auto &Phdr
: unwrapOrError(ElfFile
.program_headers())) {
356 ArrayRef
<uint8_t> Data
{ElfFile
.base() + Phdr
.p_offset
,
357 (size_t)Phdr
.p_filesz
};
358 Segments
.emplace_back(llvm::make_unique
<Segment
>(Data
));
359 Segment
&Seg
= *Segments
.back();
360 Seg
.Type
= Phdr
.p_type
;
361 Seg
.Flags
= Phdr
.p_flags
;
362 Seg
.OriginalOffset
= Phdr
.p_offset
;
363 Seg
.Offset
= Phdr
.p_offset
;
364 Seg
.VAddr
= Phdr
.p_vaddr
;
365 Seg
.PAddr
= Phdr
.p_paddr
;
366 Seg
.FileSize
= Phdr
.p_filesz
;
367 Seg
.MemSize
= Phdr
.p_memsz
;
368 Seg
.Align
= Phdr
.p_align
;
370 for (auto &Section
: Sections
) {
371 if (sectionWithinSegment(*Section
, Seg
)) {
372 Seg
.addSection(&*Section
);
373 if (!Section
->ParentSegment
||
374 Section
->ParentSegment
->Offset
> Seg
.Offset
) {
375 Section
->ParentSegment
= &Seg
;
380 // Now we do an O(n^2) loop through the segments in order to match up
382 for (auto &Child
: Segments
) {
383 for (auto &Parent
: Segments
) {
384 // Every segment will overlap with itself but we don't want a segment to
385 // be it's own parent so we avoid that situation.
386 if (&Child
!= &Parent
&& segmentOverlapsSegment(*Child
, *Parent
)) {
387 // We want a canonical "most parental" segment but this requires
388 // inspecting the ParentSegment.
389 if (compareSegments(Parent
.get(), Child
.get()))
390 if (Child
->ParentSegment
== nullptr ||
391 compareSegments(Parent
.get(), Child
->ParentSegment
)) {
392 Child
->ParentSegment
= Parent
.get();
399 template <class ELFT
>
400 void Object
<ELFT
>::initSymbolTable(const object::ELFFile
<ELFT
> &ElfFile
,
401 SymbolTableSection
*SymTab
,
402 SectionTableRef SecTable
) {
403 const Elf_Shdr
&Shdr
= *unwrapOrError(ElfFile
.getSection(SymTab
->Index
));
404 StringRef StrTabData
= unwrapOrError(ElfFile
.getStringTableForSymtab(Shdr
));
406 for (const auto &Sym
: unwrapOrError(ElfFile
.symbols(&Shdr
))) {
407 SectionBase
*DefSection
= nullptr;
408 StringRef Name
= unwrapOrError(Sym
.getName(StrTabData
));
410 if (Sym
.st_shndx
>= SHN_LORESERVE
) {
411 if (!isValidReservedSectionIndex(Sym
.st_shndx
, Machine
)) {
414 "' has unsupported value greater than or equal to SHN_LORESERVE: " +
415 Twine(Sym
.st_shndx
));
417 } else if (Sym
.st_shndx
!= SHN_UNDEF
) {
418 DefSection
= SecTable
.getSection(
419 Sym
.st_shndx
, "Symbol '" + Name
+
420 "' is defined in invalid section with index " +
421 Twine(Sym
.st_shndx
));
424 SymTab
->addSymbol(Name
, Sym
.getBinding(), Sym
.getType(), DefSection
,
425 Sym
.getValue(), Sym
.st_shndx
, Sym
.st_size
);
429 template <class ELFT
>
430 static void getAddend(uint64_t &ToSet
, const Elf_Rel_Impl
<ELFT
, false> &Rel
) {}
432 template <class ELFT
>
433 static void getAddend(uint64_t &ToSet
, const Elf_Rel_Impl
<ELFT
, true> &Rela
) {
434 ToSet
= Rela
.r_addend
;
437 template <class ELFT
, class T
>
438 void initRelocations(RelocationSection
<ELFT
> *Relocs
,
439 SymbolTableSection
*SymbolTable
, T RelRange
) {
440 for (const auto &Rel
: RelRange
) {
442 ToAdd
.Offset
= Rel
.r_offset
;
443 getAddend(ToAdd
.Addend
, Rel
);
444 ToAdd
.Type
= Rel
.getType(false);
445 ToAdd
.RelocSymbol
= SymbolTable
->getSymbolByIndex(Rel
.getSymbol(false));
446 Relocs
->addRelocation(ToAdd
);
450 SectionBase
*SectionTableRef::getSection(uint16_t Index
, Twine ErrMsg
) {
451 if (Index
== SHN_UNDEF
|| Index
> Sections
.size())
453 return Sections
[Index
- 1].get();
457 T
*SectionTableRef::getSectionOfType(uint16_t Index
, Twine IndexErrMsg
,
459 if (T
*Sec
= dyn_cast
<T
>(getSection(Index
, IndexErrMsg
)))
464 template <class ELFT
>
465 std::unique_ptr
<SectionBase
>
466 Object
<ELFT
>::makeSection(const object::ELFFile
<ELFT
> &ElfFile
,
467 const Elf_Shdr
&Shdr
) {
468 ArrayRef
<uint8_t> Data
;
469 switch (Shdr
.sh_type
) {
472 if (Shdr
.sh_flags
& SHF_ALLOC
) {
473 Data
= unwrapOrError(ElfFile
.getSectionContents(&Shdr
));
474 return llvm::make_unique
<DynamicRelocationSection
>(Data
);
476 return llvm::make_unique
<RelocationSection
<ELFT
>>();
478 // If a string table is allocated we don't want to mess with it. That would
479 // mean altering the memory image. There are no special link types or
480 // anything so we can just use a Section.
481 if (Shdr
.sh_flags
& SHF_ALLOC
) {
482 Data
= unwrapOrError(ElfFile
.getSectionContents(&Shdr
));
483 return llvm::make_unique
<Section
>(Data
);
485 return llvm::make_unique
<StringTableSection
>();
488 // Hash tables should refer to SHT_DYNSYM which we're not going to change.
489 // Because of this we don't need to mess with the hash tables either.
490 Data
= unwrapOrError(ElfFile
.getSectionContents(&Shdr
));
491 return llvm::make_unique
<Section
>(Data
);
493 Data
= unwrapOrError(ElfFile
.getSectionContents(&Shdr
));
494 return llvm::make_unique
<DynamicSymbolTableSection
>(Data
);
496 Data
= unwrapOrError(ElfFile
.getSectionContents(&Shdr
));
497 return llvm::make_unique
<DynamicSection
>(Data
);
499 auto SymTab
= llvm::make_unique
<SymbolTableSectionImpl
<ELFT
>>();
500 SymbolTable
= SymTab
.get();
501 return std::move(SymTab
);
504 return llvm::make_unique
<Section
>(Data
);
506 Data
= unwrapOrError(ElfFile
.getSectionContents(&Shdr
));
507 return llvm::make_unique
<Section
>(Data
);
511 template <class ELFT
>
512 SectionTableRef Object
<ELFT
>::readSectionHeaders(const ELFFile
<ELFT
> &ElfFile
) {
514 for (const auto &Shdr
: unwrapOrError(ElfFile
.sections())) {
519 SecPtr Sec
= makeSection(ElfFile
, Shdr
);
520 Sec
->Name
= unwrapOrError(ElfFile
.getSectionName(&Shdr
));
521 Sec
->Type
= Shdr
.sh_type
;
522 Sec
->Flags
= Shdr
.sh_flags
;
523 Sec
->Addr
= Shdr
.sh_addr
;
524 Sec
->Offset
= Shdr
.sh_offset
;
525 Sec
->OriginalOffset
= Shdr
.sh_offset
;
526 Sec
->Size
= Shdr
.sh_size
;
527 Sec
->Link
= Shdr
.sh_link
;
528 Sec
->Info
= Shdr
.sh_info
;
529 Sec
->Align
= Shdr
.sh_addralign
;
530 Sec
->EntrySize
= Shdr
.sh_entsize
;
531 Sec
->Index
= Index
++;
532 Sections
.push_back(std::move(Sec
));
535 SectionTableRef
SecTable(Sections
);
537 // Now that all of the sections have been added we can fill out some extra
538 // details about symbol tables. We need the symbol table filled out before
541 SymbolTable
->initialize(SecTable
);
542 initSymbolTable(ElfFile
, SymbolTable
, SecTable
);
545 // Now that all sections and symbols have been added we can add
546 // relocations that reference symbols and set the link and info fields for
547 // relocation sections.
548 for (auto &Section
: Sections
) {
549 if (Section
.get() == SymbolTable
)
551 Section
->initialize(SecTable
);
552 if (auto RelSec
= dyn_cast
<RelocationSection
<ELFT
>>(Section
.get())) {
553 auto Shdr
= unwrapOrError(ElfFile
.sections()).begin() + RelSec
->Index
;
554 if (RelSec
->Type
== SHT_REL
)
555 initRelocations(RelSec
, SymbolTable
, unwrapOrError(ElfFile
.rels(Shdr
)));
557 initRelocations(RelSec
, SymbolTable
,
558 unwrapOrError(ElfFile
.relas(Shdr
)));
565 template <class ELFT
> Object
<ELFT
>::Object(const ELFObjectFile
<ELFT
> &Obj
) {
566 const auto &ElfFile
= *Obj
.getELFFile();
567 const auto &Ehdr
= *ElfFile
.getHeader();
569 std::copy(Ehdr
.e_ident
, Ehdr
.e_ident
+ 16, Ident
);
571 Machine
= Ehdr
.e_machine
;
572 Version
= Ehdr
.e_version
;
573 Entry
= Ehdr
.e_entry
;
574 Flags
= Ehdr
.e_flags
;
576 SectionTableRef SecTable
= readSectionHeaders(ElfFile
);
577 readProgramHeaders(ElfFile
);
579 SectionNames
= SecTable
.getSectionOfType
<StringTableSection
>(
581 "e_shstrndx field value " + Twine(Ehdr
.e_shstrndx
) + " in elf header " +
583 "e_shstrndx field value " + Twine(Ehdr
.e_shstrndx
) + " in elf header " +
584 " is not a string table");
587 template <class ELFT
>
588 void Object
<ELFT
>::writeHeader(FileOutputBuffer
&Out
) const {
589 uint8_t *Buf
= Out
.getBufferStart();
590 Elf_Ehdr
&Ehdr
= *reinterpret_cast<Elf_Ehdr
*>(Buf
);
591 std::copy(Ident
, Ident
+ 16, Ehdr
.e_ident
);
593 Ehdr
.e_machine
= Machine
;
594 Ehdr
.e_version
= Version
;
595 Ehdr
.e_entry
= Entry
;
596 Ehdr
.e_phoff
= sizeof(Elf_Ehdr
);
597 Ehdr
.e_flags
= Flags
;
598 Ehdr
.e_ehsize
= sizeof(Elf_Ehdr
);
599 Ehdr
.e_phentsize
= sizeof(Elf_Phdr
);
600 Ehdr
.e_phnum
= Segments
.size();
601 Ehdr
.e_shentsize
= sizeof(Elf_Shdr
);
602 if (WriteSectionHeaders
) {
603 Ehdr
.e_shoff
= SHOffset
;
604 Ehdr
.e_shnum
= Sections
.size() + 1;
605 Ehdr
.e_shstrndx
= SectionNames
->Index
;
613 template <class ELFT
>
614 void Object
<ELFT
>::writeProgramHeaders(FileOutputBuffer
&Out
) const {
615 for (auto &Phdr
: Segments
)
616 Phdr
->template writeHeader
<ELFT
>(Out
);
619 template <class ELFT
>
620 void Object
<ELFT
>::writeSectionHeaders(FileOutputBuffer
&Out
) const {
621 uint8_t *Buf
= Out
.getBufferStart() + SHOffset
;
622 // This reference serves to write the dummy section header at the begining
623 // of the file. It is not used for anything else
624 Elf_Shdr
&Shdr
= *reinterpret_cast<Elf_Shdr
*>(Buf
);
626 Shdr
.sh_type
= SHT_NULL
;
633 Shdr
.sh_addralign
= 0;
636 for (auto &Section
: Sections
)
637 Section
->template writeHeader
<ELFT
>(Out
);
640 template <class ELFT
>
641 void Object
<ELFT
>::writeSectionData(FileOutputBuffer
&Out
) const {
642 for (auto &Section
: Sections
)
643 Section
->writeSection(Out
);
646 template <class ELFT
>
647 void Object
<ELFT
>::removeSections(
648 std::function
<bool(const SectionBase
&)> ToRemove
) {
650 auto Iter
= std::stable_partition(
651 std::begin(Sections
), std::end(Sections
), [=](const SecPtr
&Sec
) {
654 if (auto RelSec
= dyn_cast
<RelocationSectionBase
>(Sec
.get())) {
655 if (auto ToRelSec
= RelSec
->getSection())
656 return !ToRemove(*ToRelSec
);
660 if (SymbolTable
!= nullptr && ToRemove(*SymbolTable
))
661 SymbolTable
= nullptr;
662 if (ToRemove(*SectionNames
)) {
663 if (WriteSectionHeaders
)
664 error("Cannot remove " + SectionNames
->Name
+
665 " because it is the section header string table.");
666 SectionNames
= nullptr;
668 // Now make sure there are no remaining references to the sections that will
669 // be removed. Sometimes it is impossible to remove a reference so we emit
670 // an error here instead.
671 for (auto &RemoveSec
: make_range(Iter
, std::end(Sections
))) {
672 for (auto &Segment
: Segments
)
673 Segment
->removeSection(RemoveSec
.get());
674 for (auto &KeepSec
: make_range(std::begin(Sections
), Iter
))
675 KeepSec
->removeSectionReferences(RemoveSec
.get());
677 // Now finally get rid of them all togethor.
678 Sections
.erase(Iter
, std::end(Sections
));
681 template <class ELFT
> void ELFObject
<ELFT
>::sortSections() {
682 // Put all sections in offset order. Maintain the ordering as closely as
683 // possible while meeting that demand however.
684 auto CompareSections
= [](const SecPtr
&A
, const SecPtr
&B
) {
685 return A
->OriginalOffset
< B
->OriginalOffset
;
687 std::stable_sort(std::begin(this->Sections
), std::end(this->Sections
),
691 static uint64_t alignToAddr(uint64_t Offset
, uint64_t Addr
, uint64_t Align
) {
692 // Calculate Diff such that (Offset + Diff) & -Align == Addr & -Align.
696 static_cast<int64_t>(Addr
% Align
) - static_cast<int64_t>(Offset
% Align
);
697 // We only want to add to Offset, however, so if Diff < 0 we can add Align and
698 // (Offset + Diff) & -Align == Addr & -Align will still hold.
701 return Offset
+ Diff
;
704 // Orders segments such that if x = y->ParentSegment then y comes before x.
705 static void OrderSegments(std::vector
<Segment
*> &Segments
) {
706 std::stable_sort(std::begin(Segments
), std::end(Segments
), compareSegments
);
709 // This function finds a consistent layout for a list of segments starting from
710 // an Offset. It assumes that Segments have been sorted by OrderSegments and
711 // returns an Offset one past the end of the last segment.
712 static uint64_t LayoutSegments(std::vector
<Segment
*> &Segments
,
714 assert(std::is_sorted(std::begin(Segments
), std::end(Segments
),
716 // The only way a segment should move is if a section was between two
717 // segments and that section was removed. If that section isn't in a segment
718 // then it's acceptable, but not ideal, to simply move it to after the
719 // segments. So we can simply layout segments one after the other accounting
721 for (auto &Segment
: Segments
) {
722 // We assume that segments have been ordered by OriginalOffset and Index
723 // such that a parent segment will always come before a child segment in
724 // OrderedSegments. This means that the Offset of the ParentSegment should
725 // already be set and we can set our offset relative to it.
726 if (Segment
->ParentSegment
!= nullptr) {
727 auto Parent
= Segment
->ParentSegment
;
729 Parent
->Offset
+ Segment
->OriginalOffset
- Parent
->OriginalOffset
;
731 Offset
= alignToAddr(Offset
, Segment
->VAddr
, Segment
->Align
);
732 Segment
->Offset
= Offset
;
734 Offset
= std::max(Offset
, Segment
->Offset
+ Segment
->FileSize
);
739 // This function finds a consistent layout for a list of sections. It assumes
740 // that the ->ParentSegment of each section has already been laid out. The
741 // supplied starting Offset is used for the starting offset of any section that
742 // does not have a ParentSegment. It returns either the offset given if all
743 // sections had a ParentSegment or an offset one past the last section if there
744 // was a section that didn't have a ParentSegment.
745 template <class SecPtr
>
746 static uint64_t LayoutSections(std::vector
<SecPtr
> &Sections
, uint64_t Offset
) {
747 // Now the offset of every segment has been set we can assign the offsets
748 // of each section. For sections that are covered by a segment we should use
749 // the segment's original offset and the section's original offset to compute
750 // the offset from the start of the segment. Using the offset from the start
751 // of the segment we can assign a new offset to the section. For sections not
752 // covered by segments we can just bump Offset to the next valid location.
754 for (auto &Section
: Sections
) {
755 Section
->Index
= Index
++;
756 if (Section
->ParentSegment
!= nullptr) {
757 auto Segment
= Section
->ParentSegment
;
759 Segment
->Offset
+ (Section
->OriginalOffset
- Segment
->OriginalOffset
);
761 Offset
= alignTo(Offset
, Section
->Align
== 0 ? 1 : Section
->Align
);
762 Section
->Offset
= Offset
;
763 if (Section
->Type
!= SHT_NOBITS
)
764 Offset
+= Section
->Size
;
770 template <class ELFT
> void ELFObject
<ELFT
>::assignOffsets() {
771 // We need a temporary list of segments that has a special order to it
772 // so that we know that anytime ->ParentSegment is set that segment has
773 // already had its offset properly set.
774 std::vector
<Segment
*> OrderedSegments
;
775 for (auto &Segment
: this->Segments
)
776 OrderedSegments
.push_back(Segment
.get());
777 OrderSegments(OrderedSegments
);
778 // The size of ELF + program headers will not change so it is ok to assume
779 // that the first offset of the first segment is a good place to start
780 // outputting sections. This covers both the standard case and the PT_PHDR
783 if (!OrderedSegments
.empty()) {
784 Offset
= OrderedSegments
[0]->Offset
;
786 Offset
= sizeof(Elf_Ehdr
);
788 Offset
= LayoutSegments(OrderedSegments
, Offset
);
789 Offset
= LayoutSections(this->Sections
, Offset
);
790 // If we need to write the section header table out then we need to align the
791 // Offset so that SHOffset is valid.
792 if (this->WriteSectionHeaders
)
793 Offset
= alignTo(Offset
, sizeof(typename
ELFT::Addr
));
794 this->SHOffset
= Offset
;
797 template <class ELFT
> size_t ELFObject
<ELFT
>::totalSize() const {
798 // We already have the section header offset so we can calculate the total
799 // size by just adding up the size of each section header.
800 auto NullSectionSize
= this->WriteSectionHeaders
? sizeof(Elf_Shdr
) : 0;
801 return this->SHOffset
+ this->Sections
.size() * sizeof(Elf_Shdr
) +
805 template <class ELFT
> void ELFObject
<ELFT
>::write(FileOutputBuffer
&Out
) const {
806 this->writeHeader(Out
);
807 this->writeProgramHeaders(Out
);
808 this->writeSectionData(Out
);
809 if (this->WriteSectionHeaders
)
810 this->writeSectionHeaders(Out
);
813 template <class ELFT
> void ELFObject
<ELFT
>::finalize() {
814 // Make sure we add the names of all the sections.
815 if (this->SectionNames
!= nullptr)
816 for (const auto &Section
: this->Sections
) {
817 this->SectionNames
->addString(Section
->Name
);
819 // Make sure we add the names of all the symbols.
820 if (this->SymbolTable
!= nullptr)
821 this->SymbolTable
->addSymbolNames();
826 // Finalize SectionNames first so that we can assign name indexes.
827 if (this->SectionNames
!= nullptr)
828 this->SectionNames
->finalize();
829 // Finally now that all offsets and indexes have been set we can finalize any
831 uint64_t Offset
= this->SHOffset
+ sizeof(Elf_Shdr
);
832 for (auto &Section
: this->Sections
) {
833 Section
->HeaderOffset
= Offset
;
834 Offset
+= sizeof(Elf_Shdr
);
835 if (this->WriteSectionHeaders
)
836 Section
->NameIndex
= this->SectionNames
->findIndex(Section
->Name
);
841 template <class ELFT
> size_t BinaryObject
<ELFT
>::totalSize() const {
845 template <class ELFT
>
846 void BinaryObject
<ELFT
>::write(FileOutputBuffer
&Out
) const {
847 for (auto &Section
: this->Sections
) {
848 if ((Section
->Flags
& SHF_ALLOC
) == 0)
850 Section
->writeSection(Out
);
854 template <class ELFT
> void BinaryObject
<ELFT
>::finalize() {
855 // TODO: Create a filter range to construct OrderedSegments from so that this
856 // code can be deduped with assignOffsets above. This should also solve the
857 // todo below for LayoutSections.
858 // We need a temporary list of segments that has a special order to it
859 // so that we know that anytime ->ParentSegment is set that segment has
860 // already had it's offset properly set. We only want to consider the segments
861 // that will affect layout of allocated sections so we only add those.
862 std::vector
<Segment
*> OrderedSegments
;
863 for (auto &Section
: this->Sections
) {
864 if ((Section
->Flags
& SHF_ALLOC
) != 0 &&
865 Section
->ParentSegment
!= nullptr) {
866 OrderedSegments
.push_back(Section
->ParentSegment
);
869 OrderSegments(OrderedSegments
);
870 // Because we add a ParentSegment for each section we might have duplicate
871 // segments in OrderedSegments. If there were duplicates then LayoutSegments
872 // would do very strange things.
874 std::unique(std::begin(OrderedSegments
), std::end(OrderedSegments
));
875 OrderedSegments
.erase(End
, std::end(OrderedSegments
));
877 // Modify the first segment so that there is no gap at the start. This allows
878 // our layout algorithm to proceed as expected while not out writing out the
880 if (!OrderedSegments
.empty()) {
881 auto Seg
= OrderedSegments
[0];
882 auto Sec
= Seg
->firstSection();
883 auto Diff
= Sec
->OriginalOffset
- Seg
->OriginalOffset
;
884 Seg
->OriginalOffset
+= Diff
;
885 // The size needs to be shrunk as well
886 Seg
->FileSize
-= Diff
;
887 Seg
->MemSize
-= Diff
;
888 // The VAddr needs to be adjusted so that the alignment is correct as well
890 Seg
->PAddr
= Seg
->VAddr
;
891 // We don't want this to be shifted by alignment so we need to set the
892 // alignment to zero.
896 uint64_t Offset
= LayoutSegments(OrderedSegments
, 0);
898 // TODO: generalize LayoutSections to take a range. Pass a special range
899 // constructed from an iterator that skips values for which a predicate does
900 // not hold. Then pass such a range to LayoutSections instead of constructing
901 // AllocatedSections here.
902 std::vector
<SectionBase
*> AllocatedSections
;
903 for (auto &Section
: this->Sections
) {
904 if ((Section
->Flags
& SHF_ALLOC
) == 0)
906 AllocatedSections
.push_back(Section
.get());
908 LayoutSections(AllocatedSections
, Offset
);
910 // Now that every section has been laid out we just need to compute the total
911 // file size. This might not be the same as the offset returned by
912 // LayoutSections, because we want to truncate the last segment to the end of
913 // its last section, to match GNU objcopy's behaviour.
915 for (const auto &Section
: AllocatedSections
) {
916 if (Section
->Type
!= SHT_NOBITS
)
917 TotalSize
= std::max(TotalSize
, Section
->Offset
+ Section
->Size
);
923 template class Object
<ELF64LE
>;
924 template class Object
<ELF64BE
>;
925 template class Object
<ELF32LE
>;
926 template class Object
<ELF32BE
>;
928 template class ELFObject
<ELF64LE
>;
929 template class ELFObject
<ELF64BE
>;
930 template class ELFObject
<ELF32LE
>;
931 template class ELFObject
<ELF32BE
>;
933 template class BinaryObject
<ELF64LE
>;
934 template class BinaryObject
<ELF64BE
>;
935 template class BinaryObject
<ELF32LE
>;
936 template class BinaryObject
<ELF32BE
>;
938 } // end namespace llvm