Improve standalone bcc for on-device compilation.

Bug: 7342767

This adds functionality for driver-writers to dynamically load plugins.
If such a plugin is loaded, we then execute any function called
rsCompilerDriverInit() from it. This function can initialize any other
state the driver-writer wants.

Change-Id: I733a6a3fc59c429a542cfcaf59a57ad231a19d01
diff --git a/tools/bcc/Main.cpp b/tools/bcc/Main.cpp
index 04b6942..e5b8bc0 100644
--- a/tools/bcc/Main.cpp
+++ b/tools/bcc/Main.cpp
@@ -17,6 +17,7 @@
 #include <string>
 #include <vector>
 
+#include <dlfcn.h>
 #include <stdlib.h>
 
 #include <llvm/ADT/OwningPtr.h>
@@ -26,6 +27,7 @@
 #include <llvm/Support/CommandLine.h>
 #include <llvm/Support/FileSystem.h>
 #include <llvm/Support/MemoryBuffer.h>
+#include <llvm/Support/PluginLoader.h>
 #include <llvm/Support/raw_ostream.h>
 #include <llvm/Support/system_error.h>
 
@@ -48,6 +50,9 @@
 
 using namespace bcc;
 
+#define STR2(a) #a
+#define STR(a) STR2(a)
+
 //===----------------------------------------------------------------------===//
 // General Options
 //===----------------------------------------------------------------------===//
@@ -90,6 +95,10 @@
                                  llvm::cl::aliasopt(OptTargetTriple));
 #endif
 
+llvm::cl::opt<bool>
+OptRSDebugContext("rs-debug-ctx",
+    llvm::cl::desc("Enable build to work with a RenderScript debug context"));
+
 //===----------------------------------------------------------------------===//
 // Compiler Options
 //===----------------------------------------------------------------------===//
@@ -148,6 +157,10 @@
   pRSCD.setConfig(config);
   Compiler::ErrorCode result = RSC->config(*config);
 
+  if (OptRSDebugContext) {
+    pRSCD.setDebugContext(true);
+  }
+
   if (result != Compiler::kSuccess) {
     llvm::errs() << "Failed to configure the compiler! (detail: "
                  << Compiler::GetErrorString(result) << ")\n";
@@ -184,6 +197,15 @@
     ALOGE("Failed to configure compiler");
     return EXIT_FAILURE;
   }
+
+  // Attempt to dynamically initialize the compiler driver if such a function
+  // is present. It is only present if passed via "-load libFOO.so".
+  RSCompilerDriverInit_t rscdi = (RSCompilerDriverInit_t)
+      dlsym(RTLD_DEFAULT, STR(RS_COMPILER_DRIVER_INIT_FN));
+  if (rscdi != NULL) {
+    rscdi(&RSCD);
+  }
+
   bool built = RSCD.build(context, OptOutputPath.c_str(),
       OptOutputFilename.c_str(), bitcode, bitcodeSize,
       OptBCLibFilename.c_str(), NULL, OptEmitLLVM);