haiku/src/system/runtime_loader/add_ons.cpp

160 lines
3.8 KiB
C++
Raw Normal View History

/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "add_ons.h"
#include <util/kernel_cpp.h>
#include "runtime_loader_private.h"
typedef DoublyLinkedList<RuntimeLoaderAddOn> AddOnList;
static status_t register_defined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie);
static void unregister_defined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie);
static status_t register_undefined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie);
static void unregister_undefined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie);
static AddOnList sAddOns;
static runtime_loader_add_on_export sRuntimeLoaderAddOnExport = {
register_defined_symbol_patcher,
unregister_defined_symbol_patcher,
register_undefined_symbol_patcher,
unregister_undefined_symbol_patcher
};
// #pragma mark - add-on support functions
static status_t
register_defined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie)
{
RuntimeLoaderSymbolPatcher* patcher
= new(mynothrow) RuntimeLoaderSymbolPatcher(_patcher, cookie);
if (patcher == NULL)
return B_NO_MEMORY;
patcher->next = image->defined_symbol_patchers;
image->defined_symbol_patchers = patcher;
return B_OK;
}
static void
unregister_defined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie)
{
RuntimeLoaderSymbolPatcher** patcher = &image->defined_symbol_patchers;
while (*patcher != NULL) {
if ((*patcher)->patcher == _patcher && (*patcher)->cookie == cookie) {
RuntimeLoaderSymbolPatcher* toDelete = *patcher;
*patcher = (*patcher)->next;
delete toDelete;
return;
}
patcher = &(*patcher)->next;
}
}
static status_t
register_undefined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie)
{
RuntimeLoaderSymbolPatcher* patcher
= new(mynothrow) RuntimeLoaderSymbolPatcher(_patcher, cookie);
if (patcher == NULL)
return B_NO_MEMORY;
patcher->next = image->undefined_symbol_patchers;
image->undefined_symbol_patchers = patcher;
return B_OK;
}
static void
unregister_undefined_symbol_patcher(struct image_t* image,
runtime_loader_symbol_patcher* _patcher, void* cookie)
{
RuntimeLoaderSymbolPatcher** patcher = &image->undefined_symbol_patchers;
while (*patcher != NULL) {
if ((*patcher)->patcher == _patcher && (*patcher)->cookie == cookie) {
RuntimeLoaderSymbolPatcher* toDelete = *patcher;
*patcher = (*patcher)->next;
delete toDelete;
return;
}
patcher = &(*patcher)->next;
}
}
// #pragma mark -
void
init_add_ons()
{
// invoke static constructors
new(&sAddOns) AddOnList;
}
status_t
add_add_on(image_t* image, runtime_loader_add_on* addOnStruct)
{
RuntimeLoaderAddOn* addOn = new(mynothrow) RuntimeLoaderAddOn(image,
addOnStruct);
if (addOn == NULL)
return B_NO_MEMORY;
sAddOns.Add(addOn);
addOnStruct->init(&gRuntimeLoader, &sRuntimeLoaderAddOnExport);
return B_OK;
}
void
image_event(image_t* image, uint32 event)
{
AddOnList::Iterator it = sAddOns.GetIterator();
while (RuntimeLoaderAddOn* addOn = it.Next()) {
void (*function)(image_t* image) = NULL;
switch (event) {
case IMAGE_EVENT_LOADED:
function = addOn->addOn->image_loaded;
break;
case IMAGE_EVENT_RELOCATED:
function = addOn->addOn->image_relocated;
break;
case IMAGE_EVENT_INITIALIZED:
function = addOn->addOn->image_initialized;
break;
case IMAGE_EVENT_UNINITIALIZING:
function = addOn->addOn->image_uninitializing;
break;
case IMAGE_EVENT_UNLOADING:
function = addOn->addOn->image_unloading;
break;
}
if (function != NULL)
function(image);
}
}