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