aboutsummaryrefslogtreecommitdiff
path: root/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bytecode/Analyzer/AnalyzerWrappers.cpp')
-rw-r--r--lib/Bytecode/Analyzer/AnalyzerWrappers.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp b/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp
new file mode 100644
index 0000000000..a0e4845a1b
--- /dev/null
+++ b/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp
@@ -0,0 +1,208 @@
+//===- AnalyzerWrappers.cpp - Analyze bytecode from file or buffer -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements loading and analysis of a bytecode file and analyzing a
+// bytecode buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bytecode/Analyzer.h"
+#include "AnalyzerInternals.h"
+#include "Support/FileUtilities.h"
+#include "Support/StringExtras.h"
+#include "Config/unistd.h"
+#include <cerrno>
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// BytecodeFileAnalyzer - Analyze from an mmap'able file descriptor.
+//
+
+namespace {
+ /// BytecodeFileAnalyzer - parses a bytecode file from a file
+ class BytecodeFileAnalyzer : public BytecodeAnalyzer {
+ private:
+ unsigned char *Buffer;
+ unsigned Length;
+
+ BytecodeFileAnalyzer(const BytecodeFileAnalyzer&); // Do not implement
+ void operator=(const BytecodeFileAnalyzer &BFR); // Do not implement
+
+ public:
+ BytecodeFileAnalyzer(const std::string &Filename, BytecodeAnalysis& bca);
+ ~BytecodeFileAnalyzer();
+ };
+}
+
+static std::string ErrnoMessage (int savedErrNum, std::string descr) {
+ return ::strerror(savedErrNum) + std::string(", while trying to ") + descr;
+}
+
+BytecodeFileAnalyzer::BytecodeFileAnalyzer(const std::string &Filename,
+ BytecodeAnalysis& bca) {
+ Buffer = (unsigned char*)ReadFileIntoAddressSpace(Filename, Length);
+ if (Buffer == 0)
+ throw "Error reading file '" + Filename + "'.";
+
+ try {
+ // Parse the bytecode we mmapped in
+ if ( bca.dumpBytecode )
+ DumpBytecode(Buffer, Length, bca, Filename);
+ AnalyzeBytecode(Buffer, Length, bca, Filename);
+ } catch (...) {
+ UnmapFileFromAddressSpace(Buffer, Length);
+ throw;
+ }
+}
+
+BytecodeFileAnalyzer::~BytecodeFileAnalyzer() {
+ // Unmmap the bytecode...
+ UnmapFileFromAddressSpace(Buffer, Length);
+}
+
+//===----------------------------------------------------------------------===//
+// BytecodeBufferAnalyzer - Read from a memory buffer
+//
+
+namespace {
+ /// BytecodeBufferAnalyzer - parses a bytecode file from a buffer
+ ///
+ class BytecodeBufferAnalyzer : public BytecodeAnalyzer {
+ private:
+ const unsigned char *Buffer;
+ bool MustDelete;
+
+ BytecodeBufferAnalyzer(const BytecodeBufferAnalyzer&); // Do not implement
+ void operator=(const BytecodeBufferAnalyzer &BFR); // Do not implement
+
+ public:
+ BytecodeBufferAnalyzer(const unsigned char *Buf, unsigned Length,
+ BytecodeAnalysis& bca, const std::string &ModuleID);
+ ~BytecodeBufferAnalyzer();
+
+ };
+}
+
+BytecodeBufferAnalyzer::BytecodeBufferAnalyzer(const unsigned char *Buf,
+ unsigned Length,
+ BytecodeAnalysis& bca,
+ const std::string &ModuleID) {
+ // If not aligned, allocate a new buffer to hold the bytecode...
+ const unsigned char *ParseBegin = 0;
+ if ((intptr_t)Buf & 3) {
+ Buffer = new unsigned char[Length+4];
+ unsigned Offset = 4 - ((intptr_t)Buffer & 3); // Make sure it's aligned
+ ParseBegin = Buffer + Offset;
+ memcpy((unsigned char*)ParseBegin, Buf, Length); // Copy it over
+ MustDelete = true;
+ } else {
+ // If we don't need to copy it over, just use the caller's copy
+ ParseBegin = Buffer = Buf;
+ MustDelete = false;
+ }
+ try {
+ if ( bca.dumpBytecode )
+ DumpBytecode(ParseBegin, Length, bca, ModuleID);
+ AnalyzeBytecode(ParseBegin, Length, bca, ModuleID);
+ } catch (...) {
+ if (MustDelete) delete [] Buffer;
+ throw;
+ }
+}
+
+BytecodeBufferAnalyzer::~BytecodeBufferAnalyzer() {
+ if (MustDelete) delete [] Buffer;
+}
+
+//===----------------------------------------------------------------------===//
+// BytecodeStdinAnalyzer - Read bytecode from Standard Input
+//
+
+namespace {
+ /// BytecodeStdinAnalyzer - parses a bytecode file from stdin
+ ///
+ class BytecodeStdinAnalyzer : public BytecodeAnalyzer {
+ private:
+ std::vector<unsigned char> FileData;
+ unsigned char *FileBuf;
+
+ BytecodeStdinAnalyzer(const BytecodeStdinAnalyzer&); // Do not implement
+ void operator=(const BytecodeStdinAnalyzer &BFR); // Do not implement
+
+ public:
+ BytecodeStdinAnalyzer(BytecodeAnalysis& bca);
+ };
+}
+
+BytecodeStdinAnalyzer::BytecodeStdinAnalyzer(BytecodeAnalysis& bca ) {
+ int BlockSize;
+ unsigned char Buffer[4096*4];
+
+ // Read in all of the data from stdin, we cannot mmap stdin...
+ while ((BlockSize = ::read(0 /*stdin*/, Buffer, 4096*4))) {
+ if (BlockSize == -1)
+ throw ErrnoMessage(errno, "read from standard input");
+
+ FileData.insert(FileData.end(), Buffer, Buffer+BlockSize);
+ }
+
+ if (FileData.empty())
+ throw std::string("Standard Input empty!");
+
+ FileBuf = &FileData[0];
+ if (bca.dumpBytecode)
+ DumpBytecode(&FileData[0], FileData.size(), bca, "<stdin>");
+ AnalyzeBytecode(FileBuf, FileData.size(), bca, "<stdin>");
+}
+
+//===----------------------------------------------------------------------===//
+// Wrapper functions
+//===----------------------------------------------------------------------===//
+
+// AnalyzeBytecodeFile - analyze one file
+void llvm::AnalyzeBytecodeFile(const std::string &Filename,
+ BytecodeAnalysis& bca,
+ std::string *ErrorStr)
+{
+ try {
+ if ( Filename != "-" )
+ BytecodeFileAnalyzer bfa(Filename,bca);
+ else
+ BytecodeStdinAnalyzer bsa(bca);
+ } catch (std::string &err) {
+ if (ErrorStr) *ErrorStr = err;
+ }
+}
+
+// AnalyzeBytecodeBuffer - analyze a buffer
+void llvm::AnalyzeBytecodeBuffer(
+ const unsigned char* Buffer, ///< Pointer to start of bytecode buffer
+ unsigned BufferSize, ///< Size of the bytecode buffer
+ BytecodeAnalysis& Results, ///< The results of the analysis
+ std::string* ErrorStr ///< Errors, if any.
+ )
+{
+ try {
+ BytecodeBufferAnalyzer(Buffer, BufferSize, Results, "<buffer>" );
+ } catch (std::string& err ) {
+ if ( ErrorStr) *ErrorStr = err;
+ }
+}
+
+
+/// This function prints the contents of rhe BytecodeAnalysis structure in
+/// a human legible form.
+/// @brief Print BytecodeAnalysis structure to an ostream
+void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
+{
+ Out << "Not Implemented Yet.\n";
+}
+
+// vim: sw=2