1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// A crazy linker test to check that paths added with 6// crazy_context_add_search_path() or 7// crazy_context_add_search_path_from_address() 8// have higher priority than the default ones (from LD_LIBRARY_PATH). 9// 10// This requires creating two temporary directories and placing there libraries 11// with the same name, but different content 12// 13// $TMPDIR1/libfoo.so -> a copy of libfoo.so that contains the 'Foo' symbol. 14// $TMPDIR2/libfoo.so -> a copy of libfoo2.so that contains the 'Foo2' 15// symbol. 16// 17 18#include <crazy_linker.h> 19 20#include "test_util.h" 21 22namespace { 23 24void CheckLibraryCantLoad(const char* library_name, crazy_context_t* context) { 25 crazy_library_t* library; 26 27 if (crazy_library_open(&library, library_name, context)) 28 Panic("Could load library %s, expected this not to be possible\n", 29 library_name); 30} 31 32// Loads a library named |library_name| and checks that it contains 33// the symbols listed in |wanted_symbols|, and none of the symbols 34// listed in |unwanted_symbols|. After that, close the library and exit. 35// 36// Both |wanted_symbols| and |unwanted_symbols| are NULL-terminated 37// arrays of strings. 38void CheckLibrary(const char* library_name, 39 const char* const* wanted_symbols, 40 const char* const* unwanted_symbols, 41 crazy_context_t* context) { 42 crazy_library_t* library; 43 44 if (!crazy_library_open(&library, library_name, context)) 45 Panic("Could not open library %s: %s\n", crazy_context_get_error(context)); 46 47 size_t failures = 0; 48 49 if (wanted_symbols) { 50 for (; *wanted_symbols; ++wanted_symbols) { 51 const char* symbol_name = *wanted_symbols; 52 void* symbol_addr; 53 if (!crazy_library_find_symbol(library, symbol_name, &symbol_addr)) { 54 fprintf(stderr, 55 "Could not find symbol '%s' in library '%s'!\n", 56 symbol_name, 57 library_name); 58 failures += 1; 59 } 60 } 61 } 62 63 if (unwanted_symbols) { 64 for (; *unwanted_symbols; ++unwanted_symbols) { 65 const char* symbol_name = *unwanted_symbols; 66 void* symbol_addr; 67 if (crazy_library_find_symbol(library, symbol_name, &symbol_addr)) { 68 fprintf(stderr, 69 "Found symbol '%s' in library '%s', none expected!\n", 70 symbol_name, 71 library_name); 72 failures += 1; 73 } 74 } 75 } 76 77 if (failures > 0) 78 Panic("Found %d symbol failures in library %s\n", failures, library_name); 79 80 crazy_library_close(library); 81} 82 83} // namespace 84 85int main() { 86 String exe_path = GetCurrentExecutableDirectory(); 87 88 TempDirectory temp_dir_1; 89 TempDirectory temp_dir_2; 90 91 // List of symbols in original libfoo.so and libfoo2.so, respectively. 92 static const char* const kFooSymbols[] = {"Foo", NULL}; 93 static const char* const kFoo2Symbols[] = {"Foo2", NULL}; 94 95 // Copy libfoo.so to $TMPDIR1/libfoo.so 96 CopyFile("libfoo.so", exe_path.c_str(), "libfoo.so", temp_dir_1.path()); 97 98 // Copy libfoo2.so to $TMPDIR2/libfoo.so 99 CopyFile("libfoo2.so", exe_path.c_str(), "libfoo.so", temp_dir_2.path()); 100 101 // Create a new context object. 102 crazy_context_t* context = crazy_context_create(); 103 crazy_library_t* library; 104 105 // Reset search paths to a non-existing directory. Check that the library 106 // can't be loaded. 107 setenv("LD_LIBRARY_PATH", "/this-directory-does-not-exist", 1); 108 crazy_context_reset_search_paths(context); 109 CheckLibraryCantLoad("libfoo.so", context); 110 111 // Add the search path to the current executable, this should load the 112 // original 113 // libfoo.so. 114 crazy_context_add_search_path_for_address(context, (void*)&main); 115 CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context); 116 117 // Reset search paths to use $TMPDIR2 then $TMPDIR1 118 setenv("LD_LIBRARY_PATH", temp_dir_1.path(), 1); 119 crazy_context_reset_search_paths(context); 120 crazy_context_add_search_path(context, temp_dir_2.path()); 121 122 // Check that the copy of libfoo2.so is loaded. 123 CheckLibrary("libfoo.so", kFoo2Symbols, kFooSymbols, context); 124 125 // Reset search paths to use only $TMPDIR1 126 crazy_context_reset_search_paths(context); 127 128 // Check that the copy of libfoo.so is loaded. 129 CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context); 130 131 crazy_context_destroy(context); 132 133 return 0; 134}