diff options
author | Alex Light <allight@google.com> | 2014-08-06 13:37:23 -0700 |
---|---|---|
committer | Alex Light <allight@google.com> | 2014-08-06 15:12:32 -0700 |
commit | 4b0d2d99b596eebd6da45679896d3af54bc5a935 (patch) | |
tree | 9c5f70398324b53edb47d1819648618f58ca24e4 /patchoat | |
parent | 484e2c2d3531e5bb36f0e1e12f26c708939c6579 (diff) | |
download | art-4b0d2d99b596eebd6da45679896d3af54bc5a935.zip art-4b0d2d99b596eebd6da45679896d3af54bc5a935.tar.gz art-4b0d2d99b596eebd6da45679896d3af54bc5a935.tar.bz2 |
Make patchoat use the sht_entsize when patching.
This fixes an occasional problem with multiarch use of patchoat.
Change-Id: I80799de36774720bd985704f9b709a8378bb5af5
Diffstat (limited to 'patchoat')
-rw-r--r-- | patchoat/patchoat.cc | 40 | ||||
-rw-r--r-- | patchoat/patchoat.h | 5 |
2 files changed, 30 insertions, 15 deletions
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index 72189c3..eed20da 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -466,16 +466,13 @@ bool PatchOat::Patch(File* input_oat, off_t delta, File* output_oat, TimingLogge return true; } -bool PatchOat::CheckOatFile() { - Elf32_Shdr* patches_sec = oat_file_->FindSectionByName(".oat_patches"); - if (patches_sec == nullptr) { - return false; - } - if (patches_sec->sh_type != SHT_OAT_PATCH) { +template <typename ptr_t> +bool PatchOat::CheckOatFile(const Elf32_Shdr& patches_sec) { + if (patches_sec.sh_type != SHT_OAT_PATCH) { return false; } - uintptr_t* patches = reinterpret_cast<uintptr_t*>(oat_file_->Begin() + patches_sec->sh_offset); - uintptr_t* patches_end = patches + (patches_sec->sh_size/sizeof(uintptr_t)); + ptr_t* patches = reinterpret_cast<ptr_t*>(oat_file_->Begin() + patches_sec.sh_offset); + ptr_t* patches_end = patches + (patches_sec.sh_size / sizeof(ptr_t)); Elf32_Shdr* oat_data_sec = oat_file_->FindSectionByName(".rodata"); Elf32_Shdr* oat_text_sec = oat_file_->FindSectionByName(".text"); if (oat_data_sec == nullptr) { @@ -599,10 +596,28 @@ bool PatchOat::PatchTextSection() { LOG(ERROR) << ".oat_patches section not found. Aborting patch"; return false; } - DCHECK(CheckOatFile()) << "Oat file invalid"; - CHECK_EQ(patches_sec->sh_type, SHT_OAT_PATCH) << "Unexpected type of .oat_patches"; - uintptr_t* patches = reinterpret_cast<uintptr_t*>(oat_file_->Begin() + patches_sec->sh_offset); - uintptr_t* patches_end = patches + (patches_sec->sh_size/sizeof(uintptr_t)); + if (patches_sec->sh_type != SHT_OAT_PATCH) { + LOG(ERROR) << "Unexpected type of .oat_patches"; + return false; + } + + switch (patches_sec->sh_entsize) { + case sizeof(uint32_t): + return PatchTextSection<uint32_t>(*patches_sec); + case sizeof(uint64_t): + return PatchTextSection<uint64_t>(*patches_sec); + default: + LOG(ERROR) << ".oat_patches Entsize of " << patches_sec->sh_entsize << "bits " + << "is not valid"; + return false; + } +} + +template <typename ptr_t> +bool PatchOat::PatchTextSection(const Elf32_Shdr& patches_sec) { + DCHECK(CheckOatFile<ptr_t>(patches_sec)) << "Oat file invalid"; + ptr_t* patches = reinterpret_cast<ptr_t*>(oat_file_->Begin() + patches_sec.sh_offset); + ptr_t* patches_end = patches + (patches_sec.sh_size / sizeof(ptr_t)); Elf32_Shdr* oat_text_sec = oat_file_->FindSectionByName(".text"); CHECK(oat_text_sec != nullptr); byte* to_patch = oat_file_->Begin() + oat_text_sec->sh_offset; @@ -614,7 +629,6 @@ bool PatchOat::PatchTextSection() { CHECK_LT(reinterpret_cast<uintptr_t>(patch_loc), to_patch_end); *patch_loc += delta_; } - return true; } diff --git a/patchoat/patchoat.h b/patchoat/patchoat.h index 6960d3b..326333e 100644 --- a/patchoat/patchoat.h +++ b/patchoat/patchoat.h @@ -74,11 +74,12 @@ class PatchOat { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool InHeap(mirror::Object*); - bool CheckOatFile(); - // Patches oat in place, modifying the oat_file given to the constructor. bool PatchElf(); bool PatchTextSection(); + // Templatized version to actually do the patching with the right sized offsets. + template <typename ptr_t> bool PatchTextSection(const Elf32_Shdr& patches_sec); + template <typename ptr_t> bool CheckOatFile(const Elf32_Shdr& patches_sec); bool PatchOatHeader(); bool PatchSymbols(Elf32_Shdr* section); |