1 //===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // The StripSymbols transformation implements code stripping. Specifically, it
12 // * names for virtual registers
13 // * symbols for internal globals and functions
14 // * debug information
16 // Note that this transformation makes code much less readable, so it should
17 // only be used in situations where the 'strip' utility would be used, such as
18 // reducing code size or making it harder to reverse engineer code.
20 //===----------------------------------------------------------------------===//
22 #include "llvm/Transforms/IPO/StripSymbols.h"
23 #include "llvm/ADT/SmallPtrSet.h"
24 #include "llvm/IR/Constants.h"
25 #include "llvm/IR/DebugInfo.h"
26 #include "llvm/IR/DerivedTypes.h"
27 #include "llvm/IR/InstIterator.h"
28 #include "llvm/IR/Instructions.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/IR/PassManager.h"
31 #include "llvm/IR/TypeFinder.h"
32 #include "llvm/IR/ValueSymbolTable.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Transforms/IPO.h"
35 #include "llvm/Transforms/IPO/StripSymbols.h"
36 #include "llvm/Transforms/Utils/Local.h"
41 StripGlobalConstants("strip-global-constants", cl::init(false), cl::Hidden
,
42 cl::desc("Removes debug compile units which reference "
43 "to non-existing global constants"));
45 /// OnlyUsedBy - Return true if V is only used by Usr.
46 static bool OnlyUsedBy(Value
*V
, Value
*Usr
) {
47 for (User
*U
: V
->users())
54 static void RemoveDeadConstant(Constant
*C
) {
55 assert(C
->use_empty() && "Constant is not dead!");
56 SmallPtrSet
<Constant
*, 4> Operands
;
57 for (Value
*Op
: C
->operands())
58 if (OnlyUsedBy(Op
, C
))
59 Operands
.insert(cast
<Constant
>(Op
));
60 if (GlobalVariable
*GV
= dyn_cast
<GlobalVariable
>(C
)) {
61 if (!GV
->hasLocalLinkage()) return; // Don't delete non-static globals.
62 GV
->eraseFromParent();
63 } else if (!isa
<Function
>(C
)) {
64 // FIXME: Why does the type of the constant matter here?
65 if (isa
<StructType
>(C
->getType()) || isa
<ArrayType
>(C
->getType()) ||
66 isa
<VectorType
>(C
->getType()))
70 // If the constant referenced anything, see if we can delete it as well.
71 for (Constant
*O
: Operands
)
72 RemoveDeadConstant(O
);
75 // Strip the symbol table of its names.
77 static void StripSymtab(ValueSymbolTable
&ST
, bool PreserveDbgInfo
) {
78 for (ValueSymbolTable::iterator VI
= ST
.begin(), VE
= ST
.end(); VI
!= VE
; ) {
79 Value
*V
= VI
->getValue();
81 if (!isa
<GlobalValue
>(V
) || cast
<GlobalValue
>(V
)->hasLocalLinkage()) {
82 if (!PreserveDbgInfo
|| !V
->getName().startswith("llvm.dbg"))
83 // Set name to "", removing from symbol table!
89 // Strip any named types of their names.
90 static void StripTypeNames(Module
&M
, bool PreserveDbgInfo
) {
91 TypeFinder StructTypes
;
92 StructTypes
.run(M
, false);
94 for (StructType
*STy
: StructTypes
) {
95 if (STy
->isLiteral() || STy
->getName().empty()) continue;
97 if (PreserveDbgInfo
&& STy
->getName().startswith("llvm.dbg"))
104 /// Find values that are marked as llvm.used.
105 static void findUsedValues(GlobalVariable
*LLVMUsed
,
106 SmallPtrSetImpl
<const GlobalValue
*> &UsedValues
) {
107 if (!LLVMUsed
) return;
108 UsedValues
.insert(LLVMUsed
);
110 ConstantArray
*Inits
= cast
<ConstantArray
>(LLVMUsed
->getInitializer());
112 for (unsigned i
= 0, e
= Inits
->getNumOperands(); i
!= e
; ++i
)
113 if (GlobalValue
*GV
=
114 dyn_cast
<GlobalValue
>(Inits
->getOperand(i
)->stripPointerCasts()))
115 UsedValues
.insert(GV
);
118 /// StripSymbolNames - Strip symbol names.
119 static bool StripSymbolNames(Module
&M
, bool PreserveDbgInfo
) {
121 SmallPtrSet
<const GlobalValue
*, 8> llvmUsedValues
;
122 findUsedValues(M
.getGlobalVariable("llvm.used"), llvmUsedValues
);
123 findUsedValues(M
.getGlobalVariable("llvm.compiler.used"), llvmUsedValues
);
125 for (GlobalVariable
&GV
: M
.globals()) {
126 if (GV
.hasLocalLinkage() && !llvmUsedValues
.contains(&GV
))
127 if (!PreserveDbgInfo
|| !GV
.getName().startswith("llvm.dbg"))
128 GV
.setName(""); // Internal symbols can't participate in linkage
131 for (Function
&I
: M
) {
132 if (I
.hasLocalLinkage() && !llvmUsedValues
.contains(&I
))
133 if (!PreserveDbgInfo
|| !I
.getName().startswith("llvm.dbg"))
134 I
.setName(""); // Internal symbols can't participate in linkage
135 if (auto *Symtab
= I
.getValueSymbolTable())
136 StripSymtab(*Symtab
, PreserveDbgInfo
);
139 // Remove all names from types.
140 StripTypeNames(M
, PreserveDbgInfo
);
145 static bool stripDebugDeclareImpl(Module
&M
) {
147 Function
*Declare
= M
.getFunction("llvm.dbg.declare");
148 std::vector
<Constant
*> DeadConstants
;
151 while (!Declare
->use_empty()) {
152 CallInst
*CI
= cast
<CallInst
>(Declare
->user_back());
153 Value
*Arg1
= CI
->getArgOperand(0);
154 Value
*Arg2
= CI
->getArgOperand(1);
155 assert(CI
->use_empty() && "llvm.dbg intrinsic should have void result");
156 CI
->eraseFromParent();
157 if (Arg1
->use_empty()) {
158 if (Constant
*C
= dyn_cast
<Constant
>(Arg1
))
159 DeadConstants
.push_back(C
);
161 RecursivelyDeleteTriviallyDeadInstructions(Arg1
);
163 if (Arg2
->use_empty())
164 if (Constant
*C
= dyn_cast
<Constant
>(Arg2
))
165 DeadConstants
.push_back(C
);
167 Declare
->eraseFromParent();
170 while (!DeadConstants
.empty()) {
171 Constant
*C
= DeadConstants
.back();
172 DeadConstants
.pop_back();
173 if (GlobalVariable
*GV
= dyn_cast
<GlobalVariable
>(C
)) {
174 if (GV
->hasLocalLinkage())
175 RemoveDeadConstant(GV
);
177 RemoveDeadConstant(C
);
183 static bool stripDeadDebugInfoImpl(Module
&M
) {
184 bool Changed
= false;
186 LLVMContext
&C
= M
.getContext();
188 // Find all debug info in F. This is actually overkill in terms of what we
189 // want to do, but we want to try and be as resilient as possible in the face
190 // of potential debug info changes by using the formal interfaces given to us
191 // as much as possible.
195 // For each compile unit, find the live set of global variables/functions and
196 // replace the current list of potentially dead global variables/functions
197 // with the live list.
198 SmallVector
<Metadata
*, 64> LiveGlobalVariables
;
199 DenseSet
<DIGlobalVariableExpression
*> VisitedSet
;
201 std::set
<DIGlobalVariableExpression
*> LiveGVs
;
202 for (GlobalVariable
&GV
: M
.globals()) {
203 SmallVector
<DIGlobalVariableExpression
*, 1> GVEs
;
204 GV
.getDebugInfo(GVEs
);
205 for (auto *GVE
: GVEs
)
209 std::set
<DICompileUnit
*> LiveCUs
;
210 DebugInfoFinder LiveCUFinder
;
211 for (const Function
&F
: M
.functions()) {
212 if (auto *SP
= cast_or_null
<DISubprogram
>(F
.getSubprogram()))
213 LiveCUFinder
.processSubprogram(SP
);
214 for (const Instruction
&I
: instructions(F
))
215 LiveCUFinder
.processInstruction(M
, I
);
217 auto FoundCUs
= LiveCUFinder
.compile_units();
218 LiveCUs
.insert(FoundCUs
.begin(), FoundCUs
.end());
220 bool HasDeadCUs
= false;
221 for (DICompileUnit
*DIC
: F
.compile_units()) {
222 // Create our live global variable list.
223 bool GlobalVariableChange
= false;
224 for (auto *DIG
: DIC
->getGlobalVariables()) {
225 if (DIG
->getExpression() && DIG
->getExpression()->isConstant() &&
226 !StripGlobalConstants
)
229 // Make sure we only visit each global variable only once.
230 if (!VisitedSet
.insert(DIG
).second
)
233 // If a global variable references DIG, the global variable is live.
234 if (LiveGVs
.count(DIG
))
235 LiveGlobalVariables
.push_back(DIG
);
237 GlobalVariableChange
= true;
240 if (!LiveGlobalVariables
.empty())
242 else if (!LiveCUs
.count(DIC
))
245 // If we found dead global variables, replace the current global
246 // variable list with our new live global variable list.
247 if (GlobalVariableChange
) {
248 DIC
->replaceGlobalVariables(MDTuple::get(C
, LiveGlobalVariables
));
252 // Reset lists for the next iteration.
253 LiveGlobalVariables
.clear();
257 // Delete the old node and replace it with a new one
258 NamedMDNode
*NMD
= M
.getOrInsertNamedMetadata("llvm.dbg.cu");
259 NMD
->clearOperands();
260 if (!LiveCUs
.empty()) {
261 for (DICompileUnit
*CU
: LiveCUs
)
270 PreservedAnalyses
StripSymbolsPass::run(Module
&M
, ModuleAnalysisManager
&AM
) {
272 StripSymbolNames(M
, false);
273 PreservedAnalyses PA
;
274 PA
.preserveSet
<CFGAnalyses
>();
278 PreservedAnalyses
StripNonDebugSymbolsPass::run(Module
&M
,
279 ModuleAnalysisManager
&AM
) {
280 StripSymbolNames(M
, true);
281 PreservedAnalyses PA
;
282 PA
.preserveSet
<CFGAnalyses
>();
286 PreservedAnalyses
StripDebugDeclarePass::run(Module
&M
,
287 ModuleAnalysisManager
&AM
) {
288 stripDebugDeclareImpl(M
);
289 PreservedAnalyses PA
;
290 PA
.preserveSet
<CFGAnalyses
>();
294 PreservedAnalyses
StripDeadDebugInfoPass::run(Module
&M
,
295 ModuleAnalysisManager
&AM
) {
296 stripDeadDebugInfoImpl(M
);
297 PreservedAnalyses PA
;
298 PA
.preserveSet
<CFGAnalyses
>();