From d6704e5ed91478464e551ee9d5520584978553ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez=20Troiti=C3=B1o?= Date: Tue, 20 Jul 2021 16:40:47 -0700 Subject: [PATCH] [llvm-objcopy][MachO] Ignore all LC_SUB_* commands. The LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA, LC_SUB_CLIENT, and LC_SUB_LIBRARY are used to indicate related libraries, binaries or framework names. Their only payload is the string with the name of the object. Adding those commands to the list of ignored/skipped load commands will avoid an error that stop the process of copying/stripping and will copy their contents verbatim. Additionally, in order to have a test for this case, `yaml2obj` now allows those four commands to contain a `Content`. Differential Revision: https://reviews.llvm.org/D106412 --- llvm/lib/ObjectYAML/MachOEmitter.cpp | 24 ++++++++ llvm/lib/ObjectYAML/MachOYAML.cpp | 24 ++++++++ .../llvm-objcopy/MachO/sub-load-commands.test | 56 +++++++++++++++++++ .../llvm-objcopy/MachO/MachOLayoutBuilder.cpp | 4 ++ 4 files changed, 108 insertions(+) create mode 100644 llvm/test/tools/llvm-objcopy/MachO/sub-load-commands.test diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp index 46e4dd05a737..63179ae61400 100644 --- a/llvm/lib/ObjectYAML/MachOEmitter.cpp +++ b/llvm/lib/ObjectYAML/MachOEmitter.cpp @@ -183,6 +183,30 @@ size_t writeLoadCommandData(MachOYAML::LoadCommand &LC, return writePayloadString(LC, OS); } +template <> +size_t writeLoadCommandData( + MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) { + return writePayloadString(LC, OS); +} + +template <> +size_t writeLoadCommandData( + MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) { + return writePayloadString(LC, OS); +} + +template <> +size_t writeLoadCommandData( + MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) { + return writePayloadString(LC, OS); +} + +template <> +size_t writeLoadCommandData( + MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) { + return writePayloadString(LC, OS); +} + template <> size_t writeLoadCommandData( MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) { diff --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp index dce82ab1cada..757e46cefc40 100644 --- a/llvm/lib/ObjectYAML/MachOYAML.cpp +++ b/llvm/lib/ObjectYAML/MachOYAML.cpp @@ -233,6 +233,30 @@ void mapLoadCommandData( IO.mapOptional("Content", LoadCommand.Content); } +template <> +void mapLoadCommandData( + IO &IO, MachOYAML::LoadCommand &LoadCommand) { + IO.mapOptional("Content", LoadCommand.Content); +} + +template <> +void mapLoadCommandData( + IO &IO, MachOYAML::LoadCommand &LoadCommand) { + IO.mapOptional("Content", LoadCommand.Content); +} + +template <> +void mapLoadCommandData( + IO &IO, MachOYAML::LoadCommand &LoadCommand) { + IO.mapOptional("Content", LoadCommand.Content); +} + +template <> +void mapLoadCommandData( + IO &IO, MachOYAML::LoadCommand &LoadCommand) { + IO.mapOptional("Content", LoadCommand.Content); +} + template <> void mapLoadCommandData( IO &IO, MachOYAML::LoadCommand &LoadCommand) { diff --git a/llvm/test/tools/llvm-objcopy/MachO/sub-load-commands.test b/llvm/test/tools/llvm-objcopy/MachO/sub-load-commands.test new file mode 100644 index 000000000000..c4629b6d1635 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/sub-load-commands.test @@ -0,0 +1,56 @@ +## This test verifies that llvm-objcopy correctly ignores the LC_SUB_* load +## commands. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-objcopy %t %t2 +# RUN: cmp %t %t2 +# RUN: llvm-objdump --macho --private-headers %t2 | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 4 + sizeofcmds: 72 + flags: 0x00200085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SUB_FRAMEWORK + cmdsize: 16 + umbrella: 12 + Content: 'Bar' + ZeroPadBytes: 1 + - cmd: LC_SUB_UMBRELLA + cmdsize: 16 + sub_umbrella: 12 + Content: 'Foo' + ZeroPadBytes: 1 + - cmd: LC_SUB_LIBRARY + cmdsize: 24 + sub_library: 12 + Content: 'libfoo' + ZeroPadBytes: 6 + - cmd: LC_SUB_CLIENT + cmdsize: 16 + client: 12 + Content: 'bar' + ZeroPadBytes: 1 + +# CHECK: Load command 0 +# CHECK: cmd LC_SUB_FRAMEWORK +# CHECK: cmdsize 16 +# CHECK: umbrella Bar (offset 12) +# CHECK: Load command 1 +# CHECK: cmd LC_SUB_UMBRELLA +# CHECK: cmdsize 16 +# CHECK: sub_umbrella Foo (offset 12) +# CHECK: Load command 2 +# CHECK: cmd LC_SUB_LIBRARY +# CHECK: cmdsize 24 +# CHECK: sub_library libfoo (offset 12) +# CHECK: Load command 3 +# CHECK: cmd LC_SUB_CLIENT +# CHECK: cmdsize 16 +# CHECK: client bar (offset 12) diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp index 6ed21806fe5e..3230e5ee9415 100644 --- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp @@ -380,6 +380,10 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) { case MachO::LC_SOURCE_VERSION: case MachO::LC_THREAD: case MachO::LC_UNIXTHREAD: + case MachO::LC_SUB_FRAMEWORK: + case MachO::LC_SUB_UMBRELLA: + case MachO::LC_SUB_CLIENT: + case MachO::LC_SUB_LIBRARY: // Nothing to update. break; default: