// This file provides functions for the wetterhorn harness that are not // expressible directly in haskell. // // Currently these functions exclusively enable/disable the Haskell runtime. #include "HsFFI.h" #include "plugin_interface.h" #include const char *plugin_name = "Wetterhorn"; void* foreign_interface; void* get_foreign_interface() { return foreign_interface; } extern void performMajorGC(); void plugin_metaload(int argc, char** argv) { hs_init(&argc, &argv); } void plugin_load(int argc, char **argv, foreign_interface_t* fintf) { hs_init(&argc, &argv); foreign_interface = fintf; } void plugin_teardown(opqst_t st) { // the opaque state should be dereferenced by now. Perform a major GC to help // clean up before doing a reload. // // Used primarily in the case where the RTS is kept alive when performing a // hot-reload. performMajorGC(); hs_exit(); // There's a race condition between when this shared library is unloaded and // when the haskell runtime actually exits. Don't have a good solution for // this at the moment, so just sleep for a second. sleep(1); } static const char msg[] = "Wetterhorn Plugin v 0.01\n\n" "Welcome, and thank you for your interest.\n\n" "This is merely a plugin to the Wetterhorn Compositor and not meant to be\n" "executed as a standalone binary. This plugin requires a harness to run\n" "To use this file, please use './wtr_harness [full-path-to-wtr.so]'\n" "That will allow you to see how this compositor works in all its glory!\n"; static const int msg_sz = sizeof(msg); /* * Implemens a basic _start that prints inforamtion and exits for users on an * x86_64 system. */ __attribute__((naked)) void _start() { // Make system call to print the message asm( // Load the address of the string into rsi "mov %0, %%rsi\n" // Load the string length into edx "mov %1, %%edx\n" // Load the file descriptor for stdout into edi "mov $1, %%edi\n" // Load the syscall number for sys_write into eax "mov $1, %%eax\n" // Make the syscall "syscall\n" // Exit the program. "mov $0, %%rdi\n" "mov $60, %%rax\n" "syscall\n" : : "r"(msg), "r"(msg_sz) // Input: address of msg : "%rsi", "%edx", "%edi" // Clobbered registers ); }