1 /*
2  * Copyright (C) 2011 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 #ifndef ART_LIBDEXFILE_DEX_DEX_FILE_STRUCTS_H_
18 #define ART_LIBDEXFILE_DEX_DEX_FILE_STRUCTS_H_
19 
20 #include <android-base/logging.h>
21 #include <android-base/macros.h>
22 
23 #include <inttypes.h>
24 
25 #include "dex_file_types.h"
26 #include "modifiers.h"
27 
28 namespace art {
29 
30 class DexWriter;
31 
32 namespace dex {
33 
34 struct MapItem {
35   uint16_t type_;
36   uint16_t unused_;
37   uint32_t size_;
38   uint32_t offset_;
39 };
40 
41 struct MapList {
42   uint32_t size_;
43   MapItem list_[1];
44 
SizeMapList45   size_t Size() const { return sizeof(uint32_t) + (size_ * sizeof(MapItem)); }
46 
47  private:
48   DISALLOW_COPY_AND_ASSIGN(MapList);
49 };
50 
51 // Raw string_id_item.
52 struct StringId {
53   uint32_t string_data_off_;  // offset in bytes from the base address
54 
55  private:
56   DISALLOW_COPY_AND_ASSIGN(StringId);
57 };
58 
59 // Raw type_id_item.
60 struct TypeId {
61   dex::StringIndex descriptor_idx_;  // index into string_ids
62 
63  private:
64   DISALLOW_COPY_AND_ASSIGN(TypeId);
65 };
66 
67 // Raw field_id_item.
68 struct FieldId {
69   dex::TypeIndex class_idx_;   // index into type_ids_ array for defining class
70   dex::TypeIndex type_idx_;    // index into type_ids_ array for field type
71   dex::StringIndex name_idx_;  // index into string_ids_ array for field name
72 
73  private:
74   DISALLOW_COPY_AND_ASSIGN(FieldId);
75 };
76 
77 // Raw proto_id_item.
78 struct ProtoId {
79   dex::StringIndex shorty_idx_;     // index into string_ids array for shorty descriptor
80   dex::TypeIndex return_type_idx_;  // index into type_ids array for return type
81   uint16_t pad_;                    // padding = 0
82   uint32_t parameters_off_;         // file offset to type_list for parameter types
83 
84  private:
85   DISALLOW_COPY_AND_ASSIGN(ProtoId);
86 };
87 
88 // Raw method_id_item.
89 struct MethodId {
90   dex::TypeIndex class_idx_;   // index into type_ids_ array for defining class
91   dex::ProtoIndex proto_idx_;  // index into proto_ids_ array for method prototype
92   dex::StringIndex name_idx_;  // index into string_ids_ array for method name
93 
94  private:
95   DISALLOW_COPY_AND_ASSIGN(MethodId);
96 };
97 
98 // Base code_item, compact dex and standard dex have different code item layouts.
99 struct CodeItem {
100  protected:
101   CodeItem() = default;
102 
103  private:
104   DISALLOW_COPY_AND_ASSIGN(CodeItem);
105 };
106 
107 // Raw class_def_item.
108 struct ClassDef {
109   dex::TypeIndex class_idx_;  // index into type_ids_ array for this class
110   uint16_t pad1_;  // padding = 0
111   uint32_t access_flags_;
112   dex::TypeIndex superclass_idx_;  // index into type_ids_ array for superclass
113   uint16_t pad2_;  // padding = 0
114   uint32_t interfaces_off_;  // file offset to TypeList
115   dex::StringIndex source_file_idx_;  // index into string_ids_ for source file name
116   uint32_t annotations_off_;  // file offset to annotations_directory_item
117   uint32_t class_data_off_;  // file offset to class_data_item
118   uint32_t static_values_off_;  // file offset to EncodedArray
119 
120   // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type
121   // (class or interface). These are all in the lower 16b and do not contain runtime flags.
GetJavaAccessFlagsClassDef122   uint32_t GetJavaAccessFlags() const {
123     // Make sure that none of our runtime-only flags are set.
124     static_assert((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags,
125                   "Valid class flags not a subset of Java flags");
126     static_assert((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags,
127                   "Valid interface flags not a subset of Java flags");
128 
129     if ((access_flags_ & kAccInterface) != 0) {
130       // Interface.
131       return access_flags_ & kAccValidInterfaceFlags;
132     } else {
133       // Class.
134       return access_flags_ & kAccValidClassFlags;
135     }
136   }
137 
138  private:
139   DISALLOW_COPY_AND_ASSIGN(ClassDef);
140 };
141 
142 // Raw type_item.
143 struct TypeItem {
144   dex::TypeIndex type_idx_;  // index into type_ids section
145 
146  private:
147   DISALLOW_COPY_AND_ASSIGN(TypeItem);
148 };
149 
150 // Raw type_list.
151 class TypeList {
152  public:
Size()153   uint32_t Size() const {
154     return size_;
155   }
156 
GetTypeItem(uint32_t idx)157   const TypeItem& GetTypeItem(uint32_t idx) const {
158     DCHECK_LT(idx, this->size_);
159     return this->list_[idx];
160   }
161 
162   // Size in bytes of the part of the list that is common.
GetHeaderSize()163   static constexpr size_t GetHeaderSize() {
164     return 4U;
165   }
166 
167   // Size in bytes of the whole type list including all the stored elements.
GetListSize(size_t count)168   static constexpr size_t GetListSize(size_t count) {
169     return GetHeaderSize() + sizeof(TypeItem) * count;
170   }
171 
172  private:
173   uint32_t size_;  // size of the list, in entries
174   TypeItem list_[1];  // elements of the list
175   DISALLOW_COPY_AND_ASSIGN(TypeList);
176 };
177 
178 // raw method_handle_item
179 struct MethodHandleItem {
180   uint16_t method_handle_type_;
181   uint16_t reserved1_;            // Reserved for future use.
182   uint16_t field_or_method_idx_;  // Field index for accessors, method index otherwise.
183   uint16_t reserved2_;            // Reserved for future use.
184  private:
185   DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
186 };
187 
188 // raw call_site_id_item
189 struct CallSiteIdItem {
190   uint32_t data_off_;  // Offset into data section pointing to encoded array items.
191  private:
192   DISALLOW_COPY_AND_ASSIGN(CallSiteIdItem);
193 };
194 
195 // Raw try_item.
196 struct TryItem {
197   static constexpr size_t kAlignment = sizeof(uint32_t);
198 
199   uint32_t start_addr_;
200   uint16_t insn_count_;
201   uint16_t handler_off_;
202 
203  private:
204   TryItem() = default;
205   friend class ::art::DexWriter;
206   DISALLOW_COPY_AND_ASSIGN(TryItem);
207 };
208 
209 struct AnnotationsDirectoryItem {
210   uint32_t class_annotations_off_;
211   uint32_t fields_size_;
212   uint32_t methods_size_;
213   uint32_t parameters_size_;
214 
215  private:
216   DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
217 };
218 
219 struct FieldAnnotationsItem {
220   uint32_t field_idx_;
221   uint32_t annotations_off_;
222 
223  private:
224   DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
225 };
226 
227 struct MethodAnnotationsItem {
228   uint32_t method_idx_;
229   uint32_t annotations_off_;
230 
231  private:
232   DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
233 };
234 
235 struct ParameterAnnotationsItem {
236   uint32_t method_idx_;
237   uint32_t annotations_off_;
238 
239  private:
240   DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
241 };
242 
243 struct AnnotationSetRefItem {
244   uint32_t annotations_off_;
245 
246  private:
247   DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
248 };
249 
250 struct AnnotationSetRefList {
251   uint32_t size_;
252   AnnotationSetRefItem list_[1];
253 
254  private:
255   DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
256 };
257 
258 struct AnnotationSetItem {
259   uint32_t size_;
260   uint32_t entries_[1];
261 
262  private:
263   DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
264 };
265 
266 struct AnnotationItem {
267   uint8_t visibility_;
268   uint8_t annotation_[1];
269 
270  private:
271   DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
272 };
273 
274 struct HiddenapiClassData {
275   uint32_t size_;             // total size of the item
276   uint32_t flags_offset_[1];  // array of offsets from the beginning of this item,
277                               // indexed by class def index
278 
279   // Returns a pointer to the beginning of a uleb128-stream of hiddenapi
280   // flags for a class def of given index. Values are in the same order
281   // as fields/methods in the class data. Returns null if the class does
282   // not have class data.
GetFlagsPointerHiddenapiClassData283   const uint8_t* GetFlagsPointer(uint32_t class_def_idx) const {
284     if (flags_offset_[class_def_idx] == 0) {
285       return nullptr;
286     } else {
287       return reinterpret_cast<const uint8_t*>(this) + flags_offset_[class_def_idx];
288     }
289   }
290 
291  private:
292   DISALLOW_COPY_AND_ASSIGN(HiddenapiClassData);
293 };
294 
295 }  // namespace dex
296 }  // namespace art
297 
298 #endif  // ART_LIBDEXFILE_DEX_DEX_FILE_STRUCTS_H_
299