headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / runtime_loader / add_ons.cpp
blob4a3ba8fa1b4ed7ed1d0cf1bb2e4e4dac0c2cebc3
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
6 #include "add_ons.h"
8 #include <util/kernel_cpp.h>
10 #include "runtime_loader_private.h"
13 typedef DoublyLinkedList<RuntimeLoaderAddOn> AddOnList;
16 static status_t register_defined_symbol_patcher(struct image_t* image,
17 runtime_loader_symbol_patcher* _patcher, void* cookie);
18 static void unregister_defined_symbol_patcher(struct image_t* image,
19 runtime_loader_symbol_patcher* _patcher, void* cookie);
20 static status_t register_undefined_symbol_patcher(struct image_t* image,
21 runtime_loader_symbol_patcher* _patcher, void* cookie);
22 static void unregister_undefined_symbol_patcher(struct image_t* image,
23 runtime_loader_symbol_patcher* _patcher, void* cookie);
26 static AddOnList sAddOns;
28 static runtime_loader_add_on_export sRuntimeLoaderAddOnExport = {
29 register_defined_symbol_patcher,
30 unregister_defined_symbol_patcher,
31 register_undefined_symbol_patcher,
32 unregister_undefined_symbol_patcher
36 // #pragma mark - add-on support functions
39 static status_t
40 register_defined_symbol_patcher(struct image_t* image,
41 runtime_loader_symbol_patcher* _patcher, void* cookie)
43 RuntimeLoaderSymbolPatcher* patcher
44 = new(mynothrow) RuntimeLoaderSymbolPatcher(_patcher, cookie);
45 if (patcher == NULL)
46 return B_NO_MEMORY;
48 patcher->next = image->defined_symbol_patchers;
49 image->defined_symbol_patchers = patcher;
51 return B_OK;
55 static void
56 unregister_defined_symbol_patcher(struct image_t* image,
57 runtime_loader_symbol_patcher* _patcher, void* cookie)
59 RuntimeLoaderSymbolPatcher** patcher = &image->defined_symbol_patchers;
60 while (*patcher != NULL) {
61 if ((*patcher)->patcher == _patcher && (*patcher)->cookie == cookie) {
62 RuntimeLoaderSymbolPatcher* toDelete = *patcher;
63 *patcher = (*patcher)->next;
64 delete toDelete;
65 return;
67 patcher = &(*patcher)->next;
72 static status_t
73 register_undefined_symbol_patcher(struct image_t* image,
74 runtime_loader_symbol_patcher* _patcher, void* cookie)
76 RuntimeLoaderSymbolPatcher* patcher
77 = new(mynothrow) RuntimeLoaderSymbolPatcher(_patcher, cookie);
78 if (patcher == NULL)
79 return B_NO_MEMORY;
81 patcher->next = image->undefined_symbol_patchers;
82 image->undefined_symbol_patchers = patcher;
84 return B_OK;
88 static void
89 unregister_undefined_symbol_patcher(struct image_t* image,
90 runtime_loader_symbol_patcher* _patcher, void* cookie)
92 RuntimeLoaderSymbolPatcher** patcher = &image->undefined_symbol_patchers;
93 while (*patcher != NULL) {
94 if ((*patcher)->patcher == _patcher && (*patcher)->cookie == cookie) {
95 RuntimeLoaderSymbolPatcher* toDelete = *patcher;
96 *patcher = (*patcher)->next;
97 delete toDelete;
98 return;
100 patcher = &(*patcher)->next;
105 // #pragma mark -
108 void
109 init_add_ons()
111 // invoke static constructors
112 new(&sAddOns) AddOnList;
116 status_t
117 add_add_on(image_t* image, runtime_loader_add_on* addOnStruct)
119 RuntimeLoaderAddOn* addOn = new(mynothrow) RuntimeLoaderAddOn(image,
120 addOnStruct);
121 if (addOn == NULL)
122 return B_NO_MEMORY;
124 sAddOns.Add(addOn);
125 addOnStruct->init(&gRuntimeLoader, &sRuntimeLoaderAddOnExport);
127 return B_OK;
131 void
132 image_event(image_t* image, uint32 event)
134 AddOnList::Iterator it = sAddOns.GetIterator();
135 while (RuntimeLoaderAddOn* addOn = it.Next()) {
136 void (*function)(image_t* image) = NULL;
138 switch (event) {
139 case IMAGE_EVENT_LOADED:
140 function = addOn->addOn->image_loaded;
141 break;
142 case IMAGE_EVENT_RELOCATED:
143 function = addOn->addOn->image_relocated;
144 break;
145 case IMAGE_EVENT_INITIALIZED:
146 function = addOn->addOn->image_initialized;
147 break;
148 case IMAGE_EVENT_UNINITIALIZING:
149 function = addOn->addOn->image_uninitializing;
150 break;
151 case IMAGE_EVENT_UNLOADING:
152 function = addOn->addOn->image_unloading;
153 break;
156 if (function != NULL)
157 function(image);