Home | History | Annotate | Download | only in compiler
      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