blob: c47898e5338117c5db9b11dc6076f6ac2095c2f6 [file] [log] [blame]
Jeff Haoa8621002016-10-04 18:13:44 +00001/*
2 * Copyright (C) 2016 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 * Header file of an in-memory representation of DEX files.
17 */
18
19#ifndef ART_DEXLAYOUT_DEX_WRITER_H_
20#define ART_DEXLAYOUT_DEX_WRITER_H_
21
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080022#include <functional>
23
Jeff Haoa8621002016-10-04 18:13:44 +000024#include "base/unix_file/fd_file.h"
Mathieu Chartier603ccab2017-10-20 14:34:28 -070025#include "cdex/compact_dex_level.h"
Jeff Haoa8621002016-10-04 18:13:44 +000026#include "dex_ir.h"
Jeff Haoea7c6292016-11-14 18:10:16 -080027#include "mem_map.h"
Jeff Haoa8621002016-10-04 18:13:44 +000028#include "os.h"
29
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080030#include <queue>
31
Jeff Haoa8621002016-10-04 18:13:44 +000032namespace art {
33
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080034class DexLayout;
35class DexLayoutHotnessInfo;
36
37struct MapItem {
38 // Not using DexFile::MapItemType since compact dex and standard dex file may have different
39 // sections.
40 MapItem() = default;
41 MapItem(uint32_t type, uint32_t size, uint32_t offset)
42 : type_(type), size_(size), offset_(offset) { }
43
44 // Sort by decreasing order since the priority_queue puts largest elements first.
45 bool operator>(const MapItem& other) const {
46 return offset_ > other.offset_;
47 }
48
49 uint32_t type_ = 0u;
50 uint32_t size_ = 0u;
51 uint32_t offset_ = 0u;
52};
53
54class MapItemQueue : public
55 std::priority_queue<MapItem, std::vector<MapItem>, std::greater<MapItem>> {
56 public:
57 void AddIfNotEmpty(const MapItem& item);
58};
59
Jeff Haoa8621002016-10-04 18:13:44 +000060class DexWriter {
61 public:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080062 DexWriter(dex_ir::Header* header,
63 MemMap* mem_map,
64 DexLayout* dex_layout,
65 bool compute_offsets)
66 : header_(header),
67 mem_map_(mem_map),
68 dex_layout_(dex_layout),
69 compute_offsets_(compute_offsets) {}
Jeff Haoa8621002016-10-04 18:13:44 +000070
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080071 static void Output(dex_ir::Header* header,
72 MemMap* mem_map,
73 DexLayout* dex_layout,
74 bool compute_offsets,
75 CompactDexLevel compact_dex_level);
Jeff Haoa8621002016-10-04 18:13:44 +000076
Mathieu Chartierf95a75e2017-11-03 15:25:52 -070077 virtual ~DexWriter() {}
78
79 protected:
Jeff Haoea7c6292016-11-14 18:10:16 -080080 void WriteMemMap();
Jeff Haoa8621002016-10-04 18:13:44 +000081
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080082 size_t Write(const void* buffer, size_t length, size_t offset) WARN_UNUSED;
83 size_t WriteSleb128(uint32_t value, size_t offset) WARN_UNUSED;
84 size_t WriteUleb128(uint32_t value, size_t offset) WARN_UNUSED;
85 size_t WriteEncodedValue(dex_ir::EncodedValue* encoded_value, size_t offset) WARN_UNUSED;
86 size_t WriteEncodedValueHeader(int8_t value_type, size_t value_arg, size_t offset) WARN_UNUSED;
87 size_t WriteEncodedArray(dex_ir::EncodedValueVector* values, size_t offset) WARN_UNUSED;
88 size_t WriteEncodedAnnotation(dex_ir::EncodedAnnotation* annotation, size_t offset) WARN_UNUSED;
89 size_t WriteEncodedFields(dex_ir::FieldItemVector* fields, size_t offset) WARN_UNUSED;
90 size_t WriteEncodedMethods(dex_ir::MethodItemVector* methods, size_t offset) WARN_UNUSED;
Jeff Haoa8621002016-10-04 18:13:44 +000091
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080092 // Header and id section
Mathieu Chartierf95a75e2017-11-03 15:25:52 -070093 virtual void WriteHeader();
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080094 // reserve_only means don't write, only reserve space. This is required since the string data
95 // offsets must be assigned.
96 uint32_t WriteStringIds(uint32_t offset, bool reserve_only);
97 uint32_t WriteTypeIds(uint32_t offset);
98 uint32_t WriteProtoIds(uint32_t offset, bool reserve_only);
99 uint32_t WriteFieldIds(uint32_t offset);
100 uint32_t WriteMethodIds(uint32_t offset);
101 uint32_t WriteClassDefs(uint32_t offset, bool reserve_only);
102 uint32_t WriteCallSiteIds(uint32_t offset, bool reserve_only);
103
104 uint32_t WriteEncodedArrays(uint32_t offset);
105 uint32_t WriteAnnotations(uint32_t offset);
106 uint32_t WriteAnnotationSets(uint32_t offset);
107 uint32_t WriteAnnotationSetRefs(uint32_t offset);
108 uint32_t WriteAnnotationsDirectories(uint32_t offset);
109
110 // Data section.
111 uint32_t WriteDebugInfoItems(uint32_t offset);
112 uint32_t WriteCodeItems(uint32_t offset, bool reserve_only);
113 uint32_t WriteTypeLists(uint32_t offset);
114 uint32_t WriteStringDatas(uint32_t offset);
115 uint32_t WriteClassDatas(uint32_t offset);
116 uint32_t WriteMethodHandles(uint32_t offset);
117 uint32_t WriteMapItems(uint32_t offset, MapItemQueue* queue);
118 uint32_t GenerateAndWriteMapItems(uint32_t offset);
119
120 // Process an offset, if compute_offset is set, write into the dex ir item, otherwise read the
121 // existing offset and use that for writing.
122 void ProcessOffset(uint32_t* const offset, dex_ir::Item* item) {
123 if (compute_offsets_) {
124 item->SetOffset(*offset);
125 } else {
126 // Not computing offsets, just use the one in the item.
127 *offset = item->GetOffset();
128 }
129 }
Jeff Haoa8621002016-10-04 18:13:44 +0000130
Jeff Haoea7c6292016-11-14 18:10:16 -0800131 dex_ir::Header* const header_;
132 MemMap* const mem_map_;
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800133 DexLayout* const dex_layout_;
134 bool compute_offsets_;
Jeff Haoa8621002016-10-04 18:13:44 +0000135
Mathieu Chartierf95a75e2017-11-03 15:25:52 -0700136 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000137 DISALLOW_COPY_AND_ASSIGN(DexWriter);
138};
139
Jeff Haoa8621002016-10-04 18:13:44 +0000140} // namespace art
141
142#endif // ART_DEXLAYOUT_DEX_WRITER_H_