• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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