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_COMPILER_OAT_WRITER_H_ 18 #define ART_COMPILER_OAT_WRITER_H_ 19 20 #include <stdint.h> 21 #include <cstddef> 22 #include <memory> 23 24 #include "base/dchecked_vector.h" 25 #include "linker/relative_patcher.h" // For linker::RelativePatcherTargetProvider. 26 #include "mem_map.h" 27 #include "method_reference.h" 28 #include "mirror/class.h" 29 #include "oat.h" 30 #include "os.h" 31 #include "safe_map.h" 32 #include "ScopedFd.h" 33 #include "utils/array_ref.h" 34 35 namespace art { 36 37 class BitVector; 38 class CompiledMethod; 39 class CompilerDriver; 40 class ImageWriter; 41 class OutputStream; 42 class TimingLogger; 43 class TypeLookupTable; 44 class ZipEntry; 45 46 namespace debug { 47 struct MethodDebugInfo; 48 } // namespace debug 49 50 namespace linker { 51 class MultiOatRelativePatcher; 52 } // namespace linker 53 54 // OatHeader variable length with count of D OatDexFiles 55 // 56 // OatDexFile[0] one variable sized OatDexFile with offsets to Dex and OatClasses 57 // OatDexFile[1] 58 // ... 59 // OatDexFile[D] 60 // 61 // Dex[0] one variable sized DexFile for each OatDexFile. 62 // Dex[1] these are literal copies of the input .dex files. 63 // ... 64 // Dex[D] 65 // 66 // TypeLookupTable[0] one descriptor to class def index hash table for each OatDexFile. 67 // TypeLookupTable[1] 68 // ... 69 // TypeLookupTable[D] 70 // 71 // ClassOffsets[0] one table of OatClass offsets for each class def for each OatDexFile. 72 // ClassOffsets[1] 73 // ... 74 // ClassOffsets[D] 75 // 76 // OatClass[0] one variable sized OatClass for each of C DexFile::ClassDefs 77 // OatClass[1] contains OatClass entries with class status, offsets to code, etc. 78 // ... 79 // OatClass[C] 80 // 81 // GcMap one variable sized blob with GC map. 82 // GcMap GC maps are deduplicated. 83 // ... 84 // GcMap 85 // 86 // VmapTable one variable sized VmapTable blob (quick compiler only). 87 // VmapTable VmapTables are deduplicated. 88 // ... 89 // VmapTable 90 // 91 // MappingTable one variable sized blob with MappingTable (quick compiler only). 92 // MappingTable MappingTables are deduplicated. 93 // ... 94 // MappingTable 95 // 96 // padding if necessary so that the following code will be page aligned 97 // 98 // OatMethodHeader fixed size header for a CompiledMethod including the size of the MethodCode. 99 // MethodCode one variable sized blob with the code of a CompiledMethod. 100 // OatMethodHeader (OatMethodHeader, MethodCode) pairs are deduplicated. 101 // MethodCode 102 // ... 103 // OatMethodHeader 104 // MethodCode 105 // 106 class OatWriter { 107 public: 108 enum class CreateTypeLookupTable { 109 kCreate, 110 kDontCreate, 111 kDefault = kCreate 112 }; 113 114 OatWriter(bool compiling_boot_image, TimingLogger* timings); 115 116 // To produce a valid oat file, the user must first add sources with any combination of 117 // - AddDexFileSource(), 118 // - AddZippedDexFilesSource(), 119 // - AddRawDexFileSource(). 120 // Then the user must call in order 121 // - WriteAndOpenDexFiles() 122 // - PrepareLayout(), 123 // - WriteRodata(), 124 // - WriteCode(), 125 // - WriteHeader(). 126 127 // Add dex file source(s) from a file, either a plain dex file or 128 // a zip file with one or more dex files. 129 bool AddDexFileSource( 130 const char* filename, 131 const char* location, 132 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault); 133 // Add dex file source(s) from a zip file specified by a file handle. 134 bool AddZippedDexFilesSource( 135 ScopedFd&& zip_fd, 136 const char* location, 137 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault); 138 // Add dex file source from raw memory. 139 bool AddRawDexFileSource( 140 const ArrayRef<const uint8_t>& data, 141 const char* location, 142 uint32_t location_checksum, 143 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault); 144 dchecked_vector<const char*> GetSourceLocations() const; 145 146 // Write raw dex files to the .rodata section and open them from the oat file. The verify 147 // setting dictates whether the dex file verifier should check the dex files. This is generally 148 // the case, and should only be false for tests. 149 bool WriteAndOpenDexFiles(OutputStream* rodata, 150 File* file, 151 InstructionSet instruction_set, 152 const InstructionSetFeatures* instruction_set_features, 153 SafeMap<std::string, std::string>* key_value_store, 154 bool verify, 155 /*out*/ std::unique_ptr<MemMap>* opened_dex_files_map, 156 /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files); 157 // Prepare layout of remaining data. 158 void PrepareLayout(const CompilerDriver* compiler, 159 ImageWriter* image_writer, 160 const std::vector<const DexFile*>& dex_files, 161 linker::MultiOatRelativePatcher* relative_patcher); 162 // Write the rest of .rodata section (ClassOffsets[], OatClass[], maps). 163 bool WriteRodata(OutputStream* out); 164 // Write the code to the .text section. 165 bool WriteCode(OutputStream* out); 166 // Write the oat header. This finalizes the oat file. 167 bool WriteHeader(OutputStream* out, 168 uint32_t image_file_location_oat_checksum, 169 uintptr_t image_file_location_oat_begin, 170 int32_t image_patch_delta); 171 172 // Returns whether the oat file has an associated image. 173 bool HasImage() const { 174 // Since the image is being created at the same time as the oat file, 175 // check if there's an image writer. 176 return image_writer_ != nullptr; 177 } 178 179 bool HasBootImage() const { 180 return compiling_boot_image_; 181 } 182 183 const OatHeader& GetOatHeader() const { 184 return *oat_header_; 185 } 186 187 size_t GetSize() const { 188 return size_; 189 } 190 191 size_t GetBssSize() const { 192 return bss_size_; 193 } 194 195 size_t GetOatDataOffset() const { 196 return oat_data_offset_; 197 } 198 199 ArrayRef<const uintptr_t> GetAbsolutePatchLocations() const { 200 return ArrayRef<const uintptr_t>(absolute_patch_locations_); 201 } 202 203 ~OatWriter(); 204 205 void AddMethodDebugInfos(const std::vector<debug::MethodDebugInfo>& infos) { 206 method_info_.insert(method_info_.end(), infos.begin(), infos.end()); 207 } 208 209 ArrayRef<const debug::MethodDebugInfo> GetMethodDebugInfo() const { 210 return ArrayRef<const debug::MethodDebugInfo>(method_info_); 211 } 212 213 const CompilerDriver* GetCompilerDriver() { 214 return compiler_driver_; 215 } 216 217 private: 218 class DexFileSource; 219 class OatClass; 220 class OatDexFile; 221 222 // The function VisitDexMethods() below iterates through all the methods in all 223 // the compiled dex files in order of their definitions. The method visitor 224 // classes provide individual bits of processing for each of the passes we need to 225 // first collect the data we want to write to the oat file and then, in later passes, 226 // to actually write it. 227 class DexMethodVisitor; 228 class OatDexMethodVisitor; 229 class InitOatClassesMethodVisitor; 230 class InitCodeMethodVisitor; 231 class InitMapMethodVisitor; 232 class InitImageMethodVisitor; 233 class WriteCodeMethodVisitor; 234 class WriteMapMethodVisitor; 235 236 // Visit all the methods in all the compiled dex files in their definition order 237 // with a given DexMethodVisitor. 238 bool VisitDexMethods(DexMethodVisitor* visitor); 239 240 size_t InitOatHeader(InstructionSet instruction_set, 241 const InstructionSetFeatures* instruction_set_features, 242 uint32_t num_dex_files, 243 SafeMap<std::string, std::string>* key_value_store); 244 size_t InitOatDexFiles(size_t offset); 245 size_t InitOatClasses(size_t offset); 246 size_t InitOatMaps(size_t offset); 247 size_t InitOatCode(size_t offset); 248 size_t InitOatCodeDexFiles(size_t offset); 249 250 bool WriteClassOffsets(OutputStream* out); 251 bool WriteClasses(OutputStream* out); 252 size_t WriteMaps(OutputStream* out, const size_t file_offset, size_t relative_offset); 253 size_t WriteCode(OutputStream* out, const size_t file_offset, size_t relative_offset); 254 size_t WriteCodeDexFiles(OutputStream* out, const size_t file_offset, size_t relative_offset); 255 256 bool RecordOatDataOffset(OutputStream* out); 257 bool ReadDexFileHeader(File* file, OatDexFile* oat_dex_file); 258 bool ValidateDexFileHeader(const uint8_t* raw_header, const char* location); 259 bool WriteDexFiles(OutputStream* rodata, File* file); 260 bool WriteDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file); 261 bool SeekToDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file); 262 bool WriteDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file, ZipEntry* dex_file); 263 bool WriteDexFile(OutputStream* rodata, File* file, OatDexFile* oat_dex_file, File* dex_file); 264 bool WriteDexFile(OutputStream* rodata, OatDexFile* oat_dex_file, const uint8_t* dex_file); 265 bool WriteOatDexFiles(OutputStream* rodata); 266 bool ExtendForTypeLookupTables(OutputStream* rodata, File* file, size_t offset); 267 bool OpenDexFiles(File* file, 268 bool verify, 269 /*out*/ std::unique_ptr<MemMap>* opened_dex_files_map, 270 /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files); 271 bool WriteTypeLookupTables(MemMap* opened_dex_files_map, 272 const std::vector<std::unique_ptr<const DexFile>>& opened_dex_files); 273 bool WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta); 274 void SetMultiOatRelativePatcherAdjustment(); 275 276 enum class WriteState { 277 kAddingDexFileSources, 278 kPrepareLayout, 279 kWriteRoData, 280 kWriteText, 281 kWriteHeader, 282 kDone 283 }; 284 285 WriteState write_state_; 286 TimingLogger* timings_; 287 288 std::vector<std::unique_ptr<File>> raw_dex_files_; 289 std::vector<std::unique_ptr<ZipArchive>> zip_archives_; 290 std::vector<std::unique_ptr<ZipEntry>> zipped_dex_files_; 291 292 // Using std::list<> which doesn't move elements around on push/emplace_back(). 293 // We need this because we keep plain pointers to the strings' c_str(). 294 std::list<std::string> zipped_dex_file_locations_; 295 296 dchecked_vector<debug::MethodDebugInfo> method_info_; 297 298 const CompilerDriver* compiler_driver_; 299 ImageWriter* image_writer_; 300 const bool compiling_boot_image_; 301 302 // note OatFile does not take ownership of the DexFiles 303 const std::vector<const DexFile*>* dex_files_; 304 305 // Size required for Oat data structures. 306 size_t size_; 307 308 // The size of the required .bss section holding the DexCache data. 309 size_t bss_size_; 310 311 // Offsets of the dex cache arrays for each app dex file. For the 312 // boot image, this information is provided by the ImageWriter. 313 SafeMap<const DexFile*, size_t> dex_cache_arrays_offsets_; // DexFiles not owned. 314 315 // Offset of the oat data from the start of the mmapped region of the elf file. 316 size_t oat_data_offset_; 317 318 // data to write 319 std::unique_ptr<OatHeader> oat_header_; 320 dchecked_vector<OatDexFile> oat_dex_files_; 321 dchecked_vector<OatClass> oat_classes_; 322 std::unique_ptr<const std::vector<uint8_t>> jni_dlsym_lookup_; 323 std::unique_ptr<const std::vector<uint8_t>> quick_generic_jni_trampoline_; 324 std::unique_ptr<const std::vector<uint8_t>> quick_imt_conflict_trampoline_; 325 std::unique_ptr<const std::vector<uint8_t>> quick_resolution_trampoline_; 326 std::unique_ptr<const std::vector<uint8_t>> quick_to_interpreter_bridge_; 327 328 // output stats 329 uint32_t size_dex_file_alignment_; 330 uint32_t size_executable_offset_alignment_; 331 uint32_t size_oat_header_; 332 uint32_t size_oat_header_key_value_store_; 333 uint32_t size_dex_file_; 334 uint32_t size_interpreter_to_interpreter_bridge_; 335 uint32_t size_interpreter_to_compiled_code_bridge_; 336 uint32_t size_jni_dlsym_lookup_; 337 uint32_t size_quick_generic_jni_trampoline_; 338 uint32_t size_quick_imt_conflict_trampoline_; 339 uint32_t size_quick_resolution_trampoline_; 340 uint32_t size_quick_to_interpreter_bridge_; 341 uint32_t size_trampoline_alignment_; 342 uint32_t size_method_header_; 343 uint32_t size_code_; 344 uint32_t size_code_alignment_; 345 uint32_t size_relative_call_thunks_; 346 uint32_t size_misc_thunks_; 347 uint32_t size_vmap_table_; 348 uint32_t size_oat_dex_file_location_size_; 349 uint32_t size_oat_dex_file_location_data_; 350 uint32_t size_oat_dex_file_location_checksum_; 351 uint32_t size_oat_dex_file_offset_; 352 uint32_t size_oat_dex_file_class_offsets_offset_; 353 uint32_t size_oat_dex_file_lookup_table_offset_; 354 uint32_t size_oat_lookup_table_alignment_; 355 uint32_t size_oat_lookup_table_; 356 uint32_t size_oat_class_offsets_alignment_; 357 uint32_t size_oat_class_offsets_; 358 uint32_t size_oat_class_type_; 359 uint32_t size_oat_class_status_; 360 uint32_t size_oat_class_method_bitmaps_; 361 uint32_t size_oat_class_method_offsets_; 362 363 // The helper for processing relative patches is external so that we can patch across oat files. 364 linker::MultiOatRelativePatcher* relative_patcher_; 365 366 // The locations of absolute patches relative to the start of the executable section. 367 dchecked_vector<uintptr_t> absolute_patch_locations_; 368 369 DISALLOW_COPY_AND_ASSIGN(OatWriter); 370 }; 371 372 } // namespace art 373 374 #endif // ART_COMPILER_OAT_WRITER_H_ 375