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 22 #include <cstddef> 23 24 #include "driver/compiler_driver.h" 25 #include "mem_map.h" 26 #include "oat.h" 27 #include "mirror/class.h" 28 #include "safe_map.h" 29 #include "UniquePtr.h" 30 31 namespace art { 32 33 class OutputStream; 34 35 // OatHeader variable length with count of D OatDexFiles 36 // 37 // OatDexFile[0] one variable sized OatDexFile with offsets to Dex and OatClasses 38 // OatDexFile[1] 39 // ... 40 // OatDexFile[D] 41 // 42 // Dex[0] one variable sized DexFile for each OatDexFile. 43 // Dex[1] these are literal copies of the input .dex files. 44 // ... 45 // Dex[D] 46 // 47 // OatClass[0] one variable sized OatClass for each of C DexFile::ClassDefs 48 // OatClass[1] contains OatClass entries with class status, offsets to code, etc. 49 // ... 50 // OatClass[C] 51 // 52 // padding if necessary so that the following code will be page aligned 53 // 54 // CompiledMethod one variable sized blob with the contents of each CompiledMethod 55 // CompiledMethod 56 // CompiledMethod 57 // CompiledMethod 58 // CompiledMethod 59 // CompiledMethod 60 // ... 61 // CompiledMethod 62 // 63 class OatWriter { 64 public: 65 OatWriter(const std::vector<const DexFile*>& dex_files, 66 uint32_t image_file_location_oat_checksum, 67 uint32_t image_file_location_oat_begin, 68 const std::string& image_file_location, 69 const CompilerDriver* compiler); 70 71 const OatHeader& GetOatHeader() const { 72 return *oat_header_; 73 } 74 75 size_t GetSize() const { 76 return size_; 77 } 78 79 bool Write(OutputStream& out); 80 81 ~OatWriter(); 82 83 private: 84 size_t InitOatHeader(); 85 size_t InitOatDexFiles(size_t offset); 86 size_t InitDexFiles(size_t offset); 87 size_t InitOatClasses(size_t offset); 88 size_t InitOatCode(size_t offset) 89 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 90 size_t InitOatCodeDexFiles(size_t offset) 91 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 92 size_t InitOatCodeDexFile(size_t offset, 93 size_t& oat_class_index, 94 const DexFile& dex_file) 95 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 96 size_t InitOatCodeClassDef(size_t offset, 97 size_t oat_class_index, size_t class_def_index, 98 const DexFile& dex_file, 99 const DexFile::ClassDef& class_def) 100 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 101 size_t InitOatCodeMethod(size_t offset, size_t oat_class_index, size_t class_def_index, 102 size_t class_def_method_index, bool is_native, InvokeType type, 103 uint32_t method_idx, const DexFile*) 104 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 105 106 bool WriteTables(OutputStream& out, const size_t file_offset); 107 size_t WriteCode(OutputStream& out, const size_t file_offset); 108 size_t WriteCodeDexFiles(OutputStream& out, const size_t file_offset, size_t relative_offset); 109 size_t WriteCodeDexFile(OutputStream& out, const size_t file_offset, size_t relative_offset, 110 size_t& oat_class_index, const DexFile& dex_file); 111 size_t WriteCodeClassDef(OutputStream& out, const size_t file_offset, size_t relative_offset, 112 size_t oat_class_index, const DexFile& dex_file, 113 const DexFile::ClassDef& class_def); 114 size_t WriteCodeMethod(OutputStream& out, const size_t file_offset, size_t relative_offset, 115 size_t oat_class_index, size_t class_def_method_index, bool is_static, 116 uint32_t method_idx, const DexFile& dex_file); 117 118 void ReportWriteFailure(const char* what, uint32_t method_idx, const DexFile& dex_file, 119 OutputStream& out) const; 120 121 class OatDexFile { 122 public: 123 explicit OatDexFile(size_t offset, const DexFile& dex_file); 124 size_t SizeOf() const; 125 void UpdateChecksum(OatHeader& oat_header) const; 126 bool Write(OatWriter* oat_writer, OutputStream& out, const size_t file_offset) const; 127 128 // Offset of start of OatDexFile from beginning of OatHeader. It is 129 // used to validate file position when writing. 130 size_t offset_; 131 132 // data to write 133 uint32_t dex_file_location_size_; 134 const uint8_t* dex_file_location_data_; 135 uint32_t dex_file_location_checksum_; 136 uint32_t dex_file_offset_; 137 std::vector<uint32_t> methods_offsets_; 138 139 private: 140 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 141 }; 142 143 class OatClass { 144 public: 145 explicit OatClass(size_t offset, mirror::Class::Status status, uint32_t methods_count); 146 size_t GetOatMethodOffsetsOffsetFromOatHeader(size_t class_def_method_index_) const; 147 size_t GetOatMethodOffsetsOffsetFromOatClass(size_t class_def_method_index_) const; 148 size_t SizeOf() const; 149 void UpdateChecksum(OatHeader& oat_header) const; 150 bool Write(OatWriter* oat_writer, OutputStream& out, const size_t file_offset) const; 151 152 // Offset of start of OatClass from beginning of OatHeader. It is 153 // used to validate file position when writing. For Portable, it 154 // is also used to calculate the position of the OatMethodOffsets 155 // so that code pointers within the OatMethodOffsets can be 156 // patched to point to code in the Portable .o ELF objects. 157 size_t offset_; 158 159 // data to write 160 mirror::Class::Status status_; 161 std::vector<OatMethodOffsets> method_offsets_; 162 163 private: 164 DISALLOW_COPY_AND_ASSIGN(OatClass); 165 }; 166 167 const CompilerDriver* const compiler_driver_; 168 169 // note OatFile does not take ownership of the DexFiles 170 const std::vector<const DexFile*>* dex_files_; 171 172 // Size required for Oat data structures. 173 size_t size_; 174 175 // dependencies on the image. 176 uint32_t image_file_location_oat_checksum_; 177 uint32_t image_file_location_oat_begin_; 178 std::string image_file_location_; 179 180 // data to write 181 OatHeader* oat_header_; 182 std::vector<OatDexFile*> oat_dex_files_; 183 std::vector<OatClass*> oat_classes_; 184 UniquePtr<const std::vector<uint8_t> > interpreter_to_interpreter_bridge_; 185 UniquePtr<const std::vector<uint8_t> > interpreter_to_compiled_code_bridge_; 186 UniquePtr<const std::vector<uint8_t> > jni_dlsym_lookup_; 187 UniquePtr<const std::vector<uint8_t> > portable_resolution_trampoline_; 188 UniquePtr<const std::vector<uint8_t> > portable_to_interpreter_bridge_; 189 UniquePtr<const std::vector<uint8_t> > quick_resolution_trampoline_; 190 UniquePtr<const std::vector<uint8_t> > quick_to_interpreter_bridge_; 191 192 // output stats 193 uint32_t size_dex_file_alignment_; 194 uint32_t size_executable_offset_alignment_; 195 uint32_t size_oat_header_; 196 uint32_t size_oat_header_image_file_location_; 197 uint32_t size_dex_file_; 198 uint32_t size_interpreter_to_interpreter_bridge_; 199 uint32_t size_interpreter_to_compiled_code_bridge_; 200 uint32_t size_jni_dlsym_lookup_; 201 uint32_t size_portable_resolution_trampoline_; 202 uint32_t size_portable_to_interpreter_bridge_; 203 uint32_t size_quick_resolution_trampoline_; 204 uint32_t size_quick_to_interpreter_bridge_; 205 uint32_t size_trampoline_alignment_; 206 uint32_t size_code_size_; 207 uint32_t size_code_; 208 uint32_t size_code_alignment_; 209 uint32_t size_mapping_table_; 210 uint32_t size_vmap_table_; 211 uint32_t size_gc_map_; 212 uint32_t size_oat_dex_file_location_size_; 213 uint32_t size_oat_dex_file_location_data_; 214 uint32_t size_oat_dex_file_location_checksum_; 215 uint32_t size_oat_dex_file_offset_; 216 uint32_t size_oat_dex_file_methods_offsets_; 217 uint32_t size_oat_class_status_; 218 uint32_t size_oat_class_method_offsets_; 219 220 // Code mappings for deduplication. Deduplication is already done on a pointer basis by the 221 // compiler driver, so we can simply compare the pointers to find out if things are duplicated. 222 SafeMap<const std::vector<uint8_t>*, uint32_t> code_offsets_; 223 SafeMap<const std::vector<uint8_t>*, uint32_t> vmap_table_offsets_; 224 SafeMap<const std::vector<uint8_t>*, uint32_t> mapping_table_offsets_; 225 SafeMap<const std::vector<uint8_t>*, uint32_t> gc_map_offsets_; 226 227 DISALLOW_COPY_AND_ASSIGN(OatWriter); 228 }; 229 230 } // namespace art 231 232 #endif // ART_COMPILER_OAT_WRITER_H_ 233