| Index: third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h
|
| diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8ce381e915a667b4ce94a27db84fb7dde1dc08a1
|
| --- /dev/null
|
| +++ b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h
|
| @@ -0,0 +1,208 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CRAZY_LINKER_SHARED_LIBRARY_H
|
| +#define CRAZY_LINKER_SHARED_LIBRARY_H
|
| +
|
| +#include <link.h>
|
| +
|
| +#include "crazy_linker_elf_relro.h"
|
| +#include "crazy_linker_elf_symbols.h"
|
| +#include "crazy_linker_elf_view.h"
|
| +#include "crazy_linker_error.h"
|
| +#include "crazy_linker_rdebug.h"
|
| +#include "crazy_linker_util.h"
|
| +#include "elf_traits.h"
|
| +
|
| +namespace crazy {
|
| +
|
| +class LibraryList;
|
| +class LibraryView;
|
| +
|
| +// A class that models a shared library loaded by the crazy linker.
|
| +
|
| +// Libraries have dependencies (which are listed in their dynamic section
|
| +// as DT_NEEDED entries). Circular dependencies are forbidden, so they
|
| +// form an ADG, where the root is the crazy linker itself, since all
|
| +// libraries that it loads will depend on it (to ensure their
|
| +// dlopen/dlsym/dlclose calls are properly wrapped).
|
| +
|
| +class SharedLibrary {
|
| + public:
|
| + SharedLibrary();
|
| + ~SharedLibrary();
|
| +
|
| + size_t load_address() const { return view_.load_address(); }
|
| + size_t load_size() const { return view_.load_size(); }
|
| + size_t load_bias() const { return view_.load_bias(); }
|
| + const ELF::Phdr* phdr() const { return view_.phdr(); }
|
| + size_t phdr_count() const { return view_.phdr_count(); }
|
| + const char* base_name() const { return base_name_; }
|
| +
|
| + // Load a library (without its dependents) from an ELF file.
|
| + // Note: This does not apply relocations, nor runs constructors.
|
| + // |full_path| if the file full path.
|
| + // |load_address| is the page-aligned load address in memory, or 0.
|
| + // |file_offset| is the page-aligned file offset.
|
| + // On failure, return false and set |error| message.
|
| + //
|
| + // After this, the caller should load all library dependencies,
|
| + // Then call Relocate() and CallConstructors() to complete the
|
| + // operation.
|
| + bool Load(const char* full_path,
|
| + size_t load_address,
|
| + size_t file_offset,
|
| + Error* error);
|
| +
|
| + // Relocate this library, assuming all its dependencies are already
|
| + // loaded in |lib_list|. On failure, return false and set |error|
|
| + // message.
|
| + bool Relocate(LibraryList* lib_list,
|
| + Vector<LibraryView*>* dependencies,
|
| + Error* error);
|
| +
|
| + void GetInfo(size_t* load_address,
|
| + size_t* load_size,
|
| + size_t* relro_start,
|
| + size_t* relro_size) {
|
| + *load_address = view_.load_address();
|
| + *load_size = view_.load_size();
|
| + *relro_start = relro_start_;
|
| + *relro_size = relro_size_;
|
| + }
|
| +
|
| + // Returns true iff a given library is mapped to a virtual address range
|
| + // that contains a given address.
|
| + bool ContainsAddress(void* address) const {
|
| + size_t addr = reinterpret_cast<size_t>(address);
|
| + return load_address() <= addr && addr <= load_address() + load_size();
|
| + }
|
| +
|
| + // Call all constructors in the library.
|
| + void CallConstructors();
|
| +
|
| + // Call all destructors in the library.
|
| + void CallDestructors();
|
| +
|
| + // Return the ELF symbol entry for a given symbol, if defined by
|
| + // this library, or NULL otherwise.
|
| + const ELF::Sym* LookupSymbolEntry(const char* symbol_name);
|
| +
|
| + // Find the nearest symbol near a given |address|. On success, return
|
| + // true and set |*sym_name| to the symbol name, |*sym_addr| to its address
|
| + // in memory, and |*sym_size| to its size in bytes, if any.
|
| + bool FindNearestSymbolForAddress(void* address,
|
| + const char** sym_name,
|
| + void** sym_addr,
|
| + size_t* sym_size) {
|
| + return symbols_.LookupNearestByAddress(
|
| + address, load_bias(), sym_name, sym_addr, sym_size);
|
| + }
|
| +
|
| + // Return the address of a given |symbol_name| if it is exported
|
| + // by the library, NULL otherwise.
|
| + void* FindAddressForSymbol(const char* symbol_name);
|
| +
|
| + // Create a new Ashmem region holding a copy of the library's RELRO section,
|
| + // potentially relocated for a new |load_address|. On success, return true
|
| + // and sets |*relro_start|, |*relro_size| and |*relro_fd|. Note that the
|
| + // RELRO start address is adjusted for |load_address|, and that the caller
|
| + // becomes the owner of |*relro_fd|. On failure, return false and set
|
| + // |error| message.
|
| + bool CreateSharedRelro(size_t load_address,
|
| + size_t* relro_start,
|
| + size_t* relro_size,
|
| + int* relro_fd,
|
| + Error* error);
|
| +
|
| + // Try to use a shared relro section from another process.
|
| + // On success, return true. On failure return false and
|
| + // sets |error| message.
|
| + bool UseSharedRelro(size_t relro_start,
|
| + size_t relro_size,
|
| + int relro_fd,
|
| + Error* error);
|
| +
|
| + // Look for a symbol named 'JNI_OnLoad' in this library, and if it
|
| + // exists, call it with |java_vm| as the first parameter. If the
|
| + // function result is less than |minimum_jni_version|, fail with
|
| + // a message in |error|. On success, return true, and record
|
| + // |java_vm| to call 'JNI_OnUnload' at unload time, if present.
|
| + bool SetJavaVM(void* java_vm, int minimum_jni_version, Error* error);
|
| +
|
| + // Call 'JNI_OnUnload()' is necessary, i.e. if there was a succesful call
|
| + // to SetJavaVM() before. This will pass the same |java_vm| value to the
|
| + // callback, if it is present in the library.
|
| + void CallJniOnUnload();
|
| +
|
| + // Helper class to iterate over dependencies in a given SharedLibrary.
|
| + // Usage:
|
| + // SharedLibary::DependencyIterator iter(lib);
|
| + // while (iter.GetNext() {
|
| + // dependency_name = iter.GetName();
|
| + // ...
|
| + // }
|
| + class DependencyIterator {
|
| + public:
|
| + DependencyIterator(SharedLibrary* lib)
|
| + : iter_(&lib->view_), symbols_(&lib->symbols_), dep_name_(NULL) {}
|
| +
|
| + bool GetNext();
|
| +
|
| + const char* GetName() const { return dep_name_; }
|
| +
|
| + private:
|
| + DependencyIterator();
|
| + DependencyIterator(const DependencyIterator&);
|
| + DependencyIterator& operator=(const DependencyIterator&);
|
| +
|
| + ElfView::DynamicIterator iter_;
|
| + const ElfSymbols* symbols_;
|
| + const char* dep_name_;
|
| + };
|
| +
|
| + typedef void (*linker_function_t)();
|
| +
|
| + private:
|
| + friend class LibraryList;
|
| +
|
| + ElfView view_;
|
| + ElfSymbols symbols_;
|
| +
|
| + size_t relro_start_;
|
| + size_t relro_size_;
|
| + bool relro_used_;
|
| +
|
| + SharedLibrary* list_next_;
|
| + SharedLibrary* list_prev_;
|
| + unsigned flags_;
|
| +
|
| + linker_function_t* preinit_array_;
|
| + size_t preinit_array_count_;
|
| + linker_function_t* init_array_;
|
| + size_t init_array_count_;
|
| + linker_function_t* fini_array_;
|
| + size_t fini_array_count_;
|
| + linker_function_t init_func_;
|
| + linker_function_t fini_func_;
|
| +
|
| +#ifdef __arm__
|
| + // ARM EABI section used for stack unwinding.
|
| + unsigned* arm_exidx_;
|
| + size_t arm_exidx_count_;
|
| +#endif
|
| +
|
| + link_map_t link_map_;
|
| +
|
| + bool has_DT_SYMBOLIC_;
|
| +
|
| + void* java_vm_;
|
| +
|
| + const char* base_name_;
|
| + char full_path_[512];
|
| +};
|
| +
|
| +} // namespace crazy
|
| +
|
| +#endif // CRAZY_LINKER_SHARED_LIBRARY_H
|
|
|