Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright (C) 2014 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_ELF_PATCHER_H_
     18 #define ART_COMPILER_ELF_PATCHER_H_
     19 
     20 #include "base/mutex.h"
     21 #include "driver/compiler_driver.h"
     22 #include "elf_file.h"
     23 #include "mirror/art_method.h"
     24 #include "mirror/class.h"
     25 #include "mirror/object.h"
     26 #include "oat_file.h"
     27 #include "oat.h"
     28 #include "os.h"
     29 
     30 namespace art {
     31 
     32 class ElfPatcher {
     33  public:
     34   typedef void* (*ImageAddressCallback)(void* data, mirror::Object* obj);
     35 
     36   static bool Patch(const CompilerDriver* driver, ElfFile* elf_file,
     37                     const std::string& oat_location,
     38                     ImageAddressCallback cb, void* cb_data,
     39                     std::string* error_msg)
     40       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     41 
     42   static bool Patch(const CompilerDriver* driver, ElfFile* elf_file,
     43                     const OatFile* oat_file, uintptr_t oat_data_begin,
     44                     ImageAddressCallback cb, void* cb_data,
     45                     std::string* error_msg)
     46       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     47 
     48   static bool Patch(const CompilerDriver* driver, ElfFile* elf_file,
     49                     const std::string& oat_location,
     50                     std::string* error_msg)
     51       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     52     return ElfPatcher::Patch(driver, elf_file, oat_location,
     53                              DefaultImageAddressCallback, nullptr, error_msg);
     54   }
     55 
     56   static bool Patch(const CompilerDriver* driver, ElfFile* elf_file,
     57                     const OatFile* oat_file, uintptr_t oat_data_begin,
     58                     std::string* error_msg)
     59       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     60     return ElfPatcher::Patch(driver, elf_file, oat_file, oat_data_begin,
     61                              DefaultImageAddressCallback, nullptr, error_msg);
     62   }
     63 
     64  private:
     65   ElfPatcher(const CompilerDriver* driver, ElfFile* elf_file, const OatFile* oat_file,
     66              OatHeader* oat_header, uintptr_t oat_data_begin,
     67              ImageAddressCallback cb, void* cb_data, std::string* error_msg)
     68       : compiler_driver_(driver), elf_file_(elf_file), oat_file_(oat_file),
     69         oat_header_(oat_header), oat_data_begin_(oat_data_begin), get_image_address_(cb),
     70         cb_data_(cb_data), error_msg_(error_msg),
     71         write_patches_(compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {}
     72   ~ElfPatcher() {}
     73 
     74   static void* DefaultImageAddressCallback(void* data_unused, mirror::Object* obj) {
     75     return static_cast<void*>(obj);
     76   }
     77 
     78   bool PatchElf()
     79       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     80 
     81   mirror::ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch)
     82       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     83 
     84   mirror::Class* GetTargetType(const CompilerDriver::TypePatchInformation* patch)
     85       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     86   mirror::String* GetTargetString(const CompilerDriver::StringPatchInformation* patch)
     87       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     88 
     89   void AddPatch(uintptr_t off);
     90 
     91   void SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value)
     92       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     93 
     94   // Takes the pointer into the oat_file_ and get the pointer in to the ElfFile.
     95   uint32_t* GetPatchLocation(uintptr_t patch_ptr);
     96 
     97   bool WriteOutPatchData();
     98 
     99   uintptr_t GetBaseAddressFor(const OatFile* f) {
    100     if (f == oat_file_) {
    101       return oat_data_begin_;
    102     } else {
    103       return reinterpret_cast<uintptr_t>(f->Begin());
    104     }
    105   }
    106 
    107   const CompilerDriver* compiler_driver_;
    108 
    109   // The elf_file containing the oat_data we are patching up
    110   ElfFile* elf_file_;
    111 
    112   // The oat_file that is actually loaded.
    113   const OatFile* oat_file_;
    114 
    115   // The oat_header_ within the elf_file_
    116   OatHeader* oat_header_;
    117 
    118   // Where the elf_file will be loaded during normal runs.
    119   uintptr_t oat_data_begin_;
    120 
    121   // Callback to get image addresses.
    122   ImageAddressCallback get_image_address_;
    123   void* cb_data_;
    124 
    125   std::string* error_msg_;
    126   std::vector<uintptr_t> patches_;
    127   std::set<uintptr_t> patches_set_;
    128   bool write_patches_;
    129 
    130   DISALLOW_COPY_AND_ASSIGN(ElfPatcher);
    131 };
    132 
    133 }  // namespace art
    134 #endif  // ART_COMPILER_ELF_PATCHER_H_
    135