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