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

Unified Diff: third_party/crazy_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: Rebase to fix build. 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: third_party/crazy_linker/crazy_linker/include/crazy_linker.h
diff --git a/third_party/crazy_linker/crazy_linker/include/crazy_linker.h b/third_party/crazy_linker/crazy_linker/include/crazy_linker.h
new file mode 100644
index 0000000000000000000000000000000000000000..9462b59c0916d502ee1274a3cae68926b29488ba
--- /dev/null
+++ b/third_party/crazy_linker/crazy_linker/include/crazy_linker.h
@@ -0,0 +1,273 @@
+// 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, or from a fixed
+// file offset (both must be page-aligned).
+//
+// - 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_FAILURE = 0,
+ CRAZY_STATUS_SUCCESS = 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_library_open().
+//
+// 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.
+// Note that this calls crazy_context_reset_search_paths().
+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.
+//
+// NOTE: Calling this function appends new paths to the search list,
+// but all paths added with this function will be searched before
+// the ones listed in LD_LIBRARY_PATH.
+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. This essentially removes any paths
+// that were added with crazy_context_add_search_path() or
+// crazy_context_add_search_path_for_address().
+void crazy_context_reset_search_paths(crazy_context_t* context) _CRAZY_PUBLIC;
+
+// Record the value of |java_vm| inside of |context|. If this is not NULL,
+// which is the default, then after loading any library, the crazy linker
+// will look for a "JNI_OnLoad" symbol within it, and, if it exists, will call
+// it, passing the value of |java_vm| to it. If the function returns with
+// a jni version number that is smaller than |minimum_jni_version|, then
+// the library load will fail with an error.
+//
+// The |java_vm| field is also saved in the crazy_library_t object, and
+// used at unload time to call JNI_OnUnload() if it exists.
+void crazy_context_set_java_vm(crazy_context_t* context,
+ void* java_vm,
+ int minimum_jni_version);
+
+// Retrieves the last values set with crazy_context_set_java_vm().
+// A value of NUMM in |*java_vm| means the feature is disabled.
+void crazy_context_get_java_vm(crazy_context_t* context,
+ void** java_vm,
+ int* minimum_jni_version);
+
+// 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_SUCCESS 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 NDK system libraries (e.g. "liblog.so")
+// with this function, but they will be loaded with the system dlopen().
+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, if one
+// was created with crazy_library_enable_relro_sharing(), -1 otherwise.
+typedef struct {
+ size_t load_address;
+ size_t load_size;
+ size_t relro_start;
+ size_t relro_size;
+} 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);
+
+// Checks whether the system can support RELRO section sharing. This is
+// mainly due to the fact that old Android kernel images have a bug in their
+// implementation of Ashmem region mapping protection.
+// If this function returns CRAZY_STATUS_FAILURE, then calls to
+// crazy_library_enable_relro_sharing() will return a failure to prevent
+// the exploitation of this security issue in your code.
+crazy_status_t crazy_system_can_share_relro(void);
+
+// Create an ashmem region containing a copy of the RELRO section for a given
+// |library|. This can be used with crazy_library_use_shared_relro().
+// |load_address| can be specified as non-0 to ensure that the content of the
+// ashmem region corresponds to a RELRO relocated for a new load address.
+// on success, return CRAZY_STATUS_SUCCESS and sets |*relro_start| to the
+// start of the RELRO section in memory, |*relro_size| to its size in bytes
+// and |*relro_fd| to a file descriptor to a read-only ashmem region containing
+// the data. On failure, return false and set error message in |context|.
+// NOTE: On success, the caller becomes the owner of |*relro_fd| and is shall
+// close it appropriately.
+crazy_status_t crazy_library_create_shared_relro(crazy_library_t* library,
+ crazy_context_t* context,
+ size_t load_address,
+ size_t* relro_start,
+ size_t* relro_size,
+ int* relro_fd) _CRAZY_PUBLIC;
+
+// Use the shared RELRO section of the same library loaded in a different
+// address space. On success, return CRAZY_STATUS_SUCCESS and owns |relro_fd|.
+// On failure, return CRAZY_STATUS_FAILURE 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.
+// NOTE: The caller is responsible for closing the file descriptor after this
+// call.
+crazy_status_t crazy_library_use_shared_relro(crazy_library_t* library,
+ crazy_context_t* context,
+ size_t relro_start,
+ size_t relro_size,
+ int relro_fd) _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_SUCCESS 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_SUCCESS 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_SUCCESS
+// 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_SUCCESS 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