Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
     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