[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
This commit is contained in:
Daniel Rodríguez Troitiño 2021-07-20 16:40:47 -07:00
parent 5a333dc5da
commit d6704e5ed9
4 changed files with 108 additions and 0 deletions

View File

@ -183,6 +183,30 @@ size_t writeLoadCommandData<MachO::rpath_command>(MachOYAML::LoadCommand &LC,
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::sub_framework_command>(
MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::sub_umbrella_command>(
MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::sub_client_command>(
MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::sub_library_command>(
MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::build_version_command>(
MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {

View File

@ -233,6 +233,30 @@ void mapLoadCommandData<MachO::dylinker_command>(
IO.mapOptional("Content", LoadCommand.Content);
}
template <>
void mapLoadCommandData<MachO::sub_framework_command>(
IO &IO, MachOYAML::LoadCommand &LoadCommand) {
IO.mapOptional("Content", LoadCommand.Content);
}
template <>
void mapLoadCommandData<MachO::sub_umbrella_command>(
IO &IO, MachOYAML::LoadCommand &LoadCommand) {
IO.mapOptional("Content", LoadCommand.Content);
}
template <>
void mapLoadCommandData<MachO::sub_client_command>(
IO &IO, MachOYAML::LoadCommand &LoadCommand) {
IO.mapOptional("Content", LoadCommand.Content);
}
template <>
void mapLoadCommandData<MachO::sub_library_command>(
IO &IO, MachOYAML::LoadCommand &LoadCommand) {
IO.mapOptional("Content", LoadCommand.Content);
}
template <>
void mapLoadCommandData<MachO::build_version_command>(
IO &IO, MachOYAML::LoadCommand &LoadCommand) {

View File

@ -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)

View File

@ -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: