diff options
author | simonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-23 17:40:08 +0000 |
---|---|---|
committer | simonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-23 17:40:08 +0000 |
commit | 2a1f90bd7eacc953459f338e42845a25d4e76a58 (patch) | |
tree | ff1055a0f281a606585a80cf0f719c9bb4e085fb /third_party/android_crazy_linker | |
parent | d2ec2a2c511e09697e7bbf78ffba21b797c874d4 (diff) | |
download | chromium_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.chromium | 2 | ||||
-rw-r--r-- | third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.cpp | 51 |
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__ |