mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[llvm-objcopy][MachO] Add support for removing Swift symbols
cctools strip has the option "-T" which removes Swift symbols. This diff implements this option in llvm-strip for MachO. Test plan: make check-all Differential revision: https://reviews.llvm.org/D80099
This commit is contained in:
parent
79048330b0
commit
372d313844
@ -181,6 +181,10 @@ them.
|
||||
segments. Note that many tools will not be able to use an object without
|
||||
section headers.
|
||||
|
||||
.. option:: -T
|
||||
|
||||
Remove Swift symbols.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
|
221
test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
Normal file
221
test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
Normal file
@ -0,0 +1,221 @@
|
||||
## Verify that -T removes Swift symbols.
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000040070105 %s -o %t1
|
||||
# RUN: llvm-strip -x -T %t1
|
||||
# RUN: llvm-readobj -symbols %t1 | FileCheck --check-prefix=NO-SWIFT-SYMBOLS %s
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA_CONST \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000040070105 %s -o %t2
|
||||
# RUN: llvm-strip -x -T %t2
|
||||
# RUN: llvm-readobj -symbols %t2 | FileCheck --check-prefix=NO-SWIFT-SYMBOLS %s
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA_DIRTY \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000040070105 %s -o %t3
|
||||
# RUN: llvm-strip -x -T %t3
|
||||
# RUN: llvm-readobj -symbols %t3 | FileCheck --check-prefix=NO-SWIFT-SYMBOLS %s
|
||||
|
||||
# NO-SWIFT-SYMBOLS: Symbols [
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Symbol {
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Name: _main (1)
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Extern
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Type: Section (0xE)
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Section: __text (0x1)
|
||||
# NO-SWIFT-SYMBOLS-NEXT: RefType: UndefinedNonLazy (0x0)
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Flags [ (0x0)
|
||||
# NO-SWIFT-SYMBOLS-NEXT: ]
|
||||
# NO-SWIFT-SYMBOLS-NEXT: Value: 0x100000B70
|
||||
# NO-SWIFT-SYMBOLS-NEXT: }
|
||||
# NO-SWIFT-SYMBOLS-NEXT: ]
|
||||
|
||||
## Verify that -T does not remove (public) Swift symbols when the binary
|
||||
## does not contain __objc_imageinfo in one of the expected segments.
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
|
||||
# RUN: -D SECTION_NAME=__not_objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000040070105 %s -o %t4
|
||||
# RUN: llvm-strip -x -T %t4
|
||||
# RUN: llvm-readobj -symbols %t4 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__NOT_DATA \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000040070105 %s -o %t5
|
||||
# RUN: llvm-strip -x -T %t5
|
||||
# RUN: llvm-readobj -symbols %t5 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
|
||||
|
||||
## Verify that -T does not remove (public) Swift symbols when swift_version is zero.
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000000000000 %s -o %t6
|
||||
# RUN: llvm-strip -x -T %t6
|
||||
# RUN: llvm-readobj -symbols %t6 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
|
||||
|
||||
## Verify that -T does not remove (public) Swift symbols when the binary
|
||||
## contains invalid (too small) __objc_imageinfo.
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=4 \
|
||||
# RUN: -D SECTION_CONTENT=00000000 %s -o %t7
|
||||
# RUN: llvm-strip -x -T %t7
|
||||
# RUN: llvm-readobj -symbols %t7 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
|
||||
|
||||
## Verify that -T does not remove (public) Swift symbols
|
||||
## when the flag MH_DYLDLINK is not set.
|
||||
|
||||
# RUN: yaml2obj -D FLAGS=0x00200000 -D SEGMENT_NAME=__DATA \
|
||||
# RUN: -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
|
||||
# RUN: -D SECTION_CONTENT=0000000040070105 %s -o %t8
|
||||
# RUN: llvm-strip -x -T %t8
|
||||
# RUN: llvm-readobj -symbols %t8 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
|
||||
|
||||
# SWIFT-SYMBOLS: Symbols [
|
||||
# SWIFT-SYMBOLS-NEXT: Symbol {
|
||||
# SWIFT-SYMBOLS-NEXT: Name: _$S1a13PublicSymbol1Sivp (26)
|
||||
# SWIFT-SYMBOLS-NEXT: Extern
|
||||
# SWIFT-SYMBOLS-NEXT: Type: Section (0xE)
|
||||
# SWIFT-SYMBOLS-NEXT: Section: __text (0x1)
|
||||
# SWIFT-SYMBOLS-NEXT: RefType: UndefinedNonLazy (0x0)
|
||||
# SWIFT-SYMBOLS-NEXT: Flags [ (0x0)
|
||||
# SWIFT-SYMBOLS-NEXT: ]
|
||||
# SWIFT-SYMBOLS-NEXT: Value: 0x100001160
|
||||
# SWIFT-SYMBOLS-NEXT: }
|
||||
# SWIFT-SYMBOLS-NEXT: Symbol {
|
||||
# SWIFT-SYMBOLS-NEXT: Name: _$s1a13PublicSymbol2Sivp (1)
|
||||
# SWIFT-SYMBOLS-NEXT: Extern
|
||||
# SWIFT-SYMBOLS-NEXT: Type: Section (0xE)
|
||||
# SWIFT-SYMBOLS-NEXT: Section: __text (0x1)
|
||||
# SWIFT-SYMBOLS-NEXT: RefType: UndefinedNonLazy (0x0)
|
||||
# SWIFT-SYMBOLS-NEXT: Flags [ (0x0)
|
||||
# SWIFT-SYMBOLS-NEXT: ]
|
||||
# SWIFT-SYMBOLS-NEXT: Value: 0x100001168
|
||||
# SWIFT-SYMBOLS-NEXT: }
|
||||
# SWIFT-SYMBOLS-NEXT: Symbol {
|
||||
# SWIFT-SYMBOLS-NEXT: Name: _main (51)
|
||||
# SWIFT-SYMBOLS-NEXT: Extern
|
||||
# SWIFT-SYMBOLS-NEXT: Type: Section (0xE)
|
||||
# SWIFT-SYMBOLS-NEXT: Section: __text (0x1)
|
||||
# SWIFT-SYMBOLS-NEXT: RefType: UndefinedNonLazy (0x0)
|
||||
# SWIFT-SYMBOLS-NEXT: Flags [ (0x0)
|
||||
# SWIFT-SYMBOLS-NEXT: ]
|
||||
# SWIFT-SYMBOLS-NEXT: Value: 0x100000B70
|
||||
# SWIFT-SYMBOLS-NEXT: }
|
||||
# SWIFT-SYMBOLS-NEXT: ]
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x80000003
|
||||
filetype: 0x00000002
|
||||
ncmds: 4
|
||||
sizeofcmds: 400
|
||||
flags: [[FLAGS]]
|
||||
reserved: 0x00000000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 152
|
||||
segname: __TEXT
|
||||
vmaddr: 4294967296
|
||||
vmsize: 4096
|
||||
fileoff: 0
|
||||
filesize: 4096
|
||||
maxprot: 5
|
||||
initprot: 5
|
||||
nsects: 1
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __text
|
||||
segname: __TEXT
|
||||
addr: 0x0000000100000B70
|
||||
size: 845
|
||||
offset: 0x00000B70
|
||||
align: 4
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x80000400
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 152
|
||||
segname: [[SEGMENT_NAME]]
|
||||
vmaddr: 4294971392
|
||||
vmsize: 4096
|
||||
fileoff: 4096
|
||||
filesize: 4096
|
||||
maxprot: 3
|
||||
initprot: 3
|
||||
nsects: 1
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: [[SECTION_NAME]]
|
||||
segname: [[SEGMENT_NAME]]
|
||||
addr: 0x0000000100001090
|
||||
size: [[SECTION_SIZE]]
|
||||
offset: 0x00001090
|
||||
align: 2
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
content: "[[SECTION_CONTENT]]"
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 72
|
||||
segname: __LINKEDIT
|
||||
vmaddr: 4294975488
|
||||
vmsize: 4096
|
||||
fileoff: 8192
|
||||
filesize: 188
|
||||
maxprot: 1
|
||||
initprot: 1
|
||||
nsects: 0
|
||||
flags: 0
|
||||
- cmd: LC_SYMTAB
|
||||
cmdsize: 24
|
||||
symoff: 8192
|
||||
nsyms: 5
|
||||
stroff: 8272
|
||||
strsize: 108
|
||||
LinkEditData:
|
||||
NameList:
|
||||
- n_strx: 50
|
||||
n_type: 0x1E
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 4294971760
|
||||
- n_strx: 1
|
||||
n_type: 0x1E
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 4294971768
|
||||
- n_strx: 74
|
||||
n_type: 0x0F
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 4294971744
|
||||
- n_strx: 25
|
||||
n_type: 0x0F
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 4294971752
|
||||
- n_strx: 99
|
||||
n_type: 0x0F
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 4294970224
|
||||
StringTable:
|
||||
- ''
|
||||
- '_$s1a12LocalSymbol2Sivp'
|
||||
- '_$s1a13PublicSymbol2Sivp'
|
||||
- '_$S1a12LocalSymbol1Sivp'
|
||||
- '_$S1a13PublicSymbol1Sivp'
|
||||
- _main
|
||||
- ''
|
||||
- ''
|
||||
- ''
|
||||
...
|
@ -251,7 +251,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
||||
!Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
|
||||
!Config.SetSectionAlignment.empty() || Config.ExtractDWO ||
|
||||
Config.LocalizeHidden || Config.PreserveDates || Config.StripDWO ||
|
||||
Config.StripNonAlloc || Config.StripSections || Config.Weaken ||
|
||||
Config.StripNonAlloc || Config.StripSections ||
|
||||
Config.StripSwiftSymbols || Config.Weaken ||
|
||||
Config.DecompressDebugSections ||
|
||||
Config.DiscardMode == DiscardType::Locals ||
|
||||
!Config.SymbolsToAdd.empty() || Config.EntryExpr) {
|
||||
|
@ -912,6 +912,7 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
|
||||
if (auto Arg = InputArgs.getLastArg(STRIP_strip_all, STRIP_no_strip_all))
|
||||
Config.StripAll = Arg->getOption().getID() == STRIP_strip_all;
|
||||
Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu);
|
||||
Config.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
|
||||
Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
|
||||
Config.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
|
||||
|
||||
|
@ -219,6 +219,7 @@ struct CopyConfig {
|
||||
bool StripDebug = false;
|
||||
bool StripNonAlloc = false;
|
||||
bool StripSections = false;
|
||||
bool StripSwiftSymbols = false;
|
||||
bool StripUnneeded = false;
|
||||
bool Weaken = false;
|
||||
bool DecompressDebugSections = false;
|
||||
|
@ -604,7 +604,9 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
|
||||
// system. The only priority is that keeps/copies overrule removes.
|
||||
static Error handleArgs(const CopyConfig &Config, Object &Obj,
|
||||
const Reader &Reader, ElfType OutputElfType) {
|
||||
|
||||
if (Config.StripSwiftSymbols)
|
||||
return createStringError(llvm::errc::invalid_argument,
|
||||
"option not supported by llvm-objcopy for ELF");
|
||||
if (!Config.SplitDWO.empty())
|
||||
if (Error E =
|
||||
splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
|
||||
|
@ -65,13 +65,17 @@ static void updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
|
||||
Sym.Name = std::string(I->getValue());
|
||||
}
|
||||
|
||||
auto RemovePred = [Config](const std::unique_ptr<SymbolEntry> &N) {
|
||||
auto RemovePred = [Config, &Obj](const std::unique_ptr<SymbolEntry> &N) {
|
||||
if (N->Referenced)
|
||||
return false;
|
||||
if (Config.StripAll)
|
||||
return true;
|
||||
if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT))
|
||||
return true;
|
||||
// This behavior is consistent with cctools' strip.
|
||||
if (Config.StripSwiftSymbols && (Obj.Header.Flags & MachO::MH_DYLDLINK) &&
|
||||
Obj.SwiftVersion && *Obj.SwiftVersion && N->isSwiftSymbol())
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -283,6 +283,28 @@ void MachOReader::readIndirectSymbolTable(Object &O) const {
|
||||
}
|
||||
}
|
||||
|
||||
void MachOReader::readSwiftVersion(Object &O) const {
|
||||
struct ObjCImageInfo {
|
||||
uint32_t Version;
|
||||
uint32_t Flags;
|
||||
} ImageInfo;
|
||||
|
||||
for (const LoadCommand &LC : O.LoadCommands)
|
||||
for (const std::unique_ptr<Section> &Sec : LC.Sections)
|
||||
if (Sec->Sectname == "__objc_imageinfo" &&
|
||||
(Sec->Segname == "__DATA" || Sec->Segname == "__DATA_CONST" ||
|
||||
Sec->Segname == "__DATA_DIRTY") &&
|
||||
Sec->Content.size() >= sizeof(ObjCImageInfo)) {
|
||||
memcpy(&ImageInfo, Sec->Content.data(), sizeof(ObjCImageInfo));
|
||||
if (MachOObj.isLittleEndian() != sys::IsLittleEndianHost) {
|
||||
sys::swapByteOrder(ImageInfo.Version);
|
||||
sys::swapByteOrder(ImageInfo.Flags);
|
||||
}
|
||||
O.SwiftVersion = (ImageInfo.Flags >> 8) & 0xff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Object> MachOReader::create() const {
|
||||
auto Obj = std::make_unique<Object>();
|
||||
readHeader(*Obj);
|
||||
@ -297,6 +319,7 @@ std::unique_ptr<Object> MachOReader::create() const {
|
||||
readDataInCodeData(*Obj);
|
||||
readFunctionStartsData(*Obj);
|
||||
readIndirectSymbolTable(*Obj);
|
||||
readSwiftVersion(*Obj);
|
||||
return Obj;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ class MachOReader : public Reader {
|
||||
void readDataInCodeData(Object &O) const;
|
||||
void readFunctionStartsData(Object &O) const;
|
||||
void readIndirectSymbolTable(Object &O) const;
|
||||
void readSwiftVersion(Object &O) const;
|
||||
|
||||
public:
|
||||
explicit MachOReader(const object::MachOObjectFile &Obj) : MachOObj(Obj) {}
|
||||
|
@ -115,6 +115,11 @@ struct SymbolEntry {
|
||||
return (n_type & MachO::N_TYPE) == MachO::N_UNDF;
|
||||
}
|
||||
|
||||
bool isSwiftSymbol() const {
|
||||
return StringRef(Name).startswith("_$s") ||
|
||||
StringRef(Name).startswith("_$S");
|
||||
}
|
||||
|
||||
Optional<uint32_t> section() const {
|
||||
return n_sect == MachO::NO_SECT ? None : Optional<uint32_t>(n_sect);
|
||||
}
|
||||
@ -298,6 +303,8 @@ struct Object {
|
||||
LinkData DataInCode;
|
||||
LinkData FunctionStarts;
|
||||
|
||||
Optional<uint32_t> SwiftVersion;
|
||||
|
||||
/// The index of LC_SYMTAB load command if present.
|
||||
Optional<size_t> SymTabCommandIndex;
|
||||
/// The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.
|
||||
|
@ -15,3 +15,6 @@ def d : Flag<["-"], "d">,
|
||||
def S : Flag<["-"], "S">,
|
||||
Alias<strip_debug>,
|
||||
HelpText<"Alias for --strip-debug">;
|
||||
|
||||
def strip_swift_symbols : Flag<["-"], "T">,
|
||||
HelpText<"Remove Swift symbols">;
|
||||
|
Loading…
Reference in New Issue
Block a user