diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst index 343e1d8dbac90..c80ffd1ff97f1 100644 --- a/llvm/docs/CommandGuide/llvm-objcopy.rst +++ b/llvm/docs/CommandGuide/llvm-objcopy.rst @@ -62,6 +62,11 @@ multiple file formats. example, file and section symbols in ELF objects will not be discarded. Additionally, remove all debug sections. +.. option:: --dump-offload-bundle= + + Dump the HIP Offload Bundle entry specified by the URI syntax given, into a + code object file. + .. option:: --dump-section
= Dump the contents of section ``
`` into the file ````. Can be diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h index bad4bfdeaa46e..2ea4e558c5075 100644 --- a/llvm/include/llvm/ObjCopy/CommonConfig.h +++ b/llvm/include/llvm/ObjCopy/CommonConfig.h @@ -278,6 +278,8 @@ struct CommonConfig { bool StripUnneeded = false; bool Weaken = false; bool DecompressDebugSections = false; + bool DumpOffloadBundle = false; + bool NeedPositional = true; DebugCompressionType CompressionType = DebugCompressionType::None; diff --git a/llvm/include/llvm/Object/OffloadBundle.h b/llvm/include/llvm/Object/OffloadBundle.h index f4d5a1d878b8d..ed50cde884182 100644 --- a/llvm/include/llvm/Object/OffloadBundle.h +++ b/llvm/include/llvm/Object/OffloadBundle.h @@ -161,7 +161,7 @@ struct OffloadBundleURI { OffsetStr.getAsInteger(10, O); Str = Str.drop_front(OffsetStr.size()); - if (Str.consume_front("&size=")) + if (!Str.consume_front("&size=")) return createStringError(object_error::parse_failed, "Reading 'size' in URI"); @@ -188,8 +188,8 @@ LLVM_ABI Error extractOffloadBundleFatBinary( /// Extract code object memory from the given \p Source object file at \p Offset /// and of \p Size, and copy into \p OutputFileName. -LLVM_ABI Error extractCodeObject(const ObjectFile &Source, int64_t Offset, - int64_t Size, StringRef OutputFileName); +LLVM_ABI Error extractCodeObject(const ObjectFile &Source, size_t Offset, + size_t Size, StringRef OutputFileName); /// Extracts an Offload Bundle Entry given by URI LLVM_ABI Error extractOffloadBundleByURI(StringRef URIstr); diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp index eef8a2190c4d2..ddaece5ba168d 100644 --- a/llvm/lib/ObjCopy/ConfigManager.cpp +++ b/llvm/lib/ObjCopy/ConfigManager.cpp @@ -34,7 +34,8 @@ Expected ConfigManager::getCOFFConfig() const { Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty() || Common.GapFill != 0 || Common.PadTo != 0 || Common.ChangeSectionLMAValAll != 0 || - !Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty()) + !Common.ChangeSectionAddress.empty() || Common.DumpOffloadBundle || + !Common.ExtractSection.empty()) return createStringError(llvm::errc::invalid_argument, "option is not supported for COFF"); @@ -55,7 +56,8 @@ Expected ConfigManager::getMachOConfig() const { Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty() || Common.GapFill != 0 || Common.PadTo != 0 || Common.ChangeSectionLMAValAll != 0 || - !Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty()) + !Common.ChangeSectionAddress.empty() || Common.DumpOffloadBundle || + !Common.ExtractSection.empty()) return createStringError(llvm::errc::invalid_argument, "option is not supported for MachO"); @@ -76,7 +78,8 @@ Expected ConfigManager::getWasmConfig() const { !Common.SetSectionFlags.empty() || !Common.SetSectionType.empty() || !Common.SymbolsToRename.empty() || Common.GapFill != 0 || Common.PadTo != 0 || Common.ChangeSectionLMAValAll != 0 || - !Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty()) + !Common.ChangeSectionAddress.empty() || Common.DumpOffloadBundle || + !Common.ExtractSection.empty()) return createStringError(llvm::errc::invalid_argument, "only flags for section dumping, removal, and " "addition are supported"); @@ -106,7 +109,8 @@ Expected ConfigManager::getXCOFFConfig() const { Common.Weaken || Common.StripUnneeded || Common.DecompressDebugSections || Common.GapFill != 0 || Common.PadTo != 0 || Common.ChangeSectionLMAValAll != 0 || - !Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty()) { + !Common.ChangeSectionAddress.empty() || Common.DumpOffloadBundle || + !Common.ExtractSection.empty()) { return createStringError( llvm::errc::invalid_argument, "no flags are supported yet, only basic copying is allowed"); diff --git a/llvm/lib/Object/OffloadBundle.cpp b/llvm/lib/Object/OffloadBundle.cpp index 1e1042ce2bc21..6c28c061b481d 100644 --- a/llvm/lib/Object/OffloadBundle.cpp +++ b/llvm/lib/Object/OffloadBundle.cpp @@ -199,8 +199,8 @@ Error object::extractOffloadBundleFatBinary( return Error::success(); } -Error object::extractCodeObject(const ObjectFile &Source, int64_t Offset, - int64_t Size, StringRef OutputFileName) { +Error object::extractCodeObject(const ObjectFile &Source, size_t Offset, + size_t Size, StringRef OutputFileName) { Expected> BufferOrErr = FileOutputBuffer::create(OutputFileName, Size); @@ -211,12 +211,23 @@ Error object::extractCodeObject(const ObjectFile &Source, int64_t Offset, if (Error Err = InputBuffOrErr.takeError()) return Err; + if (Size > InputBuffOrErr->getBufferSize()) + return createStringError(inconvertibleErrorCode(), + "size in URI is larger than source"); + if (Offset > InputBuffOrErr->getBufferSize()) + return createStringError(inconvertibleErrorCode(), + "offset in URI is beyond the size of the source"); + if (Offset + Size > InputBuffOrErr->getBufferSize()) + return createStringError( + inconvertibleErrorCode(), + "offset + size in URI is beyond the size of the source"); + std::unique_ptr Buf = std::move(*BufferOrErr); std::copy(InputBuffOrErr->getBufferStart() + Offset, InputBuffOrErr->getBufferStart() + Offset + Size, Buf->getBufferStart()); if (Error E = Buf->commit()) - return E; + return createFileError(OutputFileName, std::move(E)); return Error::success(); } @@ -238,7 +249,7 @@ Error object::extractOffloadBundleByURI(StringRef URIstr) { // Create an ObjectFile object from uri.file_uri auto ObjOrErr = ObjectFile::createObjectFile(Uri.FileName); if (!ObjOrErr) - return ObjOrErr.takeError(); + return createFileError(Uri.FileName, ObjOrErr.takeError()); auto Obj = ObjOrErr->getBinary(); if (Error Err = diff --git a/llvm/test/tools/llvm-objcopy/ELF/dump-offload-bundle.test b/llvm/test/tools/llvm-objcopy/ELF/dump-offload-bundle.test new file mode 100644 index 0000000000000..132f33c8e6c55 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/dump-offload-bundle.test @@ -0,0 +1,73 @@ +## Test that --offloading with a fatbin works correctly +# REQUIRES: target={{x86_64-.*-linux.*}} +# REQUIRES: amdgpu-registered-target + +# RUN: yaml2obj %s -o %t.elf +# RUN: llvm-objcopy --dump-offload-bundle=file://%t.elf#offset=8192\&size=4048 +# RUN: llvm-objdump -d %t.elf-offset8192-size4048.co | FileCheck %s + +# RUN: not llvm-objcopy --dump-offload-bundle=file://%t.elf#offset=8192\&size=4048000 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR1 + +# RUN: not llvm-objcopy --dump-offload-bundle=file://%t.elf#offset=819200000\&size=4048 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR2 + +# RUN: not llvm-objcopy --dump-offload-bundle=file://%t.elf#offset=8192\&size=8048 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR3 + +# CHECK: s_load_dword s7, s[4:5], 0x24 // 000000001900: C00201C2 00000024 +# CHECK-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x0 // 000000001908: C00A0002 00000000 +# CHECK-NEXT: v_mov_b32_e32 v1, 0 // 000000001910: 7E020280 +# CHECK-NEXT: s_waitcnt lgkmcnt(0) // 000000001914: BF8CC07F +# CHECK-NEXT: s_and_b32 s4, s7, 0xffff // 000000001918: 8604FF07 0000FFFF +# CHECK-NEXT: s_mul_i32 s6, s6, s4 // 000000001920: 92060406 +# CHECK-NEXT: v_add_u32_e32 v0, s6, v0 // 000000001924: 68000006 +# CHECK-NEXT: v_lshlrev_b64 v[0:1], 2, v[0:1] // 000000001928: D28F0000 00020082 +# CHECK-NEXT: v_mov_b32_e32 v3, s3 // 000000001930: 7E060203 +# CHECK-NEXT: v_add_co_u32_e32 v2, vcc, s2, v0 // 000000001934: 32040002 +# CHECK-NEXT: v_addc_co_u32_e32 v3, vcc, v3, v1, vcc // 000000001938: 38060303 +# CHECK-NEXT: global_load_dword v2, v[2:3], off // 00000000193C: DC508000 027F0002 +# CHECK-NEXT: v_mov_b32_e32 v3, s1 // 000000001944: 7E060201 +# CHECK-NEXT: v_add_co_u32_e32 v0, vcc, s0, v0 // 000000001948: 32000000 +# CHECK-NEXT: v_addc_co_u32_e32 v1, vcc, v3, v1, vcc // 00000000194C: 38020303 +# CHECK-NEXT: global_load_dword v3, v[0:1], off // 000000001950: DC508000 037F0000 +# CHECK-NEXT: s_waitcnt vmcnt(0) // 000000001958: BF8C0F70 +# CHECK-NEXT: v_add_u32_e32 v2, v3, v2 // 00000000195C: 68040503 +# CHECK-NEXT: global_store_dword v[0:1], v2, off // 000000001960: DC708000 007F0200 +# CHECK-NEXT: s_endpgm // 000000001968: BF810000 + +# ERR1: error: size in URI is larger than source +# ERR2: error: offset in URI is beyond the size of the source +# ERR3: error: offset + size in URI is beyond the size of the source + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x2041B0 +ProgramHeaders: + - Type: PT_PHDR + Flags: [ PF_R ] + VAddr: 0x200040 + Align: 0x8 + Offset: 0x40 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x0 + Offset: 0x0 +Sections: + - Name: .hip_fatbin + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x201000 + AddressAlign: 0x1000 + Content: 5F5F434C414E475F4F46464C4F41445F42554E444C455F5F0200000000000000001000000000000000000000000000001B00000000000000686F73742D7838365F36342D756E6B6E6F776E2D6C696E75782D2D0010000000000000D00F0000000000001F0000000000000068697076342D616D6467636E2D616D642D616D646873612D2D676678393038000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007F454C460201014003000000000000000300E0000100000000000000000000004000000000000000100C0000000000003005000040003800090040000F000D000600000004000000400000000000000040000000000000004000000000000000F801000000000000F80100000000000008000000000000000100000004000000000000000000000000000000000000000000000000000000C008000000000000C008000000000000001000000000000001000000050000000009000000000000001900000000000000190000000000006C000000000000006C00000000000000001000000000000001000000060000007009000000000000702900000000000070290000000000007000000000000000900600000000000000100000000000000100000006000000E009000000000000E039000000000000E039000000000000000000000000000001000000000000000010000000000000020000000600000070090000000000007029000000000000702900000000000070000000000000007000000000000000080000000000000052E574640400000070090000000000007029000000000000702900000000000070000000000000009006000000000000010000000000000051E57464060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000004000000380200000000000038020000000000003802000000000000340500000000000034050000000000000400000000000000070000001D05000020000000414D44475055000083AE616D646873612E6B65726E656C7391DE0012AB2E616770725F636F756E7400A52E61726773DC001085AE2E616464726573735F7370616365A6676C6F62616CA52E6E616D65AA415F642E636F65726365A72E6F666673657400A52E73697A6508AB2E76616C75655F6B696E64AD676C6F62616C5F62756666657285AE2E616464726573735F7370616365A6676C6F62616CA52E6E616D65AA425F642E636F65726365A72E6F666673657408A52E73697A6508AB2E76616C75655F6B696E64AD676C6F62616C5F62756666657284A52E6E616D65A14EA72E6F666673657410A52E73697A6508AB2E76616C75655F6B696E64A862795F76616C756583A72E6F666673657418A52E73697A6504AB2E76616C75655F6B696E64B468696464656E5F626C6F636B5F636F756E745F7883A72E6F66667365741CA52E73697A6504AB2E76616C75655F6B696E64B468696464656E5F626C6F636B5F636F756E745F7983A72E6F666673657420A52E73697A6504AB2E76616C75655F6B696E64B468696464656E5F626C6F636B5F636F756E745F7A83A72E6F666673657424A52E73697A6502AB2E76616C75655F6B696E64B368696464656E5F67726F75705F73697A655F7883A72E6F666673657426A52E73697A6502AB2E76616C75655F6B696E64B368696464656E5F67726F75705F73697A655F7983A72E6F666673657428A52E73697A6502AB2E76616C75655F6B696E64B368696464656E5F67726F75705F73697A655F7A83A72E6F66667365742AA52E73697A6502AB2E76616C75655F6B696E64B268696464656E5F72656D61696E6465725F7883A72E6F66667365742CA52E73697A6502AB2E76616C75655F6B696E64B268696464656E5F72656D61696E6465725F7983A72E6F66667365742EA52E73697A6502AB2E76616C75655F6B696E64B268696464656E5F72656D61696E6465725F7A83A72E6F666673657440A52E73697A6508AB2E76616C75655F6B696E64B668696464656E5F676C6F62616C5F6F66667365745F7883A72E6F666673657448A52E73697A6508AB2E76616C75655F6B696E64B668696464656E5F676C6F62616C5F6F66667365745F7983A72E6F666673657450A52E73697A6508AB2E76616C75655F6B696E64B668696464656E5F676C6F62616C5F6F66667365745F7A83A72E6F666673657458A52E73697A6502AB2E76616C75655F6B696E64B068696464656E5F677269645F64696D73B92E67726F75705F7365676D656E745F66697865645F73697A6500B62E6B65726E6172675F7365676D656E745F616C69676E08B52E6B65726E6172675F7365676D656E745F73697A65CD0118A92E6C616E6775616765A84F70656E434C2043B12E6C616E67756167655F76657273696F6E920200B82E6D61785F666C61745F776F726B67726F75705F73697A65CD0400A52E6E616D65B25F5A3973696D706C65416464506A504B6A6DBB2E707269766174655F7365676D656E745F66697865645F73697A6500AB2E736770725F636F756E740CB12E736770725F7370696C6C5F636F756E7400A72E73796D626F6CB55F5A3973696D706C65416464506A504B6A6D2E6B64B82E756E69666F726D5F776F726B5F67726F75705F73697A6501B32E757365735F64796E616D69635F737461636BC2AB2E766770725F636F756E7404B12E766770725F7370696C6C5F636F756E7400AF2E7761766566726F6E745F73697A6540AD616D646873612E746172676574B9616D6467636E2D616D642D616D646873612D2D676678393038AE616D646873612E76657273696F6E92010200000000000000000000000000000000000000000000000000000000000000010000001203070000190000000000006C000000000000001400000011030600800800000000000040000000000000002A00000011000A00E03900000000000001000000000000000100000001000000010000001A000000000008400000D20001000000360A4A7A5238A4D3F113F4DD04000000040000000200000001000000000000000300000000000000000000000000000000000000005F5A3973696D706C65416464506A504B6A6D005F5A3973696D706C65416464506A504B6A6D2E6B64005F5F6869705F637569645F623730363264386333326134613933330000000000000000000000000000000000000000000000000000000000000000000000180100000000000080100000000000000000000000000000000000000000000000000000000000004000AF008C000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C20102C02400000002000AC0000000008002027E7FC08CBF07FF0486FFFF0000060406920600006800008FD2820002000302067E0200043203030638008050DC02007F020102067E0000003203030238008050DC00007F03700F8CBF03050468008070DC00027F00000081BF00000000060000000000000070070000000000000B000000000000001800000000000000050000000000000020080000000000000A000000000000004600000000000000F5FEFF6F00000000D0070000000000000400000000000000F807000000000000000000000000000000000000000000004C696E6B65723A20414D44204C4C442031392E302E3000414D4420636C616E672076657273696F6E2031392E302E306769742028202032343231322063393630313665636534313337356462646438663037356266333762643666633333323230376233290000414D4420636C616E672076657273696F6E2031382E302E3067697420287373683A2F2F6765727269746769742F6C696768746E696E672F65632F6C6C766D2D70726F6A65637420616D642D6D61696E6C696E652D6F70656E20323431373620663935303039613166393032313232343865313036333964653837653635636163616338643961372900000000000000000000000000000000000000000000000000460000000002080070290000000000000000000000000000010000001203070000190000000000006C000000000000001400000011030600800800000000000040000000000000002A00000011000A00E0390000000000000100000000000000002E6E6F7465002E64796E73796D002E676E752E68617368002E68617368002E64796E737472002E726F64617461002E74657874002E64796E616D6963002E72656C726F5F70616464696E67002E627373002E636F6D6D656E74002E73796D746162002E7368737472746162002E73747274616200005F5A3973696D706C65416464506A504B6A6D005F5A3973696D706C65416464506A504B6A6D2E6B64005F5F6869705F637569645F62373036326438633332613461393333005F44594E414D494300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000070000000200000000000000380200000000000038020000000000003405000000000000000000000000000004000000000000000000000000000000070000000B00000002000000000000007007000000000000700700000000000060000000000000000500000001000000080000000000000018000000000000000F000000F6FFFF6F0200000000000000D007000000000000D007000000000000280000000000000002000000000000000800000000000000000000000000000019000000050000000200000000000000F807000000000000F80700000000000028000000000000000200000000000000040000000000000004000000000000001F000000030000000200000000000000200800000000000020080000000000004600000000000000000000000000000001000000000000000000000000000000270000000100000002000000000000008008000000000000800800000000000040000000000000000000000000000000400000000000000000000000000000002F000000010000000600000000000000001900000000000000090000000000006C00000000000000000000000000000000010000000000000000000000000000350000000600000003000000000000007029000000000000700900000000000070000000000000000500000000000000080000000000000010000000000000003E000000080000000300000000000000E029000000000000E00900000000000020060000000000000000000000000000010000000000000000000000000000004D000000080000000300000000000000E039000000000000E0090000000000000100000000000000000000000000000001000000000000000000000000000000520000000100000030000000000000000000000000000000E009000000000000F0000000000000000000000000000000010000000000000001000000000000005B0000000200000000000000000000000000000000000000D00A00000000000078000000000000000E0000000200000008000000000000001800000000000000630000000300000000000000000000000000000000000000480B00000000000075000000000000000000000000000000010000000000000000000000000000006D0000000300000000000000000000000000000000000000BD0B0000000000004F00000000000000000000000000000001000000000000000000000000000000 + - Name: .hipFatBinSegment + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x202FD0 + AddressAlign: 0x8 + Content: '465049480100000000102000000000000000000000000000' +... diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index 3d7f33cd64bf4..5a3051416adcf 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -16,6 +16,8 @@ #include "llvm/ObjCopy/ConfigManager.h" #include "llvm/ObjCopy/MachO/MachOConfig.h" #include "llvm/Object/Binary.h" +#include "llvm/Object/OffloadBinary.h" +#include "llvm/Object/OffloadBundle.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CRC.h" @@ -284,6 +286,13 @@ static Expected parseVisibilityType(StringRef VisType) { return type; } +Expected llvm::objcopy::parseDumpOffloadBundle(StringRef URI) { + if (Error Err = object::extractOffloadBundleByURI(URI)) + return std::move(Err); + + return URI; +} + namespace { struct TargetInfo { FileFormat Format; @@ -729,6 +738,15 @@ objcopy::parseObjcopyOptions(ArrayRef ArgsArr, SmallVector Positional; + ConfigManager ConfigMgr; + CommonConfig &Config = ConfigMgr.Common; + COFFConfig &COFFConfig = ConfigMgr.COFF; + ELFConfig &ELFConfig = ConfigMgr.ELF; + MachOConfig &MachOConfig = ConfigMgr.MachO; + + if (InputArgs.hasArg(OBJCOPY_dump_offload_bundle)) + Config.NeedPositional = false; + for (auto *Arg : InputArgs.filtered(OBJCOPY_UNKNOWN)) return createStringError(errc::invalid_argument, "unknown argument '%s'", Arg->getAsString(InputArgs).c_str()); @@ -736,27 +754,31 @@ objcopy::parseObjcopyOptions(ArrayRef ArgsArr, for (auto *Arg : InputArgs.filtered(OBJCOPY_INPUT)) Positional.push_back(Arg->getValue()); - if (Positional.empty()) + if (Positional.empty() && Config.NeedPositional) return createStringError(errc::invalid_argument, "no input file specified"); - if (Positional.size() > 2) + if (Positional.size() > 2 && Config.NeedPositional) return createStringError(errc::invalid_argument, "too many positional arguments"); - ConfigManager ConfigMgr; - CommonConfig &Config = ConfigMgr.Common; - COFFConfig &COFFConfig = ConfigMgr.COFF; - ELFConfig &ELFConfig = ConfigMgr.ELF; - MachOConfig &MachOConfig = ConfigMgr.MachO; - Config.InputFilename = Positional[0]; - Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1]; - if (InputArgs.hasArg(OBJCOPY_target) && - (InputArgs.hasArg(OBJCOPY_input_target) || - InputArgs.hasArg(OBJCOPY_output_target))) - return createStringError( - errc::invalid_argument, - "--target cannot be used with --input-target or --output-target"); + if (Arg *A = InputArgs.getLastArg(OBJCOPY_dump_offload_bundle)) { + for (StringRef URIStr : llvm::split(A->getValue(), ",")) { + Expected res = llvm::objcopy::parseDumpOffloadBundle(URIStr); + if (!res) + return res.takeError(); + } + } + if (Config.NeedPositional) { + Config.InputFilename = Positional[0]; + Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1]; + if (InputArgs.hasArg(OBJCOPY_target) && + (InputArgs.hasArg(OBJCOPY_input_target) || + InputArgs.hasArg(OBJCOPY_output_target))) + return createStringError( + errc::invalid_argument, + "--target cannot be used with --input-target or --output-target"); + } if (InputArgs.hasArg(OBJCOPY_regex) && InputArgs.hasArg(OBJCOPY_wildcard)) return createStringError(errc::invalid_argument, "--regex and --wildcard are incompatible"); @@ -1427,9 +1449,9 @@ objcopy::parseInstallNameToolOptions(ArrayRef ArgsArr) { Arg->getAsString(InputArgs).c_str()); for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT)) Positional.push_back(Arg->getValue()); - if (Positional.empty()) + if (Positional.empty() && Config.NeedPositional) return createStringError(errc::invalid_argument, "no input file specified"); - if (Positional.size() > 1) + if (Positional.size() > 1 && Config.NeedPositional) return createStringError( errc::invalid_argument, "llvm-install-name-tool expects a single input file"); @@ -1445,7 +1467,6 @@ objcopy::parseInstallNameToolOptions(ArrayRef ArgsArr) { return createStringError(errc::invalid_argument, "input file: %s is not a Mach-O file", Config.InputFilename.str().c_str()); - DC.CopyConfigs.push_back(std::move(ConfigMgr)); return std::move(DC); } @@ -1552,6 +1573,11 @@ objcopy::parseStripOptions(ArrayRef RawArgsArr, exit(0); } + ConfigManager ConfigMgr; + CommonConfig &Config = ConfigMgr.Common; + ELFConfig &ELFConfig = ConfigMgr.ELF; + MachOConfig &MachOConfig = ConfigMgr.MachO; + SmallVector Positional; for (auto *Arg : InputArgs.filtered(STRIP_UNKNOWN)) return createStringError(errc::invalid_argument, "unknown argument '%s'", @@ -1568,11 +1594,6 @@ objcopy::parseStripOptions(ArrayRef RawArgsArr, errc::invalid_argument, "multiple input files cannot be used in combination with -o"); - ConfigManager ConfigMgr; - CommonConfig &Config = ConfigMgr.Common; - ELFConfig &ELFConfig = ConfigMgr.ELF; - MachOConfig &MachOConfig = ConfigMgr.MachO; - if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard)) return createStringError(errc::invalid_argument, "--regex and --wildcard are incompatible"); diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.h b/llvm/tools/llvm-objcopy/ObjcopyOptions.h index 3b8878981da47..0d8c5b627f110 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.h +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.h @@ -51,6 +51,11 @@ parseBitcodeStripOptions(ArrayRef ArgsArr, Expected parseStripOptions(ArrayRef ArgsArr, llvm::function_ref ErrorCallback); + +// parseDumpOffloadBundle reads a URI as a string and extracts the raw memory +// into a code object file named from the URI string given. +Expected parseDumpOffloadBundle(StringRef URI); + } // namespace objcopy } // namespace llvm diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td index fbc6a59d9461e..8b00274cc0a58 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -235,10 +235,13 @@ defm skip_symbols "be repeated to read symbols from many files">, MetaVarName<"filename">; +defm dump_offload_bundle : Eq<"dump-offload-bundle", "Dump the contents specified by URI">; + defm dump_section : Eq<"dump-section", "Dump contents of section named
into file ">, MetaVarName<"section=file">; + defm prefix_symbols : Eq<"prefix-symbols", "Add to the start of every symbol name">, MetaVarName<"prefix">; diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index ad67b673b2cc7..7d6395e98c2c2 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -124,88 +124,89 @@ static Error executeObjcopyOnRawBinary(ConfigManager &ConfigMgr, static Error executeObjcopy(ConfigManager &ConfigMgr) { CommonConfig &Config = ConfigMgr.Common; - Expected PermsApplierOrErr = - FilePermissionsApplier::create(Config.InputFilename); - if (!PermsApplierOrErr) - return PermsApplierOrErr.takeError(); - - std::function ObjcopyFunc; - - OwningBinary BinaryHolder; - std::unique_ptr MemoryBufferHolder; - - if (Config.InputFormat == FileFormat::Binary || - Config.InputFormat == FileFormat::IHex) { - ErrorOr> BufOrErr = - MemoryBuffer::getFileOrSTDIN(Config.InputFilename); - if (!BufOrErr) - return createFileError(Config.InputFilename, BufOrErr.getError()); - MemoryBufferHolder = std::move(*BufOrErr); - - if (Config.InputFormat == FileFormat::Binary) - ObjcopyFunc = [&](raw_ostream &OutFile) -> Error { - // Handle FileFormat::Binary. - return executeObjcopyOnRawBinary(ConfigMgr, *MemoryBufferHolder, - OutFile); - }; - else - ObjcopyFunc = [&](raw_ostream &OutFile) -> Error { - // Handle FileFormat::IHex. - return executeObjcopyOnIHex(ConfigMgr, *MemoryBufferHolder, OutFile); - }; - } else { - Expected> BinaryOrErr = - createBinary(Config.InputFilename); - if (!BinaryOrErr) - return createFileError(Config.InputFilename, BinaryOrErr.takeError()); - BinaryHolder = std::move(*BinaryOrErr); - - if (Archive *Ar = dyn_cast(BinaryHolder.getBinary())) { - // Handle Archive. - if (Error E = executeObjcopyOnArchive(ConfigMgr, *Ar)) - return E; + if (Config.NeedPositional) { + Expected PermsApplierOrErr = + FilePermissionsApplier::create(Config.InputFilename); + if (!PermsApplierOrErr) + return PermsApplierOrErr.takeError(); + + std::function ObjcopyFunc; + + OwningBinary BinaryHolder; + std::unique_ptr MemoryBufferHolder; + + if (Config.InputFormat == FileFormat::Binary || + Config.InputFormat == FileFormat::IHex) { + ErrorOr> BufOrErr = + MemoryBuffer::getFileOrSTDIN(Config.InputFilename); + if (!BufOrErr) + return createFileError(Config.InputFilename, BufOrErr.getError()); + MemoryBufferHolder = std::move(*BufOrErr); + + if (Config.InputFormat == FileFormat::Binary) { + ObjcopyFunc = [&](raw_ostream &OutFile) -> Error { + // Handle FileFormat::Binary. + return executeObjcopyOnRawBinary(ConfigMgr, *MemoryBufferHolder, + OutFile); + }; + } else + ObjcopyFunc = [&](raw_ostream &OutFile) -> Error { + // Handle FileFormat::IHex. + return executeObjcopyOnIHex(ConfigMgr, *MemoryBufferHolder, OutFile); + }; } else { - // Handle llvm::object::Binary. - ObjcopyFunc = [&](raw_ostream &OutFile) -> Error { - return executeObjcopyOnBinary(ConfigMgr, *BinaryHolder.getBinary(), - OutFile); - }; + Expected> BinaryOrErr = + createBinary(Config.InputFilename); + if (!BinaryOrErr) + return createFileError(Config.InputFilename, BinaryOrErr.takeError()); + BinaryHolder = std::move(*BinaryOrErr); + + if (Archive *Ar = dyn_cast(BinaryHolder.getBinary())) { + // Handle Archive. + if (Error E = executeObjcopyOnArchive(ConfigMgr, *Ar)) + return E; + } else { + // Handle llvm::object::Binary. + ObjcopyFunc = [&](raw_ostream &OutFile) -> Error { + return executeObjcopyOnBinary(ConfigMgr, *BinaryHolder.getBinary(), + OutFile); + }; + } } - } - if (ObjcopyFunc) { - if (Config.SplitDWO.empty()) { - // Apply transformations described by Config and store result into - // Config.OutputFilename using specified ObjcopyFunc function. - if (Error E = writeToOutput(Config.OutputFilename, ObjcopyFunc)) - return E; - } else { - Config.ExtractDWO = true; - Config.StripDWO = false; - // Copy .dwo tables from the Config.InputFilename into Config.SplitDWO - // file using specified ObjcopyFunc function. - if (Error E = writeToOutput(Config.SplitDWO, ObjcopyFunc)) - return E; - Config.ExtractDWO = false; - Config.StripDWO = true; - // Apply transformations described by Config, remove .dwo tables and - // store result into Config.OutputFilename using specified ObjcopyFunc - // function. - if (Error E = writeToOutput(Config.OutputFilename, ObjcopyFunc)) - return E; + if (ObjcopyFunc) { + if (Config.SplitDWO.empty()) { + // Apply transformations described by Config and store result into + // Config.OutputFilename using specified ObjcopyFunc function. + if (Error E = writeToOutput(Config.OutputFilename, ObjcopyFunc)) + return E; + } else { + Config.ExtractDWO = true; + Config.StripDWO = false; + // Copy .dwo tables from the Config.InputFilename into Config.SplitDWO + // file using specified ObjcopyFunc function. + if (Error E = writeToOutput(Config.SplitDWO, ObjcopyFunc)) + return E; + Config.ExtractDWO = false; + Config.StripDWO = true; + // Apply transformations described by Config, remove .dwo tables and + // store result into Config.OutputFilename using specified ObjcopyFunc + // function. + if (Error E = writeToOutput(Config.OutputFilename, ObjcopyFunc)) + return E; + } } - } - - if (Error E = - PermsApplierOrErr->apply(Config.OutputFilename, Config.PreserveDates)) - return E; - if (!Config.SplitDWO.empty()) - if (Error E = - PermsApplierOrErr->apply(Config.SplitDWO, Config.PreserveDates, - static_cast(0666))) + if (Error E = PermsApplierOrErr->apply(Config.OutputFilename, + Config.PreserveDates)) return E; + if (!Config.SplitDWO.empty()) + if (Error E = + PermsApplierOrErr->apply(Config.SplitDWO, Config.PreserveDates, + static_cast(0666))) + return E; + } return Error::success(); }