OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 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: |
| 6 // - Load a library (libfoo.so) with the linker. |
| 7 // - Find the address of the "Foo" function in it. |
| 8 // - Call the function. |
| 9 // - Close the library. |
| 10 |
| 11 #include <crazy_linker.h> |
| 12 |
| 13 #include <stdarg.h> |
| 14 #include <stdio.h> |
| 15 #include <stdlib.h> |
| 16 #include <time.h> |
| 17 #include <unistd.h> |
| 18 #include <fcntl.h> |
| 19 |
| 20 static void Panic(const char* fmt, ...) { |
| 21 va_list args; |
| 22 fprintf(stderr, "PANIC: "); |
| 23 va_start(args, fmt); |
| 24 vfprintf(stderr, fmt, args); |
| 25 va_end(args); |
| 26 exit(1); |
| 27 } |
| 28 |
| 29 static double now_ms() { |
| 30 struct timespec ts; |
| 31 clock_gettime(CLOCK_MONOTONIC, &ts); |
| 32 return (ts.tv_sec * 1000.) + (ts.tv_nsec / 1000000.); |
| 33 } |
| 34 |
| 35 static void drop_caches() { |
| 36 int fd = open("/proc/sys/vm/drop_caches", O_RDWR); |
| 37 if (fd < 0) { |
| 38 fprintf(stderr, "Could not drop caches! Please run this program as root!\n")
; |
| 39 return; |
| 40 } |
| 41 write(fd, "3\n", 2); |
| 42 close(fd); |
| 43 } |
| 44 |
| 45 class ScopedTimer { |
| 46 public: |
| 47 ScopedTimer(const char* name) { |
| 48 name_ = name; |
| 49 start_ms_ = now_ms(); |
| 50 } |
| 51 |
| 52 ~ScopedTimer() { |
| 53 double elapsed_ms = now_ms() - start_ms_; |
| 54 printf("Timer %s: %.1f\n", name_, elapsed_ms); |
| 55 } |
| 56 private: |
| 57 const char* name_; |
| 58 double start_ms_; |
| 59 }; |
| 60 |
| 61 int main(int argc, char** argv) { |
| 62 const char* library_path = "libfoo.so"; |
| 63 if (argc >= 2) |
| 64 library_path = argv[1]; |
| 65 |
| 66 { |
| 67 ScopedTimer null_timer("empty"); |
| 68 } |
| 69 |
| 70 // Load the library with dlopen(). |
| 71 void* lib; |
| 72 drop_caches(); |
| 73 { |
| 74 ScopedTimer timer("dlopen"); |
| 75 lib = dlopen(library_path, RTLD_NOW); |
| 76 } |
| 77 if (!lib) |
| 78 Panic("Could not load library with dlopen(): %s\n", dlerror()); |
| 79 |
| 80 dlclose(lib); |
| 81 |
| 82 |
| 83 crazy_library_t* library; |
| 84 crazy_context_t* context = crazy_context_create(); |
| 85 |
| 86 // Ensure the program looks in its own directory too. |
| 87 crazy_context_add_search_path_for_address( |
| 88 context, reinterpret_cast<void*>(&main)); |
| 89 |
| 90 // Load the library with the crazy linker. |
| 91 drop_caches(); |
| 92 { |
| 93 ScopedTimer timer("crazy_linker"); |
| 94 // Load libfoo.so |
| 95 if (!crazy_library_open(&library, |
| 96 library_path, |
| 97 context)) { |
| 98 Panic("Could not open library: %s\n", crazy_context_get_error(context)); |
| 99 } |
| 100 } |
| 101 crazy_library_close(library); |
| 102 |
| 103 // Load the library with the crazy linker. Preload libOpenSLES.so |
| 104 drop_caches(); |
| 105 void* sles_lib = dlopen("libOpenSLES.so", RTLD_NOW); |
| 106 { |
| 107 ScopedTimer timer("crazy_linker (preload libOpenSLES.so)"); |
| 108 // Load libfoo.so |
| 109 if (!crazy_library_open(&library, |
| 110 library_path, |
| 111 context)) { |
| 112 Panic("Could not open library: %s\n", crazy_context_get_error(context)); |
| 113 } |
| 114 } |
| 115 crazy_library_close(library); |
| 116 dlclose(sles_lib); |
| 117 |
| 118 |
| 119 // Load the library with the crazy linker. Preload libOpenSLES.so |
| 120 { |
| 121 drop_caches(); |
| 122 void* sys1_lib = dlopen("libandroid.so", RTLD_NOW); |
| 123 void* sys2_lib = dlopen("libjnigraphics.so", RTLD_NOW); |
| 124 void* sys3_lib = dlopen("libOpenSLES.so", RTLD_NOW); |
| 125 { |
| 126 ScopedTimer timer("crazy_linker (preload 3 system libs)"); |
| 127 // Load libfoo.so |
| 128 if (!crazy_library_open(&library, |
| 129 library_path, |
| 130 context)) { |
| 131 Panic("Could not open library: %s\n", crazy_context_get_error(context)); |
| 132 } |
| 133 } |
| 134 crazy_library_close(library); |
| 135 dlclose(sys3_lib); |
| 136 dlclose(sys2_lib); |
| 137 dlclose(sys1_lib); |
| 138 } |
| 139 |
| 140 // Load the library with the crazy linker. Create a shared RELRO as well. |
| 141 drop_caches(); |
| 142 { |
| 143 ScopedTimer timer("crazy_linker (with RELRO)"); |
| 144 // Load libfoo.so |
| 145 if (!crazy_library_open(&library, |
| 146 library_path, |
| 147 context)) { |
| 148 Panic("Could not open library: %s\n", crazy_context_get_error(context)); |
| 149 } |
| 150 |
| 151 if (!crazy_library_enable_relro_sharing(library, context)) { |
| 152 Panic("Could not create shared RELRO: %s\n", |
| 153 crazy_context_get_error(context)); |
| 154 } |
| 155 } |
| 156 crazy_library_close(library); |
| 157 |
| 158 printf("OK\n"); |
| 159 return 0; |
| 160 } |
OLD | NEW |