1
0
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:
Alexander Shaposhnikov 2020-05-26 16:49:56 -07:00
parent 79048330b0
commit 372d313844
11 changed files with 271 additions and 3 deletions

View File

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

View 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
- ''
- ''
- ''
...

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
};

View File

@ -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;
}

View File

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

View File

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

View File

@ -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">;