Ensure invoking obsolete methods throws errors.

This sets the entrypoint for obsolete methods to a special stub that
will ensure that calling them results in an Error being thrown.
Previously we were allowing obsolete methods to be run if they could
reach the appropriate places in the runtime.

Getting into the state where this is possible is extremely difficult
since one can only get an jmethodID to an obsolete method by snatching
it off the stack (or by inspecting internal runtime data). From there
normally invoking it will do lookup on the receiver which will get you
the original version.

Bug: 36867251
Bug: 31455788

Test: ./test.py --host -j40
Test: (with aosp_marlin-userdebug device) ./test.py --target -j4

Change-Id: I2ca0503966a4e3de18dd89cb7ff224eba1459b49
diff --git a/runtime/entrypoints/quick/quick_throw_entrypoints.cc b/runtime/entrypoints/quick/quick_throw_entrypoints.cc
index 1520e13..565b4ed 100644
--- a/runtime/entrypoints/quick/quick_throw_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_throw_entrypoints.cc
@@ -29,6 +29,15 @@
   self->QuickDeliverException();
 }
 
+extern "C" NO_RETURN uint64_t artInvokeObsoleteMethod(ArtMethod* method, Thread* self)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  DCHECK(method->IsObsolete());
+  ScopedQuickEntrypointChecks sqec(self);
+  ThrowInternalError("Attempting to invoke obsolete version of '%s'.",
+                     method->PrettyMethod().c_str());
+  self->QuickDeliverException();
+}
+
 // Called by generated code to throw an exception.
 extern "C" NO_RETURN void artDeliverExceptionFromCode(mirror::Throwable* exception, Thread* self)
     REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/runtime/entrypoints/runtime_asm_entrypoints.h b/runtime/entrypoints/runtime_asm_entrypoints.h
index 2842c5a..4ca52de 100644
--- a/runtime/entrypoints/runtime_asm_entrypoints.h
+++ b/runtime/entrypoints/runtime_asm_entrypoints.h
@@ -40,6 +40,12 @@
   return reinterpret_cast<const void*>(art_quick_to_interpreter_bridge);
 }
 
+// Return the address of stub code for attempting to invoke an obsolete method.
+extern "C" void art_invoke_obsolete_method_stub(ArtMethod*);
+static inline const void* GetInvokeObsoleteMethodStub() {
+  return reinterpret_cast<const void*>(art_invoke_obsolete_method_stub);
+}
+
 // Return the address of quick stub code for handling JNI calls.
 extern "C" void art_quick_generic_jni_trampoline(ArtMethod*);
 static inline const void* GetQuickGenericJniStub() {