<div dir="ltr">Why was this reverted? (Handy to have that info included in the commit message for posterity (so if someone else comes looking to see what happened, if they can pick up this work, etc) or even in a follow-up reply here on the mailing list can be handy)</div><br><div class="gmail_quote"><div dir="ltr">On Fri, Jul 21, 2017 at 7:44 PM Petr Hosek via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: phosek<br>
Date: Fri Jul 21 19:43:50 2017<br>
New Revision: 308822<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=308822&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=308822&view=rev</a><br>
Log:<br>
Revert "Reland "[LLVM][llvm-objcopy] Added basic plumbing to get things started""<br>
<br>
This reverts commit 2b52298eb28ba4d3eca113353a348c02a6ef1f93.<br>
<br>
Removed:<br>
llvm/trunk/test/tools/llvm-objcopy/basic-copy.test<br>
llvm/trunk/test/tools/llvm-objcopy/empty-section.test<br>
llvm/trunk/test/tools/llvm-objcopy/program-headers.test<br>
llvm/trunk/tools/llvm-objcopy/CMakeLists.txt<br>
llvm/trunk/tools/llvm-objcopy/LLVMBuild.txt<br>
llvm/trunk/tools/llvm-objcopy/Object.cpp<br>
llvm/trunk/tools/llvm-objcopy/Object.h<br>
llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp<br>
llvm/trunk/tools/llvm-objcopy/llvm-objcopy.h<br>
Modified:<br>
llvm/trunk/test/CMakeLists.txt<br>
llvm/trunk/tools/LLVMBuild.txt<br>
<br>
Modified: llvm/trunk/test/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=308822&r1=308821&r2=308822&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=308822&r1=308821&r2=308822&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CMakeLists.txt (original)<br>
+++ llvm/trunk/test/CMakeLists.txt Fri Jul 21 19:43:50 2017<br>
@@ -61,7 +61,6 @@ set(LLVM_TEST_DEPENDS<br>
llvm-modextract<br>
llvm-mt<br>
llvm-nm<br>
- llvm-objcopy<br>
llvm-objdump<br>
llvm-opt-report<br>
llvm-pdbutil<br>
<br>
Removed: llvm/trunk/test/tools/llvm-objcopy/basic-copy.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/basic-copy.test?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/basic-copy.test?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/basic-copy.test (original)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/basic-copy.test (removed)<br>
@@ -1,47 +0,0 @@<br>
-# RUN: yaml2obj %s > %t<br>
-# RUN: llvm-objcopy %t %t2<br>
-# RUN: llvm-readobj -sections %t2 | FileCheck %s<br>
-<br>
-!ELF<br>
-FileHeader:<br>
- Class: ELFCLASS64<br>
- Data: ELFDATA2LSB<br>
- Type: ET_EXEC<br>
- Machine: EM_X86_64<br>
-Sections:<br>
- - Name: .bss<br>
- Type: SHT_NOBITS<br>
- Flags: [ SHF_ALLOC ]<br>
- AddressAlign: 0x0000000000000010<br>
- Size: 64<br>
- - Name: .text<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]<br>
- AddressAlign: 0x0000000000000010<br>
- Content: "00000000"<br>
-<br>
-# CHECK: Type: SHT_NULL<br>
-<br>
-# CHECK: Name: .bss<br>
-# CHECK-NEXT: Type: SHT_NOBITS<br>
-# CHECK-NEXT: Flags [<br>
-# CHECK-NEXT: SHF_ALLOC<br>
-# CHECK-NEXT: ]<br>
-# CHECK-NEXT: Address:<br>
-# CHECK-NEXT: Offset: [[OFFSET:0x[0-9A-F]+]]<br>
-# CHECK-NEXT: Size: 64<br>
-<br>
-# CHECK: Name: .text<br>
-# CHECK-NEXT: Type: SHT_PROGBITS<br>
-# CHECK-NEXT: Flags [<br>
-# CHECK-NEXT: SHF_ALLOC<br>
-# CHECK-NEXT: SHF_EXECINSTR<br>
-# CHECK-NEXT: ]<br>
-# CHECK-NEXT: Address:<br>
-# CHECK-NEXT: Offset: [[OFFSET]]<br>
-# CHECK-NEXT: Size: 4<br>
-<br>
-# CHECK: Name: .shstrtab<br>
-# CHECK-NEXT: Type: SHT_STRTAB<br>
-# CHECK-NEXT: Flags [<br>
-# CHECK-NEXT: ]<br>
<br>
Removed: llvm/trunk/test/tools/llvm-objcopy/empty-section.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/empty-section.test?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/empty-section.test?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/empty-section.test (original)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/empty-section.test (removed)<br>
@@ -1,55 +0,0 @@<br>
-# RUN: yaml2obj %s > %t<br>
-# RUN: llvm-objcopy %t %t2<br>
-# RUN: llvm-readobj -sections %t2 | FileCheck %s<br>
-<br>
-!ELF<br>
-FileHeader:<br>
- Class: ELFCLASS64<br>
- Data: ELFDATA2LSB<br>
- Type: ET_EXEC<br>
- Machine: EM_X86_64<br>
-Sections:<br>
- - Name: .text<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]<br>
- Address: 0x0<br>
- AddressAlign: 0x0000000000001000<br>
- Content: "00000000"<br>
- - Name: .empty<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC ]<br>
- Address: 0x1000<br>
- AddressAlign: 0x0000000000001000<br>
- Content: ""<br>
- - Name: .data<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC ]<br>
- Address: 0x1000<br>
- AddressAlign: 0x0000000000001000<br>
- Content: "00000000"<br>
-<br>
-<br>
-# CHECK: Name: .text<br>
-# CHECK-NEXT: Type: SHT_PROGBITS<br>
-# CHECK-NEXT: Flags [<br>
-# CHECK-NEXT: SHF_ALLOC<br>
-# CHECK-NEXT: SHF_EXECINSTR<br>
-# CHECK-NEXT: ]<br>
-<br>
-# CHECK: Name: .empty<br>
-# CHECK-NEXT: Type: SHT_PROGBITS<br>
-# CHECK-NEXT: Flags [<br>
-# CHECK-NEXT: SHF_ALLOC<br>
-# CHECK-NEXT: ]<br>
-# CHECK-NEXT: Address: 0x1000<br>
-# CHECK-NEXT: Offset: 0x2000<br>
-# CHECK-NEXT: Size: 0<br>
-<br>
-# CHECK: Name: .data<br>
-# CHECK-NEXT: Type: SHT_PROGBITS<br>
-# CHECK-NEXT: Flags [<br>
-# CHECK-NEXT: SHF_ALLOC<br>
-# CHECK-NEXT: ]<br>
-# CHECK-NEXT: Address: 0x1000<br>
-# CHECK-NEXT: Offset: 0x2000<br>
-# CHECK-NEXT: Size: 4<br>
<br>
Removed: llvm/trunk/test/tools/llvm-objcopy/program-headers.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/program-headers.test?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/program-headers.test?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/program-headers.test (original)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/program-headers.test (removed)<br>
@@ -1,68 +0,0 @@<br>
-# RUN: yaml2obj %s -o %t<br>
-# RUN: llvm-objcopy %t %t2<br>
-# RUN: llvm-readobj -program-headers %t2 | FileCheck %s<br>
-<br>
-!ELF<br>
-FileHeader:<br>
- Class: ELFCLASS64<br>
- Data: ELFDATA2LSB<br>
- Type: ET_EXEC<br>
- Machine: EM_X86_64<br>
-Sections:<br>
- - Name: .text<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]<br>
- AddressAlign: 0x0000000000001000<br>
- Content: "00000000"<br>
- - Name: .init<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]<br>
- Content: "00000000"<br>
- AddressAlign: 0x0000000000000010<br>
- - Name: .data<br>
- Type: SHT_PROGBITS<br>
- Flags: [ SHF_ALLOC ]<br>
- Content: "00000000"<br>
- AddressAlign: 0x0000000000001000<br>
-ProgramHeaders:<br>
- - Type: PT_LOAD<br>
- Flags: [ PF_X, PF_R ]<br>
- VAddr: 0xAAAA1000<br>
- PAddr: 0xFFFF1000<br>
- Sections:<br>
- - Section: .text<br>
- - Section: .init<br>
- - Type: PT_LOAD<br>
- Flags: [ PF_R ]<br>
- VAddr: 0xAAAA2000<br>
- PAddr: 0xFFFF2000<br>
- Sections:<br>
- - Section: .data<br>
-<br>
-#CHECK: ProgramHeaders [<br>
-#CHECK-NEXT: ProgramHeader {<br>
-#CHECK-NEXT: Type: PT_LOAD<br>
-#CHECK-NEXT: Offset: 0x1000<br>
-#CHECK-NEXT: VirtualAddress: 0xAAAA1000<br>
-#CHECK-NEXT: PhysicalAddress: 0xFFFF1000<br>
-#CHECK-NEXT: FileSize: 20<br>
-#CHECK-NEXT: MemSize: 20<br>
-#CHECK-NEXT: Flags [<br>
-#CHECK-NEXT: PF_R<br>
-#CHECK-NEXT: PF_X<br>
-#CHECK-NEXT: ]<br>
-#CHECK-NEXT: Alignment: 4096<br>
-#CHECK-NEXT: }<br>
-#CHECK-NEXT: ProgramHeader {<br>
-#CHECK-NEXT: Type: PT_LOAD<br>
-#CHECK-NEXT: Offset: 0x2000<br>
-#CHECK-NEXT: VirtualAddress: 0xAAAA2000<br>
-#CHECK-NEXT: PhysicalAddress: 0xFFFF2000<br>
-#CHECK-NEXT: FileSize: 4<br>
-#CHECK-NEXT: MemSize: 4<br>
-#CHECK-NEXT: Flags [<br>
-#CHECK-NEXT: PF_R<br>
-#CHECK-NEXT: ]<br>
-#CHECK-NEXT: Alignment: 4096<br>
-#CHECK-NEXT: }<br>
-#CHECK-NEXT:]<br>
<br>
Modified: llvm/trunk/tools/LLVMBuild.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=308822&r1=308821&r2=308822&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=308822&r1=308821&r2=308822&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/LLVMBuild.txt (original)<br>
+++ llvm/trunk/tools/LLVMBuild.txt Fri Jul 21 19:43:50 2017<br>
@@ -40,7 +40,6 @@ subdirectories =<br>
llvm-modextract<br>
llvm-mt<br>
llvm-nm<br>
- llvm-objcopy<br>
llvm-objdump<br>
llvm-pdbutil<br>
llvm-profdata<br>
<br>
Removed: llvm/trunk/tools/llvm-objcopy/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CMakeLists.txt?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CMakeLists.txt?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/CMakeLists.txt (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/CMakeLists.txt (removed)<br>
@@ -1,9 +0,0 @@<br>
-set(LLVM_LINK_COMPONENTS<br>
- Core<br>
- Object<br>
- Support<br>
- )<br>
-add_llvm_tool(llvm-objcopy<br>
- llvm-objcopy.cpp<br>
- Object.cpp<br>
- )<br>
<br>
Removed: llvm/trunk/tools/llvm-objcopy/LLVMBuild.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/LLVMBuild.txt?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/LLVMBuild.txt?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/LLVMBuild.txt (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/LLVMBuild.txt (removed)<br>
@@ -1,21 +0,0 @@<br>
-;===- ./tools/llvm-objcopy/LLVMBuild.txt -----------------------*- Conf -*--===;<br>
-;<br>
-; The LLVM Compiler Infrastructure<br>
-;<br>
-; This file is distributed under the University of Illinois Open Source<br>
-; License. See LICENSE.TXT for details.<br>
-;<br>
-;===------------------------------------------------------------------------===;<br>
-;<br>
-; This is an LLVMBuild description file for the components in this subdirectory.<br>
-;<br>
-; For more information on the LLVMBuild system, please see:<br>
-;<br>
-; <a href="http://llvm.org/docs/LLVMBuild.html" rel="noreferrer" target="_blank">http://llvm.org/docs/LLVMBuild.html</a><br>
-;<br>
-;===------------------------------------------------------------------------===;<br>
-[component_0]<br>
-type = Tool<br>
-name = llvm-objcopy<br>
-parent = Tools<br>
-required_libraries = Object<br>
<br>
Removed: llvm/trunk/tools/llvm-objcopy/Object.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp (removed)<br>
@@ -1,341 +0,0 @@<br>
-//===- Object.cpp -----------------------------------------------*- C++ -*-===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-#include "Object.h"<br>
-#include "llvm-objcopy.h"<br>
-<br>
-using namespace llvm;<br>
-using namespace object;<br>
-using namespace ELF;<br>
-<br>
-template <class ELFT> void Segment::writeHeader(FileOutputBuffer &Out) const {<br>
- typedef typename ELFT::Ehdr Elf_Ehdr;<br>
- typedef typename ELFT::Phdr Elf_Phdr;<br>
-<br>
- uint8_t *Buf = Out.getBufferStart();<br>
- Buf += sizeof(Elf_Ehdr) + Index * sizeof(Elf_Phdr);<br>
- Elf_Phdr &Phdr = *reinterpret_cast<Elf_Phdr *>(Buf);<br>
- Phdr.p_type = Type;<br>
- Phdr.p_flags = Flags;<br>
- Phdr.p_offset = Offset;<br>
- Phdr.p_vaddr = VAddr;<br>
- Phdr.p_paddr = PAddr;<br>
- Phdr.p_filesz = FileSize;<br>
- Phdr.p_memsz = MemSize;<br>
- Phdr.p_align = Align;<br>
-}<br>
-<br>
-void Segment::finalize() {<br>
- auto FirstSec = firstSection();<br>
- if (FirstSec) {<br>
- // It is possible for a gap to be at the begining of a segment. Because of<br>
- // this we need to compute the new offset based on how large this gap was<br>
- // in the source file. Section layout should have already ensured that this<br>
- // space is not used for something else.<br>
- uint64_t OriginalOffset = Offset;<br>
- Offset = FirstSec->Offset - (FirstSec->OriginalOffset - OriginalOffset);<br>
- }<br>
-}<br>
-<br>
-void SectionBase::finalize() {}<br>
-<br>
-template <class ELFT><br>
-void SectionBase::writeHeader(FileOutputBuffer &Out) const {<br>
- uint8_t *Buf = Out.getBufferStart();<br>
- Buf += HeaderOffset;<br>
- typename ELFT::Shdr &Shdr = *reinterpret_cast<typename ELFT::Shdr *>(Buf);<br>
- Shdr.sh_name = NameIndex;<br>
- Shdr.sh_type = Type;<br>
- Shdr.sh_flags = Flags;<br>
- Shdr.sh_addr = Addr;<br>
- Shdr.sh_offset = Offset;<br>
- Shdr.sh_size = Size;<br>
- Shdr.sh_link = Link;<br>
- Shdr.sh_info = Info;<br>
- Shdr.sh_addralign = Align;<br>
- Shdr.sh_entsize = EntrySize;<br>
-}<br>
-<br>
-void Section::writeSection(FileOutputBuffer &Out) const {<br>
- if (Type == SHT_NOBITS)<br>
- return;<br>
- uint8_t *Buf = Out.getBufferStart() + Offset;<br>
- std::copy(std::begin(Contents), std::end(Contents), Buf);<br>
-}<br>
-<br>
-void StringTableSection::addString(StringRef Name) {<br>
- StrTabBuilder.add(Name);<br>
- Size = StrTabBuilder.getSize();<br>
-}<br>
-<br>
-uint32_t StringTableSection::findIndex(StringRef Name) const {<br>
- return StrTabBuilder.getOffset(Name);<br>
-}<br>
-<br>
-void StringTableSection::finalize() { StrTabBuilder.finalize(); }<br>
-<br>
-void StringTableSection::writeSection(FileOutputBuffer &Out) const {<br>
- StrTabBuilder.write(Out.getBufferStart() + Offset);<br>
-}<br>
-<br>
-// Returns true IFF a section is wholly inside the range of a segment<br>
-static bool sectionWithinSegment(const SectionBase &Section,<br>
- const Segment &Segment) {<br>
- // If a section is empty it should be treated like it has a size of 1. This is<br>
- // to clarify the case when an empty section lies on a boundary between two<br>
- // segments and ensures that the section "belongs" to the second segment and<br>
- // not the first.<br>
- uint64_t SecSize = Section.Size ? Section.Size : 1;<br>
- return Segment.Offset <= Section.OriginalOffset &&<br>
- Segment.Offset + Segment.FileSize >= Section.OriginalOffset + SecSize;<br>
-}<br>
-<br>
-template <class ELFT><br>
-void Object<ELFT>::readProgramHeaders(const ELFFile<ELFT> &ElfFile) {<br>
- uint32_t Index = 0;<br>
- for (const auto &Phdr : unwrapOrError(ElfFile.program_headers())) {<br>
- Segments.emplace_back(make_unique<Segment>());<br>
- Segment &Seg = *Segments.back();<br>
- Seg.Type = Phdr.p_type;<br>
- Seg.Flags = Phdr.p_flags;<br>
- Seg.Offset = Phdr.p_offset;<br>
- Seg.VAddr = Phdr.p_vaddr;<br>
- Seg.PAddr = Phdr.p_paddr;<br>
- Seg.FileSize = Phdr.p_filesz;<br>
- Seg.MemSize = Phdr.p_memsz;<br>
- Seg.Align = Phdr.p_align;<br>
- Seg.Index = Index++;<br>
- for (auto &Section : Sections) {<br>
- if (sectionWithinSegment(*Section, Seg)) {<br>
- Seg.addSection(&*Section);<br>
- if (!Section->ParentSegment ||<br>
- Section->ParentSegment->Offset > Seg.Offset) {<br>
- Section->ParentSegment = &Seg;<br>
- }<br>
- }<br>
- }<br>
- }<br>
-}<br>
-<br>
-template <class ELFT><br>
-std::unique_ptr<SectionBase><br>
-Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,<br>
- const Elf_Shdr &Shdr) {<br>
- ArrayRef<uint8_t> Data;<br>
- switch (Shdr.sh_type) {<br>
- case SHT_STRTAB:<br>
- return make_unique<StringTableSection>();<br>
- case SHT_NOBITS:<br>
- return make_unique<Section>(Data);<br>
- default:<br>
- Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));<br>
- return make_unique<Section>(Data);<br>
- };<br>
-}<br>
-<br>
-template <class ELFT><br>
-void Object<ELFT>::readSectionHeaders(const ELFFile<ELFT> &ElfFile) {<br>
- uint32_t Index = 0;<br>
- for (const auto &Shdr : unwrapOrError(ElfFile.sections())) {<br>
- if (Index == 0) {<br>
- ++Index;<br>
- continue;<br>
- }<br>
- SecPtr Sec = makeSection(ElfFile, Shdr);<br>
- Sec->Name = unwrapOrError(ElfFile.getSectionName(&Shdr));<br>
- Sec->Type = Shdr.sh_type;<br>
- Sec->Flags = Shdr.sh_flags;<br>
- Sec->Addr = Shdr.sh_addr;<br>
- Sec->Offset = Shdr.sh_offset;<br>
- Sec->OriginalOffset = Shdr.sh_offset;<br>
- Sec->Size = Shdr.sh_size;<br>
- Sec->Link = Shdr.sh_link;<br>
- Sec->Info = Shdr.sh_info;<br>
- Sec->Align = Shdr.sh_addralign;<br>
- Sec->EntrySize = Shdr.sh_entsize;<br>
- Sec->Index = Index++;<br>
- Sections.push_back(std::move(Sec));<br>
- }<br>
-}<br>
-<br>
-template <class ELFT> size_t Object<ELFT>::totalSize() const {<br>
- // We already have the section header offset so we can calculate the total<br>
- // size by just adding up the size of each section header.<br>
- return SHOffset + Sections.size() * sizeof(Elf_Shdr) + sizeof(Elf_Shdr);<br>
-}<br>
-<br>
-template <class ELFT> Object<ELFT>::Object(const ELFObjectFile<ELFT> &Obj) {<br>
- const auto &ElfFile = *Obj.getELFFile();<br>
- const auto &Ehdr = *ElfFile.getHeader();<br>
-<br>
- std::copy(Ehdr.e_ident, Ehdr.e_ident + 16, Ident);<br>
- Type = Ehdr.e_type;<br>
- Machine = Ehdr.e_machine;<br>
- Version = Ehdr.e_version;<br>
- Entry = Ehdr.e_entry;<br>
- Flags = Ehdr.e_flags;<br>
-<br>
- readSectionHeaders(ElfFile);<br>
- readProgramHeaders(ElfFile);<br>
-<br>
- SectionNames =<br>
- dyn_cast<StringTableSection>(Sections[Ehdr.e_shstrndx - 1].get());<br>
-}<br>
-<br>
-template <class ELFT> void Object<ELFT>::sortSections() {<br>
- // Put all sections in offset order. Maintain the ordering as closely as<br>
- // possible while meeting that demand however.<br>
- auto CompareSections = [](const SecPtr &A, const SecPtr &B) {<br>
- return A->OriginalOffset < B->OriginalOffset;<br>
- };<br>
- std::stable_sort(std::begin(Sections), std::end(Sections), CompareSections);<br>
-}<br>
-<br>
-template <class ELFT> void Object<ELFT>::assignOffsets() {<br>
- // Decide file offsets and indexes.<br>
- size_t PhdrSize = Segments.size() * sizeof(Elf_Phdr);<br>
- // We can put section data after the ELF header and the program headers.<br>
- uint64_t Offset = sizeof(Elf_Ehdr) + PhdrSize;<br>
- uint64_t Index = 1;<br>
- for (auto &Section : Sections) {<br>
- // The segment can have a different alignment than the section. In the case<br>
- // that there is a parent segment then as long as we satisfy the alignment<br>
- // of the segment it should follow that that the section is aligned.<br>
- if (Section->ParentSegment) {<br>
- auto FirstInSeg = Section->ParentSegment->firstSection();<br>
- if (FirstInSeg == Section.get()) {<br>
- Offset = alignTo(Offset, Section->ParentSegment->Align);<br>
- // There can be gaps at the start of a segment before the first section.<br>
- // So first we assign the alignment of the segment and then assign the<br>
- // location of the section from there<br>
- Section->Offset =<br>
- Offset + Section->OriginalOffset - Section->ParentSegment->Offset;<br>
- }<br>
- // We should respect interstitial gaps of allocated sections. We *must*<br>
- // maintain the memory image so that addresses are preserved. As, with the<br>
- // exception of SHT_NOBITS sections at the end of segments, the memory<br>
- // image is a copy of the file image, we preserve the file image as well.<br>
- // There's a strange case where a thread local SHT_NOBITS can cause the<br>
- // memory image and file image to not be the same. This occurs, on some<br>
- // systems, when a thread local SHT_NOBITS is between two SHT_PROGBITS<br>
- // and the thread local SHT_NOBITS section is at the end of a TLS segment.<br>
- // In this case to faithfully copy the segment file image we must use<br>
- // relative offsets. In any other case this would be the same as using the<br>
- // relative addresses so this should maintian the memory image as desired.<br>
- Offset = FirstInSeg->Offset + Section->OriginalOffset -<br>
- FirstInSeg->OriginalOffset;<br>
- }<br>
- // Alignment should have already been handled by the above if statement if<br>
- // this if this section is in a segment. Technically this shouldn't do<br>
- // anything bad if the alignments of the sections are all correct and the<br>
- // file image isn't corrupted. Still in sticking with the motto "maintain<br>
- // the file image" we should avoid messing up the file image if the<br>
- // alignment disagrees with the file image.<br>
- if (!Section->ParentSegment && Section->Align)<br>
- Offset = alignTo(Offset, Section->Align);<br>
- Section->Offset = Offset;<br>
- Section->Index = Index++;<br>
- if (Section->Type != SHT_NOBITS)<br>
- Offset += Section->Size;<br>
- }<br>
- // 'offset' should now be just after all the section data so we should set the<br>
- // section header table offset to be exactly here. This spot might not be<br>
- // aligned properly however so we should align it as needed. For 32-bit ELF<br>
- // this needs to be 4-byte aligned and on 64-bit it needs to be 8-byte aligned<br>
- // so the size of ELFT::Addr is used to ensure this.<br>
- Offset = alignTo(Offset, sizeof(typename ELFT::Addr));<br>
- SHOffset = Offset;<br>
-}<br>
-<br>
-template <class ELFT> void Object<ELFT>::finalize() {<br>
- for (auto &Section : Sections)<br>
- SectionNames->addString(Section->Name);<br>
-<br>
- sortSections();<br>
- assignOffsets();<br>
-<br>
- // Finalize SectionNames first so that we can assign name indexes.<br>
- SectionNames->finalize();<br>
- // Finally now that all offsets and indexes have been set we can finalize any<br>
- // remaining issues.<br>
- uint64_t Offset = SHOffset + sizeof(Elf_Shdr);<br>
- for (auto &Section : Sections) {<br>
- Section->HeaderOffset = Offset;<br>
- Offset += sizeof(Elf_Shdr);<br>
- Section->NameIndex = SectionNames->findIndex(Section->Name);<br>
- Section->finalize();<br>
- }<br>
-<br>
- for (auto &Segment : Segments)<br>
- Segment->finalize();<br>
-}<br>
-<br>
-template <class ELFT><br>
-void Object<ELFT>::writeHeader(FileOutputBuffer &Out) const {<br>
- uint8_t *Buf = Out.getBufferStart();<br>
- Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf);<br>
- std::copy(Ident, Ident + 16, Ehdr.e_ident);<br>
- Ehdr.e_type = Type;<br>
- Ehdr.e_machine = Machine;<br>
- Ehdr.e_version = Version;<br>
- Ehdr.e_entry = Entry;<br>
- Ehdr.e_phoff = sizeof(Elf_Ehdr);<br>
- Ehdr.e_shoff = SHOffset;<br>
- Ehdr.e_flags = Flags;<br>
- Ehdr.e_ehsize = sizeof(Elf_Ehdr);<br>
- Ehdr.e_phentsize = sizeof(Elf_Phdr);<br>
- Ehdr.e_phnum = Segments.size();<br>
- Ehdr.e_shentsize = sizeof(Elf_Shdr);<br>
- Ehdr.e_shnum = Sections.size() + 1;<br>
- Ehdr.e_shstrndx = SectionNames->Index;<br>
-}<br>
-<br>
-template <class ELFT><br>
-void Object<ELFT>::writeProgramHeaders(FileOutputBuffer &Out) const {<br>
- for (auto &Phdr : Segments)<br>
- Phdr->template writeHeader<ELFT>(Out);<br>
-}<br>
-<br>
-template <class ELFT><br>
-void Object<ELFT>::writeSectionHeaders(FileOutputBuffer &Out) const {<br>
- uint8_t *Buf = Out.getBufferStart() + SHOffset;<br>
- // This reference serves to write the dummy section header at the begining<br>
- // of the file.<br>
- Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(Buf);<br>
- Shdr.sh_name = 0;<br>
- Shdr.sh_type = SHT_NULL;<br>
- Shdr.sh_flags = 0;<br>
- Shdr.sh_addr = 0;<br>
- Shdr.sh_offset = 0;<br>
- Shdr.sh_size = 0;<br>
- Shdr.sh_link = 0;<br>
- Shdr.sh_info = 0;<br>
- Shdr.sh_addralign = 0;<br>
- Shdr.sh_entsize = 0;<br>
-<br>
- for (auto &Section : Sections)<br>
- Section->template writeHeader<ELFT>(Out);<br>
-}<br>
-<br>
-template <class ELFT><br>
-void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const {<br>
- for (auto &Section : Sections)<br>
- Section->writeSection(Out);<br>
-}<br>
-<br>
-template <class ELFT> void Object<ELFT>::write(FileOutputBuffer &Out) {<br>
- writeHeader(Out);<br>
- writeProgramHeaders(Out);<br>
- writeSectionData(Out);<br>
- writeSectionHeaders(Out);<br>
-}<br>
-<br>
-template class Object<ELF64LE>;<br>
-template class Object<ELF64BE>;<br>
-template class Object<ELF32LE>;<br>
-template class Object<ELF32BE>;<br>
<br>
Removed: llvm/trunk/tools/llvm-objcopy/Object.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/Object.h (removed)<br>
@@ -1,150 +0,0 @@<br>
-//===- Object.h -------------------------------------------------*- C++ -*-===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_OBJCOPY_OBJECT_H<br>
-#define LLVM_OBJCOPY_OBJECT_H<br>
-<br>
-#include "llvm/MC/StringTableBuilder.h"<br>
-#include "llvm/Object/ELFObjectFile.h"<br>
-#include "llvm/Support/FileOutputBuffer.h"<br>
-<br>
-#include <memory><br>
-#include <set><br>
-<br>
-class Segment;<br>
-<br>
-class SectionBase {<br>
-public:<br>
- llvm::StringRef Name;<br>
- Segment *ParentSegment = nullptr;<br>
- uint64_t HeaderOffset;<br>
- uint64_t OriginalOffset;<br>
- uint32_t Index;<br>
-<br>
- uint64_t Addr = 0;<br>
- uint64_t Align = 1;<br>
- uint32_t EntrySize = 0;<br>
- uint64_t Flags = 0;<br>
- uint64_t Info = 0;<br>
- uint64_t Link = llvm::ELF::SHN_UNDEF;<br>
- uint64_t NameIndex = 0;<br>
- uint64_t Offset = 0;<br>
- uint64_t Size = 0;<br>
- uint64_t Type = llvm::ELF::SHT_NULL;<br>
-<br>
- virtual ~SectionBase() {}<br>
- virtual void finalize();<br>
- template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const;<br>
- virtual void writeSection(llvm::FileOutputBuffer &Out) const = 0;<br>
-};<br>
-<br>
-class Segment {<br>
-private:<br>
- struct SectionCompare {<br>
- bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {<br>
- // Some sections might have the same address if one of them is empty. To<br>
- // fix this we can use the lexicographic ordering on ->Addr and the<br>
- // address of the actully stored section.<br>
- if (Lhs->Addr == Rhs->Addr)<br>
- return Lhs < Rhs;<br>
- return Lhs->Addr < Rhs->Addr;<br>
- }<br>
- };<br>
-<br>
- std::set<const SectionBase *, SectionCompare> Sections;<br>
-<br>
-public:<br>
- uint64_t Align;<br>
- uint64_t FileSize;<br>
- uint32_t Flags;<br>
- uint32_t Index;<br>
- uint64_t MemSize;<br>
- uint64_t Offset;<br>
- uint64_t PAddr;<br>
- uint64_t Type;<br>
- uint64_t VAddr;<br>
-<br>
- void finalize();<br>
- const SectionBase *firstSection() const {<br>
- if (!Sections.empty())<br>
- return *Sections.begin();<br>
- return nullptr;<br>
- }<br>
- void addSection(const SectionBase *sec) { Sections.insert(sec); }<br>
- template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const;<br>
-};<br>
-<br>
-class Section : public SectionBase {<br>
-private:<br>
- llvm::ArrayRef<uint8_t> Contents;<br>
-<br>
-public:<br>
- Section(llvm::ArrayRef<uint8_t> Data) : Contents(Data) {}<br>
- void writeSection(llvm::FileOutputBuffer &Out) const override;<br>
-};<br>
-<br>
-// This is just a wraper around a StringTableBuilder that implements SectionBase<br>
-class StringTableSection : public SectionBase {<br>
-private:<br>
- llvm::StringTableBuilder StrTabBuilder;<br>
-<br>
-public:<br>
- StringTableSection() : StrTabBuilder(llvm::StringTableBuilder::ELF) {<br>
- Type = llvm::ELF::SHT_STRTAB;<br>
- }<br>
-<br>
- void addString(llvm::StringRef Name);<br>
- uint32_t findIndex(llvm::StringRef Name) const;<br>
- void finalize() override;<br>
- void writeSection(llvm::FileOutputBuffer &Out) const override;<br>
- static bool classof(const SectionBase *S) {<br>
- return S->Type == llvm::ELF::SHT_STRTAB;<br>
- }<br>
-};<br>
-<br>
-template <class ELFT> class Object {<br>
-private:<br>
- typedef std::unique_ptr<SectionBase> SecPtr;<br>
- typedef std::unique_ptr<Segment> SegPtr;<br>
-<br>
- typedef typename ELFT::Shdr Elf_Shdr;<br>
- typedef typename ELFT::Ehdr Elf_Ehdr;<br>
- typedef typename ELFT::Phdr Elf_Phdr;<br>
-<br>
- StringTableSection *SectionNames;<br>
- std::vector<SecPtr> Sections;<br>
- std::vector<SegPtr> Segments;<br>
-<br>
- void sortSections();<br>
- void assignOffsets();<br>
- SecPtr makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,<br>
- const Elf_Shdr &Shdr);<br>
- void readProgramHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);<br>
- void readSectionHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);<br>
- void writeHeader(llvm::FileOutputBuffer &Out) const;<br>
- void writeProgramHeaders(llvm::FileOutputBuffer &Out) const;<br>
- void writeSectionData(llvm::FileOutputBuffer &Out) const;<br>
- void writeSectionHeaders(llvm::FileOutputBuffer &Out) const;<br>
-<br>
-public:<br>
- uint8_t Ident[16];<br>
- uint64_t Entry;<br>
- uint64_t SHOffset;<br>
- uint32_t Type;<br>
- uint32_t Machine;<br>
- uint32_t Version;<br>
- uint32_t Flags;<br>
-<br>
- Object(const llvm::object::ELFObjectFile<ELFT> &Obj);<br>
- size_t totalSize() const;<br>
- void finalize();<br>
- void write(llvm::FileOutputBuffer &Out);<br>
-};<br>
-<br>
-#endif<br>
<br>
Removed: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (removed)<br>
@@ -1,99 +0,0 @@<br>
-//===- llvm-objcopy.cpp -----------------------------------------*- C++ -*-===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-#include "llvm-objcopy.h"<br>
-#include "Object.h"<br>
-#include "llvm/Support/CommandLine.h"<br>
-#include "llvm/Support/FileOutputBuffer.h"<br>
-#include "llvm/Support/PrettyStackTrace.h"<br>
-#include "llvm/Support/Signals.h"<br>
-#include "llvm/Support/ToolOutputFile.h"<br>
-<br>
-#include <memory><br>
-#include <string><br>
-#include <system_error><br>
-<br>
-using namespace llvm;<br>
-using namespace object;<br>
-using namespace ELF;<br>
-<br>
-// The name this program was invoked as.<br>
-static StringRef ToolName;<br>
-<br>
-namespace llvm {<br>
-<br>
-LLVM_ATTRIBUTE_NORETURN void error(Twine Message) {<br>
- errs() << ToolName << ": " << Message << ".\n";<br>
- errs().flush();<br>
- exit(1);<br>
-}<br>
-<br>
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) {<br>
- assert(EC);<br>
- errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n";<br>
- exit(1);<br>
-}<br>
-<br>
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, llvm::Error E) {<br>
- assert(E);<br>
- std::string Buf;<br>
- raw_string_ostream OS(Buf);<br>
- logAllUnhandledErrors(std::move(E), OS, "");<br>
- OS.flush();<br>
- errs() << ToolName << ": '" << File << "': " << Buf;<br>
- exit(1);<br>
-}<br>
-}<br>
-<br>
-cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input>"));<br>
-cl::opt<std::string> OutputFilename(cl::Positional, cl::desc("<output>"),<br>
- cl::init("-"));<br>
-<br>
-void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) {<br>
- std::unique_ptr<FileOutputBuffer> Buffer;<br>
- Object<ELF64LE> Obj{ObjFile};<br>
- Obj.finalize();<br>
- ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =<br>
- FileOutputBuffer::create(OutputFilename, Obj.totalSize(),<br>
- FileOutputBuffer::F_executable);<br>
- if (BufferOrErr.getError())<br>
- error("failed to open " + OutputFilename);<br>
- else<br>
- Buffer = std::move(*BufferOrErr);<br>
- std::error_code EC;<br>
- std::unique_ptr<tool_output_file> Out =<br>
- make_unique<tool_output_file>(OutputFilename.data(), EC, sys::fs::F_None);<br>
- if (EC)<br>
- report_fatal_error(EC.message());<br>
- Obj.write(*Buffer);<br>
- if (auto EC = Buffer->commit())<br>
- reportError(OutputFilename, EC);<br>
- Out->keep();<br>
-}<br>
-<br>
-int main(int argc, char **argv) {<br>
- // Print a stack trace if we signal out.<br>
- sys::PrintStackTraceOnErrorSignal(argv[0]);<br>
- PrettyStackTraceProgram X(argc, argv);<br>
- llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.<br>
- cl::ParseCommandLineOptions(argc, argv, "llvm objcopy utility\n");<br>
- ToolName = argv[0];<br>
- if (InputFilename.empty()) {<br>
- cl::PrintHelpMessage();<br>
- return 2;<br>
- }<br>
- Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(InputFilename);<br>
- if (!BinaryOrErr)<br>
- reportError(InputFilename, BinaryOrErr.takeError());<br>
- Binary &Binary = *BinaryOrErr.get().getBinary();<br>
- if (ELFObjectFile<ELF64LE> *o = dyn_cast<ELFObjectFile<ELF64LE>>(&Binary)) {<br>
- CopyBinary(*o);<br>
- return 0;<br>
- }<br>
- reportError(InputFilename, object_error::invalid_file_type);<br>
-}<br>
<br>
Removed: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.h?rev=308821&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.h?rev=308821&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.h (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.h (removed)<br>
@@ -1,32 +0,0 @@<br>
-//===- llvm-objcopy.h -------------------------------------------*- C++ -*-===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-#ifndef LLVM_OBJCOPY_H<br>
-#define LLVM_OBJCOPY_H<br>
-<br>
-#include "llvm/ADT/Twine.h"<br>
-#include "llvm/Support/Error.h"<br>
-<br>
-namespace llvm {<br>
-<br>
-LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message);<br>
-<br>
-// This is taken from llvm-readobj.<br>
-// [see here](llvm/tools/llvm-readobj/llvm-readobj.h:38)<br>
-template <class T> T unwrapOrError(Expected<T> EO) {<br>
- if (EO)<br>
- return *EO;<br>
- std::string Buf;<br>
- raw_string_ostream OS(Buf);<br>
- logAllUnhandledErrors(EO.takeError(), OS, "");<br>
- OS.flush();<br>
- error(Buf);<br>
-}<br>
-}<br>
-<br>
-#endif<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>