[lld-macho] Add flag --keep-icf-stabs to LLD for MachO by alx32 · Pull Request #93137 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-lld
@llvm/pr-subscribers-lld-macho
Author: None (alx32)
Changes
This change adds the --keep-icf-stabs
which, when specified, preserves symbols that were folded by ICF in the binary's stabs entries.
This allows dsymutil
to process debug information for the folded symbols.
Full diff: https://github.com/llvm/llvm-project/pull/93137.diff
5 Files Affected:
- (modified) lld/MachO/Config.h (+1)
- (modified) lld/MachO/Driver.cpp (+1)
- (modified) lld/MachO/Options.td (+3)
- (modified) lld/MachO/SyntheticSections.cpp (+10-5)
- (modified) lld/test/MachO/stabs-icf.s (+27)
diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 7b45f7f4c39a1..96253e15f7eea 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -193,6 +193,7 @@ struct Configuration { UndefinedSymbolTreatment undefinedSymbolTreatment = UndefinedSymbolTreatment::error; ICFLevel icfLevel = ICFLevel::none;
- bool keepICFStabs = false; ObjCStubsMode objcStubsMode = ObjCStubsMode::fast; llvm::MachO::HeaderFileType outputType; std::vectorllvm::StringRef systemLibraryRoots; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index d4d8d53d69eea..4ee6a907b2f46 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1648,6 +1648,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS, config->emitChainedFixups || args.hasArg(OPT_init_offsets); config->emitRelativeMethodLists = shouldEmitRelativeMethodLists(args); config->icfLevel = getICFLevel(args);
- config->keepICFStabs = args.hasArg(OPT_keep_icf_stabs); config->dedupStrings = args.hasFlag(OPT_deduplicate_strings, OPT_no_deduplicate_strings, true); config->deadStripDuplicates = args.hasArg(OPT_dead_strip_duplicates); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 11458d92b3abe..0ad487437a554 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -85,6 +85,9 @@ def icf_eq: Joined<["--"], "icf=">, HelpText<"Set level for identical code folding (default: none)">, MetaVarName<"[none,safe,all]">, Group; +def keep_icf_stabs: Joined<["--"], "keep-icf-stabs">,
- HelpText<"For symbols that were folded by ICF - retain them as stabs entries">,
- Group;
def lto_O: Joined<["--"], "lto-O">, HelpText<"Set optimization level for LTO (default: 2)">, MetaVarName<"">, diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 29070810bb049..b3fe223938bf5 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -1220,15 +1220,18 @@ void SymtabSection::emitStabs() { continue;
// Constant-folded symbols go in the executable's symbol table, but don't
// get a stabs entry.
if (defined->wasIdenticalCodeFolded)
// get a stabs entry unless --keep-icf-stabs flag is specified
if (!config->keepICFStabs && defined->wasIdenticalCodeFolded) continue; ObjFile *file = defined->getObjectFile(); if (!file || !file->compileUnit) continue;
symbolsNeedingStabs.emplace_back(defined, defined->isec()->getFile()->id);
// We use 'originalIsec' to get the file id of the symbol since 'isec()'
// might point to the merged ICF symbol's file
symbolsNeedingStabs.emplace_back(defined,
} }defined->originalIsec->getFile()->id);
@@ -1243,7 +1246,9 @@ void SymtabSection::emitStabs() { InputFile *lastFile = nullptr; for (SortingPair &pair : symbolsNeedingStabs) { Defined *defined = pair.first;
- InputSection *isec = defined->isec();
// We use 'originalIsec' of the symbol since we care about the actual origin
// of the symbol, not the canonical location returned by
isec()
.InputSection *isec = defined->originalIsec; ObjFile *file = cast(isec->getFile());
if (lastFile == nullptr || lastFile != file) {
@@ -1256,7 +1261,7 @@ void SymtabSection::emitStabs() { }
StabsEntry symStab;
- symStab.sect = defined->isec()->parent->index;
- symStab.sect = isec->parent->index; symStab.strx = stringTableSection.addString(defined->getName()); symStab.value = defined->getVA();
diff --git a/lld/test/MachO/stabs-icf.s b/lld/test/MachO/stabs-icf.s index 99d0871ce4d2c..5f8449809ddd1 100644 --- a/lld/test/MachO/stabs-icf.s +++ b/lld/test/MachO/stabs-icf.s @@ -4,6 +4,9 @@
RUN: %lld -lSystem --icf=all %t.o -o %t
RUN: dsymutil -s %t | FileCheck %s -DDIR=%t -DSRC_PATH=%t.o
+# RUN: %lld -lSystem --icf=all %t.o -o %t_icf_stabs --keep-icf-stabs +# RUN: dsymutil -s %t_icf_stabs | FileCheck %s -DDIR=%t_icf_stabs -DSRC_PATH=%t.o --check-prefixes=ICF_STABS +
This should include no N_FUN entry for _baz (which is ICF'd into _bar),
but it does include a SECT EXT entry.
NOTE: We do not omit the N_FUN entry for _bar even though it is of size zero.
@@ -27,6 +30,30 @@
CHECK-DAG: ( {{.*}}) {{[0-9]+}} 0100 0000000000000000 'dyld_stub_binder'
CHECK-EMPTY:
- +# ICF_STABS: (N_SO ) 00 0000 0000000000000000 '/tmp{{[/\]}}test.cpp'
+# ICF_STABS-NEXT: (N_OSO ) 03 0001 {{.}} '[[SRC_PATH]]' +# ICF_STABS-NEXT: (N_FUN ) 01 0000 [[#%.16x,MAIN:]] '_main' +# ICF_STABS-NEXT: (N_FUN ) 00 0000 000000000000000b{{$}} +# ICF_STABS-NEXT: (N_FUN ) 01 0000 [[#%.16x,BAR:]] '_bar' +# ICF_STABS-NEXT: (N_FUN ) 00 0000 0000000000000000{{$}} +# ICF_STABS-NEXT: (N_FUN ) 01 0000 [[#BAR]] '_bar2' +# ICF_STABS-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} +# ICF_STABS-NEXT: (N_FUN ) 01 0000 [[#BAR]] '_baz' +# ICF_STABS-NEXT: (N_FUN ) 00 0000 0000000000000000{{$}} +# ICF_STABS-NEXT: (N_FUN ) 01 0000 [[#BAR]] '_baz2' +# ICF_STABS-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} +# ICF_STABS-NEXT: (N_SO ) 01 0000 0000000000000000{{$}} +# ICF_STABS-DAG: ( SECT EXT) 01 0000 [[#MAIN]] '_main' +# ICF_STABS-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_bar' +# ICF_STABS-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_bar2' +# ICF_STABS-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_baz' +# ICF_STABS-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_baz2' +# ICF_STABS-DAG: ( {{.}}) {{[0-9]+}} 0010 {{[0-9a-f]+}} '__mh_execute_header' +# ICF_STABS-DAG: ( {{.*}}) {{[0-9]+}} 0100 0000000000000000 'dyld_stub_binder' +# ICF_STABS-EMPTY: + + .text .globl _bar, _bar2, _baz, _baz2, _main