1 // Copyright (c) 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 test callbacks for delayed execution.
6
7 #include <stdio.h>
8 #include <crazy_linker.h>
9
10 #include "test_util.h"
11
12 typedef void (*FunctionPtr)();
13
14 namespace {
15
PostCallback(crazy_callback_t * callback,void * poster_opaque)16 bool PostCallback(crazy_callback_t* callback, void* poster_opaque) {
17 printf("Post callback, poster_opaque %p, handler %p, opaque %p\n",
18 poster_opaque,
19 callback->handler,
20 callback->opaque);
21
22 // Copy callback to the address given in poster_opaque.
23 crazy_callback_t* request =
24 reinterpret_cast<crazy_callback_t*>(poster_opaque);
25 *request = *callback;
26
27 return true;
28 }
29
CheckAndRunCallback(crazy_callback_t * callback)30 void CheckAndRunCallback(crazy_callback_t* callback) {
31 printf("Run callback, handler %p, opaque %p\n",
32 callback->handler,
33 callback->opaque);
34
35 if (!callback->handler) {
36 Panic("Post for delayed execution not invoked\n");
37 }
38
39 // Run the callback, then clear it for re-use.
40 crazy_callback_run(callback);
41 memset(callback, 0, sizeof(*callback));
42 }
43
44 } // namespace
45
main()46 int main() {
47 crazy_context_t* context = crazy_context_create();
48 crazy_library_t* library;
49
50 // DEBUG
51 crazy_context_set_load_address(context, 0x20000000);
52
53 // Create a new callback, initialized to NULLs.
54 crazy_callback_t callback = {NULL, NULL};
55
56 // Set a callback poster that copies its callback to &callback.
57 crazy_context_set_callback_poster(context, &PostCallback, &callback);
58
59 crazy_callback_poster_t poster;
60 void* poster_opaque;
61
62 // Check that the API returns the values we set.
63 crazy_context_get_callback_poster(context, &poster, &poster_opaque);
64 if (poster != &PostCallback || poster_opaque != &callback) {
65 Panic("Get callback poster error\n");
66 }
67
68 // Load libfoo.so.
69 if (!crazy_library_open(&library, "libfoo.so", context)) {
70 Panic("Could not open library: %s\n", crazy_context_get_error(context));
71 }
72 CheckAndRunCallback(&callback);
73
74 // Find the "Foo" symbol.
75 FunctionPtr foo_func;
76 if (!crazy_library_find_symbol(
77 library, "Foo", reinterpret_cast<void**>(&foo_func))) {
78 Panic("Could not find 'Foo' in libfoo.so\n");
79 }
80
81 // Call it.
82 (*foo_func)();
83
84 // Close the library.
85 crazy_library_close_with_context(library, context);
86 CheckAndRunCallback(&callback);
87
88 crazy_context_destroy(context);
89
90 return 0;
91 }
92