[llvm] 842a8cc - [llvm-objcopy][MachO] Add support for removing Swift symbols
Alexander Shaposhnikov via llvm-commits
llvm-commits at lists.llvm.org
Tue May 26 16:52:12 PDT 2020
Author: Alexander Shaposhnikov
Date: 2020-05-26T16:49:56-07:00
New Revision: 842a8cc10c4146cee6cedd94fbf556c94b8ec365
URL: https://github.com/llvm/llvm-project/commit/842a8cc10c4146cee6cedd94fbf556c94b8ec365
DIFF: https://github.com/llvm/llvm-project/commit/842a8cc10c4146cee6cedd94fbf556c94b8ec365.diff
LOG: [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
Added:
llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
Modified:
llvm/docs/CommandGuide/llvm-strip.rst
llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
llvm/tools/llvm-objcopy/CopyConfig.cpp
llvm/tools/llvm-objcopy/CopyConfig.h
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
llvm/tools/llvm-objcopy/MachO/MachOReader.h
llvm/tools/llvm-objcopy/MachO/Object.h
llvm/tools/llvm-objcopy/StripOpts.td
Removed:
################################################################################
diff --git a/llvm/docs/CommandGuide/llvm-strip.rst b/llvm/docs/CommandGuide/llvm-strip.rst
index 455dc07e9c5c..a40537bd51c1 100644
--- a/llvm/docs/CommandGuide/llvm-strip.rst
+++ b/llvm/docs/CommandGuide/llvm-strip.rst
@@ -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
-----------
diff --git a/llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test b/llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
new file mode 100644
index 000000000000..a47a2dfb9f37
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
@@ -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
+ - ''
+ - ''
+ - ''
+...
diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index 2e363f26eacc..43ec2b1fa82f 100644
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -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) {
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index ff12e4bd89f3..1e151f01e01e 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -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);
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h
index be1dca46b968..acf783c7f278 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CopyConfig.h
@@ -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;
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index f7332b7f66fe..8e14c887170d 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -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))
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index be44fdbe45f9..ae8889af8c42 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -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;
};
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
index cf32f00f3615..39a8893c1eb1 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
@@ -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;
}
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.h b/llvm/tools/llvm-objcopy/MachO/MachOReader.h
index 00c8f0d55f61..a369907147d6 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOReader.h
+++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.h
@@ -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) {}
diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h
index b0123732f80a..b9ecd1e7818f 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.h
+++ b/llvm/tools/llvm-objcopy/MachO/Object.h
@@ -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.
diff --git a/llvm/tools/llvm-objcopy/StripOpts.td b/llvm/tools/llvm-objcopy/StripOpts.td
index cd02cffae673..001da23528d7 100644
--- a/llvm/tools/llvm-objcopy/StripOpts.td
+++ b/llvm/tools/llvm-objcopy/StripOpts.td
@@ -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">;
More information about the llvm-commits
mailing list