1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_shared_library.h" 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <dlfcn.h> 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdlib.h> 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <sys/mman.h> 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <elf.h> 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_ashmem.h" 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_debug.h" 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_elf_loader.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_elf_relocations.h" 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_library_list.h" 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_library_view.h" 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_globals.h" 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_memory_mapping.h" 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_thread.h" 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_util.h" 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_wrappers.h" 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "linker_phdr.h" 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DF_SYMBOLIC 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DF_SYMBOLIC 2 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DF_TEXTREL 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DF_TEXTREL 4 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_INIT_ARRAY 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_INIT_ARRAY 25 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_INIT_ARRAYSZ 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_INIT_ARRAYSZ 27 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_FINI_ARRAY 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_FINI_ARRAY 26 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_FINI_ARRAYSZ 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_FINI_ARRAYSZ 28 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_FLAGS 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_FLAGS 30 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_PREINIT_ARRAY 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_PREINIT_ARRAY 32 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef DT_PREINIT_ARRAYSZ 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DT_PREINIT_ARRAYSZ 33 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef DT_LOOS 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define DT_LOOS 0x6000000d 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Extension dynamic tags for packed relocations. 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define DT_ANDROID_REL_OFFSET (DT_LOOS) 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define DT_ANDROID_REL_SIZE (DT_LOOS + 1) 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // __arm__ || __aarch64__ 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace crazy { 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace { 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)typedef SharedLibrary::linker_function_t linker_function_t; 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)typedef int (*JNI_OnLoadFunctionPtr)(void* vm, void* reserved); 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)typedef void (*JNI_OnUnloadFunctionPtr)(void* vm, void* reserved); 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Call a constructor or destructor function pointer. Ignore 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// NULL and -1 values intentionally. They correspond to markers 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// in the tables, or deleted values. 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// |func_type| corresponds to the type of the function, and is only 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// used for debugging (examples are "DT_INIT", "DT_INIT_ARRAY", etc...). 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void CallFunction(linker_function_t func, const char* func_type) { 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t func_address = reinterpret_cast<uintptr_t>(func); 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: %p %s\n", __FUNCTION__, func, func_type); 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (func_address != 0 && func_address != uintptr_t(-1)) 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) func(); 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// An instance of ElfRelocator::SymbolResolver that can be used 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// to resolve symbols in a shared library being loaded by 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// LibraryList::LoadLibrary. 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class SharedLibraryResolver : public ElfRelocations::SymbolResolver { 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibraryResolver(SharedLibrary* lib, 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryList* lib_list, 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector<LibraryView*>* dependencies) 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : lib_(lib), dependencies_(dependencies) {} 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void* Lookup(const char* symbol_name) { 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(digit): Add the ability to lookup inside the main executable. 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // First, look inside the current library. 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* entry = lib_->LookupSymbolEntry(symbol_name); 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (entry) 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return reinterpret_cast<void*>(lib_->load_bias() + entry->st_value); 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Special case: redirect the dynamic linker symbols to our wrappers. 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // This ensures that loaded libraries can call dlopen() / dlsym() 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // and transparently use the crazy linker to perform their duty. 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* address = WrapLinkerSymbol(symbol_name); 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (address) 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return address; 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Then look inside the dependencies. 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < dependencies_->GetCount(); ++n) { 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = (*dependencies_)[n]; 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // LOG("%s: Looking into dependency %p (%s)\n", __FUNCTION__, wrap, 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // wrap->GetName()); 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (wrap->IsSystem()) { 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) address = ::dlsym(wrap->GetSystem(), symbol_name); 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifdef __arm__ 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Android libm.so defines isnanf as weak. This means that its 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // address cannot be found by dlsym(), which always returns NULL 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // for weak symbols. However, libm.so contains the real isnanf 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // as __isnanf. If we encounter isnanf and fail to resolve it in 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // libm.so, retry with __isnanf. 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // This occurs only in clang, which lacks __builtin_isnanf. The 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // gcc compiler implements isnanf as a builtin, so the symbol 135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // isnanf never need be resolved in gcc builds. 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // http://code.google.com/p/chromium/issues/detail?id=376828 138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!address && 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !strcmp(symbol_name, "isnanf") && 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !strcmp(wrap->GetName(), "libm.so")) 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) address = ::dlsym(wrap->GetSystem(), "__isnanf"); 142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (address) 144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return address; 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (wrap->IsCrazy()) { 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary* dep = wrap->GetCrazy(); 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry = dep->LookupSymbolEntry(symbol_name); 149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (entry) 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return reinterpret_cast<void*>(dep->load_bias() + entry->st_value); 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Nothing found here. 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary* lib_; 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector<LibraryView*>* dependencies_; 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Helper class to provide a simple scoped buffer. ScopedPtr is not 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// usable here because it calls delete, not delete []. 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ScopedBuffer { 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit ScopedBuffer(size_t bytes) : buffer_(new uint8_t[bytes]) { } 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~ScopedBuffer() { delete [] buffer_; } 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8_t* Get() { return buffer_; } 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8_t* Release() { 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8_t* ptr = buffer_; 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch buffer_ = NULL; 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ptr; 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8_t* buffer_; 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Read an .android.rel.dyn packed relocations section. 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Returns an allocated buffer holding the data, or NULL on error. 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)uint8_t* ReadPackedRelocations(const char* full_path, 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) off_t offset, 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t bytes, 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Error* error) { 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileDescriptor fd; 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!fd.OpenReadOnly(full_path)) { 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->Format("Error opening file '%s'", full_path); 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (fd.SeekTo(offset) == -1) { 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->Format("Error seeking to %d in file '%s'", offset, full_path); 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedBuffer buffer(bytes); 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ssize_t bytes_read = fd.Read(buffer.Get(), bytes); 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (static_cast<size_t>(bytes_read) != bytes) { 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->Format("Error reading %d bytes from file '%s'", bytes, full_path); 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fd.Close(); 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8_t* packed_data = buffer.Release(); 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return packed_data; 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // __arm__ || __aarch64__ 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); } 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SharedLibrary::~SharedLibrary() { 219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Ensure the library is unmapped on destruction. 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (view_.load_address()) 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size()); 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) delete [] packed_relocations_; 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SharedLibrary::Load(const char* full_path, 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t load_address, 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t file_offset, 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error* error) { 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // First, record the path. 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: full path '%s'\n", __FUNCTION__, full_path); 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t full_path_len = strlen(full_path); 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (full_path_len >= sizeof(full_path_)) { 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("Path too long: %s", full_path); 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) strlcpy(full_path_, full_path, sizeof(full_path_)); 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base_name_ = GetBaseNamePtr(full_path_); 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Load the ELF binary in memory. 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Loading ELF segments for %s\n", __FUNCTION__, base_name_); 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) { 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ElfLoader loader; 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!loader.LoadAt(full_path_, file_offset, load_address, error)) { 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!view_.InitUnmapped(loader.load_start(), 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) loader.loaded_phdr(), 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) loader.phdr_count(), 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error)) { 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!symbols_.Init(&view_)) { 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *error = "Missing or malformed symbol table"; 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (phdr_table_get_relro_info(view_.phdr(), 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) view_.phdr_count(), 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) view_.load_bias(), 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &relro_start_, 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &relro_size_) < 0) { 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_start_ = 0; 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_size_ = 0; 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifdef __arm__ 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_); 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (void)phdr_table_get_arm_exidx( 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_); 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) off_t packed_relocations_offset = 0; 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t packed_relocations_size = 0; 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_); 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ElfView::DynamicIterator dyn(&view_); 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (; dyn.HasNext(); dyn.GetNext()) { 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ELF::Addr dyn_value = dyn.GetValue(); 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t dyn_addr = dyn.GetAddress(load_bias()); 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (dyn.GetTag()) { 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_DEBUG: 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (view_.dynamic_flags() & PF_W) { 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *dyn.GetValuePointer() = 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reinterpret_cast<uintptr_t>(Globals::GetRDebug()->GetAddress()); 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_INIT: 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_INIT addr=%p\n", dyn_addr); 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) init_func_ = reinterpret_cast<linker_function_t>(dyn_addr); 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_FINI: 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_FINI addr=%p\n", dyn_addr); 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fini_func_ = reinterpret_cast<linker_function_t>(dyn_addr); 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_INIT_ARRAY: 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_INIT_ARRAY addr=%p\n", dyn_addr); 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) init_array_ = reinterpret_cast<linker_function_t*>(dyn_addr); 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_INIT_ARRAYSZ: 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) init_array_count_ = dyn_value / sizeof(ELF::Addr); 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_INIT_ARRAYSZ value=%p count=%p\n", 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dyn_value, 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) init_array_count_); 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_FINI_ARRAY: 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_FINI_ARRAY addr=%p\n", dyn_addr); 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fini_array_ = reinterpret_cast<linker_function_t*>(dyn_addr); 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_FINI_ARRAYSZ: 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fini_array_count_ = dyn_value / sizeof(ELF::Addr); 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_FINI_ARRAYSZ value=%p count=%p\n", 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dyn_value, 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fini_array_count_); 325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_PREINIT_ARRAY: 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_PREINIT_ARRAY addr=%p\n", dyn_addr); 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) preinit_array_ = reinterpret_cast<linker_function_t*>(dyn_addr); 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_PREINIT_ARRAYSZ: 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) preinit_array_count_ = dyn_value / sizeof(ELF::Addr); 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_PREINIT_ARRAYSZ value=%p count=%p\n", 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dyn_value, 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) preinit_array_count_); 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_SYMBOLIC: 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" DT_SYMBOLIC\n"); 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) has_DT_SYMBOLIC_ = true; 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_FLAGS: 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (dyn_value & DF_SYMBOLIC) 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) has_DT_SYMBOLIC_ = true; 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case DT_ANDROID_REL_OFFSET: 34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_offset = dyn.GetOffset(); 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG(" DT_ANDROID_REL_OFFSET addr=%p\n", packed_relocations_offset); 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case DT_ANDROID_REL_SIZE: 35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_size = dyn.GetValue(); 35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG(" DT_ANDROID_REL_SIZE=%d\n", packed_relocations_size); 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(__mips__) 355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case DT_MIPS_RLD_MAP: 356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *dyn.GetValuePointer() = 357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress()); 358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default: 361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ; 362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 36503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If packed relocations are present in the target library, read the 36703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // section data and save it in packed_relocations_. 36803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (packed_relocations_offset && packed_relocations_size) { 36903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG("%s: Packed relocations found at offset %d, %d bytes\n", 370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch __FUNCTION__, 37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_offset, 37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_size); 37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 37403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_ = 37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ReadPackedRelocations(full_path, 37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_offset + file_offset, 37703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_size, 37803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) error); 37903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!packed_relocations_) 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG("%s: Packed relocations stored at %p\n", 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch __FUNCTION__, 38403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packed_relocations_); 385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_); 389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SharedLibrary::Relocate(LibraryList* lib_list, 393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector<LibraryView*>* dependencies, 394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error* error) { 395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Apply relocations. 396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_); 397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ElfRelocations relocations; 399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relocations.Init(&view_, error)) 401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 402f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(__arm__) || defined(__aarch64__) 40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) relocations.RegisterPackedRelocations(packed_relocations_); 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibraryResolver resolver(this, lib_list, dependencies); 408f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relocations.ApplyAll(&symbols_, &resolver, error)) 409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 411f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Relocations applied for %s\n", __FUNCTION__, base_name_); 412f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const ELF::Sym* SharedLibrary::LookupSymbolEntry(const char* symbol_name) { 416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return symbols_.LookupByName(symbol_name); 417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void* SharedLibrary::FindAddressForSymbol(const char* symbol_name) { 420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return symbols_.LookupAddressByName(symbol_name, view_.load_bias()); 421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 423f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SharedLibrary::CreateSharedRelro(size_t load_address, 424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* relro_start, 425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* relro_size, 426f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int* relro_fd, 427f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error* error) { 428f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedRelro relro; 429f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 430f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relro.Allocate(relro_size_, base_name_, error)) 431f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 432f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (load_address != 0 && load_address != this->load_address()) { 434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Need to relocate the content of the ashmem region first to accomodate 435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // for the new load address. 436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relro.CopyFromRelocated( 437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &view_, load_address, relro_start_, relro_size_, error)) 438f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 439f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 440f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Simply copy, no relocations. 441f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relro.CopyFrom(relro_start_, relro_size_, error)) 442f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 443f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 445f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Enforce read-only mode for the region's content. 446f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relro.ForceReadOnly(error)) 447f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 448f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // All good. 450f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *relro_start = relro.start(); 451f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *relro_size = relro.size(); 452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *relro_fd = relro.DetachFd(); 453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SharedLibrary::UseSharedRelro(size_t relro_start, 457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t relro_size, 458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int relro_fd, 459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error* error) { 460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: relro_start=%p relro_size=%p relro_fd=%d\n", 461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) __FUNCTION__, 462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (void*)relro_start, 463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (void*)relro_size, 464f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_fd); 465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (relro_fd < 0 || relro_size == 0) { 467f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Nothing to do here. 468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 470f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 471f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Sanity check: A shared RELRO is not already used. 472f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (relro_used_) { 473f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *error = "Library already using shared RELRO section"; 474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 476f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Sanity check: RELRO addresses must match. 478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (relro_start_ != relro_start || relro_size_ != relro_size) { 479f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("RELRO mismatch addr=%p size=%p (wanted addr=%p size=%p)", 480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_start_, 481f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_size_, 482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_start, 483f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_size); 484f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 487f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Everything's good, swap pages in this process's address space. 488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedRelro relro; 489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!relro.InitFrom(relro_start, relro_size, relro_fd, error)) 490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 492f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relro_used_ = true; 493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 494f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 495f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 496f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SharedLibrary::CallConstructors() { 497f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CallFunction(init_func_, "DT_INIT"); 498f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < init_array_count_; ++n) 499f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CallFunction(init_array_[n], "DT_INIT_ARRAY"); 500f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 501f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SharedLibrary::CallDestructors() { 503f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = fini_array_count_; n > 0; --n) { 504f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CallFunction(fini_array_[n - 1], "DT_FINI_ARRAY"); 505f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 506f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CallFunction(fini_func_, "DT_FINI"); 507f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 508f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 509f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SharedLibrary::SetJavaVM(void* java_vm, 510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int minimum_jni_version, 511f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error* error) { 512f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (java_vm == NULL) 513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 514f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 515f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Lookup for JNI_OnLoad, exit if it doesn't exist. 516f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) JNI_OnLoadFunctionPtr jni_onload = reinterpret_cast<JNI_OnLoadFunctionPtr>( 517f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FindAddressForSymbol("JNI_OnLoad")); 518f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!jni_onload) 519f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 520f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 521f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int jni_version = (*jni_onload)(java_vm, NULL); 522f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (jni_version < minimum_jni_version) { 523f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("JNI_OnLoad() in %s returned %d, expected at least %d", 524f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) full_path_, 525f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) jni_version, 526f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) minimum_jni_version); 527f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 528f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 529f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 530f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Save the JavaVM handle for unload time. 531f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) java_vm_ = java_vm; 532f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 533f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 534f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 535f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SharedLibrary::CallJniOnUnload() { 536f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!java_vm_) 537f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 538f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 539f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) JNI_OnUnloadFunctionPtr jni_on_unload = 540f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reinterpret_cast<JNI_OnUnloadFunctionPtr>( 541f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this->FindAddressForSymbol("JNI_OnUnload")); 542f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 543f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (jni_on_unload) 544f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (*jni_on_unload)(java_vm_, NULL); 545f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 546f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 547f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SharedLibrary::DependencyIterator::GetNext() { 548f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dep_name_ = NULL; 549f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (; iter_.HasNext(); iter_.GetNext()) { 550f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (iter_.GetTag() == DT_NEEDED) { 551f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dep_name_ = symbols_->GetStringById(iter_.GetValue()); 552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) iter_.GetNext(); 553f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 554f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 556f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 558f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace crazy 560