diff options
author | Petr Hosek <phosek@chromium.org> | 2017-08-01 05:31:50 +0000 |
---|---|---|
committer | Petr Hosek <phosek@chromium.org> | 2017-08-01 05:31:50 +0000 |
commit | 35fdbd56b7765e2329ca1edfe48ded65029e53bf (patch) | |
tree | 0eaca1f93eeb1a1fc605c05f483d6348204b9e0f /llvm/tools/llvm-objcopy/Object.cpp | |
parent | 43cd2ef49c843c0478569dfdb375d7c30ad0012a (diff) | |
download | bcm5719-llvm-35fdbd56b7765e2329ca1edfe48ded65029e53bf.tar.gz bcm5719-llvm-35fdbd56b7765e2329ca1edfe48ded65029e53bf.zip |
Revert "[llvm][llvm-objcopy] Added support for outputting to binary in llvm-objcopy"
The change seems to be failing on bots which are using gcc and bfd.ld
as a host compiler and linker.
This reverts commit r309658.
llvm-svn: 309660
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 205 |
1 files changed, 77 insertions, 128 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index c57dfe005ed..77ac8d913de 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -42,13 +42,6 @@ void Segment::finalize() { } } -void Segment::writeSegment(FileOutputBuffer &Out) const { - uint8_t *Buf = Out.getBufferStart() + Offset; - // We want to maintain segments' interstitial data and contents exactly. - // This lets us just copy segments directly. - std::copy(std::begin(Contents), std::end(Contents), Buf); -} - void SectionBase::finalize() {} template <class ELFT> @@ -106,8 +99,7 @@ template <class ELFT> void Object<ELFT>::readProgramHeaders(const ELFFile<ELFT> &ElfFile) { uint32_t Index = 0; for (const auto &Phdr : unwrapOrError(ElfFile.program_headers())) { - ArrayRef<uint8_t> Data{ElfFile.base() + Phdr.p_offset, Phdr.p_filesz}; - Segments.emplace_back(llvm::make_unique<Segment>(Data)); + Segments.emplace_back(llvm::make_unique<Segment>()); Segment &Seg = *Segments.back(); Seg.Type = Phdr.p_type; Seg.Flags = Phdr.p_flags; @@ -143,7 +135,7 @@ Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile, default: Data = unwrapOrError(ElfFile.getSectionContents(&Shdr)); return llvm::make_unique<Section>(Data); - } + }; } template <class ELFT> @@ -171,6 +163,12 @@ void Object<ELFT>::readSectionHeaders(const ELFFile<ELFT> &ElfFile) { } } +template <class ELFT> size_t Object<ELFT>::totalSize() const { + // We already have the section header offset so we can calculate the total + // size by just adding up the size of each section header. + return SHOffset + Sections.size() * sizeof(Elf_Shdr) + sizeof(Elf_Shdr); +} + template <class ELFT> Object<ELFT>::Object(const ELFObjectFile<ELFT> &Obj) { const auto &ElfFile = *Obj.getELFFile(); const auto &Ehdr = *ElfFile.getHeader(); @@ -189,76 +187,22 @@ template <class ELFT> Object<ELFT>::Object(const ELFObjectFile<ELFT> &Obj) { dyn_cast<StringTableSection>(Sections[Ehdr.e_shstrndx - 1].get()); } -template <class ELFT> -void Object<ELFT>::writeHeader(FileOutputBuffer &Out) const { - uint8_t *Buf = Out.getBufferStart(); - Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf); - std::copy(Ident, Ident + 16, Ehdr.e_ident); - Ehdr.e_type = Type; - Ehdr.e_machine = Machine; - Ehdr.e_version = Version; - Ehdr.e_entry = Entry; - Ehdr.e_phoff = sizeof(Elf_Ehdr); - Ehdr.e_shoff = SHOffset; - Ehdr.e_flags = Flags; - Ehdr.e_ehsize = sizeof(Elf_Ehdr); - Ehdr.e_phentsize = sizeof(Elf_Phdr); - Ehdr.e_phnum = Segments.size(); - Ehdr.e_shentsize = sizeof(Elf_Shdr); - Ehdr.e_shnum = Sections.size() + 1; - Ehdr.e_shstrndx = SectionNames->Index; -} - -template <class ELFT> -void Object<ELFT>::writeProgramHeaders(FileOutputBuffer &Out) const { - for (auto &Phdr : Segments) - Phdr->template writeHeader<ELFT>(Out); -} - -template <class ELFT> -void Object<ELFT>::writeSectionHeaders(FileOutputBuffer &Out) const { - uint8_t *Buf = Out.getBufferStart() + SHOffset; - // This reference serves to write the dummy section header at the begining - // of the file. - Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(Buf); - Shdr.sh_name = 0; - Shdr.sh_type = SHT_NULL; - Shdr.sh_flags = 0; - Shdr.sh_addr = 0; - Shdr.sh_offset = 0; - Shdr.sh_size = 0; - Shdr.sh_link = 0; - Shdr.sh_info = 0; - Shdr.sh_addralign = 0; - Shdr.sh_entsize = 0; - - for (auto &Section : Sections) - Section->template writeHeader<ELFT>(Out); -} - -template <class ELFT> -void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const { - for (auto &Section : Sections) - Section->writeSection(Out); -} - -template <class ELFT> void ELFObject<ELFT>::sortSections() { +template <class ELFT> void Object<ELFT>::sortSections() { // Put all sections in offset order. Maintain the ordering as closely as // possible while meeting that demand however. auto CompareSections = [](const SecPtr &A, const SecPtr &B) { return A->OriginalOffset < B->OriginalOffset; }; - std::stable_sort(std::begin(this->Sections), std::end(this->Sections), - CompareSections); + std::stable_sort(std::begin(Sections), std::end(Sections), CompareSections); } -template <class ELFT> void ELFObject<ELFT>::assignOffsets() { +template <class ELFT> void Object<ELFT>::assignOffsets() { // Decide file offsets and indexes. - size_t PhdrSize = this->Segments.size() * sizeof(Elf_Phdr); + size_t PhdrSize = Segments.size() * sizeof(Elf_Phdr); // We can put section data after the ELF header and the program headers. uint64_t Offset = sizeof(Elf_Ehdr) + PhdrSize; uint64_t Index = 1; - for (auto &Section : this->Sections) { + for (auto &Section : Sections) { // The segment can have a different alignment than the section. In the case // that there is a parent segment then as long as we satisfy the alignment // of the segment it should follow that that the section is aligned. @@ -305,88 +249,93 @@ template <class ELFT> void ELFObject<ELFT>::assignOffsets() { // this needs to be 4-byte aligned and on 64-bit it needs to be 8-byte aligned // so the size of ELFT::Addr is used to ensure this. Offset = alignTo(Offset, sizeof(typename ELFT::Addr)); - this->SHOffset = Offset; -} - -template <class ELFT> size_t ELFObject<ELFT>::totalSize() const { - // We already have the section header offset so we can calculate the total - // size by just adding up the size of each section header. - return this->SHOffset + this->Sections.size() * sizeof(Elf_Shdr) + - sizeof(Elf_Shdr); -} - -template <class ELFT> void ELFObject<ELFT>::write(FileOutputBuffer &Out) const { - this->writeHeader(Out); - this->writeProgramHeaders(Out); - this->writeSectionData(Out); - this->writeSectionHeaders(Out); + SHOffset = Offset; } -template <class ELFT> void ELFObject<ELFT>::finalize() { - for (const auto &Section : this->Sections) { - this->SectionNames->addString(Section->Name); - } +template <class ELFT> void Object<ELFT>::finalize() { + for (auto &Section : Sections) + SectionNames->addString(Section->Name); sortSections(); assignOffsets(); // Finalize SectionNames first so that we can assign name indexes. - this->SectionNames->finalize(); + SectionNames->finalize(); // Finally now that all offsets and indexes have been set we can finalize any // remaining issues. - uint64_t Offset = this->SHOffset + sizeof(Elf_Shdr); - for (auto &Section : this->Sections) { + uint64_t Offset = SHOffset + sizeof(Elf_Shdr); + for (auto &Section : Sections) { Section->HeaderOffset = Offset; Offset += sizeof(Elf_Shdr); - Section->NameIndex = this->SectionNames->findIndex(Section->Name); + Section->NameIndex = SectionNames->findIndex(Section->Name); Section->finalize(); } - for (auto &Segment : this->Segments) + for (auto &Segment : Segments) Segment->finalize(); } -template <class ELFT> size_t BinaryObject<ELFT>::totalSize() const { - return TotalSize; +template <class ELFT> +void Object<ELFT>::writeHeader(FileOutputBuffer &Out) const { + uint8_t *Buf = Out.getBufferStart(); + Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf); + std::copy(Ident, Ident + 16, Ehdr.e_ident); + Ehdr.e_type = Type; + Ehdr.e_machine = Machine; + Ehdr.e_version = Version; + Ehdr.e_entry = Entry; + Ehdr.e_phoff = sizeof(Elf_Ehdr); + Ehdr.e_shoff = SHOffset; + Ehdr.e_flags = Flags; + Ehdr.e_ehsize = sizeof(Elf_Ehdr); + Ehdr.e_phentsize = sizeof(Elf_Phdr); + Ehdr.e_phnum = Segments.size(); + Ehdr.e_shentsize = sizeof(Elf_Shdr); + Ehdr.e_shnum = Sections.size() + 1; + Ehdr.e_shstrndx = SectionNames->Index; } template <class ELFT> -void BinaryObject<ELFT>::write(FileOutputBuffer &Out) const { - for (auto &Segment : this->Segments) { - if (Segment->Type == llvm::ELF::PT_LOAD) { - Segment->writeSegment(Out); - } - } +void Object<ELFT>::writeProgramHeaders(FileOutputBuffer &Out) const { + for (auto &Phdr : Segments) + Phdr->template writeHeader<ELFT>(Out); } -template <class ELFT> void BinaryObject<ELFT>::finalize() { - for (auto &Segment : this->Segments) - Segment->finalize(); +template <class ELFT> +void Object<ELFT>::writeSectionHeaders(FileOutputBuffer &Out) const { + uint8_t *Buf = Out.getBufferStart() + SHOffset; + // This reference serves to write the dummy section header at the begining + // of the file. + Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(Buf); + Shdr.sh_name = 0; + Shdr.sh_type = SHT_NULL; + Shdr.sh_flags = 0; + Shdr.sh_addr = 0; + Shdr.sh_offset = 0; + Shdr.sh_size = 0; + Shdr.sh_link = 0; + Shdr.sh_info = 0; + Shdr.sh_addralign = 0; + Shdr.sh_entsize = 0; - // Put all segments in offset order. - auto CompareSegments = [](const SegPtr &A, const SegPtr &B) { - return A->Offset < B->Offset; - }; - std::sort(std::begin(this->Segments), std::end(this->Segments), - CompareSegments); - - uint64_t Offset = 0; - for (auto &Segment : this->Segments) { - if (Segment->Type == llvm::ELF::PT_LOAD) { - Offset = alignTo(Offset, Segment->Align); - Segment->Offset = Offset; - Offset += Segment->FileSize; - } - } - TotalSize = Offset; + for (auto &Section : Sections) + Section->template writeHeader<ELFT>(Out); } -template class ELFObject<ELF64LE>; -template class ELFObject<ELF64BE>; -template class ELFObject<ELF32LE>; -template class ELFObject<ELF32BE>; +template <class ELFT> +void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const { + for (auto &Section : Sections) + Section->writeSection(Out); +} + +template <class ELFT> void Object<ELFT>::write(FileOutputBuffer &Out) { + writeHeader(Out); + writeProgramHeaders(Out); + writeSectionData(Out); + writeSectionHeaders(Out); +} -template class BinaryObject<ELF64LE>; -template class BinaryObject<ELF64BE>; -template class BinaryObject<ELF32LE>; -template class BinaryObject<ELF32BE>; +template class Object<ELF64LE>; +template class Object<ELF64BE>; +template class Object<ELF32LE>; +template class Object<ELF32BE>; |