#include "hiisi.h" #include "heload/heload.h" #include #include #include #include #include #include #include std::atomic reload_requested(false); void reload_signal_handler(int) { reload_requested = true; } Engine load_hiisi() { const char *name = "build/hiisi/libhiisi-engine.so"; void *mod = dlopen(name, RTLD_NOW); Lmid_t list; dlinfo(mod, RTLD_DI_LMID, &list); printf("link-map list id: %ld\n", list); link_map *lmap = 0; dlinfo(mod, RTLD_DI_LINKMAP, &lmap); printf("Link map:\n"); printf("addr: %lu\n", lmap->l_addr); printf("name: %s\n", lmap->l_name); printf("dynamic section: %p\n", lmap->l_ld); char pathname[256]; dlinfo(mod, RTLD_DI_ORIGIN, pathname); printf("path: %s\n", pathname); /* Discover the size of the buffer that we must pass to RTLD_DI_SERINFO. */ Dl_serinfo serinfo; Dl_serinfo *sip; if (dlinfo(mod, RTLD_DI_SERINFOSIZE, &serinfo) == -1) { fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Allocate the buffer for use with RTLD_DI_SERINFO. */ sip = (Dl_serinfo*)malloc(serinfo.dls_size); if (sip == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* Initialize the 'dls_size' and 'dls_cnt' fields in the newly allocated buffer. */ if (dlinfo(mod, RTLD_DI_SERINFOSIZE, sip) == -1) { fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Fetch and print library search list. */ if (dlinfo(mod, RTLD_DI_SERINFO, sip) == -1) { fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror()); exit(EXIT_FAILURE); } for (size_t j = 0; j < serinfo.dls_cnt; j++) printf("dls_serpath[%zu].dls_name = %s\n", j, sip->dls_serpath[j].dls_name); Engine engine; engine.module = mod; *(void **)&engine.init = dlsym(mod, "init"); *(void **)&engine.event = dlsym(mod, "event"); *(void **)&engine.iterate = dlsym(mod, "iterate"); *(void **)&engine.quit = dlsym(mod, "quit"); assert(engine.init); assert(engine.event); assert(engine.iterate); assert(engine.quit); return engine; } int main(int argc, char **argv) { signal(SIGUSR1, reload_signal_handler); EngineData state; Engine hiisi = load_hiisi(); if (!hiisi.module) { printf("%s\n", dlerror()); return 1; } hiisi.init(&state, argc, argv); while (hiisi.event(&state)) { hiisi.iterate(&state); if (reload_requested) { dlclose(hiisi.module); hiisi = load_hiisi(); reload_requested = false; } } dlclose(hiisi.module); return 0; }