blob: e8eee88bcded7cc117a00a9cc8477a4bbc1bb4c5 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
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
Vladimir Marko74527972016-11-29 15:57:32 +000017#ifndef ART_DEX2OAT_LINKER_OAT_WRITER_H_
18#define ART_DEX2OAT_LINKER_OAT_WRITER_H_
Brian Carlstrom7940e442013-07-12 13:46:57 -070019
20#include <stdint.h>
Brian Carlstrom7940e442013-07-12 13:46:57 -070021#include <cstddef>
Ian Rogers700a4022014-05-19 16:49:03 -070022#include <memory>
Igor Murashkin545412b2017-08-17 15:26:54 -070023#include <vector>
Brian Carlstrom7940e442013-07-12 13:46:57 -070024
David Brazdild9c90372016-09-14 16:53:55 +010025#include "base/array_ref.h"
Vladimir Marko49b0f452015-12-10 13:49:19 +000026#include "base/dchecked_vector.h"
David Sehrc431b9d2018-03-02 12:01:51 -080027#include "base/os.h"
David Sehr79e26072018-04-06 17:58:50 -070028#include "base/mem_map.h"
David Sehr67bf42e2018-02-26 16:43:04 -080029#include "base/safe_map.h"
David Srbecky32210b92017-12-04 14:39:21 +000030#include "debug/debug_info.h"
David Sehr312f3b22018-03-19 08:39:26 -070031#include "dex/compact_dex_level.h"
32#include "dex/method_reference.h"
33#include "dex/string_reference.h"
34#include "dex/type_reference.h"
Vladimir Marko74527972016-11-29 15:57:32 +000035#include "linker/relative_patcher.h" // For RelativePatcherTargetProvider.
Brian Carlstrom7940e442013-07-12 13:46:57 -070036#include "mirror/class.h"
Artem Udovichenkod9786b02015-10-14 16:36:55 +030037#include "oat.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070038
39namespace art {
40
Brian Carlstromba150c32013-08-27 17:31:03 -070041class BitVector;
Andreas Gampe79273802014-08-05 20:21:05 -070042class CompiledMethod;
Vladimir Marko20f85592015-03-19 10:07:02 +000043class CompilerDriver;
Vladimir Markodc4bcce2018-06-21 16:15:42 +010044class CompilerOptions;
Mathieu Chartierc3a22aa2018-01-19 18:58:34 -080045class DexContainer;
Jeff Hao608f2ce2016-10-19 11:17:11 -070046class ProfileCompilationInfo;
Vladimir Marko20f85592015-03-19 10:07:02 +000047class TimingLogger;
Artem Udovichenkod9786b02015-10-14 16:36:55 +030048class TypeLookupTable;
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000049class VdexFile;
Vladimir Marko9bdf1082016-01-21 12:15:52 +000050class ZipEntry;
Brian Carlstrom7940e442013-07-12 13:46:57 -070051
David Srbeckyc5bfa972016-02-05 15:49:10 +000052namespace debug {
Vladimir Marko10c13562015-11-25 14:33:36 +000053struct MethodDebugInfo;
David Srbeckyc5bfa972016-02-05 15:49:10 +000054} // namespace debug
Vladimir Marko10c13562015-11-25 14:33:36 +000055
David Brazdil5d5a36b2016-09-14 15:34:10 +010056namespace verifier {
Vladimir Marko74527972016-11-29 15:57:32 +000057class VerifierDeps;
David Brazdil5d5a36b2016-09-14 15:34:10 +010058} // namespace verifier
59
Vladimir Marko74527972016-11-29 15:57:32 +000060namespace linker {
61
62class ImageWriter;
63class MultiOatRelativePatcher;
64class OutputStream;
65
Andreas Gampe15544172018-06-25 15:09:06 -070066enum class CopyOption {
67 kNever,
68 kAlways,
69 kOnlyIfCompressed
70};
71
Brian Carlstrom7940e442013-07-12 13:46:57 -070072// OatHeader variable length with count of D OatDexFiles
73//
Artem Udovichenkod9786b02015-10-14 16:36:55 +030074// TypeLookupTable[0] one descriptor to class def index hash table for each OatDexFile.
75// TypeLookupTable[1]
76// ...
77// TypeLookupTable[D]
78//
Vladimir Marko9bdf1082016-01-21 12:15:52 +000079// ClassOffsets[0] one table of OatClass offsets for each class def for each OatDexFile.
80// ClassOffsets[1]
81// ...
82// ClassOffsets[D]
83//
Brian Carlstrom7940e442013-07-12 13:46:57 -070084// OatClass[0] one variable sized OatClass for each of C DexFile::ClassDefs
85// OatClass[1] contains OatClass entries with class status, offsets to code, etc.
86// ...
87// OatClass[C]
88//
Vladimir Marko0eb882b2017-05-15 13:39:18 +010089// MethodBssMapping one variable sized MethodBssMapping for each dex file, optional.
90// MethodBssMapping
Vladimir Marko96c6ab92014-04-08 14:00:50 +010091// ...
Vladimir Marko0eb882b2017-05-15 13:39:18 +010092// MethodBssMapping
Vladimir Marko96c6ab92014-04-08 14:00:50 +010093//
Vladimir Marko0eb882b2017-05-15 13:39:18 +010094// VmapTable one variable sized VmapTable blob (CodeInfo or QuickeningInfo).
Vladimir Marko96c6ab92014-04-08 14:00:50 +010095// VmapTable VmapTables are deduplicated.
96// ...
97// VmapTable
98//
Vladimir Marko0eb882b2017-05-15 13:39:18 +010099// MethodInfo one variable sized blob with MethodInfo.
100// MethodInfo MethodInfos are deduplicated.
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100101// ...
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100102// MethodInfo
103//
104// OatDexFile[0] one variable sized OatDexFile with offsets to Dex and OatClasses
105// OatDexFile[1]
106// ...
107// OatDexFile[D]
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100108//
Brian Carlstrom7940e442013-07-12 13:46:57 -0700109// padding if necessary so that the following code will be page aligned
110//
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100111// OatMethodHeader fixed size header for a CompiledMethod including the size of the MethodCode.
112// MethodCode one variable sized blob with the code of a CompiledMethod.
113// OatMethodHeader (OatMethodHeader, MethodCode) pairs are deduplicated.
114// MethodCode
Brian Carlstrom7940e442013-07-12 13:46:57 -0700115// ...
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100116// OatMethodHeader
117// MethodCode
Brian Carlstrom7940e442013-07-12 13:46:57 -0700118//
119class OatWriter {
120 public:
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000121 enum class CreateTypeLookupTable {
122 kCreate,
123 kDontCreate,
124 kDefault = kCreate
125 };
126
Mathieu Chartier603ccab2017-10-20 14:34:28 -0700127 OatWriter(bool compiling_boot_image,
128 TimingLogger* timings,
129 ProfileCompilationInfo* info,
130 CompactDexLevel compact_dex_level);
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000131
132 // To produce a valid oat file, the user must first add sources with any combination of
133 // - AddDexFileSource(),
134 // - AddZippedDexFilesSource(),
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +0000135 // - AddRawDexFileSource(),
136 // - AddVdexDexFilesSource().
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000137 // Then the user must call in order
138 // - WriteAndOpenDexFiles()
Nicolas Geoffray4acefd32016-10-24 13:14:58 +0100139 // - Initialize()
140 // - WriteVerifierDeps()
141 // - WriteQuickeningInfo()
Nicolas Geoffrayf54e5df2016-12-01 10:45:08 +0000142 // - WriteChecksumsAndVdexHeader()
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000143 // - PrepareLayout(),
144 // - WriteRodata(),
145 // - WriteCode(),
Vladimir Markob066d432018-01-03 13:14:37 +0000146 // - WriteDataBimgRelRo() iff GetDataBimgRelRoSize() != 0,
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000147 // - WriteHeader().
148
149 // Add dex file source(s) from a file, either a plain dex file or
150 // a zip file with one or more dex files.
151 bool AddDexFileSource(
152 const char* filename,
153 const char* location,
154 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
155 // Add dex file source(s) from a zip file specified by a file handle.
156 bool AddZippedDexFilesSource(
Andreas Gampe43e10b02016-07-15 17:17:34 -0700157 File&& zip_fd,
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000158 const char* location,
159 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
160 // Add dex file source from raw memory.
161 bool AddRawDexFileSource(
162 const ArrayRef<const uint8_t>& data,
163 const char* location,
164 uint32_t location_checksum,
165 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +0000166 // Add dex file source(s) from a vdex file.
167 bool AddVdexDexFilesSource(
168 const VdexFile& vdex_file,
169 const char* location,
170 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
Calin Juravle1ce70852017-06-28 10:59:03 -0700171 dchecked_vector<std::string> GetSourceLocations() const;
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000172
David Brazdil7b49e6c2016-09-01 11:06:18 +0100173 // Write raw dex files to the vdex file, mmap the file and open the dex files from it.
174 // Supporting data structures are written into the .rodata section of the oat file.
175 // The `verify` setting dictates whether the dex file verifier should check the dex files.
176 // This is generally the case, and should only be false for tests.
Nicolas Geoffray81f57d12016-12-20 13:17:09 +0000177 // If `update_input_vdex` is true, then this method won't actually write the dex files,
178 // and the compiler will just re-use the existing vdex file.
David Brazdil7b49e6c2016-09-01 11:06:18 +0100179 bool WriteAndOpenDexFiles(File* vdex_file,
180 OutputStream* oat_rodata,
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000181 InstructionSet instruction_set,
182 const InstructionSetFeatures* instruction_set_features,
183 SafeMap<std::string, std::string>* key_value_store,
Andreas Gampe3a2bd292016-01-26 17:23:47 -0800184 bool verify,
Nicolas Geoffray81f57d12016-12-20 13:17:09 +0000185 bool update_input_vdex,
Nicolas Geoffray66ff8a82018-02-28 13:27:55 +0000186 CopyOption copy_dex_files,
Nicolas Geoffrayf3075272018-01-08 12:41:19 +0000187 /*out*/ std::vector<std::unique_ptr<MemMap>>* opened_dex_files_map,
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000188 /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
Vladimir Markodc4bcce2018-06-21 16:15:42 +0100189 // Initialize the writer with the given parameters.
190 void Initialize(const CompilerDriver* compiler_driver,
191 ImageWriter* image_writer,
192 const std::vector<const DexFile*>& dex_files);
Nicolas Geoffray4acefd32016-10-24 13:14:58 +0100193 bool WriteQuickeningInfo(OutputStream* vdex_out);
David Brazdil5d5a36b2016-09-14 15:34:10 +0100194 bool WriteVerifierDeps(OutputStream* vdex_out, verifier::VerifierDeps* verifier_deps);
Nicolas Geoffrayf54e5df2016-12-01 10:45:08 +0000195 bool WriteChecksumsAndVdexHeader(OutputStream* vdex_out);
David Brazdil5d5a36b2016-09-14 15:34:10 +0100196
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000197 // Prepare layout of remaining data.
Vladimir Marko74527972016-11-29 15:57:32 +0000198 void PrepareLayout(MultiOatRelativePatcher* relative_patcher);
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000199 // Write the rest of .rodata section (ClassOffsets[], OatClass[], maps).
200 bool WriteRodata(OutputStream* out);
201 // Write the code to the .text section.
202 bool WriteCode(OutputStream* out);
Vladimir Markob066d432018-01-03 13:14:37 +0000203 // Write the boot image relocation data to the .data.bimg.rel.ro section.
204 bool WriteDataBimgRelRo(OutputStream* out);
205 // Check the size of the written oat file.
206 bool CheckOatSize(OutputStream* out, size_t file_offset, size_t relative_offset);
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000207 // Write the oat header. This finalizes the oat file.
208 bool WriteHeader(OutputStream* out,
209 uint32_t image_file_location_oat_checksum,
210 uintptr_t image_file_location_oat_begin,
211 int32_t image_patch_delta);
Brian Carlstromc50d8e12013-07-23 22:35:16 -0700212
Vladimir Marko09d09432015-09-08 13:47:48 +0100213 // Returns whether the oat file has an associated image.
214 bool HasImage() const {
215 // Since the image is being created at the same time as the oat file,
216 // check if there's an image writer.
217 return image_writer_ != nullptr;
218 }
219
Mathieu Chartierda5b28a2015-11-05 08:03:47 -0800220 bool HasBootImage() const {
221 return compiling_boot_image_;
222 }
223
Brian Carlstromc50d8e12013-07-23 22:35:16 -0700224 const OatHeader& GetOatHeader() const {
225 return *oat_header_;
226 }
227
Vladimir Markob066d432018-01-03 13:14:37 +0000228 size_t GetCodeSize() const {
229 return code_size_;
230 }
231
David Brazdil7b49e6c2016-09-01 11:06:18 +0100232 size_t GetOatSize() const {
233 return oat_size_;
Brian Carlstromc50d8e12013-07-23 22:35:16 -0700234 }
235
Vladimir Markob066d432018-01-03 13:14:37 +0000236 size_t GetDataBimgRelRoSize() const {
237 return data_bimg_rel_ro_size_;
238 }
239
Vladimir Marko5c42c292015-02-25 12:02:49 +0000240 size_t GetBssSize() const {
241 return bss_size_;
242 }
243
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100244 size_t GetBssMethodsOffset() const {
245 return bss_methods_offset_;
246 }
247
Vladimir Markoaad75c62016-10-03 08:46:48 +0000248 size_t GetBssRootsOffset() const {
249 return bss_roots_offset_;
250 }
251
David Srbeckyec2cdf42017-12-08 16:21:25 +0000252 size_t GetVdexSize() const {
253 return vdex_size_;
254 }
255
Vladimir Marko944da602016-02-19 12:27:55 +0000256 size_t GetOatDataOffset() const {
257 return oat_data_offset_;
258 }
259
Brian Carlstrom7940e442013-07-12 13:46:57 -0700260 ~OatWriter();
261
David Srbecky32210b92017-12-04 14:39:21 +0000262 debug::DebugInfo GetDebugInfo() const;
Mark Mendellae9fd932014-02-10 16:14:35 -0800263
Mathieu Chartier3957bff2017-07-16 13:55:27 -0700264 const CompilerDriver* GetCompilerDriver() const {
Vladimir Markob163bb72015-03-31 21:49:49 +0100265 return compiler_driver_;
266 }
267
Vladimir Markodc4bcce2018-06-21 16:15:42 +0100268 const CompilerOptions& GetCompilerOptions() const {
269 DCHECK(compiler_options_ != nullptr);
270 return *compiler_options_;
271 }
272
Brian Carlstromc50d8e12013-07-23 22:35:16 -0700273 private:
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000274 class DexFileSource;
Mathieu Chartier3957bff2017-07-16 13:55:27 -0700275 class OatClassHeader;
Vladimir Marko49b0f452015-12-10 13:49:19 +0000276 class OatClass;
277 class OatDexFile;
278
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100279 // The function VisitDexMethods() below iterates through all the methods in all
280 // the compiled dex files in order of their definitions. The method visitor
281 // classes provide individual bits of processing for each of the passes we need to
282 // first collect the data we want to write to the oat file and then, in later passes,
283 // to actually write it.
284 class DexMethodVisitor;
285 class OatDexMethodVisitor;
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100286 class InitBssLayoutMethodVisitor;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100287 class InitOatClassesMethodVisitor;
Igor Murashkin545412b2017-08-17 15:26:54 -0700288 class LayoutCodeMethodVisitor;
289 class LayoutReserveOffsetCodeMethodVisitor;
290 struct OrderedMethodData;
291 class OrderedMethodVisitor;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100292 class InitCodeMethodVisitor;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100293 class InitMapMethodVisitor;
Mathieu Chartiercbcedbf2017-03-12 22:24:50 -0700294 class InitMethodInfoVisitor;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100295 class InitImageMethodVisitor;
296 class WriteCodeMethodVisitor;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100297 class WriteMapMethodVisitor;
Mathieu Chartiercbcedbf2017-03-12 22:24:50 -0700298 class WriteMethodInfoVisitor;
Nicolas Geoffray4acefd32016-10-24 13:14:58 +0100299 class WriteQuickeningInfoMethodVisitor;
Mathieu Chartier210531f2018-01-12 10:15:51 -0800300 class WriteQuickeningInfoOffsetsMethodVisitor;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100301
302 // Visit all the methods in all the compiled dex files in their definition order
303 // with a given DexMethodVisitor.
304 bool VisitDexMethods(DexMethodVisitor* visitor);
305
Nicolas Geoffray81f57d12016-12-20 13:17:09 +0000306 // If `update_input_vdex` is true, then this method won't actually write the dex files,
307 // and the compiler will just re-use the existing vdex file.
Mathieu Chartier792111c2018-02-15 13:02:15 -0800308 bool WriteDexFiles(OutputStream* out,
309 File* file,
310 bool update_input_vdex,
Nicolas Geoffray66ff8a82018-02-28 13:27:55 +0000311 CopyOption copy_dex_files);
Nicolas Geoffray81f57d12016-12-20 13:17:09 +0000312 bool WriteDexFile(OutputStream* out,
313 File* file,
314 OatDexFile* oat_dex_file,
315 bool update_input_vdex);
David Brazdil7b49e6c2016-09-01 11:06:18 +0100316 bool SeekToDexFile(OutputStream* out, File* file, OatDexFile* oat_dex_file);
Jeff Hao608f2ce2016-10-19 11:17:11 -0700317 bool LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_file);
David Brazdil7b49e6c2016-09-01 11:06:18 +0100318 bool WriteDexFile(OutputStream* out,
319 File* file,
320 OatDexFile* oat_dex_file,
321 ZipEntry* dex_file);
322 bool WriteDexFile(OutputStream* out,
323 File* file,
324 OatDexFile* oat_dex_file,
325 File* dex_file);
Nicolas Geoffray81f57d12016-12-20 13:17:09 +0000326 bool WriteDexFile(OutputStream* out,
327 OatDexFile* oat_dex_file,
328 const uint8_t* dex_file,
329 bool update_input_vdex);
David Brazdil7b49e6c2016-09-01 11:06:18 +0100330 bool OpenDexFiles(File* file,
331 bool verify,
Nicolas Geoffrayf3075272018-01-08 12:41:19 +0000332 /*out*/ std::vector<std::unique_ptr<MemMap>>* opened_dex_files_map,
David Brazdil7b49e6c2016-09-01 11:06:18 +0100333 /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
334
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000335 size_t InitOatHeader(InstructionSet instruction_set,
336 const InstructionSetFeatures* instruction_set_features,
337 uint32_t num_dex_files,
338 SafeMap<std::string, std::string>* key_value_store);
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100339 size_t InitClassOffsets(size_t offset);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700340 size_t InitOatClasses(size_t offset);
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100341 size_t InitOatMaps(size_t offset);
Vladimir Markof3c52b42017-11-17 17:32:12 +0000342 size_t InitIndexBssMappings(size_t offset);
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100343 size_t InitOatDexFiles(size_t offset);
Vladimir Marko49b0f452015-12-10 13:49:19 +0000344 size_t InitOatCode(size_t offset);
345 size_t InitOatCodeDexFiles(size_t offset);
Vladimir Markob066d432018-01-03 13:14:37 +0000346 size_t InitDataBimgRelRoLayout(size_t offset);
Vladimir Markoaad75c62016-10-03 08:46:48 +0000347 void InitBssLayout(InstructionSet instruction_set);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700348
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100349 size_t WriteClassOffsets(OutputStream* out, size_t file_offset, size_t relative_offset);
350 size_t WriteClasses(OutputStream* out, size_t file_offset, size_t relative_offset);
351 size_t WriteMaps(OutputStream* out, size_t file_offset, size_t relative_offset);
Vladimir Markof3c52b42017-11-17 17:32:12 +0000352 size_t WriteIndexBssMappings(OutputStream* out, size_t file_offset, size_t relative_offset);
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100353 size_t WriteOatDexFiles(OutputStream* out, size_t file_offset, size_t relative_offset);
354 size_t WriteCode(OutputStream* out, size_t file_offset, size_t relative_offset);
355 size_t WriteCodeDexFiles(OutputStream* out, size_t file_offset, size_t relative_offset);
Vladimir Markob066d432018-01-03 13:14:37 +0000356 size_t WriteDataBimgRelRo(OutputStream* out, size_t file_offset, size_t relative_offset);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700357
Vladimir Marko944da602016-02-19 12:27:55 +0000358 bool RecordOatDataOffset(OutputStream* out);
David Brazdil7b49e6c2016-09-01 11:06:18 +0100359 bool WriteTypeLookupTables(OutputStream* oat_rodata,
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000360 const std::vector<std::unique_ptr<const DexFile>>& opened_dex_files);
Mathieu Chartier120aa282017-08-05 16:03:03 -0700361 bool WriteDexLayoutSections(OutputStream* oat_rodata,
362 const std::vector<std::unique_ptr<const DexFile>>& opened_dex_files);
Vladimir Markof4da6752014-08-01 19:04:18 +0100363 bool WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta);
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100364 bool WriteUpTo16BytesAlignment(OutputStream* out, uint32_t size, uint32_t* stat);
Vladimir Marko944da602016-02-19 12:27:55 +0000365 void SetMultiOatRelativePatcherAdjustment();
Nicolas Geoffray81f57d12016-12-20 13:17:09 +0000366 void CloseSources();
Vladimir Markof4da6752014-08-01 19:04:18 +0100367
Mathieu Chartier3957bff2017-07-16 13:55:27 -0700368 bool MayHaveCompiledMethods() const;
369
David Srbecky96c84462018-02-05 15:42:40 +0000370 bool VdexWillContainDexFiles() const {
Mathieu Chartier792111c2018-02-15 13:02:15 -0800371 return dex_files_ != nullptr && extract_dex_files_into_vdex_;
David Srbecky96c84462018-02-05 15:42:40 +0000372 }
373
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000374 enum class WriteState {
375 kAddingDexFileSources,
376 kPrepareLayout,
377 kWriteRoData,
378 kWriteText,
Vladimir Markob066d432018-01-03 13:14:37 +0000379 kWriteDataBimgRelRo,
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000380 kWriteHeader,
381 kDone
382 };
383
384 WriteState write_state_;
385 TimingLogger* timings_;
386
387 std::vector<std::unique_ptr<File>> raw_dex_files_;
388 std::vector<std::unique_ptr<ZipArchive>> zip_archives_;
389 std::vector<std::unique_ptr<ZipEntry>> zipped_dex_files_;
390
391 // Using std::list<> which doesn't move elements around on push/emplace_back().
392 // We need this because we keep plain pointers to the strings' c_str().
393 std::list<std::string> zipped_dex_file_locations_;
394
David Srbeckyc5bfa972016-02-05 15:49:10 +0000395 dchecked_vector<debug::MethodDebugInfo> method_info_;
Mark Mendellae9fd932014-02-10 16:14:35 -0800396
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000397 const CompilerDriver* compiler_driver_;
Vladimir Markodc4bcce2018-06-21 16:15:42 +0100398 const CompilerOptions* compiler_options_;
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000399 ImageWriter* image_writer_;
Mathieu Chartierda5b28a2015-11-05 08:03:47 -0800400 const bool compiling_boot_image_;
Mathieu Chartier792111c2018-02-15 13:02:15 -0800401 // Whether the dex files being compiled are going to be extracted to the vdex.
402 bool extract_dex_files_into_vdex_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700403
404 // note OatFile does not take ownership of the DexFiles
405 const std::vector<const DexFile*>* dex_files_;
406
David Brazdil7b49e6c2016-09-01 11:06:18 +0100407 // Size required for Vdex data structures.
408 size_t vdex_size_;
409
410 // Offset of section holding Dex files inside Vdex.
411 size_t vdex_dex_files_offset_;
412
Mathieu Chartierc3a22aa2018-01-19 18:58:34 -0800413 // Offset of section holding shared dex data section in the Vdex.
414 size_t vdex_dex_shared_data_offset_;
415
David Brazdil5d5a36b2016-09-14 15:34:10 +0100416 // Offset of section holding VerifierDeps inside Vdex.
417 size_t vdex_verifier_deps_offset_;
418
Nicolas Geoffray4acefd32016-10-24 13:14:58 +0100419 // Offset of section holding quickening info inside Vdex.
420 size_t vdex_quickening_info_offset_;
421
Vladimir Markob066d432018-01-03 13:14:37 +0000422 // Size of the .text segment.
423 size_t code_size_;
424
Brian Carlstromc50d8e12013-07-23 22:35:16 -0700425 // Size required for Oat data structures.
David Brazdil7b49e6c2016-09-01 11:06:18 +0100426 size_t oat_size_;
Brian Carlstromc50d8e12013-07-23 22:35:16 -0700427
Vladimir Markob066d432018-01-03 13:14:37 +0000428 // The start of the required .data.bimg.rel.ro section.
429 size_t data_bimg_rel_ro_start_;
430
431 // The size of the required .data.bimg.rel.ro section holding the boot image relocations.
432 size_t data_bimg_rel_ro_size_;
433
Vladimir Markoaad75c62016-10-03 08:46:48 +0000434 // The start of the required .bss section.
435 size_t bss_start_;
436
437 // The size of the required .bss section holding the DexCache data and GC roots.
Vladimir Marko5c42c292015-02-25 12:02:49 +0000438 size_t bss_size_;
439
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100440 // The offset of the methods in .bss section.
441 size_t bss_methods_offset_;
442
Vladimir Markoaad75c62016-10-03 08:46:48 +0000443 // The offset of the GC roots in .bss section.
444 size_t bss_roots_offset_;
445
Vladimir Markob066d432018-01-03 13:14:37 +0000446 // Map for allocating .data.bimg.rel.ro entries. Indexed by the boot image offset of the
447 // relocation. The value is the assigned offset within the .data.bimg.rel.ro section.
448 SafeMap<uint32_t, size_t> data_bimg_rel_ro_entries_;
449
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100450 // Map for recording references to ArtMethod entries in .bss.
451 SafeMap<const DexFile*, BitVector> bss_method_entry_references_;
452
Vladimir Markof3c52b42017-11-17 17:32:12 +0000453 // Map for recording references to GcRoot<mirror::Class> entries in .bss.
454 SafeMap<const DexFile*, BitVector> bss_type_entry_references_;
455
456 // Map for recording references to GcRoot<mirror::String> entries in .bss.
457 SafeMap<const DexFile*, BitVector> bss_string_entry_references_;
458
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100459 // Map for allocating ArtMethod entries in .bss. Indexed by MethodReference for the target
460 // method in the dex file with the "method reference value comparator" for deduplication.
461 // The value is the target offset for patching, starting at `bss_start_ + bss_methods_offset_`.
462 SafeMap<MethodReference, size_t, MethodReferenceValueComparator> bss_method_entries_;
463
Vladimir Marko6bec91c2017-01-09 15:03:12 +0000464 // Map for allocating Class entries in .bss. Indexed by TypeReference for the source
465 // type in the dex file with the "type value comparator" for deduplication. The value
466 // is the target offset for patching, starting at `bss_start_ + bss_roots_offset_`.
467 SafeMap<TypeReference, size_t, TypeReferenceValueComparator> bss_type_entries_;
468
Vladimir Markoaad75c62016-10-03 08:46:48 +0000469 // Map for allocating String entries in .bss. Indexed by StringReference for the source
470 // string in the dex file with the "string value comparator" for deduplication. The value
471 // is the target offset for patching, starting at `bss_start_ + bss_roots_offset_`.
472 SafeMap<StringReference, size_t, StringReferenceValueComparator> bss_string_entries_;
473
Vladimir Markof4da6752014-08-01 19:04:18 +0100474 // Offset of the oat data from the start of the mmapped region of the elf file.
475 size_t oat_data_offset_;
476
Mathieu Chartier1b868492016-11-16 16:22:37 -0800477 // Fake OatDexFiles to hold type lookup tables for the compiler.
478 std::vector<std::unique_ptr<art::OatDexFile>> type_lookup_table_oat_dex_files_;
479
Brian Carlstrom7940e442013-07-12 13:46:57 -0700480 // data to write
Vladimir Marko49b0f452015-12-10 13:49:19 +0000481 std::unique_ptr<OatHeader> oat_header_;
482 dchecked_vector<OatDexFile> oat_dex_files_;
Mathieu Chartier3957bff2017-07-16 13:55:27 -0700483 dchecked_vector<OatClassHeader> oat_class_headers_;
Vladimir Marko49b0f452015-12-10 13:49:19 +0000484 dchecked_vector<OatClass> oat_classes_;
Ian Rogers700a4022014-05-19 16:49:03 -0700485 std::unique_ptr<const std::vector<uint8_t>> jni_dlsym_lookup_;
Ian Rogers700a4022014-05-19 16:49:03 -0700486 std::unique_ptr<const std::vector<uint8_t>> quick_generic_jni_trampoline_;
487 std::unique_ptr<const std::vector<uint8_t>> quick_imt_conflict_trampoline_;
488 std::unique_ptr<const std::vector<uint8_t>> quick_resolution_trampoline_;
489 std::unique_ptr<const std::vector<uint8_t>> quick_to_interpreter_bridge_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700490
491 // output stats
David Brazdil7b49e6c2016-09-01 11:06:18 +0100492 uint32_t size_vdex_header_;
Nicolas Geoffrayf54e5df2016-12-01 10:45:08 +0000493 uint32_t size_vdex_checksums_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700494 uint32_t size_dex_file_alignment_;
495 uint32_t size_executable_offset_alignment_;
496 uint32_t size_oat_header_;
Andreas Gampe22f8e5c2014-07-09 11:38:21 -0700497 uint32_t size_oat_header_key_value_store_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700498 uint32_t size_dex_file_;
David Brazdil5d5a36b2016-09-14 15:34:10 +0100499 uint32_t size_verifier_deps_;
500 uint32_t size_verifier_deps_alignment_;
Nicolas Geoffray4acefd32016-10-24 13:14:58 +0100501 uint32_t size_quickening_info_;
502 uint32_t size_quickening_info_alignment_;
Ian Rogers468532e2013-08-05 10:56:33 -0700503 uint32_t size_interpreter_to_interpreter_bridge_;
504 uint32_t size_interpreter_to_compiled_code_bridge_;
505 uint32_t size_jni_dlsym_lookup_;
Andreas Gampe2da88232014-02-27 12:26:20 -0800506 uint32_t size_quick_generic_jni_trampoline_;
Jeff Hao88474b42013-10-23 16:24:40 -0700507 uint32_t size_quick_imt_conflict_trampoline_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700508 uint32_t size_quick_resolution_trampoline_;
Ian Rogers468532e2013-08-05 10:56:33 -0700509 uint32_t size_quick_to_interpreter_bridge_;
510 uint32_t size_trampoline_alignment_;
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100511 uint32_t size_method_header_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700512 uint32_t size_code_;
513 uint32_t size_code_alignment_;
Vladimir Markob066d432018-01-03 13:14:37 +0000514 uint32_t size_data_bimg_rel_ro_;
515 uint32_t size_data_bimg_rel_ro_alignment_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100516 uint32_t size_relative_call_thunks_;
Vladimir Markoc74658b2015-03-31 10:26:41 +0100517 uint32_t size_misc_thunks_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700518 uint32_t size_vmap_table_;
Mathieu Chartiercbcedbf2017-03-12 22:24:50 -0700519 uint32_t size_method_info_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700520 uint32_t size_oat_dex_file_location_size_;
521 uint32_t size_oat_dex_file_location_data_;
522 uint32_t size_oat_dex_file_location_checksum_;
523 uint32_t size_oat_dex_file_offset_;
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000524 uint32_t size_oat_dex_file_class_offsets_offset_;
Vladimir Marko49b0f452015-12-10 13:49:19 +0000525 uint32_t size_oat_dex_file_lookup_table_offset_;
Mathieu Chartier120aa282017-08-05 16:03:03 -0700526 uint32_t size_oat_dex_file_dex_layout_sections_offset_;
527 uint32_t size_oat_dex_file_dex_layout_sections_;
528 uint32_t size_oat_dex_file_dex_layout_sections_alignment_;
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100529 uint32_t size_oat_dex_file_method_bss_mapping_offset_;
Vladimir Markof3c52b42017-11-17 17:32:12 +0000530 uint32_t size_oat_dex_file_type_bss_mapping_offset_;
531 uint32_t size_oat_dex_file_string_bss_mapping_offset_;
Vladimir Marko49b0f452015-12-10 13:49:19 +0000532 uint32_t size_oat_lookup_table_alignment_;
533 uint32_t size_oat_lookup_table_;
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000534 uint32_t size_oat_class_offsets_alignment_;
535 uint32_t size_oat_class_offsets_;
Brian Carlstromba150c32013-08-27 17:31:03 -0700536 uint32_t size_oat_class_type_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700537 uint32_t size_oat_class_status_;
Brian Carlstromba150c32013-08-27 17:31:03 -0700538 uint32_t size_oat_class_method_bitmaps_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700539 uint32_t size_oat_class_method_offsets_;
Vladimir Marko0eb882b2017-05-15 13:39:18 +0100540 uint32_t size_method_bss_mappings_;
Vladimir Markof3c52b42017-11-17 17:32:12 +0000541 uint32_t size_type_bss_mappings_;
542 uint32_t size_string_bss_mappings_;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700543
Vladimir Marko944da602016-02-19 12:27:55 +0000544 // The helper for processing relative patches is external so that we can patch across oat files.
Vladimir Marko74527972016-11-29 15:57:32 +0000545 MultiOatRelativePatcher* relative_patcher_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100546
David Srbeckyf8980872015-05-22 17:04:47 +0100547 // The locations of absolute patches relative to the start of the executable section.
Vladimir Marko9bdf1082016-01-21 12:15:52 +0000548 dchecked_vector<uintptr_t> absolute_patch_locations_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100549
Jeff Hao608f2ce2016-10-19 11:17:11 -0700550 // Profile info used to generate new layout of files.
551 ProfileCompilationInfo* profile_compilation_info_;
552
Mathieu Chartier603ccab2017-10-20 14:34:28 -0700553 // Compact dex level that is generated.
554 CompactDexLevel compact_dex_level_;
555
Igor Murashkin545412b2017-08-17 15:26:54 -0700556 using OrderedMethodList = std::vector<OrderedMethodData>;
557
558 // List of compiled methods, sorted by the order defined in OrderedMethodData.
559 // Methods can be inserted more than once in case of duplicated methods.
560 // This pointer is only non-null after InitOatCodeDexFiles succeeds.
561 std::unique_ptr<OrderedMethodList> ordered_methods_;
562
Mathieu Chartierc3a22aa2018-01-19 18:58:34 -0800563 // Container of shared dex data.
564 std::unique_ptr<DexContainer> dex_container_;
565
Brian Carlstrom7940e442013-07-12 13:46:57 -0700566 DISALLOW_COPY_AND_ASSIGN(OatWriter);
567};
568
Vladimir Marko74527972016-11-29 15:57:32 +0000569} // namespace linker
Brian Carlstrom7940e442013-07-12 13:46:57 -0700570} // namespace art
571
Vladimir Marko74527972016-11-29 15:57:32 +0000572#endif // ART_DEX2OAT_LINKER_OAT_WRITER_H_