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