Added LLVM project notice to the top of every C++ source file.
[oota-llvm.git] / lib / Bytecode / Reader / ReaderWrappers.cpp
1 //===- ReaderWrappers.cpp - Parse bytecode from file or buffer  -----------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements loading and parsing a bytecode file and parsing a
11 // bytecode module from a given buffer.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "ReaderInternals.h"
16 #include "llvm/Module.h"
17 #include "llvm/Instructions.h"
18 #include "Support/StringExtras.h"
19 #include "Config/fcntl.h"
20 #include <sys/stat.h>
21 #include "Config/unistd.h"
22 #include "Config/sys/mman.h"
23
24 //===----------------------------------------------------------------------===//
25 // BytecodeFileReader - Read from an mmap'able file descriptor.
26 //
27
28 namespace {
29   /// FDHandle - Simple handle class to make sure a file descriptor gets closed
30   /// when the object is destroyed.
31   ///
32   class FDHandle {
33     int FD;
34   public:
35     FDHandle(int fd) : FD(fd) {}
36     operator int() const { return FD; }
37     ~FDHandle() {
38       if (FD != -1) close(FD);
39     }
40   };
41
42   /// BytecodeFileReader - parses a bytecode file from a file
43   ///
44   class BytecodeFileReader : public BytecodeParser {
45   private:
46     unsigned char *Buffer;
47     int Length;
48
49     BytecodeFileReader(const BytecodeFileReader&); // Do not implement
50     void operator=(const BytecodeFileReader &BFR); // Do not implement
51
52   public:
53     BytecodeFileReader(const std::string &Filename);
54     ~BytecodeFileReader();
55   };
56 }
57
58 BytecodeFileReader::BytecodeFileReader(const std::string &Filename) {
59   FDHandle FD = open(Filename.c_str(), O_RDONLY);
60   if (FD == -1)
61     throw std::string("Error opening file!");
62
63   // Stat the file to get its length...
64   struct stat StatBuf;
65   if (fstat(FD, &StatBuf) == -1 || StatBuf.st_size == 0)
66     throw std::string("Error stat'ing file!");
67
68   // mmap in the file all at once...
69   Length = StatBuf.st_size;
70   Buffer = (unsigned char*)mmap(0, Length, PROT_READ, MAP_PRIVATE, FD, 0);
71
72   if (Buffer == (unsigned char*)MAP_FAILED)
73     throw std::string("Error mmapping file!");
74
75   try {
76     // Parse the bytecode we mmapped in
77     ParseBytecode(Buffer, Length, Filename);
78   } catch (...) {
79     munmap((char*)Buffer, Length);
80     throw;
81   }
82 }
83
84 BytecodeFileReader::~BytecodeFileReader() {
85   // Unmmap the bytecode...
86   munmap((char*)Buffer, Length);
87 }
88
89 //===----------------------------------------------------------------------===//
90 // BytecodeBufferReader - Read from a memory buffer
91 //
92
93 namespace {
94   /// BytecodeBufferReader - parses a bytecode file from a buffer
95   ///
96   class BytecodeBufferReader : public BytecodeParser {
97   private:
98     const unsigned char *Buffer;
99     bool MustDelete;
100
101     BytecodeBufferReader(const BytecodeBufferReader&); // Do not implement
102     void operator=(const BytecodeBufferReader &BFR);   // Do not implement
103
104   public:
105     BytecodeBufferReader(const unsigned char *Buf, unsigned Length,
106                          const std::string &ModuleID);
107     ~BytecodeBufferReader();
108
109   };
110 }
111
112 BytecodeBufferReader::BytecodeBufferReader(const unsigned char *Buf,
113                                            unsigned Length,
114                                            const std::string &ModuleID)
115 {
116   // If not aligned, allocate a new buffer to hold the bytecode...
117   const unsigned char *ParseBegin = 0;
118   if ((intptr_t)Buf & 3) {
119     Buffer = new unsigned char[Length+4];
120     unsigned Offset = 4 - ((intptr_t)Buffer & 3);   // Make sure it's aligned
121     ParseBegin = Buffer + Offset;
122     memcpy((unsigned char*)ParseBegin, Buf, Length);    // Copy it over
123     MustDelete = true;
124   } else {
125     // If we don't need to copy it over, just use the caller's copy
126     ParseBegin = Buffer = Buf;
127     MustDelete = false;
128   }
129   try {
130     ParseBytecode(ParseBegin, Length, ModuleID);
131   } catch (...) {
132     if (MustDelete) delete [] Buffer;
133     throw;
134   }
135 }
136
137 BytecodeBufferReader::~BytecodeBufferReader() {
138   if (MustDelete) delete [] Buffer;
139 }
140
141 //===----------------------------------------------------------------------===//
142 //  BytecodeStdinReader - Read bytecode from Standard Input
143 //
144
145 namespace {
146   /// BytecodeStdinReader - parses a bytecode file from stdin
147   /// 
148   class BytecodeStdinReader : public BytecodeParser {
149   private:
150     std::vector<unsigned char> FileData;
151     unsigned char *FileBuf;
152
153     BytecodeStdinReader(const BytecodeStdinReader&); // Do not implement
154     void operator=(const BytecodeStdinReader &BFR);  // Do not implement
155
156   public:
157     BytecodeStdinReader();
158   };
159 }
160
161 BytecodeStdinReader::BytecodeStdinReader() {
162   int BlockSize;
163   unsigned char Buffer[4096*4];
164
165   // Read in all of the data from stdin, we cannot mmap stdin...
166   while ((BlockSize = read(0 /*stdin*/, Buffer, 4096*4))) {
167     if (BlockSize == -1)
168       throw std::string("Error reading from stdin!");
169     
170     FileData.insert(FileData.end(), Buffer, Buffer+BlockSize);
171   }
172
173   if (FileData.empty())
174     throw std::string("Standard Input empty!");
175
176   FileBuf = &FileData[0];
177   ParseBytecode(FileBuf, FileData.size(), "<stdin>");
178 }
179
180 //===----------------------------------------------------------------------===//
181 //  Varargs transmogrification code...
182 //
183
184 // CheckVarargs - This is used to automatically translate old-style varargs to
185 // new style varargs for backwards compatibility.
186 static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
187   Module *M = MP->getModule();
188   
189   // Check to see if va_start takes arguments...
190   Function *F = M->getNamedFunction("llvm.va_start");
191   if (F == 0) return MP;  // No varargs use, just return.
192
193   if (F->getFunctionType()->getNumParams() == 0)
194     return MP;  // Modern varargs processing, just return.
195
196   // If we get to this point, we know that we have an old-style module.
197   // Materialize the whole thing to perform the rewriting.
198   MP->materializeModule();
199
200   // If the user is making use of obsolete varargs intrinsics, adjust them for
201   // the user.
202   if (Function *F = M->getNamedFunction("llvm.va_start")) {
203     assert(F->asize() == 1 && "Obsolete va_start takes 1 argument!");
204         
205     const Type *RetTy = F->getFunctionType()->getParamType(0);
206     RetTy = cast<PointerType>(RetTy)->getElementType();
207     Function *NF = M->getOrInsertFunction("llvm.va_start", RetTy, 0);
208         
209     for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
210       if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
211         Value *V = new CallInst(NF, "", CI);
212         new StoreInst(V, CI->getOperand(1), CI);
213         CI->getParent()->getInstList().erase(CI);
214       }
215     F->setName("");
216   }
217
218   if (Function *F = M->getNamedFunction("llvm.va_end")) {
219     assert(F->asize() == 1 && "Obsolete va_end takes 1 argument!");
220     const Type *ArgTy = F->getFunctionType()->getParamType(0);
221     ArgTy = cast<PointerType>(ArgTy)->getElementType();
222     Function *NF = M->getOrInsertFunction("llvm.va_end", Type::VoidTy,
223                                                   ArgTy, 0);
224         
225     for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
226       if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
227         Value *V = new LoadInst(CI->getOperand(1), "", CI);
228         new CallInst(NF, V, "", CI);
229         CI->getParent()->getInstList().erase(CI);
230       }
231     F->setName("");
232   }
233       
234   if (Function *F = M->getNamedFunction("llvm.va_copy")) {
235     assert(F->asize() == 2 && "Obsolete va_copy takes 2 argument!");
236     const Type *ArgTy = F->getFunctionType()->getParamType(0);
237     ArgTy = cast<PointerType>(ArgTy)->getElementType();
238     Function *NF = M->getOrInsertFunction("llvm.va_copy", ArgTy,
239                                                   ArgTy, 0);
240         
241     for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
242       if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
243         Value *V = new CallInst(NF, CI->getOperand(2), "", CI);
244         new StoreInst(V, CI->getOperand(1), CI);
245         CI->getParent()->getInstList().erase(CI);
246       }
247     F->setName("");
248   }
249   return MP;
250 }
251
252
253 //===----------------------------------------------------------------------===//
254 // Wrapper functions
255 //===----------------------------------------------------------------------===//
256
257 /// getBytecodeBufferModuleProvider - lazy function-at-a-time loading from a
258 /// buffer
259 ModuleProvider* 
260 getBytecodeBufferModuleProvider(const unsigned char *Buffer, unsigned Length,
261                                 const std::string &ModuleID) {
262   return CheckVarargs(new BytecodeBufferReader(Buffer, Length, ModuleID));
263 }
264
265 /// ParseBytecodeBuffer - Parse a given bytecode buffer
266 ///
267 Module *ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length,
268                             const std::string &ModuleID, std::string *ErrorStr){
269   try {
270     std::auto_ptr<ModuleProvider>
271       AMP(getBytecodeBufferModuleProvider(Buffer, Length, ModuleID));
272     return AMP->releaseModule();
273   } catch (std::string &err) {
274     if (ErrorStr) *ErrorStr = err;
275     return 0;
276   }
277 }
278
279 /// getBytecodeModuleProvider - lazy function-at-a-time loading from a file
280 ///
281 ModuleProvider *getBytecodeModuleProvider(const std::string &Filename) {
282   if (Filename != std::string("-"))        // Read from a file...
283     return CheckVarargs(new BytecodeFileReader(Filename));
284   else                                     // Read from stdin
285     return CheckVarargs(new BytecodeStdinReader());
286 }
287
288 /// ParseBytecodeFile - Parse the given bytecode file
289 ///
290 Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
291   try {
292     std::auto_ptr<ModuleProvider> AMP(getBytecodeModuleProvider(Filename));
293     return AMP->releaseModule();
294   } catch (std::string &err) {
295     if (ErrorStr) *ErrorStr = err;
296     return 0;
297   }
298 }