[llvm] r349605 - [llvm-objcopy] Initial COFF support
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 20 13:20:59 PST 2018
Unfortunately neither of my directly available setups (macOS and Ubuntu
16.04) have got the nonnull attribute on memcpy there, so I can't seem to
reproduce this issue with ubsan even before the change I committed. But
I'll patch the other similar cases as well in a moment.
// Martin
On Thu, 20 Dec 2018, Kostya Serebryany wrote:
> Thanks! Please make sure to run with ubsan after the fix, there seem to be
> at least 3 similar instances.
> This is what I've done locally:
> cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
> -DLLVM_USE_SANITIZER=Undefined -DLLVM_ENABLE_ASSERTIONS=YES ~/llvm
> ninja check-llvm
>
> I'd recommend using more C++-ish code, e.g. at least
> - memcpy(Ptr, S.AuxData.data(), S.AuxData.size());
> + std::copy(S.AuxData.begin(), S.AuxData.end(), Ptr);
>
>
>
>
>
>
>
>
> On Wed, Dec 19, 2018 at 9:33 AM Kostya Serebryany <kcc at google.com> wrote:
> Hi,
> ubsan seems to be unhappy with this change, please fix ASAP
>
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/27463/
> steps/check-llvm%20ubsan/logs/stdio
>
> b/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-objcopy/COFF/Writer.cpp:
> 228:17: runtime error: null pointer passed as argument 2, which is declared
> to never be null
> /usr/include/string.h:43:28: note: nonnull attribute specified here
> #0 0x436e89 in llvm::objcopy::coff::COFFWriter::writeSections() /b/sanit
> izer-x86_64-linux-fast/build/llvm/tools/llvm-objcopy/COFF/Writer.cpp:228:5
> #1 0x436f2a in llvm::objcopy::coff::COFFWriter::write(bool) /b/sanitizer
> -x86_64-linux-fast/build/llvm/tools/llvm-objcopy/COFF/Writer.cpp:255:3
> #2 0x432664 in llvm::objcopy::coff::executeObjcopyOnBinary(llvm::objcopy
> ::CopyConfig const&, llvm::object::COFFObjectFile&, llvm::objcopy::Buffer&)
> /b/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-objcopy/COFF/COFFObjcop
> y.cpp:35:10
> #3 0x42ef45 in executeObjcopy /b/sanitizer-x86_64-linux-fast/build/llvm/
> tools/llvm-objcopy/llvm-objcopy.cpp:211:7
> #4 0x42ef45 in main /b/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm
> -objcopy/llvm-objcopy.cpp:231
> #5 0x7f702c5862e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+
> 0x202e0)
> #6 0x409c09 in _start (/b/sanitizer-x86_64-linux-fast/build/llvm_build_u
> bsan/bin/llvm-objcopy+0x409c09)
>
>
> --
>
> On Tue, Dec 18, 2018 at 11:27 PM Martin Storsjo via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> Author: mstorsjo
> Date: Tue Dec 18 23:24:38 2018
> New Revision: 349605
>
> URL:
> http://llvm.org/viewvc/llvm-project?rev=349605&view=rev
> Log:
> [llvm-objcopy] Initial COFF support
>
> This is an initial implementation of no-op passthrough
> copying of COFF
> with objcopy.
>
> Differential Revision: https://reviews.llvm.org/D54939
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/COFF/
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/
>
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-exe.yaml
>
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-obj.yaml
>
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-exe.yaml
>
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-obj.yaml
>
> llvm/trunk/test/tools/llvm-objcopy/COFF/basic-copy.test
> llvm/trunk/tools/llvm-objcopy/COFF/
> llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
> llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h
> llvm/trunk/tools/llvm-objcopy/COFF/Object.h
> llvm/trunk/tools/llvm-objcopy/COFF/Reader.cpp
> llvm/trunk/tools/llvm-objcopy/COFF/Reader.h
> llvm/trunk/tools/llvm-objcopy/COFF/Writer.cpp
> llvm/trunk/tools/llvm-objcopy/COFF/Writer.h
> Modified:
> llvm/trunk/include/llvm/Object/COFF.h
> llvm/trunk/lib/Object/COFFObjectFile.cpp
> llvm/trunk/tools/llvm-objcopy/CMakeLists.txt
> llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
>
> Modified: llvm/trunk/include/llvm/Object/COFF.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?r
> ev=349605&r1=349604&r2=349605&view=diff
> ===========================================================================
> ===
> --- llvm/trunk/include/llvm/Object/COFF.h (original)
> +++ llvm/trunk/include/llvm/Object/COFF.h Tue Dec 18
> 23:24:38 2018
> @@ -971,6 +971,9 @@ public:
> return nullptr;
> return reinterpret_cast<const dos_header *>(base());
> }
> + std::error_code getCOFFHeader(const coff_file_header
> *&Res) const;
> + std::error_code
> + getCOFFBigObjHeader(const coff_bigobj_file_header
> *&Res) const;
> std::error_code getPE32Header(const pe32_header *&Res)
> const;
> std::error_code getPE32PlusHeader(const pe32plus_header
> *&Res) const;
> std::error_code getDataDirectory(uint32_t index,
>
> Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cp
> p?rev=349605&r1=349604&r2=349605&view=diff
> ===========================================================================
> ===
> --- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
> +++ llvm/trunk/lib/Object/COFFObjectFile.cpp Tue Dec 18
> 23:24:38 2018
> @@ -938,6 +938,18 @@ iterator_range<base_reloc_iterator>
> COFF
> return make_range(base_reloc_begin(),
> base_reloc_end());
> }
>
> +std::error_code
> +COFFObjectFile::getCOFFHeader(const coff_file_header
> *&Res) const {
> + Res = COFFHeader;
> + return std::error_code();
> +}
> +
> +std::error_code
> +COFFObjectFile::getCOFFBigObjHeader(const
> coff_bigobj_file_header *&Res) const {
> + Res = COFFBigObjHeader;
> + return std::error_code();
> +}
> +
> std::error_code COFFObjectFile::getPE32Header(const
> pe32_header *&Res) const {
> Res = PE32Header;
> return std::error_code();
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-exe.yaml
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/COFF
> /Inputs/i386-exe.yaml?rev=349605&view=auto
> ===========================================================================
> ===
> ---
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-exe.yaml
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-exe.yaml
> Tue Dec 18 23:24:38 2018
> @@ -0,0 +1,84 @@
> +--- !COFF
> +OptionalHeader:
> + AddressOfEntryPoint: 4144
> + ImageBase: 4194304
> + SectionAlignment: 4096
> + FileAlignment: 512
> + MajorOperatingSystemVersion: 6
> + MinorOperatingSystemVersion: 0
> + MajorImageVersion: 0
> + MinorImageVersion: 0
> + MajorSubsystemVersion: 6
> + MinorSubsystemVersion: 0
> + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
> + DLLCharacteristics: [
> IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,
> IMAGE_DLL_CHARACTERISTICS_NX_COMPAT,
> IMAGE_DLL_CHARACTERISTICS_NO_SEH,
> IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
> + SizeOfStackReserve: 1048576
> + SizeOfStackCommit: 4096
> + SizeOfHeapReserve: 1048576
> + SizeOfHeapCommit: 4096
> + ExportTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ImportTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ResourceTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ExceptionTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + CertificateTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + BaseRelocationTable:
> + RelativeVirtualAddress: 12288
> + Size: 12
> + Debug:
> + RelativeVirtualAddress: 0
> + Size: 0
> + Architecture:
> + RelativeVirtualAddress: 0
> + Size: 0
> + GlobalPtr:
> + RelativeVirtualAddress: 0
> + Size: 0
> + TlsTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + LoadConfigTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + BoundImport:
> + RelativeVirtualAddress: 0
> + Size: 0
> + IAT:
> + RelativeVirtualAddress: 0
> + Size: 0
> + DelayImportDescriptor:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ClrRuntimeHeader:
> + RelativeVirtualAddress: 0
> + Size: 0
> +header:
> + Machine: IMAGE_FILE_MACHINE_I386
> + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE,
> IMAGE_FILE_32BIT_MACHINE ]
> +sections:
> + - Name: .text
> + Characteristics: [ IMAGE_SCN_CNT_CODE,
> IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
> + VirtualAddress: 4096
> + VirtualSize: 83
> + SectionData: 5589E5508B45088B0D00204000034D088945FC89C883C4045DC3660F1F4400005589E55DC3
> 662E0F1F840000000000905589E583EC08E8E5FFFFFFC745FC00000000C7042402000000E8B
> 2FFFFFF83C4085DC3
> + - Name: .data
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> + VirtualAddress: 8192
> + VirtualSize: 4
> + SectionData: '01000000'
> + - Name: .reloc
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + VirtualAddress: 12288
> + VirtualSize: 12
> + SectionData: 001000000C00000009300000
> +symbols: []
> +...
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-obj.yaml
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/COFF
> /Inputs/i386-obj.yaml?rev=349605&view=auto
> ===========================================================================
> ===
> ---
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-obj.yaml
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/i386-obj.yaml
> Tue Dec 18 23:24:38 2018
> @@ -0,0 +1,244 @@
> +--- !COFF
> +header:
> + Machine: IMAGE_FILE_MACHINE_I386
> + Characteristics: [ ]
> +sections:
> + - Name: .text
> + Characteristics: [ IMAGE_SCN_CNT_CODE,
> IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
> + Alignment: 16
> + SectionData: 5589E5508B45088B0D00000000034D088945FC89C883C4045DC3660F1F4400005589E55DC3
> 662E0F1F840000000000905589E583EC08E800000000C745FC00000000C7042402000000E80
> 000000083C4085DC3
> + Relocations:
> + - VirtualAddress: 9
> + SymbolName: _x
> + Type: IMAGE_REL_I386_DIR32
> + - VirtualAddress: 55
> + SymbolName: ___main
> + Type: IMAGE_REL_I386_REL32
> + - VirtualAddress: 74
> + SymbolName: _f
> + Type: IMAGE_REL_I386_REL32
> + - Name: .data
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> + Alignment: 4
> + SectionData: '01000000'
> + - Name: .bss
> + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> + Alignment: 4
> + SectionData: ''
> + - Name: .debug_str
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 636C616E672076657273696F6E20382E302E3020287472756E6B203334363337382920286C
> 6C766D2F7472756E6B203334363339302900736F757263652E63002F686F6D652F6D6172746
> 96E2F636F64652F6C6C766D2F6275696C642F6F626A636F70792D696E707574007800696E74
> 0066005F5F6D61696E006D61696E007900
> + - Name: .debug_abbrev
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 011101250E1305030E10171B0E110112060000023400030E49133A0B3B0B02180000032400
> 030E3E0B0B0B0000042E01110112064018030E3A0B3B0B271949133F1900000505000218030
> E3A0B3B0B49130000062E00110112064018030E3A0B3B0B27193F190000072E001101120640
> 18030E3A0B3B0B49133F19000000
> + - Name: .debug_info
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 850000000400000000000401000000000C0037000000000000004000000000000000530000
> 00026B000000370000000101050300000000036D000000050404000000001A0000000155710
> 00000010337000000050291087F000000010337000000000620000000050000000155730000
> 00010707300000002300000001557A00000001093700000000
> + Relocations:
> + - VirtualAddress: 6
> + SymbolName: .debug_abbrev
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 12
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 18
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 22
> + SymbolName: .debug_line
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 26
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 30
> + SymbolName: .text
> + Type: IMAGE_REL_I386_DIR32
> + - VirtualAddress: 39
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 51
> + SymbolName: _x
> + Type: IMAGE_REL_I386_DIR32
> + - VirtualAddress: 56
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 63
> + SymbolName: .text
> + Type: IMAGE_REL_I386_DIR32
> + - VirtualAddress: 73
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 87
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 99
> + SymbolName: .text
> + Type: IMAGE_REL_I386_DIR32
> + - VirtualAddress: 109
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - VirtualAddress: 116
> + SymbolName: .text
> + Type: IMAGE_REL_I386_DIR32
> + - VirtualAddress: 126
> + SymbolName: .debug_str
> + Type: IMAGE_REL_I386_SECREL
> + - Name: .debug_macinfo
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: '00'
> + - Name: .debug_line
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 52000000040020000000010101FB0E0D00010101010000000100000100736F757263652E63
> 00000000000005020000000014050A0A75050C0666050366050006CB05010A3D0500C9050A0
> A0821050306BA0205000101
> + Relocations:
> + - VirtualAddress: 45
> + SymbolName: .text
> + Type: IMAGE_REL_I386_DIR32
> + - Name: .llvm_addrsig
> + Characteristics: [ IMAGE_SCN_LNK_REMOVE ]
> + Alignment: 1
> + SectionData: '1314'
> +symbols:
> + - Name: .text
> + Value: 0
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 83
> + NumberOfRelocations: 3
> + NumberOfLinenumbers: 0
> + CheckSum: 4183332250
> + Number: 1
> + - Name: .data
> + Value: 0
> + SectionNumber: 2
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 4
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 3099354981
> + Number: 2
> + - Name: .bss
> + Value: 0
> + SectionNumber: 3
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 0
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 0
> + Number: 3
> + - Name: .debug_str
> + Value: 0
> + SectionNumber: 4
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 129
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 2876129505
> + Number: 4
> + - Name: .debug_abbrev
> + Value: 0
> + SectionNumber: 5
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 126
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 2218663305
> + Number: 5
> + - Name: .debug_info
> + Value: 0
> + SectionNumber: 6
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 137
> + NumberOfRelocations: 16
> + NumberOfLinenumbers: 0
> + CheckSum: 2577207131
> + Number: 6
> + - Name: .debug_macinfo
> + Value: 0
> + SectionNumber: 7
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 1
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 0
> + Number: 7
> + - Name: .debug_line
> + Value: 0
> + SectionNumber: 8
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 86
> + NumberOfRelocations: 1
> + NumberOfLinenumbers: 0
> + CheckSum: 2357396799
> + Number: 8
> + - Name: .llvm_addrsig
> + Value: 0
> + SectionNumber: 9
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 2
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 2067109359
> + Number: 9
> + - Name: '@feat.00'
> + Value: 1
> + SectionNumber: -1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + - Name: _f
> + Value: 0
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
> + - Name: _x
> + Value: 0
> + SectionNumber: 2
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + - Name: ___main
> + Value: 32
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
> + - Name: _main
> + Value: 48
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
> +...
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-exe.yaml
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/COFF
> /Inputs/x86_64-exe.yaml?rev=349605&view=auto
> ===========================================================================
> ===
> ---
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-exe.yaml
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-exe.yaml
> Tue Dec 18 23:24:38 2018
> @@ -0,0 +1,89 @@
> +--- !COFF
> +OptionalHeader:
> + AddressOfEntryPoint: 4144
> + ImageBase: 1073741824
> + SectionAlignment: 4096
> + FileAlignment: 512
> + MajorOperatingSystemVersion: 6
> + MinorOperatingSystemVersion: 0
> + MajorImageVersion: 0
> + MinorImageVersion: 0
> + MajorSubsystemVersion: 6
> + MinorSubsystemVersion: 0
> + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
> + DLLCharacteristics: [
> IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA,
> IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,
> IMAGE_DLL_CHARACTERISTICS_NX_COMPAT,
> IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
> + SizeOfStackReserve: 1048576
> + SizeOfStackCommit: 4096
> + SizeOfHeapReserve: 1048576
> + SizeOfHeapCommit: 4096
> + ExportTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ImportTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ResourceTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ExceptionTable:
> + RelativeVirtualAddress: 16384
> + Size: 24
> + CertificateTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + BaseRelocationTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + Debug:
> + RelativeVirtualAddress: 0
> + Size: 0
> + Architecture:
> + RelativeVirtualAddress: 0
> + Size: 0
> + GlobalPtr:
> + RelativeVirtualAddress: 0
> + Size: 0
> + TlsTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + LoadConfigTable:
> + RelativeVirtualAddress: 0
> + Size: 0
> + BoundImport:
> + RelativeVirtualAddress: 0
> + Size: 0
> + IAT:
> + RelativeVirtualAddress: 0
> + Size: 0
> + DelayImportDescriptor:
> + RelativeVirtualAddress: 0
> + Size: 0
> + ClrRuntimeHeader:
> + RelativeVirtualAddress: 0
> + Size: 0
> +header:
> + Machine: IMAGE_FILE_MACHINE_AMD64
> + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE,
> IMAGE_FILE_LARGE_ADDRESS_AWARE ]
> +sections:
> + - Name: .text
> + Characteristics: [ IMAGE_SCN_CNT_CODE,
> IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
> + VirtualAddress: 4096
> + VirtualSize: 87
> + SectionData: 50894C24048B0DF51F0000034C240489C859C3662E0F1F8400000000000F1F00C3662E0F1F
> 8400000000000F1F440000554883EC30488D6C2430E8E1FFFFFFC745FC00000000B90200000
> 0E8B0FFFFFF904883C4305DC3
> + - Name: .rdata
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ ]
> + VirtualAddress: 8192
> + VirtualSize: 20
> + SectionData:
> 0101010001020000010A03350A03055201500000
> + - Name: .data
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> + VirtualAddress: 12288
> + VirtualSize: 4
> + SectionData: '01000000'
> + - Name: .pdata
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ ]
> + VirtualAddress: 16384
> + VirtualSize: 24
> + SectionData:
> '001000001310000000200000301000005710000008200000'
> +symbols: []
> +...
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-obj.yaml
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/COFF
> /Inputs/x86_64-obj.yaml?rev=349605&view=auto
> ===========================================================================
> ===
> ---
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-obj.yaml
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/COFF/Inputs/x86_64-obj.yaml
> Tue Dec 18 23:24:38 2018
> @@ -0,0 +1,295 @@
> +--- !COFF
> +header:
> + Machine: IMAGE_FILE_MACHINE_AMD64
> + Characteristics: [ ]
> +sections:
> + - Name: .text
> + Characteristics: [ IMAGE_SCN_CNT_CODE,
> IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
> + Alignment: 16
> + SectionData: 50894C24048B0D00000000034C240489C859C3662E0F1F8400000000000F1F00C3662E0F1F
> 8400000000000F1F440000554883EC30488D6C2430E800000000C745FC00000000B90200000
> 0E800000000904883C4305DC3
> + Relocations:
> + - VirtualAddress: 7
> + SymbolName: x
> + Type: IMAGE_REL_AMD64_REL32
> + - VirtualAddress: 59
> + SymbolName: __main
> + Type: IMAGE_REL_AMD64_REL32
> + - VirtualAddress: 76
> + SymbolName: f
> + Type: IMAGE_REL_AMD64_REL32
> + - Name: .data
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> + Alignment: 4
> + SectionData: '01000000'
> + - Name: .bss
> + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> + Alignment: 4
> + SectionData: ''
> + - Name: .xdata
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ ]
> + Alignment: 4
> + SectionData:
> 0101010001020000010A03350A03055201500000
> + - Name: .debug_str
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 636C616E672076657273696F6E20382E302E3020287472756E6B203334363337382920286C
> 6C766D2F7472756E6B203334363339302900736F757263652E63002F686F6D652F6D6172746
> 96E2F636F64652F6C6C766D2F6275696C642F6F626A636F70792D696E707574007800696E74
> 0066005F5F6D61696E006D61696E007900
> + - Name: .debug_abbrev
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 011101250E1305030E10171B0E110112060000023400030E49133A0B3B0B02180000032400
> 030E3E0B0B0B0000042E01110112064018030E3A0B3B0B271949133F1900000505000218030
> E3A0B3B0B49130000062E00110112064018030E3A0B3B0B27193F190000072E001101120640
> 18030E3A0B3B0B49133F19000000
> + - Name: .debug_info
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 990000000400000000000801000000000C0037000000000000004000000000000000000000
> 0057000000026B0000003F000000010109030000000000000000036D0000000504040000000
> 0000000001300000001577100000001033F000000050291047F00000001033F000000000620
> 000000000000000100000001577300000001070730000000000000002700000001567A00000
> 001093F00000000
> + Relocations:
> + - VirtualAddress: 6
> + SymbolName: .debug_abbrev
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 12
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 18
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 22
> + SymbolName: .debug_line
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 26
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 30
> + SymbolName: .text
> + Type: IMAGE_REL_AMD64_ADDR64
> + - VirtualAddress: 43
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 55
> + SymbolName: x
> + Type: IMAGE_REL_AMD64_ADDR64
> + - VirtualAddress: 64
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 71
> + SymbolName: .text
> + Type: IMAGE_REL_AMD64_ADDR64
> + - VirtualAddress: 85
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 99
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 111
> + SymbolName: .text
> + Type: IMAGE_REL_AMD64_ADDR64
> + - VirtualAddress: 125
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - VirtualAddress: 132
> + SymbolName: .text
> + Type: IMAGE_REL_AMD64_ADDR64
> + - VirtualAddress: 146
> + SymbolName: .debug_str
> + Type: IMAGE_REL_AMD64_SECREL
> + - Name: .debug_macinfo
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: '00'
> + - Name: .pdata
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ ]
> + Alignment: 4
> + SectionData:
> '000000001300000000000000000000002700000008000000'
> + Relocations:
> + - VirtualAddress: 0
> + SymbolName: f
> + Type: IMAGE_REL_AMD64_ADDR32NB
> + - VirtualAddress: 4
> + SymbolName: f
> + Type: IMAGE_REL_AMD64_ADDR32NB
> + - VirtualAddress: 8
> + SymbolName: .xdata
> + Type: IMAGE_REL_AMD64_ADDR32NB
> + - VirtualAddress: 12
> + SymbolName: main
> + Type: IMAGE_REL_AMD64_ADDR32NB
> + - VirtualAddress: 16
> + SymbolName: main
> + Type: IMAGE_REL_AMD64_ADDR32NB
> + - VirtualAddress: 20
> + SymbolName: .xdata
> + Type: IMAGE_REL_AMD64_ADDR32NB
> + - Name: .debug_line
> + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
> + Alignment: 1
> + SectionData: 57000000040020000000010101FB0E0D00010101010000000100000100736F757263652E63
> 0000000000000902000000000000000014050A0A59050C066605034A050006081505010A130
> 500F3050A0A08590503069E0207000101
> + Relocations:
> + - VirtualAddress: 45
> + SymbolName: .text
> + Type: IMAGE_REL_AMD64_ADDR64
> + - Name: .llvm_addrsig
> + Characteristics: [ IMAGE_SCN_LNK_REMOVE ]
> + Alignment: 1
> + SectionData: '1718'
> +symbols:
> + - Name: .text
> + Value: 0
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 87
> + NumberOfRelocations: 3
> + NumberOfLinenumbers: 0
> + CheckSum: 4237828689
> + Number: 1
> + - Name: .data
> + Value: 0
> + SectionNumber: 2
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 4
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 3099354981
> + Number: 2
> + - Name: .bss
> + Value: 0
> + SectionNumber: 3
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 0
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 0
> + Number: 3
> + - Name: .xdata
> + Value: 0
> + SectionNumber: 4
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 20
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 3415491858
> + Number: 4
> + - Name: .debug_str
> + Value: 0
> + SectionNumber: 5
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 129
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 2876129505
> + Number: 5
> + - Name: .debug_abbrev
> + Value: 0
> + SectionNumber: 6
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 126
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 2218663305
> + Number: 6
> + - Name: .debug_info
> + Value: 0
> + SectionNumber: 7
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 157
> + NumberOfRelocations: 16
> + NumberOfLinenumbers: 0
> + CheckSum: 603506744
> + Number: 7
> + - Name: .debug_macinfo
> + Value: 0
> + SectionNumber: 8
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 1
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 0
> + Number: 8
> + - Name: .pdata
> + Value: 0
> + SectionNumber: 9
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 24
> + NumberOfRelocations: 6
> + NumberOfLinenumbers: 0
> + CheckSum: 2036901199
> + Number: 9
> + - Name: .debug_line
> + Value: 0
> + SectionNumber: 10
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 91
> + NumberOfRelocations: 1
> + NumberOfLinenumbers: 0
> + CheckSum: 633454091
> + Number: 10
> + - Name: .llvm_addrsig
> + Value: 0
> + SectionNumber: 11
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + SectionDefinition:
> + Length: 2
> + NumberOfRelocations: 0
> + NumberOfLinenumbers: 0
> + CheckSum: 384769216
> + Number: 11
> + - Name: '@feat.00'
> + Value: 0
> + SectionNumber: -1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + - Name: f
> + Value: 0
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
> + - Name: x
> + Value: 0
> + SectionNumber: 2
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_NULL
> + StorageClass: IMAGE_SYM_CLASS_STATIC
> + - Name: __main
> + Value: 32
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
> + - Name: main
> + Value: 48
> + SectionNumber: 1
> + SimpleType: IMAGE_SYM_TYPE_NULL
> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
> +...
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/COFF/basic-copy.test
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/COFF
> /basic-copy.test?rev=349605&view=auto
> ===========================================================================
> ===
> ---
> llvm/trunk/test/tools/llvm-objcopy/COFF/basic-copy.test
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/COFF/basic-copy.test
> Tue Dec 18 23:24:38 2018
> @@ -0,0 +1,42 @@
> +Test plain passthrough copying with llvm-objcopy, by
> checking that obj2yaml
> +produces identical output for both input and output
> object files/executables.
> +(Intentionally not comparing to the original input yaml,
> in case there are
> +superficial differences like line endings.) In order to
> have a check of the
> +whole file and not just individual fields with FileCheck,
> checking with
> +obj2yaml+cmp instead of llvm-readobj+cmp, as llvm-readobj
> also prints file
> +details that can differ between otherwise equal files
> (such as file offsets).
> +
> +Actual copied object files/executables can differ in,
> among others, the
> +following aspects:
> +- The padding of executable sections (lld uses 0xcc,
> which is int3 on x86)
> +- The actual layout of the string table (it can be filled
> linearly,
> + strings can be dedupliated, the table can be optimized
> by sharing tails
> + of longer strings; different parts in llvm do each of
> these three options)
> +- The size indication for an empty/missing string table
> can either be 4
> + or left out altogether
> +- Alignment of section data
> +- Checksums
> +
> +RUN: yaml2obj %p/Inputs/i386-obj.yaml > %t.i386.o
> +RUN: llvm-objcopy %t.i386.o %t.i386-copy.o
> +RUN: obj2yaml %t.i386.o > %t.i386.o.yaml
> +RUN: obj2yaml %t.i386-copy.o > %t.i386-copy.o.yaml
> +RUN: cmp %t.i386.o.yaml %t.i386-copy.o.yaml
> +
> +RUN: yaml2obj %p/Inputs/x86_64-obj.yaml > %t.x86_64.o
> +RUN: llvm-objcopy %t.x86_64.o %t.x86_64-copy.o
> +RUN: obj2yaml %t.x86_64.o > %t.x86_64.o.yaml
> +RUN: obj2yaml %t.x86_64-copy.o > %t.x86_64-copy.o.yaml
> +RUN: cmp %t.x86_64.o.yaml %t.x86_64-copy.o.yaml
> +
> +RUN: yaml2obj %p/Inputs/i386-exe.yaml > %t.i386.exe
> +RUN: llvm-objcopy %t.i386.exe %t.i386-copy.exe
> +RUN: obj2yaml %t.i386.exe > %t.i386.exe.yaml
> +RUN: obj2yaml %t.i386-copy.exe > %t.i386-copy.exe.yaml
> +RUN: cmp %t.i386.exe.yaml %t.i386-copy.exe.yaml
> +
> +RUN: yaml2obj %p/Inputs/x86_64-exe.yaml > %t.x86_64.exe
> +RUN: llvm-objcopy %t.x86_64.exe %t.x86_64-copy.exe
> +RUN: obj2yaml %t.x86_64.exe > %t.x86_64.exe.yaml
> +RUN: obj2yaml %t.x86_64-copy.exe >
> %t.x86_64-copy.exe.yaml
> +RUN: cmp %t.x86_64.exe.yaml %t.x86_64-copy.exe.yaml
>
> Modified: llvm/trunk/tools/llvm-objcopy/CMakeLists.txt
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CMakeList
> s.txt?rev=349605&r1=349604&r2=349605&view=diff
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/CMakeLists.txt
> (original)
> +++ llvm/trunk/tools/llvm-objcopy/CMakeLists.txt Tue Dec
> 18 23:24:38 2018
> @@ -17,6 +17,9 @@ add_llvm_tool(llvm-objcopy
> Buffer.cpp
> CopyConfig.cpp
> llvm-objcopy.cpp
> + COFF/COFFObjcopy.cpp
> + COFF/Reader.cpp
> + COFF/Writer.cpp
> ELF/ELFObjcopy.cpp
> ELF/Object.cpp
> DEPENDS
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/COFF
> Objcopy.cpp?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
> (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp Tue
> Dec 18 23:24:38 2018
> @@ -0,0 +1,40 @@
> +//===- COFFObjcopy.cpp
> ----------------------------------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#include "COFFObjcopy.h"
> +#include "Buffer.h"
> +#include "CopyConfig.h"
> +#include "Object.h"
> +#include "Reader.h"
> +#include "Writer.h"
> +#include "llvm-objcopy.h"
> +
> +#include "llvm/Object/Binary.h"
> +#include "llvm/Object/COFF.h"
> +#include <cassert>
> +
> +namespace llvm {
> +namespace objcopy {
> +namespace coff {
> +
> +using namespace object;
> +using namespace COFF;
> +
> +void executeObjcopyOnBinary(const CopyConfig &Config,
> + object::COFFObjectFile &In,
> Buffer &Out) {
> + COFFReader Reader(In);
> + std::unique_ptr<Object> Obj = Reader.create();
> + assert(Obj && "Unable to deserialize COFF object");
> + COFFWriter Writer(*Obj, Out);
> + Writer.write();
> +}
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/COFF
> Objcopy.h?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h
> (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h Tue
> Dec 18 23:24:38 2018
> @@ -0,0 +1,31 @@
> +//===- COFFObjcopy.h
> --------------------------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#ifndef LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
> +#define LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
> +
> +namespace llvm {
> +
> +namespace object {
> +class COFFObjectFile;
> +} // end namespace object
> +
> +namespace objcopy {
> +struct CopyConfig;
> +class Buffer;
> +
> +namespace coff {
> +void executeObjcopyOnBinary(const CopyConfig &Config,
> + object::COFFObjectFile &In,
> Buffer &Out);
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
> +
> +#endif // LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/Object.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/Obje
> ct.h?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/Object.h (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/Object.h Tue Dec 18
> 23:24:38 2018
> @@ -0,0 +1,110 @@
> +//===- Object.h
> -------------------------------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#ifndef LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
> +#define LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
> +
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/BinaryFormat/COFF.h"
> +#include "llvm/Object/COFF.h"
> +#include <cstddef>
> +#include <cstdint>
> +#include <vector>
> +
> +namespace llvm {
> +namespace objcopy {
> +namespace coff {
> +
> +struct Section {
> + object::coff_section Header;
> + ArrayRef<uint8_t> Contents;
> + std::vector<object::coff_relocation> Relocs;
> + StringRef Name;
> +};
> +
> +struct Symbol {
> + object::coff_symbol32 Sym;
> + StringRef Name;
> + ArrayRef<uint8_t> AuxData;
> +};
> +
> +struct Object {
> + bool IsPE = false;
> +
> + object::dos_header DosHeader;
> + ArrayRef<uint8_t> DosStub;
> +
> + object::coff_file_header CoffFileHeader;
> +
> + bool Is64 = false;
> + object::pe32plus_header PeHeader;
> + uint32_t BaseOfData = 0; // pe32plus_header lacks this
> field.
> +
> + std::vector<object::data_directory> DataDirectories;
> + std::vector<Section> Sections;
> + std::vector<Symbol> Symbols;
> +};
> +
> +// Copy between coff_symbol16 and coff_symbol32.
> +// The source and destination files can use either
> coff_symbol16 or
> +// coff_symbol32, while we always store them as
> coff_symbol32 in the
> +// intermediate data structure.
> +template <class Symbol1Ty, class Symbol2Ty>
> +void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
> + static_assert(sizeof(Dest.Name.ShortName) ==
> sizeof(Src.Name.ShortName),
> + "Mismatched name sizes");
> + memcpy(Dest.Name.ShortName, Src.Name.ShortName,
> sizeof(Dest.Name.ShortName));
> + Dest.Value = Src.Value;
> + Dest.SectionNumber = Src.SectionNumber;
> + Dest.Type = Src.Type;
> + Dest.StorageClass = Src.StorageClass;
> + Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
> +}
> +
> +// Copy between pe32_header and pe32plus_header.
> +// We store the intermediate state in a pe32plus_header.
> +template <class PeHeader1Ty, class PeHeader2Ty>
> +void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty
> &Src) {
> + Dest.Magic = Src.Magic;
> + Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
> + Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
> + Dest.SizeOfCode = Src.SizeOfCode;
> + Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
> + Dest.SizeOfUninitializedData =
> Src.SizeOfUninitializedData;
> + Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
> + Dest.BaseOfCode = Src.BaseOfCode;
> + Dest.ImageBase = Src.ImageBase;
> + Dest.SectionAlignment = Src.SectionAlignment;
> + Dest.FileAlignment = Src.FileAlignment;
> + Dest.MajorOperatingSystemVersion =
> Src.MajorOperatingSystemVersion;
> + Dest.MinorOperatingSystemVersion =
> Src.MinorOperatingSystemVersion;
> + Dest.MajorImageVersion = Src.MajorImageVersion;
> + Dest.MinorImageVersion = Src.MinorImageVersion;
> + Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
> + Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
> + Dest.Win32VersionValue = Src.Win32VersionValue;
> + Dest.SizeOfImage = Src.SizeOfImage;
> + Dest.SizeOfHeaders = Src.SizeOfHeaders;
> + Dest.CheckSum = Src.CheckSum;
> + Dest.Subsystem = Src.Subsystem;
> + Dest.DLLCharacteristics = Src.DLLCharacteristics;
> + Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
> + Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
> + Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
> + Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
> + Dest.LoaderFlags = Src.LoaderFlags;
> + Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
> +}
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
> +
> +#endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/Reader.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/Read
> er.cpp?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/Reader.cpp (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/Reader.cpp Tue Dec
> 18 23:24:38 2018
> @@ -0,0 +1,141 @@
> +//===- Reader.cpp
> ---------------------------------------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#include "Reader.h"
> +#include "Object.h"
> +#include "llvm-objcopy.h"
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/Object/COFF.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include <cstddef>
> +#include <cstdint>
> +
> +namespace llvm {
> +namespace objcopy {
> +namespace coff {
> +
> +using namespace object;
> +
> +Reader::~Reader() {}
> +
> +void COFFReader::readExecutableHeaders(Object &Obj) const
> {
> + const dos_header *DH = COFFObj.getDOSHeader();
> + Obj.Is64 = COFFObj.is64();
> + if (!DH)
> + return;
> +
> + Obj.IsPE = true;
> + Obj.DosHeader = *DH;
> + if (DH->AddressOfNewExeHeader > sizeof(*DH))
> + Obj.DosStub =
> ArrayRef<uint8_t>(reinterpret_cast<const uint8_t
> *>(&DH[1]),
> +
> DH->AddressOfNewExeHeader - sizeof(*DH));
> +
> + if (COFFObj.is64()) {
> + const pe32plus_header *PE32Plus = nullptr;
> + if (auto EC = COFFObj.getPE32PlusHeader(PE32Plus))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + Obj.PeHeader = *PE32Plus;
> + } else {
> + const pe32_header *PE32 = nullptr;
> + if (auto EC = COFFObj.getPE32Header(PE32))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + copyPeHeader(Obj.PeHeader, *PE32);
> + // The pe32plus_header (stored in Object) lacks the
> BaseOfData field.
> + Obj.BaseOfData = PE32->BaseOfData;
> + }
> +
> + for (size_t I = 0; I < Obj.PeHeader.NumberOfRvaAndSize;
> I++) {
> + const data_directory *Dir;
> + if (auto EC = COFFObj.getDataDirectory(I, Dir))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + Obj.DataDirectories.emplace_back(*Dir);
> + }
> +}
> +
> +void COFFReader::readSections(Object &Obj) const {
> + // Section indexing starts from 1.
> + for (size_t I = 1, E = COFFObj.getNumberOfSections(); I
> <= E; I++) {
> + const coff_section *Sec;
> + if (auto EC = COFFObj.getSection(I, Sec))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + Obj.Sections.push_back(Section());
> + Section &S = Obj.Sections.back();
> + S.Header = *Sec;
> + if (auto EC = COFFObj.getSectionContents(Sec,
> S.Contents))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + ArrayRef<coff_relocation> Relocs =
> COFFObj.getRelocations(Sec);
> + S.Relocs.insert(S.Relocs.end(), Relocs.begin(),
> Relocs.end());
> + if (auto EC = COFFObj.getSectionName(Sec, S.Name))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + if (Sec->hasExtendedRelocations())
> + reportError(
> + COFFObj.getFileName(),
> + make_error<StringError>("Extended relocations
> not supported yet",
> +
> object_error::parse_failed));
> + }
> +}
> +
> +void COFFReader::readSymbols(Object &Obj, bool IsBigObj)
> const {
> + for (uint32_t I = 0, E =
> COFFObj.getRawNumberOfSymbols(); I < E;) {
> + Expected<COFFSymbolRef> SymOrErr =
> COFFObj.getSymbol(I);
> + if (!SymOrErr)
> + reportError(COFFObj.getFileName(),
> SymOrErr.takeError());
> + COFFSymbolRef SymRef = *SymOrErr;
> +
> + Obj.Symbols.push_back(Symbol());
> + Symbol &Sym = Obj.Symbols.back();
> + // Copy symbols from the original form into an
> intermediate coff_symbol32.
> + if (IsBigObj)
> + copySymbol(Sym.Sym,
> + *reinterpret_cast<const coff_symbol32
> *>(SymRef.getRawPtr()));
> + else
> + copySymbol(Sym.Sym,
> + *reinterpret_cast<const coff_symbol16
> *>(SymRef.getRawPtr()));
> + if (auto EC = COFFObj.getSymbolName(SymRef,
> Sym.Name))
> + reportError(COFFObj.getFileName(), std::move(EC));
> + Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
> + assert((Sym.AuxData.size() %
> + (IsBigObj ? sizeof(coff_symbol32) :
> sizeof(coff_symbol16))) == 0);
> + I += 1 + SymRef.getNumberOfAuxSymbols();
> + }
> +}
> +
> +std::unique_ptr<Object> COFFReader::create() const {
> + auto Obj = llvm::make_unique<Object>();
> +
> + const coff_file_header *CFH = nullptr;
> + const coff_bigobj_file_header *CBFH = nullptr;
> + COFFObj.getCOFFHeader(CFH);
> + COFFObj.getCOFFBigObjHeader(CBFH);
> + bool IsBigObj = false;
> + if (CFH) {
> + Obj->CoffFileHeader = *CFH;
> + } else {
> + if (!CBFH)
> + reportError(COFFObj.getFileName(),
> + make_error<StringError>("No COFF file
> header returned",
> +
> object_error::parse_failed));
> + // Only copying the few fields from the bigobj header
> that we need
> + // and won't recreate in the end.
> + Obj->CoffFileHeader.Machine = CBFH->Machine;
> + Obj->CoffFileHeader.TimeDateStamp =
> CBFH->TimeDateStamp;
> + IsBigObj = true;
> + }
> +
> + readExecutableHeaders(*Obj);
> + readSections(*Obj);
> + readSymbols(*Obj, IsBigObj);
> +
> + return Obj;
> +}
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/Reader.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/Read
> er.h?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/Reader.h (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/Reader.h Tue Dec 18
> 23:24:38 2018
> @@ -0,0 +1,47 @@
> +//===- Reader.h
> -------------------------------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#ifndef LLVM_TOOLS_OBJCOPY_COFF_READER_H
> +#define LLVM_TOOLS_OBJCOPY_COFF_READER_H
> +
> +#include "Buffer.h"
> +#include "llvm/BinaryFormat/COFF.h"
> +#include "llvm/Object/COFF.h"
> +
> +namespace llvm {
> +namespace objcopy {
> +namespace coff {
> +
> +class Object;
> +
> +using object::COFFObjectFile;
> +
> +class Reader {
> +public:
> + virtual ~Reader();
> + virtual std::unique_ptr<Object> create() const = 0;
> +};
> +
> +class COFFReader : public Reader {
> + const COFFObjectFile &COFFObj;
> +
> + void readExecutableHeaders(Object &Obj) const;
> + void readSections(Object &Obj) const;
> + void readSymbols(Object &Obj, bool IsBigObj) const;
> +
> +public:
> + explicit COFFReader(const COFFObjectFile &O) :
> COFFObj(O) {}
> + std::unique_ptr<Object> create() const override;
> +};
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
> +
> +#endif // LLVM_TOOLS_OBJCOPY_COFF_READER_H
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/Writer.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/Writ
> er.cpp?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/Writer.cpp (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/Writer.cpp Tue Dec
> 18 23:24:38 2018
> @@ -0,0 +1,318 @@
> +//===- Writer.cpp
> ---------------------------------------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#include "Writer.h"
> +#include "Object.h"
> +#include "llvm-objcopy.h"
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/BinaryFormat/COFF.h"
> +#include "llvm/Object/COFF.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include <cstddef>
> +#include <cstdint>
> +
> +namespace llvm {
> +namespace objcopy {
> +namespace coff {
> +
> +using namespace object;
> +using namespace COFF;
> +
> +Writer::~Writer() {}
> +
> +void COFFWriter::layoutSections() {
> + for (auto &S : Obj.Sections) {
> + if (S.Header.SizeOfRawData > 0)
> + S.Header.PointerToRawData = FileSize;
> + FileSize += S.Header.SizeOfRawData; // For
> executables, this is already
> + // aligned to
> FileAlignment.
> + if (S.Header.NumberOfRelocations > 0)
> + S.Header.PointerToRelocations = FileSize;
> + FileSize += S.Relocs.size() *
> sizeof(coff_relocation);
> + FileSize = alignTo(FileSize, FileAlignment);
> +
> + if (S.Header.Characteristics &
> IMAGE_SCN_CNT_INITIALIZED_DATA)
> + SizeOfInitializedData += S.Header.SizeOfRawData;
> + }
> +}
> +
> +size_t COFFWriter::finalizeStringTable() {
> + for (auto &S : Obj.Sections)
> + if (S.Name.size() > COFF::NameSize)
> + StrTabBuilder.add(S.Name);
> +
> + for (const auto &S : Obj.Symbols)
> + if (S.Name.size() > COFF::NameSize)
> + StrTabBuilder.add(S.Name);
> +
> + StrTabBuilder.finalize();
> +
> + for (auto &S : Obj.Sections) {
> + if (S.Name.size() > COFF::NameSize) {
> + snprintf(S.Header.Name, sizeof(S.Header.Name),
> "/%d",
> + (int)StrTabBuilder.getOffset(S.Name));
> + } else {
> + strncpy(S.Header.Name, S.Name.data(),
> COFF::NameSize);
> + }
> + }
> + for (auto &S : Obj.Symbols) {
> + if (S.Name.size() > COFF::NameSize) {
> + S.Sym.Name.Offset.Zeroes = 0;
> + S.Sym.Name.Offset.Offset =
> StrTabBuilder.getOffset(S.Name);
> + } else {
> + strncpy(S.Sym.Name.ShortName, S.Name.data(),
> COFF::NameSize);
> + }
> + }
> + return StrTabBuilder.getSize();
> +}
> +
> +template <class SymbolTy>
> +std::pair<size_t, size_t>
> COFFWriter::finalizeSymbolTable() {
> + size_t SymTabSize = Obj.Symbols.size() *
> sizeof(SymbolTy);
> + for (const auto &S : Obj.Symbols)
> + SymTabSize += S.AuxData.size();
> + return std::make_pair(SymTabSize, sizeof(SymbolTy));
> +}
> +
> +void COFFWriter::finalize(bool IsBigObj) {
> + size_t SizeOfHeaders = 0;
> + FileAlignment = 1;
> + size_t PeHeaderSize = 0;
> + if (Obj.IsPE) {
> + Obj.DosHeader.AddressOfNewExeHeader =
> + sizeof(Obj.DosHeader) + Obj.DosStub.size();
> + SizeOfHeaders += Obj.DosHeader.AddressOfNewExeHeader
> + sizeof(PEMagic);
> +
> + FileAlignment = Obj.PeHeader.FileAlignment;
> + Obj.PeHeader.NumberOfRvaAndSize =
> Obj.DataDirectories.size();
> +
> + PeHeaderSize = Obj.Is64 ? sizeof(pe32plus_header) :
> sizeof(pe32_header);
> + SizeOfHeaders +=
> + PeHeaderSize + sizeof(data_directory) *
> Obj.DataDirectories.size();
> + }
> + Obj.CoffFileHeader.NumberOfSections =
> Obj.Sections.size();
> + SizeOfHeaders +=
> + IsBigObj ? sizeof(coff_bigobj_file_header) :
> sizeof(coff_file_header);
> + SizeOfHeaders += sizeof(coff_section) *
> Obj.Sections.size();
> + SizeOfHeaders = alignTo(SizeOfHeaders, FileAlignment);
> +
> + Obj.CoffFileHeader.SizeOfOptionalHeader =
> + PeHeaderSize + sizeof(data_directory) *
> Obj.DataDirectories.size();
> +
> + FileSize = SizeOfHeaders;
> + SizeOfInitializedData = 0;
> +
> + layoutSections();
> +
> + if (Obj.IsPE) {
> + Obj.PeHeader.SizeOfHeaders = SizeOfHeaders;
> + Obj.PeHeader.SizeOfInitializedData =
> SizeOfInitializedData;
> +
> + if (!Obj.Sections.empty()) {
> + const Section &S = Obj.Sections.back();
> + Obj.PeHeader.SizeOfImage =
> + alignTo(S.Header.VirtualAddress +
> S.Header.VirtualSize,
> + Obj.PeHeader.SectionAlignment);
> + }
> +
> + // If the PE header had a checksum, clear it, since
> it isn't valid
> + // any longer. (We don't calculate a new one.)
> + Obj.PeHeader.CheckSum = 0;
> + }
> +
> + size_t StrTabSize = finalizeStringTable();
> + size_t SymTabSize, SymbolSize;
> + std::tie(SymTabSize, SymbolSize) = IsBigObj
> + ?
> finalizeSymbolTable<coff_symbol32>()
> + :
> finalizeSymbolTable<coff_symbol16>();
> +
> + size_t PointerToSymbolTable = FileSize;
> + // StrTabSize <= 4 is the size of an empty string
> table, only consisting
> + // of the length field.
> + if (SymTabSize == 0 && StrTabSize <= 4) {
> + // Don't point to the symbol table if empty.
> + PointerToSymbolTable = 0;
> + // For executables, skip the length field of an empty
> string table.
> + if (Obj.IsPE)
> + StrTabSize = 0;
> + }
> +
> + size_t NumRawSymbols = SymTabSize / SymbolSize;
> + Obj.CoffFileHeader.PointerToSymbolTable =
> PointerToSymbolTable;
> + Obj.CoffFileHeader.NumberOfSymbols = NumRawSymbols;
> + FileSize += SymTabSize + StrTabSize;
> + FileSize = alignTo(FileSize, FileAlignment);
> +}
> +
> +void COFFWriter::writeHeaders(bool IsBigObj) {
> + uint8_t *Ptr = Buf.getBufferStart();
> + if (Obj.IsPE) {
> + memcpy(Ptr, &Obj.DosHeader, sizeof(Obj.DosHeader));
> + Ptr += sizeof(Obj.DosHeader);
> + memcpy(Ptr, Obj.DosStub.data(), Obj.DosStub.size());
> + Ptr += Obj.DosStub.size();
> + memcpy(Ptr, PEMagic, sizeof(PEMagic));
> + Ptr += sizeof(PEMagic);
> + }
> + if (!IsBigObj) {
> + memcpy(Ptr, &Obj.CoffFileHeader,
> sizeof(Obj.CoffFileHeader));
> + Ptr += sizeof(Obj.CoffFileHeader);
> + } else {
> + // Generate a coff_bigobj_file_header, filling it in
> with the values
> + // from Obj.CoffFileHeader. All extra fields that
> don't exist in
> + // coff_file_header can be set to hardcoded values.
> + coff_bigobj_file_header BigObjHeader;
> + BigObjHeader.Sig1 = IMAGE_FILE_MACHINE_UNKNOWN;
> + BigObjHeader.Sig2 = 0xffff;
> + BigObjHeader.Version =
> BigObjHeader::MinBigObjectVersion;
> + BigObjHeader.Machine = Obj.CoffFileHeader.Machine;
> + BigObjHeader.TimeDateStamp =
> Obj.CoffFileHeader.TimeDateStamp;
> + memcpy(BigObjHeader.UUID, BigObjMagic,
> sizeof(BigObjMagic));
> + BigObjHeader.unused1 = 0;
> + BigObjHeader.unused2 = 0;
> + BigObjHeader.unused3 = 0;
> + BigObjHeader.unused4 = 0;
> + // The value in Obj.CoffFileHeader.NumberOfSections
> is truncated, thus
> + // get the original one instead.
> + BigObjHeader.NumberOfSections = Obj.Sections.size();
> + BigObjHeader.PointerToSymbolTable =
> Obj.CoffFileHeader.PointerToSymbolTable;
> + BigObjHeader.NumberOfSymbols =
> Obj.CoffFileHeader.NumberOfSymbols;
> +
> + memcpy(Ptr, &BigObjHeader, sizeof(BigObjHeader));
> + Ptr += sizeof(BigObjHeader);
> + }
> + if (Obj.IsPE) {
> + if (Obj.Is64) {
> + memcpy(Ptr, &Obj.PeHeader, sizeof(Obj.PeHeader));
> + Ptr += sizeof(Obj.PeHeader);
> + } else {
> + pe32_header PeHeader;
> + copyPeHeader(PeHeader, Obj.PeHeader);
> + // The pe32plus_header (stored in Object) lacks the
> BaseOfData field.
> + PeHeader.BaseOfData = Obj.BaseOfData;
> +
> + memcpy(Ptr, &PeHeader, sizeof(PeHeader));
> + Ptr += sizeof(PeHeader);
> + }
> + for (const auto &DD : Obj.DataDirectories) {
> + memcpy(Ptr, &DD, sizeof(DD));
> + Ptr += sizeof(DD);
> + }
> + }
> + for (const auto &S : Obj.Sections) {
> + memcpy(Ptr, &S.Header, sizeof(S.Header));
> + Ptr += sizeof(S.Header);
> + }
> +}
> +
> +void COFFWriter::writeSections() {
> + for (const auto &S : Obj.Sections) {
> + uint8_t *Ptr = Buf.getBufferStart() +
> S.Header.PointerToRawData;
> + memcpy(Ptr, S.Contents.data(), S.Contents.size());
> +
> + // For executable sections, pad the remainder of the
> raw data size with
> + // 0xcc, which is int3 on x86.
> + if ((S.Header.Characteristics & IMAGE_SCN_CNT_CODE)
> &&
> + S.Header.SizeOfRawData > S.Contents.size())
> + memset(Ptr + S.Contents.size(), 0xcc,
> + S.Header.SizeOfRawData - S.Contents.size());
> +
> + Ptr += S.Header.SizeOfRawData;
> + memcpy(Ptr, S.Relocs.data(), S.Relocs.size() *
> sizeof(coff_relocation));
> + }
> +}
> +
> +template <class SymbolTy> void
> COFFWriter::writeSymbolStringTables() {
> + uint8_t *Ptr = Buf.getBufferStart() +
> Obj.CoffFileHeader.PointerToSymbolTable;
> + for (const auto &S : Obj.Symbols) {
> + // Convert symbols back to the right size, from
> coff_symbol32.
> + copySymbol<SymbolTy,
> coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
> + S.Sym);
> + Ptr += sizeof(SymbolTy);
> + memcpy(Ptr, S.AuxData.data(), S.AuxData.size());
> + Ptr += S.AuxData.size();
> + }
> + if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
> + // Always write a string table in object files, even
> an empty one.
> + StrTabBuilder.write(Ptr);
> + Ptr += StrTabBuilder.getSize();
> + }
> +}
> +
> +void COFFWriter::write(bool IsBigObj) {
> + finalize(IsBigObj);
> +
> + Buf.allocate(FileSize);
> +
> + writeHeaders(IsBigObj);
> + writeSections();
> + if (IsBigObj)
> + writeSymbolStringTables<coff_symbol32>();
> + else
> + writeSymbolStringTables<coff_symbol16>();
> +
> + if (Obj.IsPE)
> + patchDebugDirectory();
> +
> + if (auto E = Buf.commit())
> + reportError(Buf.getName(),
> errorToErrorCode(std::move(E)));
> +}
> +
> +// Locate which sections contain the debug directories,
> iterate over all
> +// the debug_directory structs in there, and set the
> PointerToRawData field
> +// in all of them, according to their new physical
> location in the file.
> +void COFFWriter::patchDebugDirectory() {
> + if (Obj.DataDirectories.size() < DEBUG_DIRECTORY)
> + return;
> + const data_directory *Dir =
> &Obj.DataDirectories[DEBUG_DIRECTORY];
> + if (Dir->Size <= 0)
> + return;
> + for (const auto &S : Obj.Sections) {
> + if (Dir->RelativeVirtualAddress >=
> S.Header.VirtualAddress &&
> + Dir->RelativeVirtualAddress <
> + S.Header.VirtualAddress +
> S.Header.SizeOfRawData) {
> + if (Dir->RelativeVirtualAddress + Dir->Size >
> + S.Header.VirtualAddress +
> S.Header.SizeOfRawData)
> + reportError(Buf.getName(),
> + make_error<StringError>(
> + "Debug directory extends past end
> of section",
> + object_error::parse_failed));
> +
> + size_t Offset = Dir->RelativeVirtualAddress -
> S.Header.VirtualAddress;
> + uint8_t *Ptr = Buf.getBufferStart() +
> S.Header.PointerToRawData + Offset;
> + uint8_t *End = Ptr + Dir->Size;
> + while (Ptr < End) {
> + debug_directory *Debug =
> reinterpret_cast<debug_directory *>(Ptr);
> + Debug->PointerToRawData =
> + S.Header.PointerToRawData + Offset +
> sizeof(debug_directory);
> + Ptr += sizeof(debug_directory) +
> Debug->SizeOfData;
> + Offset += sizeof(debug_directory) +
> Debug->SizeOfData;
> + }
> + // Debug directory found and patched, all done.
> + return;
> + }
> + }
> + reportError(Buf.getName(),
> + make_error<StringError>("Debug directory
> not found",
> +
> object_error::parse_failed));
> +}
> +
> +void COFFWriter::write() {
> + bool IsBigObj = Obj.Sections.size() >
> MaxNumberOfSections16;
> + if (IsBigObj && Obj.IsPE)
> + reportError(Buf.getName(),
> + make_error<StringError>("Too many
> sections for executable",
> +
> object_error::parse_failed));
> + write(IsBigObj);
> +}
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
>
> Added: llvm/trunk/tools/llvm-objcopy/COFF/Writer.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/Writ
> er.h?rev=349605&view=auto
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/COFF/Writer.h (added)
> +++ llvm/trunk/tools/llvm-objcopy/COFF/Writer.h Tue Dec 18
> 23:24:38 2018
> @@ -0,0 +1,68 @@
> +//===- Writer.h
> -------------------------------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of
> Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===---------------------------------------------------------------------
> -===//
> +
> +#ifndef LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
> +#define LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
> +
> +#include "Buffer.h"
> +#include "llvm/MC/StringTableBuilder.h"
> +#include <cstddef>
> +#include <utility>
> +
> +namespace llvm {
> +namespace objcopy {
> +namespace coff {
> +
> +class Object;
> +
> +class Writer {
> +protected:
> + Object &Obj;
> + Buffer &Buf;
> +
> +public:
> + virtual ~Writer();
> + virtual void write() = 0;
> +
> + Writer(Object &O, Buffer &B) : Obj(O), Buf(B) {}
> +};
> +
> +class COFFWriter : public Writer {
> + size_t FileSize;
> + size_t FileAlignment;
> + size_t SizeOfInitializedData;
> + StringTableBuilder StrTabBuilder;
> +
> + void layoutSections();
> + size_t finalizeStringTable();
> + template <class SymbolTy> std::pair<size_t, size_t>
> finalizeSymbolTable();
> +
> + void finalize(bool IsBigObj);
> +
> + void writeHeaders(bool IsBigObj);
> + void writeSections();
> + template <class SymbolTy> void
> writeSymbolStringTables();
> +
> + void write(bool IsBigObj);
> +
> + void patchDebugDirectory();
> +
> +public:
> + virtual ~COFFWriter() {}
> + void write() override;
> +
> + COFFWriter(Object &Obj, Buffer &Buf)
> + : Writer(Obj, Buf),
> StrTabBuilder(StringTableBuilder::WinCOFF) {}
> +};
> +
> +} // end namespace coff
> +} // end namespace objcopy
> +} // end namespace llvm
> +
> +#endif // LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
>
> Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objc
> opy.cpp?rev=349605&r1=349604&r2=349605&view=diff
> ===========================================================================
> ===
> --- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
> (original)
> +++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Tue Dec
> 18 23:24:38 2018
> @@ -9,6 +9,7 @@
>
> #include "llvm-objcopy.h"
> #include "Buffer.h"
> +#include "COFF/COFFObjcopy.h"
> #include "CopyConfig.h"
> #include "ELF/ELFObjcopy.h"
>
> @@ -19,6 +20,7 @@
> #include "llvm/Object/Archive.h"
> #include "llvm/Object/ArchiveWriter.h"
> #include "llvm/Object/Binary.h"
> +#include "llvm/Object/COFF.h"
> #include "llvm/Object/ELFObjectFile.h"
> #include "llvm/Object/ELFTypes.h"
> #include "llvm/Object/Error.h"
> @@ -125,6 +127,8 @@ static void
> executeObjcopyOnBinary(const
> Buffer &Out) {
> if (auto *ELFBinary =
> dyn_cast<object::ELFObjectFileBase>(&In))
> return elf::executeObjcopyOnBinary(Config,
> *ELFBinary, Out);
> + else if (auto *COFFBinary =
> dyn_cast<object::COFFObjectFile>(&In))
> + return coff::executeObjcopyOnBinary(Config,
> *COFFBinary, Out);
> else
> error("Unsupported object file format");
> }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
>
More information about the llvm-commits
mailing list