blob: 92a002edc716ac8cff5cac87a8a4955c04d30308 [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"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/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 Chartierf6e31472017-12-28 13:32:08 -080094 virtual size_t GetHeaderSize() const;
Mathieu Chartier3e0c5172017-11-12 12:58:40 -080095 // reserve_only means don't write, only reserve space. This is required since the string data
96 // offsets must be assigned.
97 uint32_t WriteStringIds(uint32_t offset, bool reserve_only);
98 uint32_t WriteTypeIds(uint32_t offset);
99 uint32_t WriteProtoIds(uint32_t offset, bool reserve_only);
100 uint32_t WriteFieldIds(uint32_t offset);
101 uint32_t WriteMethodIds(uint32_t offset);
102 uint32_t WriteClassDefs(uint32_t offset, bool reserve_only);
103 uint32_t WriteCallSiteIds(uint32_t offset, bool reserve_only);
104
105 uint32_t WriteEncodedArrays(uint32_t offset);
106 uint32_t WriteAnnotations(uint32_t offset);
107 uint32_t WriteAnnotationSets(uint32_t offset);
108 uint32_t WriteAnnotationSetRefs(uint32_t offset);
109 uint32_t WriteAnnotationsDirectories(uint32_t offset);
110
111 // Data section.
112 uint32_t WriteDebugInfoItems(uint32_t offset);
113 uint32_t WriteCodeItems(uint32_t offset, bool reserve_only);
114 uint32_t WriteTypeLists(uint32_t offset);
115 uint32_t WriteStringDatas(uint32_t offset);
116 uint32_t WriteClassDatas(uint32_t offset);
117 uint32_t WriteMethodHandles(uint32_t offset);
118 uint32_t WriteMapItems(uint32_t offset, MapItemQueue* queue);
119 uint32_t GenerateAndWriteMapItems(uint32_t offset);
120
121 // Process an offset, if compute_offset is set, write into the dex ir item, otherwise read the
122 // existing offset and use that for writing.
123 void ProcessOffset(uint32_t* const offset, dex_ir::Item* item) {
124 if (compute_offsets_) {
125 item->SetOffset(*offset);
126 } else {
127 // Not computing offsets, just use the one in the item.
128 *offset = item->GetOffset();
129 }
130 }
Jeff Haoa8621002016-10-04 18:13:44 +0000131
Jeff Haoea7c6292016-11-14 18:10:16 -0800132 dex_ir::Header* const header_;
133 MemMap* const mem_map_;
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800134 DexLayout* const dex_layout_;
135 bool compute_offsets_;
Jeff Haoa8621002016-10-04 18:13:44 +0000136
Mathieu Chartierf95a75e2017-11-03 15:25:52 -0700137 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000138 DISALLOW_COPY_AND_ASSIGN(DexWriter);
139};
140
Jeff Haoa8621002016-10-04 18:13:44 +0000141} // namespace art
142
143#endif // ART_DEXLAYOUT_DEX_WRITER_H_