xref: /aosp_15_r20/external/llvm/tools/llvm-extract/llvm-extract.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- llvm-extract.cpp - LLVM function extraction utility ----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This utility changes the input module to only contain a single function,
11*9880d681SAndroid Build Coastguard Worker // which is primarily used for debugging transformations.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/BitcodeWriterPass.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRPrintingPasses.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IRReader/IRReader.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/PrettyStackTrace.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Regex.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Signals.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SystemUtils.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ToolOutputFile.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO.h"
34*9880d681SAndroid Build Coastguard Worker #include <memory>
35*9880d681SAndroid Build Coastguard Worker using namespace llvm;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker // InputFilename - The filename to read from.
38*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string>
39*9880d681SAndroid Build Coastguard Worker InputFilename(cl::Positional, cl::desc("<input bitcode file>"),
40*9880d681SAndroid Build Coastguard Worker               cl::init("-"), cl::value_desc("filename"));
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string>
43*9880d681SAndroid Build Coastguard Worker OutputFilename("o", cl::desc("Specify output filename"),
44*9880d681SAndroid Build Coastguard Worker                cl::value_desc("filename"), cl::init("-"));
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
47*9880d681SAndroid Build Coastguard Worker Force("f", cl::desc("Enable binary output on terminals"));
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
50*9880d681SAndroid Build Coastguard Worker DeleteFn("delete", cl::desc("Delete specified Globals from Module"));
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker // ExtractFuncs - The functions to extract from the module.
53*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
54*9880d681SAndroid Build Coastguard Worker ExtractFuncs("func", cl::desc("Specify function to extract"),
55*9880d681SAndroid Build Coastguard Worker              cl::ZeroOrMore, cl::value_desc("function"));
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker // ExtractRegExpFuncs - The functions, matched via regular expression, to
58*9880d681SAndroid Build Coastguard Worker // extract from the module.
59*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
60*9880d681SAndroid Build Coastguard Worker ExtractRegExpFuncs("rfunc", cl::desc("Specify function(s) to extract using a "
61*9880d681SAndroid Build Coastguard Worker                                      "regular expression"),
62*9880d681SAndroid Build Coastguard Worker                    cl::ZeroOrMore, cl::value_desc("rfunction"));
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker // ExtractAlias - The alias to extract from the module.
65*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
66*9880d681SAndroid Build Coastguard Worker ExtractAliases("alias", cl::desc("Specify alias to extract"),
67*9880d681SAndroid Build Coastguard Worker                cl::ZeroOrMore, cl::value_desc("alias"));
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker // ExtractRegExpAliases - The aliases, matched via regular expression, to
71*9880d681SAndroid Build Coastguard Worker // extract from the module.
72*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
73*9880d681SAndroid Build Coastguard Worker ExtractRegExpAliases("ralias", cl::desc("Specify alias(es) to extract using a "
74*9880d681SAndroid Build Coastguard Worker                                         "regular expression"),
75*9880d681SAndroid Build Coastguard Worker                      cl::ZeroOrMore, cl::value_desc("ralias"));
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker // ExtractGlobals - The globals to extract from the module.
78*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
79*9880d681SAndroid Build Coastguard Worker ExtractGlobals("glob", cl::desc("Specify global to extract"),
80*9880d681SAndroid Build Coastguard Worker                cl::ZeroOrMore, cl::value_desc("global"));
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker // ExtractRegExpGlobals - The globals, matched via regular expression, to
83*9880d681SAndroid Build Coastguard Worker // extract from the module...
84*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
85*9880d681SAndroid Build Coastguard Worker ExtractRegExpGlobals("rglob", cl::desc("Specify global(s) to extract using a "
86*9880d681SAndroid Build Coastguard Worker                                        "regular expression"),
87*9880d681SAndroid Build Coastguard Worker                      cl::ZeroOrMore, cl::value_desc("rglobal"));
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
90*9880d681SAndroid Build Coastguard Worker OutputAssembly("S",
91*9880d681SAndroid Build Coastguard Worker                cl::desc("Write output as LLVM assembly"), cl::Hidden);
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> PreserveBitcodeUseListOrder(
94*9880d681SAndroid Build Coastguard Worker     "preserve-bc-uselistorder",
95*9880d681SAndroid Build Coastguard Worker     cl::desc("Preserve use-list order when writing LLVM bitcode."),
96*9880d681SAndroid Build Coastguard Worker     cl::init(true), cl::Hidden);
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> PreserveAssemblyUseListOrder(
99*9880d681SAndroid Build Coastguard Worker     "preserve-ll-uselistorder",
100*9880d681SAndroid Build Coastguard Worker     cl::desc("Preserve use-list order when writing LLVM assembly."),
101*9880d681SAndroid Build Coastguard Worker     cl::init(false), cl::Hidden);
102*9880d681SAndroid Build Coastguard Worker 
main(int argc,char ** argv)103*9880d681SAndroid Build Coastguard Worker int main(int argc, char **argv) {
104*9880d681SAndroid Build Coastguard Worker   // Print a stack trace if we signal out.
105*9880d681SAndroid Build Coastguard Worker   sys::PrintStackTraceOnErrorSignal(argv[0]);
106*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceProgram X(argc, argv);
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker   LLVMContext Context;
109*9880d681SAndroid Build Coastguard Worker   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
110*9880d681SAndroid Build Coastguard Worker   cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n");
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   // Use lazy loading, since we only care about selected global values.
113*9880d681SAndroid Build Coastguard Worker   SMDiagnostic Err;
114*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<Module> M = getLazyIRFileModule(InputFilename, Err, Context);
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   if (!M.get()) {
117*9880d681SAndroid Build Coastguard Worker     Err.print(argv[0], errs());
118*9880d681SAndroid Build Coastguard Worker     return 1;
119*9880d681SAndroid Build Coastguard Worker   }
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   // Use SetVector to avoid duplicates.
122*9880d681SAndroid Build Coastguard Worker   SetVector<GlobalValue *> GVs;
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   // Figure out which aliases we should extract.
125*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0, e = ExtractAliases.size(); i != e; ++i) {
126*9880d681SAndroid Build Coastguard Worker     GlobalAlias *GA = M->getNamedAlias(ExtractAliases[i]);
127*9880d681SAndroid Build Coastguard Worker     if (!GA) {
128*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": program doesn't contain alias named '"
129*9880d681SAndroid Build Coastguard Worker              << ExtractAliases[i] << "'!\n";
130*9880d681SAndroid Build Coastguard Worker       return 1;
131*9880d681SAndroid Build Coastguard Worker     }
132*9880d681SAndroid Build Coastguard Worker     GVs.insert(GA);
133*9880d681SAndroid Build Coastguard Worker   }
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker   // Extract aliases via regular expression matching.
136*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0, e = ExtractRegExpAliases.size(); i != e; ++i) {
137*9880d681SAndroid Build Coastguard Worker     std::string Error;
138*9880d681SAndroid Build Coastguard Worker     Regex RegEx(ExtractRegExpAliases[i]);
139*9880d681SAndroid Build Coastguard Worker     if (!RegEx.isValid(Error)) {
140*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": '" << ExtractRegExpAliases[i] << "' "
141*9880d681SAndroid Build Coastguard Worker         "invalid regex: " << Error;
142*9880d681SAndroid Build Coastguard Worker     }
143*9880d681SAndroid Build Coastguard Worker     bool match = false;
144*9880d681SAndroid Build Coastguard Worker     for (Module::alias_iterator GA = M->alias_begin(), E = M->alias_end();
145*9880d681SAndroid Build Coastguard Worker          GA != E; GA++) {
146*9880d681SAndroid Build Coastguard Worker       if (RegEx.match(GA->getName())) {
147*9880d681SAndroid Build Coastguard Worker         GVs.insert(&*GA);
148*9880d681SAndroid Build Coastguard Worker         match = true;
149*9880d681SAndroid Build Coastguard Worker       }
150*9880d681SAndroid Build Coastguard Worker     }
151*9880d681SAndroid Build Coastguard Worker     if (!match) {
152*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": program doesn't contain global named '"
153*9880d681SAndroid Build Coastguard Worker              << ExtractRegExpAliases[i] << "'!\n";
154*9880d681SAndroid Build Coastguard Worker       return 1;
155*9880d681SAndroid Build Coastguard Worker     }
156*9880d681SAndroid Build Coastguard Worker   }
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   // Figure out which globals we should extract.
159*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
160*9880d681SAndroid Build Coastguard Worker     GlobalValue *GV = M->getNamedGlobal(ExtractGlobals[i]);
161*9880d681SAndroid Build Coastguard Worker     if (!GV) {
162*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": program doesn't contain global named '"
163*9880d681SAndroid Build Coastguard Worker              << ExtractGlobals[i] << "'!\n";
164*9880d681SAndroid Build Coastguard Worker       return 1;
165*9880d681SAndroid Build Coastguard Worker     }
166*9880d681SAndroid Build Coastguard Worker     GVs.insert(GV);
167*9880d681SAndroid Build Coastguard Worker   }
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker   // Extract globals via regular expression matching.
170*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) {
171*9880d681SAndroid Build Coastguard Worker     std::string Error;
172*9880d681SAndroid Build Coastguard Worker     Regex RegEx(ExtractRegExpGlobals[i]);
173*9880d681SAndroid Build Coastguard Worker     if (!RegEx.isValid(Error)) {
174*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' "
175*9880d681SAndroid Build Coastguard Worker         "invalid regex: " << Error;
176*9880d681SAndroid Build Coastguard Worker     }
177*9880d681SAndroid Build Coastguard Worker     bool match = false;
178*9880d681SAndroid Build Coastguard Worker     for (auto &GV : M->globals()) {
179*9880d681SAndroid Build Coastguard Worker       if (RegEx.match(GV.getName())) {
180*9880d681SAndroid Build Coastguard Worker         GVs.insert(&GV);
181*9880d681SAndroid Build Coastguard Worker         match = true;
182*9880d681SAndroid Build Coastguard Worker       }
183*9880d681SAndroid Build Coastguard Worker     }
184*9880d681SAndroid Build Coastguard Worker     if (!match) {
185*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": program doesn't contain global named '"
186*9880d681SAndroid Build Coastguard Worker              << ExtractRegExpGlobals[i] << "'!\n";
187*9880d681SAndroid Build Coastguard Worker       return 1;
188*9880d681SAndroid Build Coastguard Worker     }
189*9880d681SAndroid Build Coastguard Worker   }
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker   // Figure out which functions we should extract.
192*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) {
193*9880d681SAndroid Build Coastguard Worker     GlobalValue *GV = M->getFunction(ExtractFuncs[i]);
194*9880d681SAndroid Build Coastguard Worker     if (!GV) {
195*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": program doesn't contain function named '"
196*9880d681SAndroid Build Coastguard Worker              << ExtractFuncs[i] << "'!\n";
197*9880d681SAndroid Build Coastguard Worker       return 1;
198*9880d681SAndroid Build Coastguard Worker     }
199*9880d681SAndroid Build Coastguard Worker     GVs.insert(GV);
200*9880d681SAndroid Build Coastguard Worker   }
201*9880d681SAndroid Build Coastguard Worker   // Extract functions via regular expression matching.
202*9880d681SAndroid Build Coastguard Worker   for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) {
203*9880d681SAndroid Build Coastguard Worker     std::string Error;
204*9880d681SAndroid Build Coastguard Worker     StringRef RegExStr = ExtractRegExpFuncs[i];
205*9880d681SAndroid Build Coastguard Worker     Regex RegEx(RegExStr);
206*9880d681SAndroid Build Coastguard Worker     if (!RegEx.isValid(Error)) {
207*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' "
208*9880d681SAndroid Build Coastguard Worker         "invalid regex: " << Error;
209*9880d681SAndroid Build Coastguard Worker     }
210*9880d681SAndroid Build Coastguard Worker     bool match = false;
211*9880d681SAndroid Build Coastguard Worker     for (Module::iterator F = M->begin(), E = M->end(); F != E;
212*9880d681SAndroid Build Coastguard Worker          F++) {
213*9880d681SAndroid Build Coastguard Worker       if (RegEx.match(F->getName())) {
214*9880d681SAndroid Build Coastguard Worker         GVs.insert(&*F);
215*9880d681SAndroid Build Coastguard Worker         match = true;
216*9880d681SAndroid Build Coastguard Worker       }
217*9880d681SAndroid Build Coastguard Worker     }
218*9880d681SAndroid Build Coastguard Worker     if (!match) {
219*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": program doesn't contain global named '"
220*9880d681SAndroid Build Coastguard Worker              << ExtractRegExpFuncs[i] << "'!\n";
221*9880d681SAndroid Build Coastguard Worker       return 1;
222*9880d681SAndroid Build Coastguard Worker     }
223*9880d681SAndroid Build Coastguard Worker   }
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker   auto Materialize = [&](GlobalValue &GV) {
226*9880d681SAndroid Build Coastguard Worker     if (std::error_code EC = GV.materialize()) {
227*9880d681SAndroid Build Coastguard Worker       errs() << argv[0] << ": error reading input: " << EC.message() << "\n";
228*9880d681SAndroid Build Coastguard Worker       exit(1);
229*9880d681SAndroid Build Coastguard Worker     }
230*9880d681SAndroid Build Coastguard Worker   };
231*9880d681SAndroid Build Coastguard Worker 
232*9880d681SAndroid Build Coastguard Worker   // Materialize requisite global values.
233*9880d681SAndroid Build Coastguard Worker   if (!DeleteFn) {
234*9880d681SAndroid Build Coastguard Worker     for (size_t i = 0, e = GVs.size(); i != e; ++i)
235*9880d681SAndroid Build Coastguard Worker       Materialize(*GVs[i]);
236*9880d681SAndroid Build Coastguard Worker   } else {
237*9880d681SAndroid Build Coastguard Worker     // Deleting. Materialize every GV that's *not* in GVs.
238*9880d681SAndroid Build Coastguard Worker     SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end());
239*9880d681SAndroid Build Coastguard Worker     for (auto &F : *M) {
240*9880d681SAndroid Build Coastguard Worker       if (!GVSet.count(&F))
241*9880d681SAndroid Build Coastguard Worker         Materialize(F);
242*9880d681SAndroid Build Coastguard Worker     }
243*9880d681SAndroid Build Coastguard Worker   }
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker   {
246*9880d681SAndroid Build Coastguard Worker     std::vector<GlobalValue *> Gvs(GVs.begin(), GVs.end());
247*9880d681SAndroid Build Coastguard Worker     legacy::PassManager Extract;
248*9880d681SAndroid Build Coastguard Worker     Extract.add(createGVExtractionPass(Gvs, DeleteFn));
249*9880d681SAndroid Build Coastguard Worker     Extract.run(*M);
250*9880d681SAndroid Build Coastguard Worker 
251*9880d681SAndroid Build Coastguard Worker     // Now that we have all the GVs we want, mark the module as fully
252*9880d681SAndroid Build Coastguard Worker     // materialized.
253*9880d681SAndroid Build Coastguard Worker     // FIXME: should the GVExtractionPass handle this?
254*9880d681SAndroid Build Coastguard Worker     M->materializeAll();
255*9880d681SAndroid Build Coastguard Worker   }
256*9880d681SAndroid Build Coastguard Worker 
257*9880d681SAndroid Build Coastguard Worker   // In addition to deleting all other functions, we also want to spiff it
258*9880d681SAndroid Build Coastguard Worker   // up a little bit.  Do this now.
259*9880d681SAndroid Build Coastguard Worker   legacy::PassManager Passes;
260*9880d681SAndroid Build Coastguard Worker 
261*9880d681SAndroid Build Coastguard Worker   if (!DeleteFn)
262*9880d681SAndroid Build Coastguard Worker     Passes.add(createGlobalDCEPass());           // Delete unreachable globals
263*9880d681SAndroid Build Coastguard Worker   Passes.add(createStripDeadDebugInfoPass());    // Remove dead debug info
264*9880d681SAndroid Build Coastguard Worker   Passes.add(createStripDeadPrototypesPass());   // Remove dead func decls
265*9880d681SAndroid Build Coastguard Worker 
266*9880d681SAndroid Build Coastguard Worker   std::error_code EC;
267*9880d681SAndroid Build Coastguard Worker   tool_output_file Out(OutputFilename, EC, sys::fs::F_None);
268*9880d681SAndroid Build Coastguard Worker   if (EC) {
269*9880d681SAndroid Build Coastguard Worker     errs() << EC.message() << '\n';
270*9880d681SAndroid Build Coastguard Worker     return 1;
271*9880d681SAndroid Build Coastguard Worker   }
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker   if (OutputAssembly)
274*9880d681SAndroid Build Coastguard Worker     Passes.add(
275*9880d681SAndroid Build Coastguard Worker         createPrintModulePass(Out.os(), "", PreserveAssemblyUseListOrder));
276*9880d681SAndroid Build Coastguard Worker   else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
277*9880d681SAndroid Build Coastguard Worker     Passes.add(createBitcodeWriterPass(Out.os(), PreserveBitcodeUseListOrder));
278*9880d681SAndroid Build Coastguard Worker 
279*9880d681SAndroid Build Coastguard Worker   Passes.run(*M.get());
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker   // Declare success.
282*9880d681SAndroid Build Coastguard Worker   Out.keep();
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker   return 0;
285*9880d681SAndroid Build Coastguard Worker }
286