blob: 24296c8f1d5cfaa2d8b651d1e351ecfd7ae44e32 [file] [log] [blame]
Mathieu Chartier69147f12017-11-06 20:02:24 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// TODO: Dex helpers have ART specific APIs, we may want to refactor these for use in dexdump.
18
David Sehr334b9d72018-02-12 18:27:56 -080019#ifndef ART_LIBDEXFILE_DEX_CODE_ITEM_ACCESSORS_H_
20#define ART_LIBDEXFILE_DEX_CODE_ITEM_ACCESSORS_H_
Mathieu Chartier69147f12017-11-06 20:02:24 -080021
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080022#include <android-base/logging.h>
23
Andreas Gampe2f7a55c2019-05-09 15:46:38 -070024#include "dex_instruction.h"
Mathieu Chartier69147f12017-11-06 20:02:24 -080025
26namespace art {
27
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080028namespace dex {
29struct CodeItem;
30struct TryItem;
31} // namespace dex
32
Mathieu Chartier69147f12017-11-06 20:02:24 -080033class ArtMethod;
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080034class DexFile;
Andreas Gampe2f7a55c2019-05-09 15:46:38 -070035class DexInstructionIterator;
Andreas Gampe7458a7a2019-01-02 10:32:11 -080036template <typename Iter>
37class IterationRange;
Mathieu Chartier69147f12017-11-06 20:02:24 -080038
39// Abstracts accesses to the instruction fields of code items for CompactDexFile and
40// StandardDexFile.
41class CodeItemInstructionAccessor {
42 public:
Mathieu Chartier698ebbc2018-01-05 11:00:42 -080043 ALWAYS_INLINE CodeItemInstructionAccessor(const DexFile& dex_file,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080044 const dex::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -080045
46 ALWAYS_INLINE explicit CodeItemInstructionAccessor(ArtMethod* method);
47
48 ALWAYS_INLINE DexInstructionIterator begin() const;
49
50 ALWAYS_INLINE DexInstructionIterator end() const;
51
Mathieu Chartier808c7a52017-12-15 11:19:33 -080052 IterationRange<DexInstructionIterator> InstructionsFrom(uint32_t start_dex_pc) const;
53
Mathieu Chartier69147f12017-11-06 20:02:24 -080054 uint32_t InsnsSizeInCodeUnits() const {
55 return insns_size_in_code_units_;
56 }
57
Mathieu Chartier05dc23e2018-05-22 11:56:14 -070058 uint32_t InsnsSizeInBytes() const {
59 static constexpr uint32_t kCodeUnitSizeInBytes = 2u;
60 return insns_size_in_code_units_ * kCodeUnitSizeInBytes;
61 }
62
Mathieu Chartier69147f12017-11-06 20:02:24 -080063 const uint16_t* Insns() const {
64 return insns_;
65 }
66
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -080067 // Return the instruction for a dex pc.
68 const Instruction& InstructionAt(uint32_t dex_pc) const {
Mathieu Chartier808c7a52017-12-15 11:19:33 -080069 DCHECK_LT(dex_pc, InsnsSizeInCodeUnits());
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -080070 return *Instruction::At(insns_ + dex_pc);
71 }
72
Mathieu Chartier69147f12017-11-06 20:02:24 -080073 // Return true if the accessor has a code item.
74 bool HasCodeItem() const {
75 return Insns() != nullptr;
76 }
77
Mathieu Chartier69147f12017-11-06 20:02:24 -080078 protected:
79 CodeItemInstructionAccessor() = default;
80
Mathieu Chartier8740c662018-01-11 14:50:02 -080081 ALWAYS_INLINE void Init(uint32_t insns_size_in_code_units, const uint16_t* insns);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080082 ALWAYS_INLINE void Init(const DexFile& dex_file, const dex::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -080083
Andreas Gampe7458a7a2019-01-02 10:32:11 -080084 template <typename DexFileCodeItemType>
85 ALWAYS_INLINE void Init(const DexFileCodeItemType& code_item);
86
Mathieu Chartier69147f12017-11-06 20:02:24 -080087 private:
88 // size of the insns array, in 2 byte code units. 0 if there is no code item.
89 uint32_t insns_size_in_code_units_ = 0;
90
91 // Pointer to the instructions, null if there is no code item.
Yi Kong4b22b342018-08-02 14:43:21 -070092 const uint16_t* insns_ = nullptr;
Mathieu Chartier69147f12017-11-06 20:02:24 -080093};
94
95// Abstracts accesses to code item fields other than debug info for CompactDexFile and
96// StandardDexFile.
97class CodeItemDataAccessor : public CodeItemInstructionAccessor {
98 public:
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080099 ALWAYS_INLINE CodeItemDataAccessor(const DexFile& dex_file, const dex::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -0800100
Mathieu Chartier69147f12017-11-06 20:02:24 -0800101 uint16_t RegistersSize() const {
102 return registers_size_;
103 }
104
105 uint16_t InsSize() const {
106 return ins_size_;
107 }
108
109 uint16_t OutsSize() const {
110 return outs_size_;
111 }
112
113 uint16_t TriesSize() const {
114 return tries_size_;
115 }
116
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800117 IterationRange<const dex::TryItem*> TryItems() const;
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800118
119 const uint8_t* GetCatchHandlerData(size_t offset = 0) const;
120
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800121 const dex::TryItem* FindTryItem(uint32_t try_dex_pc) const;
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800122
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800123 inline const void* CodeItemDataEnd() const;
124
Mathieu Chartier69147f12017-11-06 20:02:24 -0800125 protected:
126 CodeItemDataAccessor() = default;
127
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800128 ALWAYS_INLINE void Init(const DexFile& dex_file, const dex::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -0800129
Andreas Gampe7458a7a2019-01-02 10:32:11 -0800130 template <typename DexFileCodeItemType>
131 ALWAYS_INLINE void Init(const DexFileCodeItemType& code_item);
132
Mathieu Chartier69147f12017-11-06 20:02:24 -0800133 private:
134 // Fields mirrored from the dex/cdex code item.
135 uint16_t registers_size_;
136 uint16_t ins_size_;
137 uint16_t outs_size_;
138 uint16_t tries_size_;
139};
140
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800141// Abstract accesses to code item data including debug info offset. More heavy weight than the other
142// helpers.
143class CodeItemDebugInfoAccessor : public CodeItemDataAccessor {
144 public:
145 CodeItemDebugInfoAccessor() = default;
146
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800147 // Initialize with an existing offset.
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800148 ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile& dex_file,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800149 const dex::CodeItem* code_item,
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800150 uint32_t dex_method_index) {
151 Init(dex_file, code_item, dex_method_index);
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800152 }
153
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800154 ALWAYS_INLINE void Init(const DexFile& dex_file,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800155 const dex::CodeItem* code_item,
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800156 uint32_t dex_method_index);
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800157
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800158 ALWAYS_INLINE explicit CodeItemDebugInfoAccessor(ArtMethod* method);
159
160 uint32_t DebugInfoOffset() const {
161 return debug_info_offset_;
162 }
163
Mathieu Chartiere5afbf32018-09-12 17:51:54 -0700164 template<typename NewLocalVisitor>
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800165 bool DecodeDebugLocalInfo(bool is_static,
166 uint32_t method_idx,
Mathieu Chartiere5afbf32018-09-12 17:51:54 -0700167 const NewLocalVisitor& new_local) const;
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800168
Mathieu Chartier3e2e1232018-09-11 12:35:30 -0700169 // Visit each parameter in the debug information. Returns the line number.
170 // The argument of the Visitor is dex::StringIndex.
171 template <typename Visitor>
172 uint32_t VisitParameterNames(const Visitor& visitor) const;
173
174 template <typename Visitor>
175 bool DecodeDebugPositionInfo(const Visitor& visitor) const;
176
177 bool GetLineNumForPc(const uint32_t pc, uint32_t* line_num) const;
178
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800179 protected:
Andreas Gampe7458a7a2019-01-02 10:32:11 -0800180 template <typename DexFileCodeItemType>
181 ALWAYS_INLINE void Init(const DexFileCodeItemType& code_item, uint32_t dex_method_index);
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800182
183 private:
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800184 const DexFile* dex_file_ = nullptr;
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800185 uint32_t debug_info_offset_ = 0u;
186};
187
Mathieu Chartier69147f12017-11-06 20:02:24 -0800188} // namespace art
189
David Sehr334b9d72018-02-12 18:27:56 -0800190#endif // ART_LIBDEXFILE_DEX_CODE_ITEM_ACCESSORS_H_