Skip to content

Commit ef3ca61

Browse files
authored
Merge pull request #2890 from apple/🍒/ganymede/625bd94c6d645c4cae40649800de8047bacd3f53
[dsymutil] Add flag to force a static variable to keep its enclosing …
2 parents 99de991 + 55669b1 commit ef3ca61

File tree

11 files changed

+72
-7
lines changed

11 files changed

+72
-7
lines changed

llvm/docs/CommandGuide/dsymutil.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ OPTIONS
5050

5151
Print this help output.
5252

53+
.. option:: --keep-function-for-static
54+
55+
Make a static variable keep the enclosing function even if it would have been
56+
omitted otherwise.
57+
5358
.. option:: --minimize, -z
5459

5560
When used when creating a dSYM file, this option will suppress the emission of

llvm/include/llvm/DWARFLinker/DWARFLinker.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ class DWARFLinker {
279279
/// update existing DWARF info(for the linked binary).
280280
void setUpdate(bool Update) { Options.Update = Update; }
281281

282+
/// Set whether to keep the enclosing function for a static variable.
283+
void setKeepFunctionForStatic(bool KeepFunctionForStatic) {
284+
Options.KeepFunctionForStatic = KeepFunctionForStatic;
285+
}
286+
282287
/// Use specified number of threads for parallel files linking.
283288
void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
284289

@@ -779,6 +784,10 @@ class DWARFLinker {
779784
/// Update
780785
bool Update = false;
781786

787+
/// Whether we want a static variable to force us to keep its enclosing
788+
/// function.
789+
bool KeepFunctionForStatic = false;
790+
782791
/// Number of threads.
783792
unsigned Threads = 1;
784793

llvm/lib/DWARFLinker/DWARFLinker.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -434,13 +434,15 @@ unsigned DWARFLinker::shouldKeepVariableDIE(AddressesMap &RelocMgr,
434434
return Flags | TF_Keep;
435435
}
436436

437-
// See if there is a relocation to a valid debug map entry inside
438-
// this variable's location. The order is important here. We want to
439-
// always check if the variable has a valid relocation, so that the
440-
// DIEInfo is filled. However, we don't want a static variable in a
441-
// function to force us to keep the enclosing function.
442-
if (!RelocMgr.hasLiveMemoryLocation(DIE, MyInfo) ||
443-
(Flags & TF_InFunctionScope))
437+
// See if there is a relocation to a valid debug map entry inside this
438+
// variable's location. The order is important here. We want to always check
439+
// if the variable has a valid relocation, so that the DIEInfo is filled.
440+
// However, we don't want a static variable in a function to force us to keep
441+
// the enclosing function, unless requested explicitly.
442+
const bool HasLiveMemoryLocation =
443+
RelocMgr.hasLiveMemoryLocation(DIE, MyInfo);
444+
if (!HasLiveMemoryLocation || ((Flags & TF_InFunctionScope) &&
445+
!LLVM_UNLIKELY(Options.KeepFunctionForStatic)))
444446
return Flags;
445447

446448
if (Options.Verbose) {
Binary file not shown.
Binary file not shown.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
$ cat main.cpp
2+
#include <stdio.h>
3+
4+
static void Foo(void)
5+
{
6+
typedef struct {
7+
int x1;
8+
int x2;
9+
} FOO_VAR_TYPE;
10+
static FOO_VAR_TYPE MyDummyVar __attribute__((aligned(4), used, section("TAD_VIRTUAL, TAD_DUMMY_DATA"), nocommon));
11+
printf("Foo called");
12+
}
13+
14+
int main()
15+
{
16+
Foo();
17+
return 1;
18+
}
19+
20+
$ clang++ -O2 -g main.cpp -c -o main.o
21+
$ clang++ main.o -o main.out
22+
23+
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/keep_func/main.out -o %t.omit.dSYM
24+
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/keep_func/main.out -o %t.keep.dSYM -keep-function-for-static
25+
RUN: llvm-dwarfdump %t.omit.dSYM | FileCheck %s --check-prefix OMIT
26+
RUN: llvm-dwarfdump %t.keep.dSYM | FileCheck %s --check-prefix KEEP
27+
28+
KEEP: DW_AT_name ("MyDummyVar")
29+
KEEP: DW_AT_name ("FOO_VAR_TYPE")
30+
KEEP: DW_AT_name ("x1")
31+
KEEP: DW_AT_name ("x2")
32+
33+
OMIT-NOT: DW_AT_name ("MyDummyVar")
34+
OMIT-NOT: DW_AT_name ("FOO_VAR_TYPE")
35+
OMIT-NOT: DW_AT_name ("x1")
36+
OMIT-NOT: DW_AT_name ("x2")

llvm/test/tools/dsymutil/cmdline.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHECK: -dump-debug-map
1111
CHECK: -flat
1212
CHECK: -gen-reproducer
1313
CHECK: -help
14+
CHECK: -keep-function-for-static
1415
CHECK: -minimize
1516
CHECK: -no-odr
1617
CHECK: -no-output

llvm/tools/dsymutil/DwarfLinkerForBinary.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
322322
GeneralLinker.setNumThreads(Options.Threads);
323323
GeneralLinker.setAccelTableKind(Options.TheAccelTableKind);
324324
GeneralLinker.setPrependPath(Options.PrependPath);
325+
GeneralLinker.setKeepFunctionForStatic(Options.KeepFunctionForStatic);
325326
if (Options.Translator)
326327
GeneralLinker.setStringsTranslator(TranslationLambda);
327328
GeneralLinker.setWarningHandler(

llvm/tools/dsymutil/LinkUtils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ struct LinkOptions {
4545
/// Do not check swiftmodule timestamp
4646
bool NoTimestamp = false;
4747

48+
/// Whether we want a static variable to force us to keep its enclosing
49+
/// function.
50+
bool KeepFunctionForStatic = false;
51+
4852
/// Number of threads.
4953
unsigned Threads = 1;
5054

llvm/tools/dsymutil/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def verbose: F<"verbose">,
2424
HelpText<"Enable verbose mode.">,
2525
Group<grp_general>;
2626

27+
def keep_func_for_static: F<"keep-function-for-static">,
28+
HelpText<"Make a static variable keep the enclosing function even if it would have been omitted otherwise.">,
29+
Group<grp_general>;
30+
2731
def statistics: F<"statistics">,
2832
HelpText<"Print statistics about the contribution of each object file to "
2933
"the linked debug info. This prints a table after linking with the "

llvm/tools/dsymutil/dsymutil.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct DsymutilOptions {
9292
bool InputIsYAMLDebugMap = false;
9393
bool PaperTrailWarnings = false;
9494
bool Verify = false;
95+
bool ForceKeepFunctionForStatic = false;
9596
std::string SymbolMap;
9697
std::string OutputFile;
9798
std::string Toolchain;
@@ -230,6 +231,8 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
230231
Options.LinkOpts.Update = Args.hasArg(OPT_update);
231232
Options.LinkOpts.Verbose = Args.hasArg(OPT_verbose);
232233
Options.LinkOpts.Statistics = Args.hasArg(OPT_statistics);
234+
Options.LinkOpts.KeepFunctionForStatic =
235+
Args.hasArg(OPT_keep_func_for_static);
233236

234237
if (opt::Arg *ReproducerPath = Args.getLastArg(OPT_use_reproducer)) {
235238
Options.ReproMode = ReproducerMode::Use;

0 commit comments

Comments
 (0)