Pass the debug_info_offset explicitly.

In order to use debug_info_offset for encoding implementation details,
rewrite all indirect users of it to fetch it before calling DexFile
methods.

This allows keeping the DexFile interface clean of runtime
considerations.

Test: test.py
Change-Id: I4591e0039b5f822f4409aae411071ecbe97082b1
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index 37c2d32..d599994 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -35,6 +35,7 @@
 #include "mirror/array.h"
 #include "mirror/class-inl.h"
 #include "mirror/class.h"
+#include "oat_file.h"
 
 namespace art {
 namespace debug {
@@ -49,7 +50,8 @@
   std::vector<const char*> names;
   if (mi->code_item != nullptr) {
     DCHECK(mi->dex_file != nullptr);
-    const uint8_t* stream = mi->dex_file->GetDebugInfoStream(mi->code_item);
+    uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*mi->dex_file, mi->code_item);
+    const uint8_t* stream = mi->dex_file->GetDebugInfoStream(debug_info_offset);
     if (stream != nullptr) {
       DecodeUnsignedLeb128(&stream);  // line.
       uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
@@ -257,7 +259,9 @@
 
       // Write local variables.
       LocalInfos local_infos;
+      uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex, dex_code);
       if (dex->DecodeDebugLocalInfo(dex_code,
+                                    debug_info_offset,
                                     is_static,
                                     mi->dex_method_index,
                                     LocalInfoCallback,
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index 6e72b46..943e03a 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -26,6 +26,7 @@
 #include "debug/src_map_elem.h"
 #include "dex_file-inl.h"
 #include "linker/elf_builder.h"
+#include "oat_file.h"
 #include "stack_map.h"
 
 namespace art {
@@ -158,7 +159,9 @@
       PositionInfos dex2line_map;
       DCHECK(mi->dex_file != nullptr);
       const DexFile* dex = mi->dex_file;
-      if (!dex->DecodeDebugPositionInfo(mi->code_item, PositionInfoCallback, &dex2line_map)) {
+      uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex, mi->code_item);
+      if (!dex->DecodeDebugPositionInfo(
+              mi->code_item, debug_info_offset, PositionInfoCallback, &dex2line_map)) {
         continue;
       }
 
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 61840cc..978d0c2 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -29,6 +29,7 @@
 #include "driver/compiler_options.h"
 #include "imtable-inl.h"
 #include "mirror/dex_cache.h"
+#include "oat_file.h"
 #include "optimizing_compiler_stats.h"
 #include "quicken_info.h"
 #include "scoped_thread_state_change-inl.h"
@@ -447,7 +448,8 @@
                                                      /* expandable */ false,
                                                      kArenaAllocGraphBuilder);
   locations->ClearAllBits();
-  dex_file_->DecodeDebugPositionInfo(code_item_, Callback::Position, locations);
+  uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file_, code_item_);
+  dex_file_->DecodeDebugPositionInfo(code_item_, debug_info_offset, Callback::Position, locations);
   // Instruction-specific tweaks.
   IterationRange<DexInstructionIterator> instructions = code_item_->Instructions();
   for (const DexInstructionPcPair& inst : instructions) {
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 84ccaa0..a7af193 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -1202,9 +1202,11 @@
   // Positions and locals table in the debug info.
   bool is_static = (flags & kAccStatic) != 0;
   fprintf(gOutFile, "      positions     : \n");
-  pDexFile->DecodeDebugPositionInfo(pCode, dumpPositionsCb, nullptr);
+  uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode);
+  pDexFile->DecodeDebugPositionInfo(pCode, debug_info_offset, dumpPositionsCb, nullptr);
   fprintf(gOutFile, "      locals        : \n");
-  pDexFile->DecodeDebugLocalInfo(pCode, is_static, idx, dumpLocalsCb, nullptr);
+  pDexFile->DecodeDebugLocalInfo(
+      pCode, debug_info_offset, is_static, idx, dumpLocalsCb, nullptr);
 }
 
 /*
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index a8ba950..2af579c 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -570,16 +570,17 @@
   uint32_t tries_size = disk_code_item.tries_size_;
 
   // TODO: Calculate the size of the debug info.
-  const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(&disk_code_item);
+  uint32_t debug_info_offset = dex_file.GetDebugInfoOffset(&disk_code_item);
+  const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(debug_info_offset);
   DebugInfoItem* debug_info = nullptr;
   if (debug_info_stream != nullptr) {
-    debug_info = debug_info_items_map_.GetExistingObject(disk_code_item.debug_info_off_);
+    debug_info = debug_info_items_map_.GetExistingObject(debug_info_offset);
     if (debug_info == nullptr) {
       uint32_t debug_info_size = GetDebugInfoStreamSize(debug_info_stream);
       uint8_t* debug_info_buffer = new uint8_t[debug_info_size];
       memcpy(debug_info_buffer, debug_info_stream, debug_info_size);
       debug_info = new DebugInfoItem(debug_info_size, debug_info_buffer);
-      AddItem(debug_info_items_map_, debug_info_items_, debug_info, disk_code_item.debug_info_off_);
+      AddItem(debug_info_items_map_, debug_info_items_, debug_info, debug_info_offset);
     }
   }
 
diff --git a/dexlist/Android.bp b/dexlist/Android.bp
index 03943bf..8ecff42 100644
--- a/dexlist/Android.bp
+++ b/dexlist/Android.bp
@@ -17,7 +17,7 @@
     host_supported: true,
     srcs: ["dexlist.cc"],
     cflags: ["-Wall", "-Werror"],
-    shared_libs: ["libart"],
+    shared_libs: ["libart", "libbase"],
 }
 
 art_cc_test {
diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc
index e3ca59c..3bd903d 100644
--- a/dexlist/dexlist.cc
+++ b/dexlist/dexlist.cc
@@ -120,7 +120,8 @@
 
   // Find the first line.
   int firstLine = -1;
-  pDexFile->DecodeDebugPositionInfo(pCode, positionsCb, &firstLine);
+  uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode);
+  pDexFile->DecodeDebugPositionInfo(pCode, debug_info_offset, positionsCb, &firstLine);
 
   // Method signature.
   const Signature signature = pDexFile->GetMethodSignature(pMethodId);
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index cf93bf0..448ce41 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -48,6 +48,7 @@
 #include "mirror/object_array-inl.h"
 #include "modifiers.h"
 #include "nativehelper/scoped_local_ref.h"
+#include "oat_file.h"
 #include "runtime_callbacks.h"
 #include "scoped_thread_state_change-inl.h"
 #include "stack.h"
@@ -259,7 +260,9 @@
   };
 
   LocalVariableContext context(env);
+  uint32_t debug_info_offset = art::OatFile::GetDebugInfoOffset(*dex_file, code_item);
   if (!dex_file->DecodeDebugLocalInfo(code_item,
+                                      debug_info_offset,
                                       art_method->IsStatic(),
                                       art_method->GetDexMethodIndex(),
                                       LocalVariableContext::Callback,
@@ -480,7 +483,9 @@
   }
 
   LineNumberContext context;
-  bool success = dex_file->DecodeDebugPositionInfo(code_item, CollectLineNumbers, &context);
+  uint32_t debug_info_offset = art::OatFile::GetDebugInfoOffset(*dex_file, code_item);
+  bool success = dex_file->DecodeDebugPositionInfo(
+      code_item, debug_info_offset, CollectLineNumbers, &context);
   if (!success) {
     return ERR(ABSENT_INFORMATION);
   }
@@ -648,7 +653,9 @@
     };
 
     GetLocalVariableInfoContext context(slot_, dex_pc, descriptor, type);
+    uint32_t debug_info_offset = art::OatFile::GetDebugInfoOffset(*dex_file, code_item);
     if (!dex_file->DecodeDebugLocalInfo(code_item,
+                                        debug_info_offset,
                                         method->IsStatic(),
                                         method->GetDexMethodIndex(),
                                         GetLocalVariableInfoContext::Callback,
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 3784212..1dcd935 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -58,6 +58,7 @@
 #include "mirror/throwable.h"
 #include "nativehelper/scoped_local_ref.h"
 #include "nativehelper/scoped_primitive_array.h"
+#include "oat_file.h"
 #include "obj_ptr-inl.h"
 #include "reflection.h"
 #include "safe_map.h"
@@ -1680,7 +1681,9 @@
   context.pReply = pReply;
 
   if (code_item != nullptr) {
-    m->GetDexFile()->DecodeDebugPositionInfo(code_item, DebugCallbackContext::Callback, &context);
+    uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item);
+    m->GetDexFile()->DecodeDebugPositionInfo(
+        code_item, debug_info_offset, DebugCallbackContext::Callback, &context);
   }
 
   JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
@@ -1737,9 +1740,10 @@
 
   const DexFile::CodeItem* code_item = m->GetCodeItem();
   if (code_item != nullptr) {
+    uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item);
     m->GetDexFile()->DecodeDebugLocalInfo(
-        code_item, m->IsStatic(), m->GetDexMethodIndex(), DebugCallbackContext::Callback,
-        &context);
+        code_item, debug_info_offset, m->IsStatic(), m->GetDexMethodIndex(),
+        DebugCallbackContext::Callback, &context);
   }
 
   JDWP::Set4BE(expandBufGetBuffer(pReply) + variable_count_offset, context.variable_count);
@@ -3886,7 +3890,9 @@
   if (m != nullptr && !m->IsNative()) {
     const DexFile::CodeItem* const code_item = m->GetCodeItem();
     DebugCallbackContext context(single_step_control, line_number, code_item);
-    m->GetDexFile()->DecodeDebugPositionInfo(code_item, DebugCallbackContext::Callback, &context);
+    uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item);
+    m->GetDexFile()->DecodeDebugPositionInfo(
+        code_item, debug_info_offset, DebugCallbackContext::Callback, &context);
   }
 
   // Activate single-step in the thread.
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index c926a0d..1880968 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -386,6 +386,7 @@
 
 template<typename NewLocalCallback>
 bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item,
+                                   uint32_t debug_info_offset,
                                    bool is_static,
                                    uint32_t method_idx,
                                    NewLocalCallback new_local_callback,
@@ -398,7 +399,7 @@
   for (; it.HasNext(); it.Next()) {
     arg_descriptors.push_back(it.GetDescriptor());
   }
-  return DecodeDebugLocalInfo(GetDebugInfoStream(code_item),
+  return DecodeDebugLocalInfo(GetDebugInfoStream(debug_info_offset),
                               GetLocation(),
                               GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)),
                               arg_descriptors,
@@ -488,12 +489,13 @@
 
 template<typename DexDebugNewPosition>
 bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item,
+                                      uint32_t debug_info_offset,
                                       DexDebugNewPosition position_functor,
                                       void* context) const {
   if (code_item == nullptr) {
     return false;
   }
-  return DecodeDebugPositionInfo(GetDebugInfoStream(code_item),
+  return DecodeDebugPositionInfo(GetDebugInfoStream(debug_info_offset),
                                  [this](uint32_t idx) {
                                    return StringDataByIdx(dex::StringIndex(idx));
                                  },
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index cdefb23..2166ed1 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -698,6 +698,15 @@
     return reinterpret_cast<const CodeItem*>(addr);
   }
 
+  uint32_t GetDebugInfoOffset(const CodeItem* code_item) const {
+    if (code_item == nullptr) {
+      return 0;
+    }
+    CHECK(oat_dex_file_ == nullptr)
+        << "Should only use GetDebugInfoOffset in a non runtime setup";
+    return code_item->debug_info_off_;
+  }
+
   const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const;
 
   // Returns the number of prototype identifiers in the .dex file.
@@ -775,11 +784,10 @@
   static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
 
   // Get the pointer to the start of the debugging data
-  const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const {
+  const uint8_t* GetDebugInfoStream(uint32_t debug_info_off) const {
     // Check that the offset is in bounds.
     // Note that although the specification says that 0 should be used if there
     // is no debug information, some applications incorrectly use 0xFFFFFFFF.
-    const uint32_t debug_info_off = code_item->debug_info_off_;
     return (debug_info_off == 0 || debug_info_off >= size_) ? nullptr : begin_ + debug_info_off;
   }
 
@@ -936,6 +944,7 @@
                                    void* context);
   template<typename NewLocalCallback>
   bool DecodeDebugLocalInfo(const CodeItem* code_item,
+                            uint32_t debug_info_offset,
                             bool is_static,
                             uint32_t method_idx,
                             NewLocalCallback new_local,
@@ -949,6 +958,7 @@
                                       void* context);
   template<typename DexDebugNewPosition>
   bool DecodeDebugPositionInfo(const CodeItem* code_item,
+                               uint32_t debug_info_offset,
                                DexDebugNewPosition position_functor,
                                void* context) const;
 
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 27060ae..b44bd51 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -28,6 +28,7 @@
 #include "jvalue-inl.h"
 #include "mirror/field.h"
 #include "mirror/method.h"
+#include "oat_file.h"
 #include "reflection.h"
 #include "thread.h"
 #include "well_known_classes.h"
@@ -1571,7 +1572,9 @@
 
   // A method with no line number info should return -1
   DexFile::LineNumFromPcContext context(rel_pc, -1);
-  dex_file->DecodeDebugPositionInfo(code_item, DexFile::LineNumForPcCb, &context);
+  uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file, code_item);
+  dex_file->DecodeDebugPositionInfo(
+      code_item, debug_info_offset, DexFile::LineNumForPcCb, &context);
   return context.line_num_;
 }
 
diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc
index c963f6e..14c36b4 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -730,7 +730,8 @@
       kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true);
   const DexFile::ClassDef& class_def = raw->GetClassDef(0);
   const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1));
-  ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, true, 1, Callback, nullptr));
+  uint32_t debug_info_offset = raw->GetDebugInfoOffset(code_item);
+  ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, debug_info_offset, true, 1, Callback, nullptr));
 }
 
 }  // namespace art
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 69bd46d..726fbd0 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -1455,6 +1455,14 @@
   }
 }
 
+uint32_t OatFile::GetDebugInfoOffset(const DexFile& dex_file ATTRIBUTE_UNUSED,
+                                     const DexFile::CodeItem* code_item) {
+  if (code_item == nullptr) {
+    return 0;
+  }
+  return code_item->debug_info_off_;
+}
+
 const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
                                                   const uint32_t* dex_location_checksum,
                                                   std::string* error_msg) const {
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 7d4e6df..73d64e0 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -109,11 +109,15 @@
   static OatFile* OpenWritable(File* file, const std::string& location,
                                const char* abs_dex_location,
                                std::string* error_msg);
-  // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
+  // Open an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
   static OatFile* OpenReadable(File* file, const std::string& location,
                                const char* abs_dex_location,
                                std::string* error_msg);
 
+  // Return the debug info offset of the code item `item` located in `dex_file`.
+  static uint32_t GetDebugInfoOffset(const DexFile& dex_file,
+                                     const DexFile::CodeItem* item);
+
   virtual ~OatFile();
 
   bool IsExecutable() const {