Chromium Code Reviews| 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; |
| } |