|
|
1.1 ! root 1: /* tag: plugin interface for openbios forth kernel ! 2: * ! 3: * Copyright (C) 2003, 2004 Stefan Reinauer ! 4: * ! 5: * See the file "COPYING" for further information about ! 6: * the copyright and warranty status of this work. ! 7: */ ! 8: ! 9: #include "sysinclude.h" ! 10: #include <stdio.h> ! 11: #include <stdlib.h> ! 12: #include <string.h> ! 13: #include <dlfcn.h> ! 14: ! 15: #include "unix/plugins.h" ! 16: ! 17: unsigned char *plugindir = "/usr/share/OpenBIOS/plugins"; ! 18: #define PLUGINDIR plugindir ! 19: #define PATHSIZE 256 ! 20: ! 21: #define CONFIG_DEBUG_PLUGINS ! 22: ! 23: typedef struct iorange iorange_t; ! 24: struct iorange { ! 25: const char *name; ! 26: unsigned int start; ! 27: unsigned int end; ! 28: io_ops_t *ops; ! 29: iorange_t *next; ! 30: }; ! 31: ! 32: static iorange_t *ioranges = NULL; ! 33: ! 34: typedef struct plugin plugin_t; ! 35: struct plugin { ! 36: const char *name; ! 37: plugin_t *next; ! 38: }; ! 39: ! 40: static plugin_t *plugins = NULL; ! 41: ! 42: io_ops_t *find_iorange(u32 reg) ! 43: { ! 44: iorange_t *range = ioranges; ! 45: while (range) { ! 46: if (range->start <= reg && range->end >= reg) ! 47: return range->ops; ! 48: range = range->next; ! 49: } ! 50: return NULL; ! 51: } ! 52: ! 53: int register_iorange(const char *name, io_ops_t * ops, unsigned int rstart, ! 54: unsigned int rend) ! 55: { ! 56: iorange_t *newrange; ! 57: ! 58: /* intersection check */ ! 59: newrange = ioranges; ! 60: while (newrange) { ! 61: int fail = 0; ! 62: /* new section swallows old section */ ! 63: if (newrange->start >= rstart && newrange->end <= rend) ! 64: fail = -1; ! 65: /* new section start or end point are within range */ ! 66: if (newrange->start <= rstart && newrange->end >= rstart) ! 67: fail = -1; ! 68: if (newrange->start <= rend && newrange->end >= rend) ! 69: fail = -1; ! 70: if (fail) { ! 71: printf("Error: overlapping IO regions: %s and %s\n", ! 72: newrange->name, name); ! 73: return -1; ! 74: } ! 75: newrange = newrange->next; ! 76: } ! 77: ! 78: newrange = malloc(sizeof(iorange_t)); ! 79: ! 80: newrange->name = name; ! 81: newrange->ops = ops; ! 82: newrange->start = rstart; ! 83: newrange->end = rend; ! 84: newrange->next = ioranges; ! 85: ! 86: ioranges = newrange; ! 87: ! 88: return 0; ! 89: } ! 90: ! 91: int is_loaded(const char *plugin_name) ! 92: { ! 93: plugin_t *p = plugins; ! 94: while (p) { ! 95: if (!strcmp(plugin_name, p->name)) ! 96: return -1; ! 97: p = p->next; ! 98: } ! 99: return 0; ! 100: } ! 101: ! 102: int load_plugin(const char *plugin_name) ! 103: { ! 104: void *handle; ! 105: char *error; ! 106: char path[PATHSIZE]; ! 107: ! 108: int (*init_plugin) (void); ! 109: char **deps; ! 110: char **plugin_info; ! 111: plugin_t *p; ! 112: ! 113: if (is_loaded(plugin_name)) { ! 114: printf("Plugin %s already loaded.\n", plugin_name); ! 115: return 0; ! 116: } ! 117: ! 118: strncpy(path, PLUGINDIR, PATHSIZE); ! 119: strncat(path, "/plugin_", PATHSIZE); ! 120: strncat(path, plugin_name, PATHSIZE); ! 121: strncat(path, ".so", PATHSIZE); ! 122: ! 123: #if DEBUG ! 124: printf("Opening plugin %s\n", path); ! 125: #endif ! 126: ! 127: handle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); ! 128: if (!handle) { ! 129: error = dlerror(); ! 130: printf("Error: Could not open plugin \"%s\": %s\n", ! 131: plugin_name, error); ! 132: exit(1); ! 133: } ! 134: #ifdef CONFIG_DEBUG_PLUGINS ! 135: plugin_info = dlsym(handle, "plugin_author"); ! 136: if ((error = dlerror()) == NULL) ! 137: printf("Plugin %s author: %s\n", plugin_name, *plugin_info); ! 138: plugin_info = dlsym(handle, "plugin_license"); ! 139: if ((error = dlerror()) == NULL) ! 140: printf("Plugin %s license: %s\n", plugin_name, *plugin_info); ! 141: plugin_info = dlsym(handle, "plugin_description"); ! 142: if ((error = dlerror()) == NULL) ! 143: printf("Plugin %s descr.: %s\n", plugin_name, *plugin_info); ! 144: #endif ! 145: p = malloc(sizeof(plugin_t)); ! 146: p->next = plugins; ! 147: p->name = plugin_name; ! 148: plugins = p; ! 149: ! 150: deps = dlsym(handle, "plugin_deps"); ! 151: if ((error = dlerror()) != NULL) ! 152: deps = NULL; ! 153: ! 154: ! 155: strncpy(path, "plugin_", PATHSIZE); ! 156: strncat(path, plugin_name, PATHSIZE); ! 157: strncat(path, "_init", PATHSIZE); ! 158: ! 159: init_plugin = dlsym(handle, path); ! 160: if ((error = dlerror()) != NULL) { ! 161: printf("error: %s\n", error); ! 162: exit(1); ! 163: } ! 164: ! 165: if (deps) { ! 166: int i = 0; ! 167: char *walk = deps[0]; ! 168: #ifdef CONFIG_DEBUG_PLUGINS ! 169: printf("\nPlugin %s dependencies:", plugin_name); ! 170: #endif ! 171: while (walk) { ! 172: printf(" %s", walk); ! 173: if (!is_loaded(walk)) { ! 174: #ifdef CONFIG_DEBUG_PLUGINS ! 175: printf("(loading)\n"); ! 176: #endif ! 177: load_plugin(walk); ! 178: } ! 179: #ifdef CONFIG_DEBUG_PLUGINS ! 180: else { ! 181: printf("(loaded)"); ! 182: } ! 183: #endif ! 184: walk = deps[++i]; ! 185: } ! 186: } ! 187: ! 188: printf("\n"); ! 189: #if DEBUG ! 190: printf("Initializing module:\n"); ! 191: #endif ! 192: ! 193: return init_plugin(); ! 194: ! 195: // We don't dlclose the handle here since ! 196: // we want to keep our symbols for later use. ! 197: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.