A dirty (but useful) hack to decode thread offsets in disassembly.

Plus more readable x86 formatting.

Also fix a bug decoding LDR (immediate, Thumb) encoding T1.

Change-Id: I95c79d3fb4d912d1ef386b5843abd37d3652a476
diff --git a/src/thread.cc b/src/thread.cc
index b26928f..0a44b53 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1459,6 +1459,113 @@
 #endif
 }
 
+void Thread::DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers) {
+  CHECK_EQ(size_of_pointers, 4U); // TODO: support 64-bit targets.
+#define DO_THREAD_OFFSET(x) if (offset == static_cast<uint32_t>(OFFSETOF_MEMBER(Thread, x))) { os << # x; } else
+#define DO_THREAD_ENTRY_POINT_OFFSET(x) if (offset == ENTRYPOINT_OFFSET(x)) { os << # x; } else
+  DO_THREAD_OFFSET(card_table_)
+  DO_THREAD_OFFSET(exception_)
+  DO_THREAD_OFFSET(jni_env_)
+  DO_THREAD_OFFSET(self_)
+  DO_THREAD_OFFSET(stack_end_)
+  DO_THREAD_OFFSET(suspend_count_)
+  DO_THREAD_OFFSET(thin_lock_id_)
+  DO_THREAD_OFFSET(top_of_managed_stack_)
+  DO_THREAD_OFFSET(top_of_managed_stack_pc_)
+  DO_THREAD_OFFSET(top_sirt_)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocArrayFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocArrayFromCodeWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocObjectFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pAllocObjectFromCodeWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckAndAllocArrayFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckAndAllocArrayFromCodeWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInstanceofNonTrivialFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCanPutArrayElementFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckCastFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDebugMe)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUpdateDebuggerFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInitializeStaticStorage)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInitializeTypeAndVerifyAccessFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInitializeTypeFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pResolveStringFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet32Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet32Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet64Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSet64Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSetObjInstance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pSetObjStatic)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet32Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet32Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet64Instance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGet64Static)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGetObjInstance)
+  DO_THREAD_ENTRY_POINT_OFFSET(pGetObjStatic)
+  DO_THREAD_ENTRY_POINT_OFFSET(pHandleFillArrayDataFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDecodeJObjectInThread)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFindNativeMethod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLockObjectFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUnlockObjectFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmpgDouble)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmpgFloat)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmplDouble)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCmplFloat)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDadd)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDmul)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDsub)
+  DO_THREAD_ENTRY_POINT_OFFSET(pF2d)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFmod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pI2d)
+  DO_THREAD_ENTRY_POINT_OFFSET(pL2d)
+  DO_THREAD_ENTRY_POINT_OFFSET(pD2f)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFadd)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFmodf)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFmul)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFsub)
+  DO_THREAD_ENTRY_POINT_OFFSET(pI2f)
+  DO_THREAD_ENTRY_POINT_OFFSET(pL2f)
+  DO_THREAD_ENTRY_POINT_OFFSET(pD2iz)
+  DO_THREAD_ENTRY_POINT_OFFSET(pF2iz)
+  DO_THREAD_ENTRY_POINT_OFFSET(pIdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pIdivmod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pD2l)
+  DO_THREAD_ENTRY_POINT_OFFSET(pF2l)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLdiv)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLdivmod)
+  DO_THREAD_ENTRY_POINT_OFFSET(pLmul)
+  DO_THREAD_ENTRY_POINT_OFFSET(pShlLong)
+  DO_THREAD_ENTRY_POINT_OFFSET(pShrLong)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUshrLong)
+  DO_THREAD_ENTRY_POINT_OFFSET(pIndexOf)
+  DO_THREAD_ENTRY_POINT_OFFSET(pMemcmp16)
+  DO_THREAD_ENTRY_POINT_OFFSET(pStringCompareTo)
+  DO_THREAD_ENTRY_POINT_OFFSET(pMemcpy)
+  DO_THREAD_ENTRY_POINT_OFFSET(pFindInterfaceMethodInCache)
+  DO_THREAD_ENTRY_POINT_OFFSET(pUnresolvedDirectMethodTrampolineFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeInterfaceTrampoline)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck)
+  DO_THREAD_ENTRY_POINT_OFFSET(pCheckSuspendFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pTestSuspendFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pDeliverException)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowAbstractMethodErrorFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowArrayBoundsFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowDivZeroFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowNoSuchMethodFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowNullPointerFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowStackOverflowFromCode)
+  DO_THREAD_ENTRY_POINT_OFFSET(pThrowVerificationErrorFromCode)
+  {
+    os << offset;
+  }
+#undef DO_THREAD_OFFSET
+#undef DO_THREAD_ENTRY_POINT_OFFSET
+}
+
 class CatchBlockStackVisitor : public Thread::StackVisitor {
  public:
   CatchBlockStackVisitor(Class* to_find, Context* ljc)