Code for loading shared libraries and calling JNI_OnLoad.

This causes a bit of log spam as we call unimplemented JNI functions,
but fixing those is my first job tomorrow. The exciting thing here is
that we're now loading libcore's classes and libcore's JNI.

I've changed ParsedOptions' std::vector of verbose options over to a
std::set for the convenience of callers, and defaulted -verbose:jni to
on. (This is not the cause of the log spam.)

The only nasty bit here is that icu4c doesn't like being initialized
more than 10 times, because it has a 10-element fixed-size array. The
u_cleanup function is not publicly accessible, so we have to fiddle
around with dlsym(3) twice in one patch...

Change-Id: I9f6b5d74621eb2e88d04a89f00335067fda4ccbe
diff --git a/src/jni_internal.h b/src/jni_internal.h
index 50e3925..5d89dd8 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -10,13 +10,36 @@
 #include "macros.h"
 #include "reference_table.h"
 
+#include <map>
+#include <string>
+
 namespace art {
 
 class Runtime;
+class SharedLibrary;
 class Thread;
 
 struct JavaVMExt {
-  JavaVMExt(Runtime* runtime, bool check_jni);
+  JavaVMExt(Runtime* runtime, bool check_jni, bool verbose_jni);
+
+  /*
+   * Load native code from the specified absolute pathname.  Per the spec,
+   * if we've already loaded a library with the specified pathname, we
+   * return without doing anything.
+   *
+   * TODO: for better results we should canonicalize the pathname.  For fully
+   * correct results we should stat to get the inode and compare that.  The
+   * existing implementation is fine so long as everybody is using
+   * System.loadLibrary.
+   *
+   * The library will be associated with the specified class loader.  The JNI
+   * spec says we can't load the same library into more than one class loader.
+   *
+   * Returns true on success. On failure, returns false and sets *detail to a
+   * human-readable description of the error or NULL if no detail is
+   * available; ownership of the string is transferred to the caller.
+   */
+  bool LoadNativeLibrary(const std::string& path, Object* class_loader, char** detail);
 
   // Must be first to correspond with JNIEnv.
   const struct JNIInvokeInterface* fns;
@@ -24,6 +47,7 @@
   Runtime* runtime;
 
   bool check_jni;
+  bool verbose_jni;
 
   // Used to hold references to pinned primitive arrays.
   ReferenceTable pin_table;
@@ -33,6 +57,8 @@
 
   // JNI weak global references.
   IndirectReferenceTable weak_globals;
+
+  std::map<std::string, SharedLibrary*> libraries;
 };
 
 struct JNIEnvExt {