crazy_linker_library_list.cpp revision 116680a4aac90f2aa7413d9095a592090648e557
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_library_list.h" 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <dlfcn.h> 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_debug.h" 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_library_view.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_globals.h" 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_rdebug.h" 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_shared_library.h" 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_system.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "crazy_linker_util.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "crazy_linker_zip.h" 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace crazy { 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace { 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// A helper struct used when looking up symbols in libraries. 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)struct SymbolLookupState { 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* found_addr; 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* weak_addr; 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int weak_count; 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SymbolLookupState() : found_addr(NULL), weak_addr(NULL), weak_count(0) {} 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Check a symbol entry. 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool CheckSymbol(const char* symbol, SharedLibrary* lib) { 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* entry = lib->LookupSymbolEntry(symbol); 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!entry) 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* address = reinterpret_cast<void*>(lib->load_bias() + entry->st_value); 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If this is a strong symbol, record it and return true. 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (ELF_ST_BIND(entry->st_info) == STB_GLOBAL) { 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) found_addr = address; 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If this is a weak symbol, record the first one and 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // increment the weak_count. 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (++weak_count == 1) 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_addr = address; 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LibraryList::LibraryList() : head_(0), count_(0), has_error_(false) { 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Nothing for now 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LibraryList::~LibraryList() { 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Invalidate crazy library list. 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) head_ = NULL; 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Destroy all known libraries. 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (!known_libraries_.IsEmpty()) { 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = known_libraries_.PopLast(); 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) delete wrap; 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LibraryView* LibraryList::FindLibraryByName(const char* lib_name) { 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Sanity check. 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!lib_name) 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < known_libraries_.GetCount(); ++n) { 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = known_libraries_[n]; 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!strcmp(lib_name, wrap->GetName())) 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return wrap; 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void* LibraryList::FindSymbolFrom(const char* symbol_name, LibraryView* from) { 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SymbolLookupState lookup_state; 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!from) 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Use a work-queue and a set to ensure to perform a breadth-first 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // search. 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector<LibraryView*> work_queue; 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Set<LibraryView*> visited_set; 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) work_queue.PushBack(from); 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (!work_queue.IsEmpty()) { 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* lib = work_queue.PopFirst(); 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib->IsCrazy()) { 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lookup_state.CheckSymbol(symbol_name, lib->GetCrazy())) 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return lookup_state.found_addr; 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (lib->IsSystem()) { 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(digit): Support weak symbols in system libraries. 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // With the current code, all symbols in system libraries 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // are assumed to be non-weak. 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* addr = lib->LookupSymbol(symbol_name); 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (addr) 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return addr; 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If this is a crazy library, add non-visited dependencies 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // to the work queue. 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib->IsCrazy()) { 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary::DependencyIterator iter(lib->GetCrazy()); 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (iter.GetNext()) { 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* dependency = FindKnownLibrary(iter.GetName()); 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (dependency && !visited_set.Has(dependency)) { 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) work_queue.PushBack(dependency); 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) visited_set.Add(dependency); 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lookup_state.weak_count >= 1) { 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // There was at least a single weak symbol definition, so use 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the first one found in breadth-first search order. 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return lookup_state.weak_addr; 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // There was no symbol definition. 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LibraryView* LibraryList::FindLibraryForAddress(void* address) { 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Linearly scan all libraries, looking for one that contains 135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // a given address. NOTE: This doesn't check that this falls 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // inside one of the mapped library segments. 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < known_libraries_.GetCount(); ++n) { 138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = known_libraries_[n]; 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(digit): Search addresses inside system libraries. 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (wrap->IsCrazy()) { 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary* lib = wrap->GetCrazy(); 142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib->ContainsAddress(address)) 143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return wrap; 144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifdef __arm__ 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)_Unwind_Ptr LibraryList::FindArmExIdx(void* pc, int* count) { 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (SharedLibrary* lib = head_; lib; lib = lib->list_next_) { 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib->ContainsAddress(pc)) { 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *count = static_cast<int>(lib->arm_exidx_count_); 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return reinterpret_cast<_Unwind_Ptr>(lib->arm_exidx_); 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *count = 0; 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else // !__arm__ 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int LibraryList::IteratePhdr(PhdrIterationCallback callback, void* data) { 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int result = 0; 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (SharedLibrary* lib = head_; lib; lib = lib->list_next_) { 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dl_phdr_info info; 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.dlpi_addr = lib->link_map_.l_addr; 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.dlpi_name = lib->link_map_.l_name; 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.dlpi_phdr = lib->phdr(); 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.dlpi_phnum = lib->phdr_count(); 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = callback(&info, sizeof(info), data); 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (result) 171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return result; 174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif // !__arm__ 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void LibraryList::UnloadLibrary(LibraryView* wrap) { 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Sanity check. 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: for %s (ref_count=%d)\n", 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) __FUNCTION__, 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) wrap->GetName(), 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) wrap->ref_count()); 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!wrap->IsSystem() && !wrap->IsCrazy()) 185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!wrap->SafeDecrementRef()) 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If this is a crazy library, perform manual cleanup first. 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (wrap->IsCrazy()) { 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary* lib = wrap->GetCrazy(); 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Remove from internal list of crazy libraries. 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib->list_next_) 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->list_next_->list_prev_ = lib->list_prev_; 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib->list_prev_) 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->list_prev_->list_next_ = lib->list_next_; 199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib == head_) 200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) head_ = lib->list_next_; 201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Call JNI_OnUnload, if necessary, then the destructors. 203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->CallJniOnUnload(); 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->CallDestructors(); 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Unload the dependencies recursively. 207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary::DependencyIterator iter(lib); 208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (iter.GetNext()) { 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* dependency = FindKnownLibrary(iter.GetName()); 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (dependency) 211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UnloadLibrary(dependency); 212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Tell GDB of this removal. 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Globals::GetRDebug()->DelEntry(&lib->link_map_); 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) known_libraries_.Remove(wrap); 219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Delete the wrapper, which will delete the crazy library, or 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // dlclose() the system one. 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) delete wrap; 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LibraryView* LibraryList::LoadLibrary(const char* lib_name, 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int dlopen_mode, 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t load_address, 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) off_t file_offset, 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SearchPathList* search_path_list, 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error* error) { 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* base_name = GetBaseNamePtr(lib_name); 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: lib_name='%s'\n", __FUNCTION__, lib_name); 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // First check whether a library with the same base name was 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // already loaded. 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = FindKnownLibrary(lib_name); 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (wrap) { 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (load_address) { 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Check that this is a crazy library and that is was loaded at 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the correct address. 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!wrap->IsCrazy()) { 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("System library can't be loaded at fixed address %08x", 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) load_address); 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t actual_address = wrap->GetCrazy()->load_address(); 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (actual_address != load_address) { 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("Library already loaded at @%08x, can't load it at @%08x", 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) actual_address, 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) load_address); 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) wrap->AddRef(); 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return wrap; 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (IsSystemLibrary(lib_name)) { 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // This is a system library, probably because we're loading the 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // library as a dependency. 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Loading system library '%s'\n", __FUNCTION__, lib_name); 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ::dlerror(); 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* system_lib = dlopen(lib_name, dlopen_mode); 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!system_lib) { 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("Can't load system library %s: %s", lib_name, ::dlerror()); 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = new LibraryView(); 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) wrap->SetSystem(system_lib, lib_name); 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) known_libraries_.PushBack(wrap); 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: System library %s loaded at %p\n", __FUNCTION__, lib_name, wrap); 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" name=%s\n", wrap->GetName()); 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return wrap; 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScopedPtr<SharedLibrary> lib(new SharedLibrary()); 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Find the full library path. 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String full_path; 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!strchr(lib_name, '/')) { 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Looking through the search path list\n", __FUNCTION__); 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* path = search_path_list->FindFile(lib_name); 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!path) { 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("Can't find library file %s", lib_name); 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) full_path = path; 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (lib_name[0] != '/') { 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Need to transform this into a full path. 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) full_path = GetCurrentDirectory(); 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (full_path.size() && full_path[full_path.size() - 1] != '/') 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) full_path += '/'; 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) full_path += lib_name; 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Absolute path. Easy. 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) full_path = lib_name; 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Full library path: %s\n", __FUNCTION__, full_path.c_str()); 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!PathIsFile(full_path.c_str())) { 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("Library file doesn't exist: %s", full_path.c_str()); 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Load the library 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!lib->Load(full_path.c_str(), load_address, file_offset, error)) 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Load all dependendent libraries. 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Loading dependencies of %s\n", __FUNCTION__, base_name); 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedLibrary::DependencyIterator iter(lib.Get()); 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector<LibraryView*> dependencies; 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (iter.GetNext()) { 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Error dep_error; 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* dependency = LoadLibrary(iter.GetName(), 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dlopen_mode, 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0U /* load address */, 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0U /* file offset */, 325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_path_list, 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &dep_error); 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!dependency) { 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error->Format("When loading %s: %s", base_name, dep_error.c_str()); 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dependencies.PushBack(dependency); 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (CRAZY_DEBUG) { 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Dependencies loaded for %s\n", __FUNCTION__, base_name); 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < dependencies.GetCount(); ++n) 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" ... %p %s\n", dependencies[n], dependencies[n]->GetName()); 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(" dependencies @%p\n", &dependencies); 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Relocate the library. 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Relocating %s\n", __FUNCTION__, base_name); 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!lib->Relocate(this, &dependencies, error)) 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Notify GDB of load. 346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->link_map_.l_addr = lib->load_address(); 347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->link_map_.l_name = const_cast<char*>(lib->base_name_); 348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->link_map_.l_ld = reinterpret_cast<uintptr_t>(lib->view_.dynamic()); 349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Globals::GetRDebug()->AddEntry(&lib->link_map_); 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The library was properly loaded, add it to the list of crazy 352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // libraries. IMPORTANT: Do this _before_ calling the constructors 353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // because these could call dlopen(). 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->list_next_ = head_; 355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->list_prev_ = NULL; 356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (head_) 357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) head_->list_prev_ = lib.Get(); 358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) head_ = lib.Get(); 359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Then create a new LibraryView for it. 361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) wrap = new LibraryView(); 362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) wrap->SetCrazy(lib.Get(), lib_name); 363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) known_libraries_.PushBack(wrap); 364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Running constructors for %s\n", __FUNCTION__, base_name); 366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Now run the constructors. 368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib->CallConstructors(); 369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG("%s: Done loading %s\n", __FUNCTION__, base_name); 371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) lib.Release(); 372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return wrap; 374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// We identify the abi tag for which the linker is running. This allows 377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// us to select the library which matches the abi of the linker. 378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(__arm__) && defined(__ARM_ARCH_7A__) 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CURRENT_ABI "armeabi-v7a" 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#elif defined(__arm__) 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CURRENT_ABI "armeabi" 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#elif defined(__i386__) 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CURRENT_ABI "x86" 385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#elif defined(__mips__) 386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CURRENT_ABI "mips" 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#elif defined(__x86_64__) 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CURRENT_ABI "x86_64" 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#elif defined(__aarch64__) 390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CURRENT_ABI "arm64-v8a" 391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#error "Unsupported target abi" 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kMaxFilenameInZip = 256; 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst size_t kPageSize = 4096; 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 398116680a4aac90f2aa7413d9095a592090648e557Ben MurdochLibraryView* LibraryList::LoadLibraryInZipFile(const char* zip_file_path, 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* lib_name, 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int dlopen_flags, 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uintptr_t load_address, 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SearchPathList* search_path_list, 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Error* error) { 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch String fullname; 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fullname.Reserve(kMaxFilenameInZip); 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fullname = "lib/"; 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fullname += CURRENT_ABI; 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fullname += "/crazy."; 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fullname += lib_name; 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (fullname.size() + 1 > kMaxFilenameInZip) { 412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->Format("Filename too long for a file in a zip file %s\n", 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fullname.c_str()); 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int offset = FindStartOffsetOfFileInZipFile(zip_file_path, fullname.c_str()); 418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (offset == -1) { 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((offset & (kPageSize - 1)) != 0) { 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->Format("Library %s is not page aligned in zipfile %s\n", 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch lib_name, zip_file_path); 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return LoadLibrary( 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zip_file_path, dlopen_flags, load_address, offset, 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch search_path_list, error); 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void LibraryList::AddLibrary(LibraryView* wrap) { 434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) known_libraries_.PushBack(wrap); 435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LibraryView* LibraryList::FindKnownLibrary(const char* name) { 438f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* base_name = GetBaseNamePtr(name); 439f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < known_libraries_.GetCount(); ++n) { 440f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LibraryView* wrap = known_libraries_[n]; 441f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!strcmp(base_name, wrap->GetName())) 442f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return wrap; 443f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 445f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 446f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 447f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace crazy 448