[llvm] remove empty __LLVM segment in llvm-bitcode-strip

When running llvm-bitcode-strip we want to remove the __LLVM
segment as well as the __bundle section when there are no other
sections in the segment.

Differential Revision: https://reviews.llvm.org/D120927
This commit is contained in:
Richard Howell 2022-03-03 11:23:44 -08:00
parent 1c6e752cfc
commit 5917219438
5 changed files with 181 additions and 29 deletions

View File

@ -29,6 +29,9 @@ struct MachOConfig {
// install-name-tool's id option
Optional<StringRef> SharedLibId;
// Segments to remove if they are empty
DenseSet<StringRef> EmptySegmentsToRemove;
// Boolean options
bool StripSwiftSymbols = false;
bool KeepUndefined = false;

View File

@ -258,6 +258,21 @@ static Error processLoadCommands(const MachOConfig &MachOConfig, Object &Obj) {
if (!MachOConfig.RPathToPrepend.empty())
Obj.updateLoadCommandIndexes();
// Remove any empty segments if required.
if (!MachOConfig.EmptySegmentsToRemove.empty()) {
auto RemovePred = [&MachOConfig](const LoadCommand &LC) {
if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_SEGMENT_64 ||
LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_SEGMENT) {
return LC.Sections.empty() &&
MachOConfig.EmptySegmentsToRemove.contains(
LC.getSegmentName().getValue());
}
return false;
};
if (Error E = Obj.removeLoadCommands(RemovePred))
return E;
}
return Error::success();
}

View File

@ -0,0 +1,117 @@
## Test bitcode segment is not removed when not empty.
# RUN: yaml2obj %s -o %t
# RUN: llvm-bitcode-strip -r %t -o %t2
# RUN: llvm-readobj --macho-segment --sections %t2 | FileCheck --implicit-check-not=Name: %s
# CHECK: Name: __text
# CHECK-NEXT: Segment: __TEXT
# CHECK: Name: __bundle
# CHECK-NEXT: Segment: __DATA
# CHECK: Name: __notbundle
# CHECK-NEXT: Segment: __LLVM
# CHECK: Cmd: LC_SEGMENT_64
# CHECK-NEXT: Name: __TEXT
# CHECK: Cmd: LC_SEGMENT_64
# CHECK-NEXT: Name: __DATA
# CHECK: Cmd: LC_SEGMENT_64
# CHECK-NEXT: Name: __LLVM
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x00000001
ncmds: 3
sizeofcmds: 536
flags: 0x00002000
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: __TEXT
vmaddr: 0
vmsize: 4
fileoff: 568
filesize: 4
maxprot: 7
initprot: 7
nsects: 1
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000000000000
content: 'AABBCCDD'
size: 4
offset: 568
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: __DATA
vmaddr: 4
vmsize: 4
fileoff: 572
filesize: 4
maxprot: 7
initprot: 7
nsects: 1
flags: 0
Sections:
- sectname: __bundle
segname: __DATA
addr: 0x0000000000000004
content: 'DDAADDAA'
size: 4
offset: 572
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_SEGMENT_64
cmdsize: 232
segname: __LLVM
vmaddr: 8
vmsize: 8
fileoff: 576
filesize: 8
maxprot: 7
initprot: 7
nsects: 2
flags: 0
Sections:
- sectname: __bundle
segname: __LLVM
addr: 0x0000000000000008
content: 'EEFFEEFF'
size: 4
offset: 576
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __notbundle
segname: __LLVM
addr: 0x0000000000000008
content: 'EEFFEEFF'
size: 4
offset: 580
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000

View File

@ -1,14 +1,16 @@
## Test bitcode section removal.
## Test bitcode section and segment removal.
# RUN: yaml2obj %s -o %t
# RUN: llvm-bitcode-strip -r %t -o %t2
# RUN: llvm-readobj --sections %t2 | FileCheck --implicit-check-not=Name: %s
# RUN: llvm-readobj --macho-segment --sections %t2 | FileCheck --implicit-check-not=Name: %s
# CHECK: Name: __text
# CHECK-NEXT: Segment: __TEXT
# CHECK: Name: __bundle
# CHECK-NEXT: Segment: __DATA
# CHECK: Name: __notbundle
# CHECK-NEXT: Segment: __LLVM
# CHECK: Cmd: LC_SEGMENT_64
# CHECK-NEXT: Name: __TEXT
# CHECK: Cmd: LC_SEGMENT_64
# CHECK-NEXT: Name: __DATA
--- !mach-o
FileHeader:
@ -16,21 +18,21 @@ FileHeader:
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x00000001
ncmds: 1
sizeofcmds: 392
ncmds: 3
sizeofcmds: 456
flags: 0x00002000
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 392
segname: ''
cmdsize: 152
segname: __TEXT
vmaddr: 0
vmsize: 16
fileoff: 424
filesize: 16
vmsize: 4
fileoff: 488
filesize: 4
maxprot: 7
initprot: 7
nsects: 4
nsects: 1
flags: 0
Sections:
- sectname: __text
@ -38,7 +40,7 @@ LoadCommands:
addr: 0x0000000000000000
content: 'AABBCCDD'
size: 4
offset: 424
offset: 488
align: 0
reloff: 0x00000000
nreloc: 0
@ -46,12 +48,24 @@ LoadCommands:
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: __DATA
vmaddr: 4
vmsize: 4
fileoff: 492
filesize: 4
maxprot: 7
initprot: 7
nsects: 1
flags: 0
Sections:
- sectname: __bundle
segname: __DATA
addr: 0x0000000000000004
content: 'DDAADDAA'
size: 4
offset: 428
offset: 492
align: 0
reloff: 0x00000000
nreloc: 0
@ -59,25 +73,24 @@ LoadCommands:
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: __LLVM
vmaddr: 8
vmsize: 4
fileoff: 496
filesize: 4
maxprot: 7
initprot: 7
nsects: 1
flags: 0
Sections:
- sectname: __bundle
segname: __LLVM
addr: 0x0000000000000008
content: 'EEFFEEFF'
size: 4
offset: 432
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __notbundle
segname: __LLVM
addr: 0x0000000000000008
content: 'EEFFEEFF'
size: 4
offset: 436
offset: 496
align: 0
reloff: 0x00000000
nreloc: 0

View File

@ -14,6 +14,7 @@
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/ObjCopy/CommonConfig.h"
#include "llvm/ObjCopy/ConfigManager.h"
#include "llvm/ObjCopy/MachO/MachOConfig.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CRC.h"
@ -1189,6 +1190,7 @@ objcopy::parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr,
DriverConfig DC;
ConfigManager ConfigMgr;
CommonConfig &Config = ConfigMgr.Common;
MachOConfig &MachOConfig = ConfigMgr.MachO;
BitcodeStripOptTable T;
unsigned MissingArgumentIndex, MissingArgumentCount;
opt::InputArgList InputArgs =
@ -1233,9 +1235,11 @@ objcopy::parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr,
if (!InputArgs.hasArg(BITCODE_STRIP_remove))
return createStringError(errc::invalid_argument, "no action specified");
// We only support -r for now, which removes all bitcode sections.
// We only support -r for now, which removes all bitcode sections and
// the __LLVM segment if it's now empty.
cantFail(Config.ToRemove.addMatcher(NameOrPattern::create(
"__LLVM,__bundle", MatchStyle::Literal, ErrorCallback)));
MachOConfig.EmptySegmentsToRemove.insert("__LLVM");
DC.CopyConfigs.push_back(std::move(ConfigMgr));
return std::move(DC);