test_load_library_callbacks.cpp revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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 test callbacks for delayed execution.
6
7#include <stdio.h>
8#include <crazy_linker.h>
9
10#include "test_util.h"
11
12typedef void (*FunctionPtr)();
13
14namespace {
15
16bool 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
30void 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
46int 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