1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

[llvm-objcopy][MachO] Add support for --keep-undefined

This diff introduces --keep-undefined in llvm-objcopy/llvm-strip for Mach-O
which makes the tools preserve undefined symbols.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D97040
This commit is contained in:
Alexander Shaposhnikov 2021-03-08 18:54:00 -08:00
parent 299420b69e
commit 98aa5107b5
8 changed files with 122 additions and 2 deletions

View File

@ -470,6 +470,13 @@ them.
Mark all defined global symbols as weak in the output.
MACH-O-SPECIFIC OPTIONS
--------------------
.. option:: --keep-undefined
Keep undefined symbols, even if they would otherwise be stripped.
SUPPORTED FORMATS
-----------------

View File

@ -0,0 +1,105 @@
## This test verifies that llvm-objcopy and llvm-strip do not remove
## undefined symbols if --keep-undefined is specified.
# RUN: yaml2obj %s -o %t
# RUN: llvm-objcopy --strip-all --keep-undefined %t %t.stripped
# RUN: llvm-readobj --symbols %t.stripped | FileCheck %s
# RUN: llvm-strip --keep-undefined %t -o %t.stripped.2
# RUN: cmp %t.stripped %t.stripped.2
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: _u (1)
# CHECK-NEXT: Extern
# CHECK-NEXT: Type: Undef (0x0)
# CHECK-NEXT: Section: (0x0)
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
# CHECK-NEXT: Flags [ (0x220)
# CHECK-NEXT: AltEntry (0x200)
# CHECK-NEXT: NoDeadStrip (0x20)
# CHECK-NEXT: ]
# CHECK-NEXT: Value: 0x4
# CHECK-NEXT: }
# CHECK-NEXT: ]
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x1000007
cpusubtype: 0x3
filetype: 0x1
ncmds: 3
sizeofcmds: 256
flags: 0x2000
reserved: 0x0
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: ''
vmaddr: 0
vmsize: 0
fileoff: 288
filesize: 0
maxprot: 7
initprot: 7
nsects: 1
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0
size: 0
offset: 0x120
align: 0
reloff: 0x0
nreloc: 0
flags: 0x80000000
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: ''
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 288
nsyms: 2
stroff: 320
strsize: 8
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 1
iextdefsym: 1
nextdefsym: 0
iundefsym: 1
nundefsym: 1
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
LinkEditData:
NameList:
- n_strx: 4
n_type: 0xE
n_sect: 1
n_desc: 32
n_value: 0
- n_strx: 1
n_type: 0x1
n_sect: 0
n_desc: 544
n_value: 4
StringTable:
- ''
- _u
- _d
- ''
...

View File

@ -258,7 +258,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
!Config.SectionsToRename.empty() || !Config.SetSectionAlignment.empty() ||
Config.ExtractDWO || Config.LocalizeHidden || Config.PreserveDates ||
Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
Config.StripSwiftSymbols || Config.Weaken ||
Config.StripSwiftSymbols || Config.KeepUndefined || Config.Weaken ||
Config.DecompressDebugSections ||
Config.DiscardMode == DiscardType::Locals ||
!Config.SymbolsToAdd.empty() || Config.EntryExpr) {

View File

@ -84,6 +84,9 @@ def K : JoinedOrSeparate<["-"], "K">,
def keep_file_symbols : Flag<["--"], "keep-file-symbols">,
HelpText<"Do not remove file symbols">;
def keep_undefined : Flag<["--"], "keep-undefined">,
HelpText<"Do not remove undefined symbols">;
def only_keep_debug
: Flag<["--"], "only-keep-debug">,
HelpText<

View File

@ -720,6 +720,7 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
: DiscardType::Locals;
Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
Config.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined);
Config.DecompressDebugSections =
InputArgs.hasArg(OBJCOPY_decompress_debug_sections);
if (Config.DiscardMode == DiscardType::All) {
@ -1097,6 +1098,7 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
Config.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
Config.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
Config.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined);
for (auto Arg : InputArgs.filtered(STRIP_keep_section))
if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create(

View File

@ -215,6 +215,7 @@ struct CopyConfig {
bool ExtractDWO = false;
bool ExtractMainPartition = false;
bool KeepFileSymbols = false;
bool KeepUndefined = false;
bool LocalizeHidden = false;
bool OnlyKeepDebug = false;
bool PreserveDates = false;

View File

@ -532,7 +532,7 @@ 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)
if (Config.StripSwiftSymbols || Config.KeepUndefined)
return createStringError(llvm::errc::invalid_argument,
"option not supported by llvm-objcopy for ELF");
if (!Config.SplitDWO.empty())

View File

@ -94,6 +94,8 @@ static void updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
auto RemovePred = [Config, &Obj](const std::unique_ptr<SymbolEntry> &N) {
if (N->Referenced)
return false;
if (Config.KeepUndefined && N->isUndefinedSymbol())
return false;
if (Config.StripAll)
return true;
if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT))