Add bccMarkExternalSymbol (to specify external symbol.)

By default libbcc will internalize every symbol, and perform
LTO.  However, in many situations we have to export a specific
function, such as "root" or "init" for RenderScript, so we are
adding bccMarkExternalSymbol.

Change-Id: I136eb8ff68e9ccf8c6595eb470f9718e1cb1e4ab
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index 16bd687..7807194 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -78,6 +78,8 @@
 
 #include <string.h>
 
+#include <algorithm>
+#include <iterator>
 #include <string>
 #include <vector>
 
@@ -706,10 +708,21 @@
     }
   }
 
+  // TODO(logan): Remove this after we have finished the
+  // bccMarkExternalSymbol API.
+
   // root() and init() are born to be exported
   ExportSymbols.push_back("root");
   ExportSymbols.push_back("init");
 
+  // User-defined exporting symbols
+  std::vector<char const *> const &UserDefinedExternalSymbols =
+    mpResult->getUserDefinedExternalSymbols();
+
+  std::copy(UserDefinedExternalSymbols.begin(),
+            UserDefinedExternalSymbols.end(),
+            std::back_inserter(ExportSymbols));
+
   // We now create passes list performing LTO. These are copied from
   // (including comments) llvm::createStandardLTOPasses().
 
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index 46b385f..2855240 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -22,6 +22,9 @@
 
 #include "Compiler.h"
 
+#include <vector>
+#include <string>
+
 #include <stddef.h>
 
 namespace llvm {
@@ -69,6 +72,9 @@
     // Note: mSourceList[1] (library source)
     // TODO(logan): Generalize this, use vector or SmallVector instead!
 
+    // External Function List
+    std::vector<char const *> mUserDefinedExternalSymbols;
+
     // Register Symbol Lookup Function
     BCCSymbolLookupFn mpExtSymbolLookupFn;
     void *mpExtSymbolLookupFnContext;
@@ -99,6 +105,14 @@
                       char const *path,
                       unsigned long flags);
 
+    void markExternalSymbol(char const *name) {
+      mUserDefinedExternalSymbols.push_back(name);
+    }
+
+    std::vector<char const *> const &getUserDefinedExternalSymbols() const {
+      return mUserDefinedExternalSymbols;
+    }
+
     int prepareExecutable(char const *cacheDir,
                           char const *cacheName,
                           unsigned long flags);
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index 5972ddf..6a1a9e8 100644
--- a/lib/ExecutionEngine/ScriptCompiled.h
+++ b/lib/ExecutionEngine/ScriptCompiled.h
@@ -18,6 +18,7 @@
 #define BCC_SCRIPTCOMPILED_H
 
 #include "Compiler.h"
+#include "Script.h"
 
 #include <bcc/bcc.h>
 
@@ -32,8 +33,6 @@
 }
 
 namespace bcc {
-  class Script;
-
   class ScriptCompiled {
     friend class Compiler;
     friend class CodeEmitter;
@@ -137,6 +136,10 @@
     void getObjectSlotList(size_t objectSlotListSize,
                            uint32_t *objectSlotList);
 
+    std::vector<char const *> const & getUserDefinedExternalSymbols() const {
+      return mpOwner->getUserDefinedExternalSymbols();
+    }
+
 #if USE_OLD_JIT
     char *getContext() {
       return mContext;
diff --git a/lib/ExecutionEngine/bcc.cpp b/lib/ExecutionEngine/bcc.cpp
index 6199c16..3d24ac5 100644
--- a/lib/ExecutionEngine/bcc.cpp
+++ b/lib/ExecutionEngine/bcc.cpp
@@ -117,6 +117,12 @@
 }
 
 
+extern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) {
+  BCC_FUNC_LOGGER();
+  unwrap(script)->markExternalSymbol(name);
+}
+
+
 extern "C" int bccPrepareSharedObject(BCCScriptRef script,
                                       char const *cacheDir,
                                       char const *cacheName,