Add code_item_accessors-no_art-inl and use it in dexlist, dexdump
Added new helper to prevent inclusion of ART code. Removed accesses to
dex code.
Bug: 63756964
Bug: 70852830
Test: test-art-host-gtest -j40
Test: mm test-art-host-dexdump -j40
Change-Id: Ie0220df464a5cc2b81c0ee3e0483cdf2de003092
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 527a5b9..f64c89a 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -44,6 +44,7 @@
#include "android-base/stringprintf.h"
+#include "code_item_accessors-no_art-inl.h"
#include "dex_file-inl.h"
#include "dex_file_loader.h"
#include "dex_file_types.h"
@@ -949,14 +950,14 @@
fprintf(gOutFile, "%06x:", codeOffset + 0x10 + insnIdx * 2);
// Dump (part of) raw bytes.
- const u2* insns = pCode->insns_;
+ CodeItemInstructionAccessor accessor(pDexFile, pCode);
for (u4 i = 0; i < 8; i++) {
if (i < insnWidth) {
if (i == 7) {
fprintf(gOutFile, " ... ");
} else {
// Print 16-bit value in little-endian order.
- const u1* bytePtr = (const u1*) &insns[insnIdx + i];
+ const u1* bytePtr = (const u1*) &accessor.Insns()[insnIdx + i];
fprintf(gOutFile, " %02x%02x", bytePtr[0], bytePtr[1]);
}
} else {
@@ -966,7 +967,7 @@
// Dump pseudo-instruction or opcode.
if (pDecInsn->Opcode() == Instruction::NOP) {
- const u2 instr = get2LE((const u1*) &insns[insnIdx]);
+ const u2 instr = get2LE((const u1*) &accessor.Insns()[insnIdx]);
if (instr == Instruction::kPackedSwitchSignature) {
fprintf(gOutFile, "|%04x: packed-switch-data (%d units)", insnIdx, insnWidth);
} else if (instr == Instruction::kSparseSwitchSignature) {
@@ -1167,16 +1168,15 @@
codeOffset, codeOffset, dot.get(), name, signature.ToString().c_str());
// Iterate over all instructions.
- const u2* insns = pCode->insns_;
- for (u4 insnIdx = 0; insnIdx < pCode->insns_size_in_code_units_;) {
- const Instruction* instruction = Instruction::At(&insns[insnIdx]);
+ CodeItemDataAccessor accessor(pDexFile, pCode);
+ for (const DexInstructionPcPair& pair : accessor) {
+ const Instruction* instruction = &pair.Inst();
const u4 insnWidth = instruction->SizeInCodeUnits();
if (insnWidth == 0) {
- fprintf(stderr, "GLITCH: zero-width instruction at idx=0x%04x\n", insnIdx);
+ fprintf(stderr, "GLITCH: zero-width instruction at idx=0x%04x\n", pair.DexPc());
break;
}
- dumpInstruction(pDexFile, pCode, codeOffset, insnIdx, insnWidth, instruction);
- insnIdx += insnWidth;
+ dumpInstruction(pDexFile, pCode, codeOffset, pair.DexPc(), insnWidth, instruction);
} // for
}
@@ -1185,11 +1185,13 @@
*/
static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags,
const DexFile::CodeItem* pCode, u4 codeOffset) {
- fprintf(gOutFile, " registers : %d\n", pCode->registers_size_);
- fprintf(gOutFile, " ins : %d\n", pCode->ins_size_);
- fprintf(gOutFile, " outs : %d\n", pCode->outs_size_);
+ CodeItemDebugInfoAccessor accessor(pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode));
+
+ fprintf(gOutFile, " registers : %d\n", accessor.RegistersSize());
+ fprintf(gOutFile, " ins : %d\n", accessor.InsSize());
+ fprintf(gOutFile, " outs : %d\n", accessor.OutsSize());
fprintf(gOutFile, " insns size : %d 16-bit code units\n",
- pCode->insns_size_in_code_units_);
+ accessor.InsnsSizeInCodeUnits());
// Bytecode disassembly, if requested.
if (gOptions.disassemble) {
@@ -1202,17 +1204,9 @@
// Positions and locals table in the debug info.
bool is_static = (flags & kAccStatic) != 0;
fprintf(gOutFile, " positions : \n");
- uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode);
- pDexFile->DecodeDebugPositionInfo(debug_info_offset, dumpPositionsCb, nullptr);
+ pDexFile->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), dumpPositionsCb, nullptr);
fprintf(gOutFile, " locals : \n");
- pDexFile->DecodeDebugLocalInfo(pCode->registers_size_,
- pCode->ins_size_,
- pCode->insns_size_in_code_units_,
- debug_info_offset,
- is_static,
- idx,
- dumpLocalsCb,
- nullptr);
+ accessor.DecodeDebugLocalInfo(is_static, idx, dumpLocalsCb, nullptr);
}
/*
diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc
index 4c13ed6..2c910d4 100644
--- a/dexlist/dexlist.cc
+++ b/dexlist/dexlist.cc
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include "base/logging.h" // For InitLogging.
+#include "code_item_accessors-no_art-inl.h"
#include "dex_file-inl.h"
#include "dex_file_loader.h"
#include "mem_map.h"
@@ -99,6 +100,7 @@
if (pCode == nullptr || codeOffset == 0) {
return;
}
+ CodeItemDebugInfoAccessor accessor(pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode));
// Method information.
const DexFile::MethodId& pMethodId = pDexFile->GetMethodId(idx);
@@ -121,8 +123,7 @@
// Find the first line.
int firstLine = -1;
- uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode);
- pDexFile->DecodeDebugPositionInfo(debug_info_offset, positionsCb, &firstLine);
+ pDexFile->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), positionsCb, &firstLine);
// Method signature.
const Signature signature = pDexFile->GetMethodSignature(pMethodId);
@@ -130,7 +131,7 @@
// Dump actual method information.
fprintf(gOutFile, "0x%08x %d %s %s %s %s %d\n",
- insnsOff, pCode->insns_size_in_code_units_ * 2,
+ insnsOff, accessor.InsnsSizeInCodeUnits() * 2,
className.get(), methodName, typeDesc, fileName, firstLine);
free(typeDesc);
diff --git a/runtime/code_item_accessors-inl.h b/runtime/code_item_accessors-inl.h
index 4f4d8cc..1ba3c55 100644
--- a/runtime/code_item_accessors-inl.h
+++ b/runtime/code_item_accessors-inl.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_CODE_ITEM_ACCESSORS_INL_H_
#define ART_RUNTIME_CODE_ITEM_ACCESSORS_INL_H_
-#include "code_item_accessors.h"
+#include "code_item_accessors-no_art-inl.h"
#include "art_method-inl.h"
#include "cdex/compact_dex_file.h"
@@ -27,45 +27,9 @@
namespace art {
-inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) {
- insns_size_in_code_units_ = code_item.insns_size_in_code_units_;
- insns_ = code_item.insns_;
-}
-
-inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) {
- insns_size_in_code_units_ = code_item.insns_size_in_code_units_;
- insns_ = code_item.insns_;
-}
-
-inline void CodeItemInstructionAccessor::Init(const DexFile* dex_file,
- const DexFile::CodeItem* code_item) {
- DCHECK(dex_file != nullptr);
- DCHECK(code_item != nullptr);
- if (dex_file->IsCompactDexFile()) {
- Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
- } else {
- DCHECK(dex_file->IsStandardDexFile());
- Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
- }
-}
-
-inline CodeItemInstructionAccessor::CodeItemInstructionAccessor(
- const DexFile* dex_file,
- const DexFile::CodeItem* code_item) {
- Init(dex_file, code_item);
-}
-
inline CodeItemInstructionAccessor::CodeItemInstructionAccessor(ArtMethod* method)
: CodeItemInstructionAccessor(method->GetDexFile(), method->GetCodeItem()) {}
-inline DexInstructionIterator CodeItemInstructionAccessor::begin() const {
- return DexInstructionIterator(insns_, 0u);
-}
-
-inline DexInstructionIterator CodeItemInstructionAccessor::end() const {
- return DexInstructionIterator(insns_, insns_size_in_code_units_);
-}
-
inline CodeItemInstructionAccessor CodeItemInstructionAccessor::CreateNullable(
ArtMethod* method) {
DCHECK(method != nullptr);
@@ -79,78 +43,14 @@
return ret;
}
-inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) {
- CodeItemInstructionAccessor::Init(code_item);
- registers_size_ = code_item.registers_size_;
- ins_size_ = code_item.ins_size_;
- outs_size_ = code_item.outs_size_;
- tries_size_ = code_item.tries_size_;
-}
-
-inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) {
- CodeItemInstructionAccessor::Init(code_item);
- registers_size_ = code_item.registers_size_;
- ins_size_ = code_item.ins_size_;
- outs_size_ = code_item.outs_size_;
- tries_size_ = code_item.tries_size_;
-}
-
-inline void CodeItemDataAccessor::Init(const DexFile* dex_file,
- const DexFile::CodeItem* code_item) {
- DCHECK(dex_file != nullptr);
- DCHECK(code_item != nullptr);
- if (dex_file->IsCompactDexFile()) {
- CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
- } else {
- DCHECK(dex_file->IsStandardDexFile());
- CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
- }
-}
-
-inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile* dex_file,
- const DexFile::CodeItem* code_item) {
- Init(dex_file, code_item);
-}
-
inline CodeItemDataAccessor::CodeItemDataAccessor(ArtMethod* method)
: CodeItemDataAccessor(method->GetDexFile(), method->GetCodeItem()) {}
-inline CodeItemDataAccessor CodeItemDataAccessor::CreateNullable(
- const DexFile* dex_file,
- const DexFile::CodeItem* code_item) {
- CodeItemDataAccessor ret;
- if (code_item != nullptr) {
- ret.Init(dex_file, code_item);
- } else {
- DCHECK(!ret.HasCodeItem()) << "Should be null initialized";
- }
- return ret;
-}
-
inline CodeItemDataAccessor CodeItemDataAccessor::CreateNullable(ArtMethod* method) {
DCHECK(method != nullptr);
return CreateNullable(method->GetDexFile(), method->GetCodeItem());
}
-inline IterationRange<const DexFile::TryItem*> CodeItemDataAccessor::TryItems() const {
- const DexFile::TryItem* try_items = DexFile::GetTryItems(end(), 0u);
- return {
- try_items,
- try_items + TriesSize() };
-}
-
-inline const uint8_t* CodeItemDataAccessor::GetCatchHandlerData(size_t offset) const {
- return DexFile::GetCatchHandlerData(end(), TriesSize(), offset);
-}
-
-inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_dex_pc) const {
- IterationRange<const DexFile::TryItem*> try_items(TryItems());
- int32_t index = DexFile::FindTryItem(try_items.begin(),
- try_items.end() - try_items.begin(),
- try_dex_pc);
- return index != -1 ? &try_items.begin()[index] : nullptr;
-}
-
inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(ArtMethod* method)
: CodeItemDebugInfoAccessor(method->GetDexFile(), method->GetCodeItem()) {}
@@ -159,21 +59,7 @@
if (code_item == nullptr) {
return;
}
- debug_info_offset_ = OatFile::GetDebugInfoOffset(*dex_file, code_item);
- if (dex_file->IsCompactDexFile()) {
- Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
- } else {
- DCHECK(dex_file->IsStandardDexFile());
- Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
- }
-}
-
-inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item) {
- CodeItemDataAccessor::Init(code_item);
-}
-
-inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) {
- CodeItemDataAccessor::Init(code_item);
+ Init(dex_file, code_item, OatFile::GetDebugInfoOffset(*dex_file, code_item));
}
} // namespace art
diff --git a/runtime/code_item_accessors-no_art-inl.h b/runtime/code_item_accessors-no_art-inl.h
new file mode 100644
index 0000000..96321b5
--- /dev/null
+++ b/runtime/code_item_accessors-no_art-inl.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_CODE_ITEM_ACCESSORS_NO_ART_INL_H_
+#define ART_RUNTIME_CODE_ITEM_ACCESSORS_NO_ART_INL_H_
+
+#include "code_item_accessors.h"
+
+#include "cdex/compact_dex_file.h"
+#include "dex_file-inl.h"
+#include "standard_dex_file.h"
+
+// The no ART version is used by binaries that don't include the whole runtime.
+
+namespace art {
+
+inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) {
+ insns_size_in_code_units_ = code_item.insns_size_in_code_units_;
+ insns_ = code_item.insns_;
+}
+
+inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) {
+ insns_size_in_code_units_ = code_item.insns_size_in_code_units_;
+ insns_ = code_item.insns_;
+}
+
+inline void CodeItemInstructionAccessor::Init(const DexFile* dex_file,
+ const DexFile::CodeItem* code_item) {
+ DCHECK(dex_file != nullptr);
+ DCHECK(code_item != nullptr);
+ if (dex_file->IsCompactDexFile()) {
+ Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
+ } else {
+ DCHECK(dex_file->IsStandardDexFile());
+ Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
+ }
+}
+
+inline CodeItemInstructionAccessor::CodeItemInstructionAccessor(
+ const DexFile* dex_file,
+ const DexFile::CodeItem* code_item) {
+ Init(dex_file, code_item);
+}
+
+inline DexInstructionIterator CodeItemInstructionAccessor::begin() const {
+ return DexInstructionIterator(insns_, 0u);
+}
+
+inline DexInstructionIterator CodeItemInstructionAccessor::end() const {
+ return DexInstructionIterator(insns_, insns_size_in_code_units_);
+}
+
+inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) {
+ CodeItemInstructionAccessor::Init(code_item);
+ registers_size_ = code_item.registers_size_;
+ ins_size_ = code_item.ins_size_;
+ outs_size_ = code_item.outs_size_;
+ tries_size_ = code_item.tries_size_;
+}
+
+inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) {
+ CodeItemInstructionAccessor::Init(code_item);
+ registers_size_ = code_item.registers_size_;
+ ins_size_ = code_item.ins_size_;
+ outs_size_ = code_item.outs_size_;
+ tries_size_ = code_item.tries_size_;
+}
+
+inline void CodeItemDataAccessor::Init(const DexFile* dex_file,
+ const DexFile::CodeItem* code_item) {
+ DCHECK(dex_file != nullptr);
+ DCHECK(code_item != nullptr);
+ if (dex_file->IsCompactDexFile()) {
+ CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
+ } else {
+ DCHECK(dex_file->IsStandardDexFile());
+ CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
+ }
+}
+
+inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile* dex_file,
+ const DexFile::CodeItem* code_item) {
+ Init(dex_file, code_item);
+}
+
+inline CodeItemDataAccessor CodeItemDataAccessor::CreateNullable(
+ const DexFile* dex_file,
+ const DexFile::CodeItem* code_item) {
+ CodeItemDataAccessor ret;
+ if (code_item != nullptr) {
+ ret.Init(dex_file, code_item);
+ } else {
+ DCHECK(!ret.HasCodeItem()) << "Should be null initialized";
+ }
+ return ret;
+}
+
+inline IterationRange<const DexFile::TryItem*> CodeItemDataAccessor::TryItems() const {
+ const DexFile::TryItem* try_items = DexFile::GetTryItems(end(), 0u);
+ return {
+ try_items,
+ try_items + TriesSize() };
+}
+
+inline const uint8_t* CodeItemDataAccessor::GetCatchHandlerData(size_t offset) const {
+ return DexFile::GetCatchHandlerData(end(), TriesSize(), offset);
+}
+
+inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_dex_pc) const {
+ IterationRange<const DexFile::TryItem*> try_items(TryItems());
+ int32_t index = DexFile::FindTryItem(try_items.begin(),
+ try_items.end() - try_items.begin(),
+ try_dex_pc);
+ return index != -1 ? &try_items.begin()[index] : nullptr;
+}
+
+inline void CodeItemDebugInfoAccessor::Init(const DexFile* dex_file,
+ const DexFile::CodeItem* code_item,
+ uint32_t debug_info_offset) {
+ dex_file_ = dex_file;
+ debug_info_offset_ = debug_info_offset;
+ if (dex_file->IsCompactDexFile()) {
+ Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
+ } else {
+ DCHECK(dex_file->IsStandardDexFile());
+ Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
+ }
+}
+
+inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item) {
+ CodeItemDataAccessor::Init(code_item);
+}
+
+inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) {
+ CodeItemDataAccessor::Init(code_item);
+}
+
+template<typename NewLocalCallback>
+inline bool CodeItemDebugInfoAccessor::DecodeDebugLocalInfo(bool is_static,
+ uint32_t method_idx,
+ NewLocalCallback new_local,
+ void* context) const {
+ return dex_file_->DecodeDebugLocalInfo(RegistersSize(),
+ InsSize(),
+ InsnsSizeInCodeUnits(),
+ DebugInfoOffset(),
+ is_static,
+ method_idx,
+ new_local,
+ context);
+}
+
+
+} // namespace art
+
+#endif // ART_RUNTIME_CODE_ITEM_ACCESSORS_NO_ART_INL_H_
diff --git a/runtime/code_item_accessors.h b/runtime/code_item_accessors.h
index a089a27..9f40114 100644
--- a/runtime/code_item_accessors.h
+++ b/runtime/code_item_accessors.h
@@ -142,17 +142,35 @@
ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file,
const DexFile::CodeItem* code_item);
+ // Initialize with an existing offset.
+ ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file,
+ const DexFile::CodeItem* code_item,
+ uint32_t debug_info_offset) {
+ Init(dex_file, code_item, debug_info_offset);
+ }
+
+ ALWAYS_INLINE void Init(const DexFile* dex_file,
+ const DexFile::CodeItem* code_item,
+ uint32_t debug_info_offset);
+
ALWAYS_INLINE explicit CodeItemDebugInfoAccessor(ArtMethod* method);
uint32_t DebugInfoOffset() const {
return debug_info_offset_;
}
+ template<typename NewLocalCallback>
+ bool DecodeDebugLocalInfo(bool is_static,
+ uint32_t method_idx,
+ NewLocalCallback new_local,
+ void* context) const;
+
protected:
ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item);
ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
private:
+ const DexFile* dex_file_ = nullptr;
uint32_t debug_info_offset_ = 0u;
};