Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(716)

Side by Side Diff: tools/pnacl-hack-memset/pnacl-hack-memset.cpp

Issue 2262373002: Create one-off tool pnacl-hack-memset (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/pnacl-hack-memset/Makefile ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright 2013 The Native Client Authors. All rights reserved. 1 /* Copyright 2016 The Native Client Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can 2 * Use of this source code is governed by a BSD-style license that can
3 * be found in the LICENSE file. 3 * be found in the LICENSE file.
4 */ 4 */
5 5
6 //===-- pnacl-thaw.cpp - The low-level NaCl bitcode thawer ----------------===// 6 //===-- pnacl-thaw.cpp - The low-level NaCl bitcode thawer ----------------===//
Jim Stichnoth 2016/08/22 21:55:44 oops
Karl 2016/08/23 15:17:31 Corrected.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // Converts NaCl wire format back to LLVM bitcode. 10 // Converts NaCl wire format back to LLVM bitcode.
11 // 11 //
12 //===----------------------------------------------------------------------===// 12 //===----------------------------------------------------------------------===//
13 13
14 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 14 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
15 #include "llvm/Bitcode/ReaderWriter.h" 15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/InstIterator.h"
17 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h" 19 #include "llvm/IR/Module.h"
18 #include "llvm/Support/CommandLine.h" 20 #include "llvm/Support/CommandLine.h"
19 #include "llvm/Support/DataStream.h" 21 #include "llvm/Support/DataStream.h"
20 #include "llvm/Support/FileSystem.h" 22 #include "llvm/Support/FileSystem.h"
21 #include "llvm/Support/ManagedStatic.h" 23 #include "llvm/Support/ManagedStatic.h"
22 #include "llvm/Support/PrettyStackTrace.h" 24 #include "llvm/Support/PrettyStackTrace.h"
23 #include "llvm/Support/Signals.h" 25 #include "llvm/Support/Signals.h"
24 #include "llvm/Support/StreamingMemoryObject.h" 26 #include "llvm/Support/StreamingMemoryObject.h"
25 #include "llvm/Support/ToolOutputFile.h" 27 #include "llvm/Support/ToolOutputFile.h"
26 28
27 using namespace llvm; 29 using namespace llvm;
28 30
29 namespace { 31 namespace {
30 32
31 static cl::opt<std::string> 33 static cl::opt<std::string>
32 OutputFilename("o", cl::desc("Specify thawed pexe filename"), 34 OutputFilename("o", cl::desc("Specify fixed pexe filename"),
33 » cl::value_desc("filename"), cl::init("-")); 35 cl::value_desc("fixed pexe file"), cl::init("-"));
34 36
35 static cl::opt<std::string> 37 static cl::opt<std::string>
36 InputFilename(cl::Positional, cl::desc("<frozen file>"), cl::init("-")); 38 InputFilename(cl::Positional, cl::desc("<pexe file>"), cl::init("-"));
39
40 static cl::opt<bool>
41 ShowFixes("show-fixes", cl::desc("Show fixes to memset"), cl::init(false));
37 42
38 static void WriteOutputFile(const Module *M) { 43 static void WriteOutputFile(const Module *M) {
39 44
40 std::error_code EC; 45 std::error_code EC;
41 std::unique_ptr<tool_output_file> Out( 46 std::unique_ptr<tool_output_file> Out(
42 new tool_output_file(OutputFilename, EC, sys::fs::F_None)); 47 new tool_output_file(OutputFilename, EC, sys::fs::F_None));
43 if (EC) { 48 if (EC) {
44 errs() << EC.message() << '\n'; 49 errs() << EC.message() << '\n';
45 exit(1); 50 exit(1);
46 } 51 }
47 52
48 WriteBitcodeToFile(M, Out->os()); 53 NaClWriteBitcodeToFile(M, Out->os(), /* AcceptSupportedOnly = */ false);
49 54
50 // Declare success. 55 // Declare success.
51 Out->keep(); 56 Out->keep();
52 } 57 }
53 58
54 static Module *readBitcode(std::string &Filename, LLVMContext &Context, 59 static Module *readBitcode(std::string &Filename, LLVMContext &Context,
Jim Stichnoth 2016/08/22 21:55:43 Optional: remove "static" for consistency with rem
Karl 2016/08/23 15:17:31 Done.
55 std::string &ErrorMessage) { 60 std::string &ErrorMessage) {
56 // Use the bitcode streaming interface 61 // Use the bitcode streaming interface
57 DataStreamer *Streamer = getDataFileStreamer(InputFilename, &ErrorMessage); 62 DataStreamer *Streamer = getDataFileStreamer(InputFilename, &ErrorMessage);
58 if (Streamer == nullptr) 63 if (Streamer == nullptr)
59 return nullptr; 64 return nullptr;
60 std::unique_ptr<StreamingMemoryObject> Buffer( 65 std::unique_ptr<StreamingMemoryObject> Buffer(
61 new StreamingMemoryObjectImpl(Streamer)); 66 new StreamingMemoryObjectImpl(Streamer));
62 std::string DisplayFilename; 67 std::string DisplayFilename;
63 if (Filename == "-") 68 if (Filename == "-")
64 DisplayFilename = "<stdin>"; 69 DisplayFilename = "<stdin>";
65 else 70 else
66 DisplayFilename = Filename; 71 DisplayFilename = Filename;
67 DiagnosticHandlerFunction DiagnosticHandler = nullptr; 72 DiagnosticHandlerFunction DiagnosticHandler = nullptr;
68 Module *M = getNaClStreamedBitcodeModule( 73 Module *M = getNaClStreamedBitcodeModule(
69 DisplayFilename, Buffer.release(), Context, DiagnosticHandler, 74 DisplayFilename, Buffer.release(), Context, DiagnosticHandler,
70 &ErrorMessage, /*AcceptSupportedOnly=*/false); 75 &ErrorMessage, /*AcceptSupportedOnly=*/false);
71 if (!M) 76 if (!M)
72 return nullptr; 77 return nullptr;
73 if (std::error_code EC = M->materializeAllPermanently()) { 78 if (std::error_code EC = M->materializeAllPermanently()) {
74 ErrorMessage = EC.message(); 79 ErrorMessage = EC.message();
75 delete M; 80 delete M;
76 return nullptr; 81 return nullptr;
77 } 82 }
78 return M; 83 return M;
79 } 84 }
80 85
86 size_t fixCallToMemset(CallInst &Call) {
Jim Stichnoth 2016/08/22 21:55:43 Document return value
Jim Stichnoth 2016/08/22 21:55:44 Can this be CallInst *Call? Makes it clearer at t
Karl 2016/08/23 15:17:31 Done.
87 if (Call.getNumArgOperands() != 5)
88 return 0;
89 Value* Val = Call.getArgOperand(1);
Jim Stichnoth 2016/08/22 21:55:43 "Value *Val" rather than "Value* Val", right? here
Karl 2016/08/23 15:17:31 Correct. Fixing. I was getting too used to the Chr
90 auto* CVal = dyn_cast<ConstantInt>(Val);
91 if (CVal == nullptr)
92 return 0;
93 if (!CVal->getType()->isIntegerTy(8))
94 return 0;
95 const APInt & IVal = CVal->getUniqueInteger();
96 if (!IVal.isNegative())
97 return 0;
98 Value* Count = Call.getArgOperand(2);
99 auto* CCount = dyn_cast<ConstantInt>(Count);
100 if (CCount == nullptr)
101 return 0;
102 if (!CCount->getType()->isIntegerTy(32))
103 return 0;
104 if (ShowFixes) {
105 Call.print(errs());
106 errs() << "\n-->\n";
107 }
108 auto* Zero = ConstantInt::getSigned(CCount->getType(), 0);
109 Value* Add = BinaryOperator::Create(Instruction::BinaryOps::Add,
110 CCount, Zero);
111 auto *IAdd = dyn_cast<Instruction>(Add);
112 if (IAdd == nullptr)
113 return 0;
114 Call.setArgOperand(2, Add);
115 IAdd->insertBefore(&Call);
116 if (ShowFixes) {
117 IAdd->print(errs());
118 errs() << "\n";
119 Call.print(errs());
120 errs() << "\n\n";
121 }
122 return 1;
123 }
124
125 size_t fixCallsToMemset(Instruction &I) {
126 size_t Count = 0;
127 if (auto *Call = dyn_cast<CallInst>(&I)) {
128 if (Function *F = Call->getCalledFunction()) {
129 if ("llvm.memset.p0i8.i32" == F->getName()) {
130 Count += fixCallToMemset(*Call);
131 }
132 }
133 }
134 return Count;
135 }
136
137 size_t fixCallsToMemset(BasicBlock &B) {
138 size_t Count = 0;
139 for (auto &I : B) {
140 Count += fixCallsToMemset(I);
141 }
142 return Count;
143 }
144
145 size_t fixCallsToMemset(Function &F) {
146 size_t Count = 0;
147 for (auto &B : F) {
148 Count += fixCallsToMemset(B);
149 }
150 return Count;
151 }
152
153 size_t fixCallsToMemset(Module *M) {
154 size_t ErrorCount = 0;
155 for (auto &F : *M) {
156 if (!F.isDeclaration())
157 ErrorCount += fixCallsToMemset(F);
158 }
159 return ErrorCount;
160 }
161
81 } // end of anonymous namespace 162 } // end of anonymous namespace
82 163
83 int main(int argc, char **argv) { 164 int main(int argc, char **argv) {
84 // Print a stack trace if we signal out. 165 // Print a stack trace if we signal out.
85 sys::PrintStackTraceOnErrorSignal(); 166 sys::PrintStackTraceOnErrorSignal();
86 PrettyStackTraceProgram X(argc, argv); 167 PrettyStackTraceProgram X(argc, argv);
87 168
88 LLVMContext &Context = getGlobalContext(); 169 LLVMContext &Context = getGlobalContext();
89 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 170 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
90 171
91 cl::ParseCommandLineOptions( 172 cl::ParseCommandLineOptions(
92 argc, argv, "Converts NaCl pexe wire format into LLVM bitcode format\n"); 173 argc, argv, "Converts NaCl pexe wire format into LLVM bitcode format\n");
93 174
94 std::string ErrorMessage; 175 std::string ErrorMessage;
95 std::unique_ptr<Module> M(readBitcode(InputFilename, Context, ErrorMessage)); 176 std::unique_ptr<Module> M(readBitcode(InputFilename, Context, ErrorMessage));
96 177
97 if (!M.get()) { 178 if (!M.get()) {
98 errs() << argv[0] << ": "; 179 errs() << argv[0] << ": ";
99 if (ErrorMessage.size()) 180 if (ErrorMessage.size())
100 errs() << ErrorMessage << "\n"; 181 errs() << ErrorMessage << "\n";
101 else 182 else
102 errs() << "bitcode didn't read correctly.\n"; 183 errs() << "bitcode didn't read correctly.\n";
103 return 1; 184 return 1;
104 } 185 }
105 186
187 size_t ErrorCount = fixCallsToMemset(M.get());
188 if (ErrorCount > 0) {
189 errs() << argv[0] << ": " << "Fixed " << ErrorCount << " calls to memset.\n" ;
Jim Stichnoth 2016/08/22 21:55:43 80-col
Jim Stichnoth 2016/08/22 21:55:43 ... << ": Fixed " << ... i.e. concatenate strings
Karl 2016/08/23 15:17:31 Done.
190 }
191
106 WriteOutputFile(M.get()); 192 WriteOutputFile(M.get());
107 return 0; 193 return 0;
108 } 194 }
OLDNEW
« no previous file with comments | « tools/pnacl-hack-memset/Makefile ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698