Improve our choices of exceptions to throw.

Change-Id: I81b22db4013fda9b0a982c16c403f0165ee4be8d
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 769a336..514a061 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -35,12 +35,11 @@
   va_end(args);
 }
 
-void ThrowVirtualMachineError(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
-void ThrowVirtualMachineError(const char* fmt, ...) {
+void ThrowClassFormatError(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
+void ThrowClassFormatError(const char* fmt, ...) {
   va_list args;
   va_start(args, fmt);
-  UNIMPLEMENTED(FATAL) << "VirtualMachineError is abstract, throw something else";
-  Thread::Current()->ThrowNewExceptionV("Ljava/lang/VirtualMachineError;", fmt, args);
+  Thread::Current()->ThrowNewExceptionV("Ljava/lang/ClassFormatError;", fmt, args);
   va_end(args);
 }
 
@@ -1662,25 +1661,23 @@
     Class* super_class = ResolveType(dex_file, klass->GetSuperClassTypeIdx(), klass);
     if (super_class == NULL) {
       DCHECK(Thread::Current()->IsExceptionPending());
-      // TODO: can't ThrowVirtualMachineError, its abstract
-      // ThrowVirtualMachineError("Failed to resolve superclass with type index %d for class %s",
-      //     klass->GetSuperClassTypeIdx(), PrettyDescriptor(klass->GetDescriptor()).c_str());
       return false;
     }
     klass->SetSuperClass(super_class);
   }
   for (size_t i = 0; i < klass->NumInterfaces(); ++i) {
     uint32_t idx = klass->GetInterfacesTypeIdx()->Get(i);
-    Class *interface = ResolveType(dex_file, idx, klass);
+    Class* interface = ResolveType(dex_file, idx, klass);
     klass->SetInterface(i, interface);
     if (interface == NULL) {
-      ThrowVirtualMachineError("Failed to resolve interface with type index %d for class %s",
-          idx, PrettyDescriptor(klass->GetDescriptor()).c_str());
+      DCHECK(Thread::Current()->IsExceptionPending());
       return false;
     }
     // Verify
     if (!klass->CanAccess(interface)) {
-      ThrowVirtualMachineError("Inaccessible interface %s implemented by class %s",
+      // TODO: the RI seemed to ignore this in my testing.
+      Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;",
+          "Interface %s implemented by class %s is inaccessible",
           PrettyDescriptor(interface->GetDescriptor()).c_str(),
           PrettyDescriptor(klass->GetDescriptor()).c_str());
       return false;
@@ -1711,13 +1708,17 @@
   // Verify
   if (super->IsFinal() || super->IsInterface()) {
     Thread::Current()->ThrowNewException("Ljava/lang/IncompatibleClassChangeError;",
-        "Superclass %s is %s", PrettyDescriptor(super->GetDescriptor()).c_str(),
+        "Superclass %s of %s is %s",
+        PrettyDescriptor(super->GetDescriptor()).c_str(),
+        PrettyDescriptor(klass->GetDescriptor()).c_str(),
         super->IsFinal() ? "declared final" : "an interface");
     return false;
   }
   if (!klass->CanAccess(super)) {
     Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;",
-        "Superclass %s is inaccessible", PrettyDescriptor(super->GetDescriptor()).c_str());
+        "Superclass %s is inaccessible by %s",
+        PrettyDescriptor(super->GetDescriptor()).c_str(),
+        PrettyDescriptor(klass->GetDescriptor()).c_str());
     return false;
   }
 #ifndef NDEBUG
@@ -1736,7 +1737,7 @@
     // No vtable.
     size_t count = klass->NumVirtualMethods();
     if (!IsUint(16, count)) {
-      ThrowVirtualMachineError("Too many methods on interface: %d", count);
+      ThrowClassFormatError("Too many methods on interface: %d", count);
       return false;
     }
     for (size_t i = 0; i < count; ++i) {
@@ -1770,7 +1771,7 @@
         if (local_method->HasSameNameAndDescriptor(super_method)) {
           // Verify
           if (super_method->IsFinal()) {
-            ThrowVirtualMachineError("Method %s.%s overrides final method in class %s",
+            ThrowLinkageError("Method %s.%s overrides final method in class %s",
                 PrettyDescriptor(klass->GetDescriptor()).c_str(),
                 local_method->GetName()->ToModifiedUtf8().c_str(),
                 PrettyDescriptor(super_method->GetDeclaringClass()->GetDescriptor()).c_str());
@@ -1789,7 +1790,7 @@
       }
     }
     if (!IsUint(16, actual_count)) {
-      ThrowVirtualMachineError("Too many methods defined on class: %d", actual_count);
+      ThrowClassFormatError("Too many methods defined on class: %d", actual_count);
       return false;
     }
     // Shrink vtable if possible
@@ -1802,7 +1803,7 @@
     CHECK(klass->GetDescriptor()->Equals("Ljava/lang/Object;"));
     uint32_t num_virtual_methods = klass->NumVirtualMethods();
     if (!IsUint(16, num_virtual_methods)) {
-      ThrowVirtualMachineError("Too many methods: %d", num_virtual_methods);
+      ThrowClassFormatError("Too many methods: %d", num_virtual_methods);
       return false;
     }
     ObjectArray<Method>* vtable = AllocObjectArray<Method>(num_virtual_methods);