summaryrefslogtreecommitdiffstats
path: root/patchoat
diff options
context:
space:
mode:
authorAlex Light <allight@google.com>2014-08-06 13:37:23 -0700
committerAlex Light <allight@google.com>2014-08-06 15:12:32 -0700
commit4b0d2d99b596eebd6da45679896d3af54bc5a935 (patch)
tree9c5f70398324b53edb47d1819648618f58ca24e4 /patchoat
parent484e2c2d3531e5bb36f0e1e12f26c708939c6579 (diff)
downloadart-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.cc40
-rw-r--r--patchoat/patchoat.h5
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);