| Index: third_party/android_crazy_linker/src/tests/test_search_path_list.cpp
|
| diff --git a/third_party/android_crazy_linker/src/tests/test_search_path_list.cpp b/third_party/android_crazy_linker/src/tests/test_search_path_list.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..17ffa5809dcd06bf44f84a543f8e8e83ba00cd3b
|
| --- /dev/null
|
| +++ b/third_party/android_crazy_linker/src/tests/test_search_path_list.cpp
|
| @@ -0,0 +1,134 @@
|
| +// 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.
|
| +
|
| +// A crazy linker test to check that paths added with
|
| +// crazy_context_add_search_path() or
|
| +// crazy_context_add_search_path_from_address()
|
| +// have higher priority than the default ones (from LD_LIBRARY_PATH).
|
| +//
|
| +// This requires creating two temporary directories and placing there libraries
|
| +// with the same name, but different content
|
| +//
|
| +// $TMPDIR1/libfoo.so -> a copy of libfoo.so that contains the 'Foo' symbol.
|
| +// $TMPDIR2/libfoo.so -> a copy of libfoo2.so that contains the 'Foo2'
|
| +// symbol.
|
| +//
|
| +
|
| +#include <crazy_linker.h>
|
| +
|
| +#include "test_util.h"
|
| +
|
| +namespace {
|
| +
|
| +void CheckLibraryCantLoad(const char* library_name, crazy_context_t* context) {
|
| + crazy_library_t* library;
|
| +
|
| + if (crazy_library_open(&library, library_name, context))
|
| + Panic("Could load library %s, expected this not to be possible\n",
|
| + library_name);
|
| +}
|
| +
|
| +// Loads a library named |library_name| and checks that it contains
|
| +// the symbols listed in |wanted_symbols|, and none of the symbols
|
| +// listed in |unwanted_symbols|. After that, close the library and exit.
|
| +//
|
| +// Both |wanted_symbols| and |unwanted_symbols| are NULL-terminated
|
| +// arrays of strings.
|
| +void CheckLibrary(const char* library_name,
|
| + const char* const* wanted_symbols,
|
| + const char* const* unwanted_symbols,
|
| + crazy_context_t* context) {
|
| + crazy_library_t* library;
|
| +
|
| + if (!crazy_library_open(&library, library_name, context))
|
| + Panic("Could not open library %s: %s\n", crazy_context_get_error(context));
|
| +
|
| + size_t failures = 0;
|
| +
|
| + if (wanted_symbols) {
|
| + for (; *wanted_symbols; ++wanted_symbols) {
|
| + const char* symbol_name = *wanted_symbols;
|
| + void* symbol_addr;
|
| + if (!crazy_library_find_symbol(library, symbol_name, &symbol_addr)) {
|
| + fprintf(stderr,
|
| + "Could not find symbol '%s' in library '%s'!\n",
|
| + symbol_name,
|
| + library_name);
|
| + failures += 1;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (unwanted_symbols) {
|
| + for (; *unwanted_symbols; ++unwanted_symbols) {
|
| + const char* symbol_name = *unwanted_symbols;
|
| + void* symbol_addr;
|
| + if (crazy_library_find_symbol(library, symbol_name, &symbol_addr)) {
|
| + fprintf(stderr,
|
| + "Found symbol '%s' in library '%s', none expected!\n",
|
| + symbol_name,
|
| + library_name);
|
| + failures += 1;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (failures > 0)
|
| + Panic("Found %d symbol failures in library %s\n", failures, library_name);
|
| +
|
| + crazy_library_close(library);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +int main() {
|
| + String exe_path = GetCurrentExecutableDirectory();
|
| +
|
| + TempDirectory temp_dir_1;
|
| + TempDirectory temp_dir_2;
|
| +
|
| + // List of symbols in original libfoo.so and libfoo2.so, respectively.
|
| + static const char* const kFooSymbols[] = {"Foo", NULL};
|
| + static const char* const kFoo2Symbols[] = {"Foo2", NULL};
|
| +
|
| + // Copy libfoo.so to $TMPDIR1/libfoo.so
|
| + CopyFile("libfoo.so", exe_path.c_str(), "libfoo.so", temp_dir_1.path());
|
| +
|
| + // Copy libfoo2.so to $TMPDIR2/libfoo.so
|
| + CopyFile("libfoo2.so", exe_path.c_str(), "libfoo.so", temp_dir_2.path());
|
| +
|
| + // Create a new context object.
|
| + crazy_context_t* context = crazy_context_create();
|
| + crazy_library_t* library;
|
| +
|
| + // Reset search paths to a non-existing directory. Check that the library
|
| + // can't be loaded.
|
| + setenv("LD_LIBRARY_PATH", "/this-directory-does-not-exist", 1);
|
| + crazy_context_reset_search_paths(context);
|
| + CheckLibraryCantLoad("libfoo.so", context);
|
| +
|
| + // Add the search path to the current executable, this should load the
|
| + // original
|
| + // libfoo.so.
|
| + crazy_context_add_search_path_for_address(context, (void*)&main);
|
| + CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context);
|
| +
|
| + // Reset search paths to use $TMPDIR2 then $TMPDIR1
|
| + setenv("LD_LIBRARY_PATH", temp_dir_1.path(), 1);
|
| + crazy_context_reset_search_paths(context);
|
| + crazy_context_add_search_path(context, temp_dir_2.path());
|
| +
|
| + // Check that the copy of libfoo2.so is loaded.
|
| + CheckLibrary("libfoo.so", kFoo2Symbols, kFooSymbols, context);
|
| +
|
| + // Reset search paths to use only $TMPDIR1
|
| + crazy_context_reset_search_paths(context);
|
| +
|
| + // Check that the copy of libfoo.so is loaded.
|
| + CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context);
|
| +
|
| + crazy_context_destroy(context);
|
| +
|
| + return 0;
|
| +}
|
|
|