Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3442)

Unified Diff: base/android/linker/crazy_linker/include/crazy_linker.h

Issue 23717023: Android: Add chrome-specific dynamic linker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename library Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/android/linker/crazy_linker/include/crazy_linker.h
diff --git a/base/android/linker/crazy_linker/include/crazy_linker.h b/base/android/linker/crazy_linker/include/crazy_linker.h
new file mode 100644
index 0000000000000000000000000000000000000000..827db39e3e6aac7a9de48b1641ec711778bba5b2
--- /dev/null
+++ b/base/android/linker/crazy_linker/include/crazy_linker.h
@@ -0,0 +1,238 @@
+// 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_H
+#define CRAZY_LINKER_H
+
+// This is the crazy linker, a custom dynamic linker that can be used
+// by NDK applications to load shared libraries (not executables) with
+// a twist.
+//
+// Compared to the dynamic linker, the crazy one has the following
+// features:
+//
+// - It can use an arbitrary search path.
+//
+// - It can load a library at a memory fixed address.
+//
+// - It can share the RELRO section between two libraries
+// loaded at the same address in two distinct processes.
+//
+#include <dlfcn.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Function attribute to indicate that it needs to be exported by
+// the library.
+#define _CRAZY_PUBLIC __attribute__((__visibility__("default")))
+
+// Status values returned by crazy linker functions to indicate
+// success or failure. They were chosen to match boolean values,
+// this allows one to test for failures with:
+//
+// if (!crazy_linker_function(....)) {
+// ... an error occured.
+// }
+//
+// If the function called used a crazy_context_t, it is possible to
+// retrieve the error details with crazy_context_get_error().
+typedef enum {
+ CRAZY_STATUS_KO = 0,
+ CRAZY_STATUS_OK = 1
+} crazy_status_t;
+
+// Opaque handle to a context object that will hold parameters
+// for the crazy linker's operations. For example, this is where
+// you would set the explicit load address, and other user-provided
+// values before calling functions like crazy_linker_load().
+//
+// The context holds a list of library search paths, initialized to
+// the content of the LD_LIBRARY_PATH variable on creation.
+//
+// The context also holds a string buffer to hold error messages that
+// can be queried with crazy_context_get_error().
+typedef struct crazy_context_t crazy_context_t;
+
+// Create a new context object.
+crazy_context_t* crazy_context_create(void) _CRAZY_PUBLIC;
+
+// Return current error string, or NULL if there was no error.
+const char* crazy_context_get_error(crazy_context_t* context)
+ _CRAZY_PUBLIC;
+
+// Clear error in a given context.
+void crazy_context_clear_error(crazy_context_t* context)
+ _CRAZY_PUBLIC;
+
+// Set the explicit load address in a context object. Value 0 means
+// the address is randomized.
+void crazy_context_set_load_address(crazy_context_t* context,
+ size_t load_address) _CRAZY_PUBLIC;
+
+// Return the current load address in a context.
+size_t crazy_context_get_load_address(crazy_context_t* context)
+ _CRAZY_PUBLIC;
+
+// Set the explicit file offset in a context object. The value should
+// always page-aligned, or the load will fail.
+void crazy_context_set_file_offset(crazy_context_t* context,
+ size_t file_offset) _CRAZY_PUBLIC;
+
+// Return the current file offset in a context object.
+size_t crazy_context_get_file_offset(crazy_context_t* context);
+
+// Add one or more paths to the list of library search paths held
+// by a given context. |path| is a string using a column (:) as a
+// list separator. As with the PATH variable, an empty list item
+// is equivalent to '.', the current directory.
+// This can fail if too many paths are added to the context.
+crazy_status_t crazy_context_add_search_path(crazy_context_t* context,
+ const char* file_path)
+ _CRAZY_PUBLIC;
+
+// Find the ELF binary that contains |address|, and add its directory
+// path to the context's list of search directories. This is useful to
+// load libraries in the same directory than the current program itself.
+crazy_status_t crazy_context_add_search_path_for_address(
+ crazy_context_t* context,
+ void* address) _CRAZY_PUBLIC;
+
+// Reset the search paths to the value of the LD_LIBRARY_PATH
+// environment variable.
+void crazy_context_reset_search_paths(crazy_context_t* context)
+ _CRAZY_PUBLIC;
+
+// Destroy a given context object.
+void crazy_context_destroy(crazy_context_t* context) _CRAZY_PUBLIC;
+
+// Opaque handle to a library as seen/loaded by the crazy linker.
+typedef struct crazy_library_t crazy_library_t;
+
+// Try to open or load a library with the crazy linker.
+// |lib_name| if the library name or path. If it contains a directory
+// separator (/), this is treated as a explicit file path, otherwise
+// it is treated as a base name, and the context's search path list
+// will be used to locate the corresponding file.
+// |context| is a linker context handle. Can be NULL for defaults.
+// On success, return CRAZY_STATUS_OK and sets |*library|.
+// Libraries are reference-counted, trying to open the same library
+// twice will return the same library handle.
+//
+// NOTE: The load address and file offset from the context only apply
+// to the library being loaded (when not already in the process). If the
+// operations needs to load any dependency libraries, these will use
+// offset and address values of 0 to do so.
+//
+// NOTE: It is possible to open system libraries (e.g. "libc.so")
+// with this function. If the library is already in the process,
+// a proper crazy_library_t handle will be returned for it. If the
+// system library is not loaded yet, it will be loaded through
+// dlopen() instead of the crazy linker.
+crazy_status_t crazy_library_open(crazy_library_t** library,
+ const char* lib_name,
+ crazy_context_t* context)
+ _CRAZY_PUBLIC;
+
+// A structure used to hold information about a given library.
+// |load_address| is the library's actual (page-aligned) load address.
+// |load_size| is the library's actual (page-aligned) size.
+// |relro_start| is the address of the library's RELRO section in memory.
+// |relso_size| is the size of the library's RELRO section (or 0 if none).
+// |relro_fd| is the ashmem file descriptor for the shared section, or -1.
+typedef struct {
+ size_t load_address;
+ size_t load_size;
+ size_t relro_start;
+ size_t relro_size;
+ int relro_fd;
+} crazy_library_info_t;
+
+// Retrieve information about a given library.
+// |library| is a library handle.
+// |context| will get an error message on failure.
+// On success, return true and sets |*info|.
+// Note that this function will fail for system libraries.
+crazy_status_t crazy_library_get_info(crazy_library_t* library,
+ crazy_context_t* context,
+ crazy_library_info_t* info);
+
+
+// Enable RELRO section sharing for this library. This can only be
+// called once per library loaded through crazy_library_open(), and
+// will only work for non-system libraries.
+// On success, return CRAZY_STATUS_OK and sets |*library_info| with
+// all relevant data. On failure, return CRAZY_STATUS_KO and sets
+// the error message in |context|.
+crazy_status_t crazy_library_enable_relro_sharing(
+ crazy_library_t* library,
+ crazy_context_t* context) _CRAZY_PUBLIC;
+
+// Use the shared RELRO section of the same library loaded in a different
+// address space. On success, return CRAZY_STATUS_OK and owns |relro_fd|.
+// On failure, return CRAZY_STATUS_KO and sets error message in |context|.
+// |library| is the library handle.
+// |relro_start| is the address of the RELRO section in memory.
+// |relro_size| is the size of the RELRO section.
+// |relro_fd| is the file descriptor for the shared RELRO ashmem region.
+// |context| will receive an error in case of failure.
+// NOTE: This will fail if this is a system library, or if the RELRO
+// parameters do not match the library's actual load address.
+crazy_status_t crazy_library_use_relro_sharing(
+ crazy_library_t* library,
+ size_t relro_start,
+ size_t relro_size,
+ int relro_fd,
+ crazy_context_t* context) _CRAZY_PUBLIC;
+
+// Look for a library named |library_name| in the set of currently
+// loaded libraries, and return a handle for it in |*library| on success.
+// Note that this increments the reference count on the library, thus
+// the caller shall call crazy_library_close() when it's done with it.
+crazy_status_t crazy_library_find_by_name(const char* library_name,
+ crazy_library_t** library);
+
+// Find the library that contains a given |address| in memory.
+// On success, return CRAZY_STATUS_OK and sets |*library|.
+crazy_status_t crazy_linker_find_library_from_address(
+ void* address, crazy_library_t** library) _CRAZY_PUBLIC;
+
+// Lookup a symbol's address by its |symbol_name| in a given library.
+// This only looks at the symbols in |library|.
+// On success, returns CRAZY_STATUS_OK and sets |*symbol_address|,
+// which could be NULL for some symbols.
+crazy_status_t crazy_library_find_symbol(
+ crazy_library_t* library,
+ const char* symbol_name,
+ void** symbol_address) _CRAZY_PUBLIC;
+
+// Lookup a symbol's address in all libraries known by the crazy linker.
+// |symbol_name| is the symbol name. On success, returns CRAZY_STATUS_OK
+// and sets |*symbol_address|.
+// NOTE: This will _not_ look into system libraries that were not opened
+// with the crazy linker.
+crazy_status_t crazy_linker_find_symbol(
+ const char* symbol_name,
+ void** symbol_address) _CRAZY_PUBLIC;
+
+// Find the in-process library that contains a given memory address.
+// Note that this works even if the memory is inside a system library that
+// was not previously opened with crazy_library_open().
+// |address| is the memory address.
+// On success, returns CRAZY_STATUS_OK and sets |*library|.
+// The caller muyst call crazy_library_close() once it's done with the
+// library.
+crazy_status_t crazy_library_find_from_address(
+ void* address, crazy_library_t** library) _CRAZY_PUBLIC;
+
+// Close a library. This decrements its reference count. If it reaches
+// zero, the library be unloaded from the process.
+void crazy_library_close(crazy_library_t* library) _CRAZY_PUBLIC;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CRAZY_LINKER_H */

Powered by Google App Engine
This is Rietveld 408576698