Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Unified Diff: third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp

Issue 340523003: Support for unpacked ARM packed relocations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fork_switch
Patch Set: Tidy README.chromium Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp
index 591a1fdadd1eb76f8e85beaa10b6b47e5f212117..3be989889b039172288b6d5f5194776a2f2d646c 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp
@@ -10,6 +10,7 @@
#include "crazy_linker_elf_symbols.h"
#include "crazy_linker_elf_view.h"
#include "crazy_linker_error.h"
+#include "crazy_linker_system.h"
#include "crazy_linker_util.h"
#include "linker_phdr.h"
@@ -65,6 +66,14 @@
#endif // __i386__
+// 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)
rmcilroy 2014/06/18 10:56:05 nit - just move this up to the preceding ifdef __a
simonb1 2014/06/18 15:41:28 Moved to crazy_linker_shared_library.cpp in patch
+
+#endif // __arm__
+
namespace crazy {
namespace {
@@ -221,6 +230,16 @@ bool ElfRelocations::Init(const ElfView* view, Error* error) {
has_text_relocations_ ? "true" : "false",
has_symbolic_ ? "true" : "false");
break;
+#if defined(__arm__)
+ case DT_ANDROID_ARM_REL_OFFSET:
+ arm_packed_relocations_ = dyn.GetOffset();
+ RLOG(" DT_ANDROID_ARM_REL_OFFSET addr=%p\n", arm_packed_relocations_);
+ break;
+ case DT_ANDROID_ARM_REL_SIZE:
+ arm_packed_relocations_size_ = dyn.GetValue();
+ RLOG(" DT_ANDROID_ARM_REL_SIZE=%d\n", arm_packed_relocations_size_);
+ break;
+#endif
#if defined(__mips__)
case DT_MIPS_SYMTABNO:
RLOG(" DT_MIPS_SYMTABNO value=%d\n", dyn_value);
@@ -261,6 +280,7 @@ bool ElfRelocations::Init(const ElfView* view, Error* error) {
bool ElfRelocations::ApplyAll(const ElfSymbols* symbols,
SymbolResolver* resolver,
+ const char* full_path CRAZY_UNUSED,
rmcilroy 2014/06/18 10:56:05 Rather than passing the full path here, and having
simonb1 2014/06/18 15:41:28 Done. It's a bit more diffuse, so greater occurre
Error* error) {
LOG("%s: Enter\n", __FUNCTION__);
@@ -286,7 +306,7 @@ bool ElfRelocations::ApplyAll(const ElfSymbols* symbols,
return false;
}
- else if (relocations_type_ == DT_RELA) {
+ if (relocations_type_ == DT_RELA) {
if (!ApplyRelaRelocs(reinterpret_cast<ELF::Rela*>(plt_relocations_),
plt_relocations_size_ / sizeof(ELF::Rela),
symbols,
@@ -301,6 +321,11 @@ bool ElfRelocations::ApplyAll(const ElfSymbols* symbols,
return false;
}
+#ifdef __arm__
+ if (!ApplyArmPackedRelocs(full_path, error))
+ return false;
+#endif
+
#ifdef __mips__
if (!RelocateMipsGot(symbols, resolver, error))
return false;
@@ -641,6 +666,126 @@ bool ElfRelocations::ApplyRelaRelocs(const ELF::Rela* rela,
return true;
}
+#ifdef __arm__
+
+// Helper class for decoding packed ARM relocation data.
+// http://en.wikipedia.org/wiki/LEB128
+class Leb128Decoder {
+ public:
+ explicit Leb128Decoder(const uint8_t* encoding)
+ : encoding_(encoding), cursor_(0) { }
+
+ uint32_t Dequeue() {
+ size_t extent = cursor_;
+ while (encoding_[extent] >> 7)
+ extent++;
+
+ uint32_t value = 0;
+ for (size_t i = extent; i > cursor_; --i) {
+ value = (value << 7) | (encoding_[i] & 127);
+ }
+ value = (value << 7) | (encoding_[cursor_] & 127);
+
+ cursor_ = extent + 1;
+ return value;
+ }
+
+ private:
+ const uint8_t* encoding_;
+ size_t cursor_;
+};
+
+// Helper class to provide a simple scoped buffer. ScopedPtr is not
+// usable here because it calls delete, not delete [].
+class ScopedBuffer {
+ public:
+ explicit ScopedBuffer(size_t bytes) : buffer_(new uint8_t[bytes]) { }
+ ~ScopedBuffer() { delete [] buffer_; }
+
+ uint8_t* Get() { return buffer_; }
+
+ private:
+ uint8_t* buffer_;
+};
+
+bool ElfRelocations::ApplyArmPackedRelocs(const char* full_path,
+ Error* error) {
+ RLOG("%s: packed_relocations=%p, packed_relocations_size=%d\n",
+ __FUNCTION__,
+ arm_packed_relocations_,
+ arm_packed_relocations_size_);
+
+ if (arm_packed_relocations_size_ == 0)
+ return true;
+
+ // Allocate and then read the packed relocations section.
+ ScopedBuffer scoped_packed_data(arm_packed_relocations_size_);
+ uint8_t* packed_data = scoped_packed_data.Get();
+
+ FileDescriptor fd;
+ if (!fd.OpenReadOnly(full_path)) {
+ error->Format("Error opening file '%s'", full_path);
+ return false;
+ }
+ if (fd.SeekTo(arm_packed_relocations_) == -1) {
+ error->Format("Error seeking to %d in file '%s'",
+ arm_packed_relocations_,
+ full_path);
+ return false;
+ }
+ const ssize_t bytes = fd.Read(packed_data, arm_packed_relocations_size_);
+ if (bytes != arm_packed_relocations_size_) {
+ error->Format("Error reading %d bytes from file '%s'",
+ arm_packed_relocations_size_,
+ full_path);
+ return false;
+ }
+ fd.Close();
+
+ Leb128Decoder decoder(packed_data);
+
+ // Check for the initial APR1 header.
+ if (decoder.Dequeue() != 'A' || decoder.Dequeue() != 'P' ||
+ decoder.Dequeue() != 'R' || decoder.Dequeue() != '1') {
+ error->Format("Bad packed relocations ident, expected APR1");
+ return false;
+ }
+
+ // Find the count of pairs and the start address.
+ size_t pairs = decoder.Dequeue();
+ const Elf32_Addr start_address = decoder.Dequeue();
+
+ // Emit initial R_ARM_RELATIVE relocation.
+ Elf32_Rel relocation = {start_address, R_ARM_RELATIVE};
+ const ELF::Addr sym_addr = 0;
+ const bool resolved = false;
+ if (!ApplyRelReloc(&relocation, sym_addr, resolved, error))
+ return false;
+
+ size_t unpacked_count = 1;
+
+ // Emit relocations for each count-delta pair.
+ while (pairs) {
+ size_t count = decoder.Dequeue();
+ const size_t delta = decoder.Dequeue();
+
+ // Emit count R_ARM_RELATIVE relocations with delta offset.
+ while (count) {
+ relocation.r_offset += delta;
+ if (!ApplyRelReloc(&relocation, sym_addr, resolved, error))
+ return false;
+ unpacked_count++;
+ count--;
+ }
+ pairs--;
+ }
+
+ RLOG("%s: unpacked_count=%d\n", __FUNCTION__, unpacked_count);
+ return true;
+}
+
+#endif // __arm__
+
#ifdef __mips__
bool ElfRelocations::RelocateMipsGot(const ElfSymbols* symbols,
SymbolResolver* resolver,

Powered by Google App Engine
This is Rietveld 408576698