summaryrefslogtreecommitdiffstats
path: root/third_party/android_crazy_linker
diff options
context:
space:
mode:
authorsimonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-23 17:40:08 +0000
committersimonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-23 17:40:08 +0000
commit2a1f90bd7eacc953459f338e42845a25d4e76a58 (patch)
treeff1055a0f281a606585a80cf0f719c9bb4e085fb /third_party/android_crazy_linker
parentd2ec2a2c511e09697e7bbf78ffba21b797c874d4 (diff)
downloadchromium_src-2a1f90bd7eacc953459f338e42845a25d4e76a58.zip
chromium_src-2a1f90bd7eacc953459f338e42845a25d4e76a58.tar.gz
chromium_src-2a1f90bd7eacc953459f338e42845a25d4e76a58.tar.bz2
Fix MIPS breakage introduced when adding support for arm64.
MIPS shared libraries lack a DT_PLTREL, but current code insists on seeing either DT_REL or DT_RELA. This stops the crazy linker from working correctly on MIPS: /LibraryLoader( 4421): Loading: chromium_android_linker I/LibraryLoader( 4421): Loading: chrome.2056.0 E/chromium_android_linker( 4421): LoadLibrary: Could not open libchrome.2056.0.so: Unsupported or missing DT_PLTREL in dynamic section Remove the requirement for relocations_type_ to be set by DT_PLTREL. If not set by DT_PLTREL then assign based on the presence of either DT_REL or DT_RELA. BUG=386594 Review URL: https://codereview.chromium.org/343933002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279134 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/android_crazy_linker')
-rw-r--r--third_party/android_crazy_linker/README.chromium2
-rw-r--r--third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp51
2 files changed, 35 insertions, 18 deletions
diff --git a/third_party/android_crazy_linker/README.chromium b/third_party/android_crazy_linker/README.chromium
index e843964..ad87dc6 100644
--- a/third_party/android_crazy_linker/README.chromium
+++ b/third_party/android_crazy_linker/README.chromium
@@ -30,3 +30,5 @@ index 5fa16df..bc03739 100644
(Re-add license header to crazy_linker_elf_view.cpp)
- Fix for crbug/373695 (NDK crazy linker: Bug in library file name handling)
+
+- Fix for crbug/386594 (Crazy linker fails to load a browser on MIPS)
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 591a1fd..a8d1629 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
@@ -242,11 +242,20 @@ bool ElfRelocations::Init(const ElfView* view, Error* error) {
}
}
- if (relocations_type_ != DT_REL && relocations_type_ != DT_RELA) {
- *error = "Unsupported or missing DT_PLTREL in dynamic section";
+ if (has_rel_relocations && has_rela_relocations) {
+ *error = "Combining DT_REL and DT_RELA is not currently supported";
return false;
}
+ // If DT_PLTREL did not explicitly assign relocations_type_, set it
+ // here based on the type of relocations found.
+ if (relocations_type_ != DT_REL && relocations_type_ != DT_RELA) {
+ if (has_rel_relocations)
+ relocations_type_ = DT_REL;
+ else if (has_rela_relocations)
+ relocations_type_ = DT_RELA;
+ }
+
if (relocations_type_ == DT_REL && has_rela_relocations) {
*error = "Found DT_RELA in dyn section, but DT_PLTREL is DT_REL";
return false;
@@ -286,7 +295,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,
@@ -578,13 +587,16 @@ bool ElfRelocations::ApplyRelRelocs(const ELF::Rel* rel,
// If this is a symbolic relocation, compute the symbol's address.
if (__builtin_expect(rel_symbol != 0, 0)) {
- resolved = ResolveSymbol(rel_type,
- rel_symbol,
- symbols,
- resolver,
- reloc,
- &sym_addr,
- error);
+ if (!ResolveSymbol(rel_type,
+ rel_symbol,
+ symbols,
+ resolver,
+ reloc,
+ &sym_addr,
+ error)) {
+ return false;
+ }
+ resolved = true;
}
if (!ApplyRelReloc(rel, sym_addr, resolved, error))
@@ -625,13 +637,16 @@ bool ElfRelocations::ApplyRelaRelocs(const ELF::Rela* rela,
// If this is a symbolic relocation, compute the symbol's address.
if (__builtin_expect(rel_symbol != 0, 0)) {
- resolved = ResolveSymbol(rel_type,
- rel_symbol,
- symbols,
- resolver,
- reloc,
- &sym_addr,
- error);
+ if (!ResolveSymbol(rel_type,
+ rel_symbol,
+ symbols,
+ resolver,
+ reloc,
+ &sym_addr,
+ error)) {
+ return false;
+ }
+ resolved = true;
}
if (!ApplyRelaReloc(rela, sym_addr, resolved, error))
@@ -803,7 +818,7 @@ void ElfRelocations::CopyAndRelocate(size_t src_addr,
if (relocations_type_ == DT_REL)
RelocateRel(src_addr, dst_addr, map_addr, size);
- else if (relocations_type_ == DT_RELA)
+ if (relocations_type_ == DT_RELA)
RelocateRela(src_addr, dst_addr, map_addr, size);
#ifdef __mips__