Index: third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp |
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp |
index e01649992cd40104afaaf7b436c6c25071f3a173..c41bf5fc0c13b78873036f01696296e3097aae91 100644 |
--- a/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp |
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp |
@@ -58,6 +58,14 @@ |
#define DT_PREINIT_ARRAYSZ 33 |
#endif |
+// Processor-specific extension dynamic tags for packed relocations. |
+#ifdef __arm__ |
+ |
+#define DT_ANDROID_ARM_REL_OFFSET (DT_LOPROC) |
+#define DT_ANDROID_ARM_REL_SIZE (DT_LOPROC + 1) |
+ |
+#endif // __arm__ |
+ |
namespace crazy { |
namespace { |
@@ -148,6 +156,40 @@ class SharedLibraryResolver : public ElfRelocations::SymbolResolver { |
Vector<LibraryView*>* dependencies_; |
}; |
+#ifdef __arm__ |
+ |
+// Read an .android.rel.dyn ARM packed relocations section. |
+// Returns an allocated buffer holding the data, or NULL on error. |
+uint8_t* ReadArmPackedRelocs(const char* full_path, |
+ off_t offset, |
+ size_t bytes, |
+ Error* error) { |
+ uint8_t* packed_data = new uint8_t[bytes]; |
+ |
+ FileDescriptor fd; |
+ if (!fd.OpenReadOnly(full_path)) { |
+ error->Format("Error opening file '%s'", full_path); |
+ delete [] packed_data; |
+ return NULL; |
+ } |
+ if (fd.SeekTo(offset) == -1) { |
+ error->Format("Error seeking to %d in file '%s'", offset, full_path); |
+ delete [] packed_data; |
+ return NULL; |
+ } |
+ const ssize_t bytes_read = fd.Read(packed_data, bytes); |
+ if (bytes_read != bytes) { |
+ error->Format("Error reading %d bytes from file '%s'", bytes, full_path); |
+ delete [] packed_data; |
+ return NULL; |
+ } |
+ fd.Close(); |
+ |
+ return packed_data; |
+} |
+ |
+#endif // __arm__ |
+ |
} // namespace |
SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); } |
@@ -156,6 +198,10 @@ SharedLibrary::~SharedLibrary() { |
// Ensure the library is unmapped on destruction. |
if (view_.load_address()) |
munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size()); |
+ |
+#ifdef __arm__ |
+ delete [] arm_packed_relocs_; |
rmcilroy
2014/06/19 10:49:44
I think you could still use your ScopedBuffer clas
simonb (inactive)
2014/06/23 14:51:32
Done.
|
+#endif |
} |
bool SharedLibrary::Load(const char* full_path, |
@@ -209,6 +255,9 @@ bool SharedLibrary::Load(const char* full_path, |
LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_); |
(void)phdr_table_get_arm_exidx( |
phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_); |
+ |
+ off_t arm_packed_relocs_offset = 0; |
+ size_t arm_packed_relocs_size = 0; |
#endif |
LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_); |
@@ -269,6 +318,16 @@ bool SharedLibrary::Load(const char* full_path, |
if (dyn_value & DF_SYMBOLIC) |
has_DT_SYMBOLIC_ = true; |
break; |
+#if defined(__arm__) |
+ case DT_ANDROID_ARM_REL_OFFSET: |
+ arm_packed_relocs_offset = dyn.GetOffset(); |
+ LOG(" DT_ANDROID_ARM_REL_OFFSET addr=%p\n", arm_packed_relocs_offset); |
+ break; |
+ case DT_ANDROID_ARM_REL_SIZE: |
+ arm_packed_relocs_size = dyn.GetValue(); |
+ LOG(" DT_ANDROID_ARM_REL_SIZE=%d\n", arm_packed_relocs_size); |
+ break; |
+#endif |
#if defined(__mips__) |
case DT_MIPS_RLD_MAP: |
*dyn.GetValuePointer() = |
@@ -280,6 +339,29 @@ bool SharedLibrary::Load(const char* full_path, |
} |
} |
+#ifdef __arm__ |
+ // If ARM packed relocations are present in the target library, read the |
+ // section data and save it in arm_packed_relocs_. |
+ if (arm_packed_relocs_offset && arm_packed_relocs_size) { |
+ LOG("%s: ARM packed relocations found at offset %d, %d bytes\n", |
+ __FUNCTION__, |
+ arm_packed_relocs_offset, |
+ arm_packed_relocs_size); |
+ |
+ arm_packed_relocs_ = |
+ ReadArmPackedRelocs(full_path, |
+ arm_packed_relocs_offset + file_offset, |
+ arm_packed_relocs_size, |
+ error); |
+ if (!arm_packed_relocs_) |
+ return false; |
+ |
+ LOG("%s: ARM packed relocations stored at %p\n", |
+ __FUNCTION__, |
+ arm_packed_relocs_); |
+ } |
+#endif |
+ |
LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_); |
return true; |
} |
@@ -299,6 +381,13 @@ bool SharedLibrary::Relocate(LibraryList* lib_list, |
if (!relocations.ApplyAll(&symbols_, &resolver, error)) |
return false; |
+#ifdef __arm__ |
+ // If present, also apply ARM packed relocations. |
+ if (arm_packed_relocs_ && |
+ !relocations.ApplyArmPackedRelocs(arm_packed_relocs_, error)) |
+ return false; |
rmcilroy
2014/06/19 10:49:43
I'm not sure the PackedRelocs really fits well in
simonb (inactive)
2014/06/23 14:51:32
Addressed by moving ApplyArmPackedRelocs() inside
|
+#endif |
+ |
LOG("%s: Relocations applied for %s\n", __FUNCTION__, base_name_); |
return true; |
} |