GLdispatch: Simplify the dispatch stub bookkeeping.
Changed the interface in stub.h to work with function indexes instead of mapi_stub pointers. The mapi_stub structure is now an internal detail in stub.c. The mapi_stub struct now only contains a name and a slot. Removed the dynamic_stubs array. Instead, it just keeps an array of the function names for each dynamic stub. It now looks up the function pointers with entry_get_public, and the slot number is always equal to the index, so the name is the only thing it needs to keep track of.
This commit is contained in:
parent
59b622a771
commit
7832167379
|
@ -83,19 +83,21 @@ _glapi_get_dispatch_table_size(void)
|
|||
return MAPI_TABLE_NUM_SLOTS;
|
||||
}
|
||||
|
||||
static const struct mapi_stub *
|
||||
static int
|
||||
_glapi_get_stub(const char *name, int generate)
|
||||
{
|
||||
const struct mapi_stub *stub;
|
||||
int index;
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
if (!name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
stub = stub_find_public(name);
|
||||
if (!stub)
|
||||
stub = stub_find_dynamic(name, generate);
|
||||
index = stub_find_public(name);
|
||||
if (index < 0) {
|
||||
index = stub_find_dynamic(name, generate);
|
||||
}
|
||||
|
||||
return stub;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,8 +106,7 @@ _glapi_get_stub(const char *name, int generate)
|
|||
int
|
||||
_glapi_get_proc_offset(const char *funcName)
|
||||
{
|
||||
const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);
|
||||
return (stub) ? stub_get_slot(stub) : -1;
|
||||
return _glapi_get_stub(funcName, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,8 +117,12 @@ _glapi_get_proc_offset(const char *funcName)
|
|||
_glapi_proc
|
||||
_glapi_get_proc_address(const char *funcName)
|
||||
{
|
||||
const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);
|
||||
return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;
|
||||
int index = _glapi_get_stub(funcName, 1);
|
||||
if (index >= 0) {
|
||||
return stub_get_addr(index);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,8 +131,7 @@ _glapi_get_proc_address(const char *funcName)
|
|||
const char *
|
||||
_glapi_get_proc_name(unsigned int offset)
|
||||
{
|
||||
const struct mapi_stub *stub = stub_find_by_slot(offset);
|
||||
return stub ? stub_get_name(stub) : NULL;
|
||||
return stub_get_name(offset);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,9 +33,7 @@
|
|||
#include "entry.h"
|
||||
#include "stub.h"
|
||||
#include "table.h"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#define MAPI_LAST_SLOT (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1)
|
||||
#include "utils_misc.h"
|
||||
|
||||
struct mapi_stub {
|
||||
/*!
|
||||
|
@ -44,14 +42,6 @@ struct mapi_stub {
|
|||
const char *name;
|
||||
|
||||
int slot;
|
||||
mapi_func addr;
|
||||
|
||||
/**
|
||||
* A buffer to store the name of the function. This is only used for
|
||||
* dynamic stubs. For static stubs, mapi_stub::name is a static
|
||||
* string and mapi_stub::nameBuffer is NULL.
|
||||
*/
|
||||
char *nameBuffer;
|
||||
};
|
||||
|
||||
/* define public_stubs */
|
||||
|
@ -74,21 +64,28 @@ stub_compare(const void *key, const void *elem)
|
|||
/**
|
||||
* Return the public stub with the given name.
|
||||
*/
|
||||
const struct mapi_stub *
|
||||
int
|
||||
stub_find_public(const char *name)
|
||||
{
|
||||
const struct mapi_stub *stub;
|
||||
|
||||
// All of the function names start with "gl", so skip that prefix when
|
||||
// comparing names.
|
||||
if (name[0] == 'g' && name[1] == 'l') {
|
||||
name += 2;
|
||||
}
|
||||
|
||||
return (const struct mapi_stub *) bsearch(name, public_stubs,
|
||||
ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare);
|
||||
stub = (const struct mapi_stub *) bsearch(name, public_stubs,
|
||||
ARRAY_LEN(public_stubs), sizeof(public_stubs[0]), stub_compare);
|
||||
if (stub != NULL) {
|
||||
return (stub - public_stubs);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(STATIC_DISPATCH_ONLY)
|
||||
static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
|
||||
static char *dynamic_stub_names[MAPI_TABLE_NUM_DYNAMIC];
|
||||
static int num_dynamic_stubs;
|
||||
|
||||
void stub_cleanup_dynamic(void)
|
||||
|
@ -97,9 +94,8 @@ void stub_cleanup_dynamic(void)
|
|||
|
||||
// Free the copies of the stub names.
|
||||
for (i=0; i<num_dynamic_stubs; i++) {
|
||||
struct mapi_stub *stub = &dynamic_stubs[i];
|
||||
free(stub->nameBuffer);
|
||||
stub->nameBuffer = NULL;
|
||||
free(dynamic_stub_names[i]);
|
||||
dynamic_stub_names[i] = NULL;
|
||||
}
|
||||
|
||||
num_dynamic_stubs = 0;
|
||||
|
@ -108,127 +104,95 @@ void stub_cleanup_dynamic(void)
|
|||
/**
|
||||
* Add a dynamic stub.
|
||||
*/
|
||||
static struct mapi_stub *
|
||||
int
|
||||
stub_add_dynamic(const char *name)
|
||||
{
|
||||
struct mapi_stub *stub;
|
||||
int idx;
|
||||
|
||||
idx = num_dynamic_stubs;
|
||||
/* minus 1 to make sure we can never reach the last slot */
|
||||
if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1)
|
||||
return NULL;
|
||||
return -1;
|
||||
|
||||
stub = &dynamic_stubs[idx];
|
||||
// Make sure that we have a dispatch stub for this index. If the stubs are
|
||||
// in C instead of assembly, then we can't use dynamic dispatch stubs, and
|
||||
// entry_get_public will return NULL.
|
||||
if (entry_get_public(MAPI_TABLE_NUM_STATIC + idx) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(dynamic_stub_names[idx] == NULL);
|
||||
|
||||
/*
|
||||
* name is the pointer passed to glXGetProcAddress, so the caller may free
|
||||
* or modify it later. Allocate a copy of the name to store.
|
||||
*/
|
||||
stub->nameBuffer = strdup(name);
|
||||
if (stub->nameBuffer == NULL) {
|
||||
return NULL;
|
||||
dynamic_stub_names[idx] = strdup(name);
|
||||
if (dynamic_stub_names[idx] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Assign the next unused slot. */
|
||||
stub->slot = MAPI_TABLE_NUM_STATIC + idx;
|
||||
stub->addr = entry_get_public(stub->slot);
|
||||
if (!stub->addr) {
|
||||
free(stub->nameBuffer);
|
||||
stub->nameBuffer = NULL;
|
||||
return NULL;
|
||||
}
|
||||
stub->name = stub->nameBuffer;
|
||||
|
||||
num_dynamic_stubs = idx + 1;
|
||||
|
||||
return stub;
|
||||
return (MAPI_TABLE_NUM_STATIC + idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dynamic stub with the given name. If no such stub exists and
|
||||
* generate is true, a new stub is generated.
|
||||
*/
|
||||
struct mapi_stub *
|
||||
int
|
||||
stub_find_dynamic(const char *name, int generate)
|
||||
{
|
||||
struct mapi_stub *stub = NULL;
|
||||
int count, i;
|
||||
int found = -1;
|
||||
int i;
|
||||
|
||||
if (generate)
|
||||
assert(!stub_find_public(name));
|
||||
|
||||
count = num_dynamic_stubs;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (strcmp(name, dynamic_stubs[i].name) == 0) {
|
||||
stub = &dynamic_stubs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a dynamic stub */
|
||||
if (generate && !stub)
|
||||
stub = stub_add_dynamic(name);
|
||||
|
||||
return stub;
|
||||
}
|
||||
|
||||
const struct mapi_stub *
|
||||
stub_find_by_slot(int slot)
|
||||
{
|
||||
assert(slot >= 0);
|
||||
|
||||
if (slot < ARRAY_SIZE(public_stubs)) {
|
||||
return &public_stubs[slot];
|
||||
} else if (slot - ARRAY_SIZE(public_stubs) < num_dynamic_stubs) {
|
||||
return &dynamic_stubs[slot - ARRAY_SIZE(public_stubs)];
|
||||
} else {
|
||||
return NULL;
|
||||
if (generate) {
|
||||
assert(stub_find_public(name) < 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_dynamic_stubs; i++) {
|
||||
if (strcmp(name, dynamic_stub_names[i]) == 0) {
|
||||
found = MAPI_TABLE_NUM_STATIC + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a dynamic stub */
|
||||
if (generate && found < 0) {
|
||||
found = stub_add_dynamic(name);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of a stub.
|
||||
*/
|
||||
const char *
|
||||
stub_get_name(const struct mapi_stub *stub)
|
||||
stub_get_name(int index)
|
||||
{
|
||||
return stub->name;
|
||||
if (index < MAPI_TABLE_NUM_STATIC) {
|
||||
return public_stubs[index].name;
|
||||
} else {
|
||||
return dynamic_stub_names[index - MAPI_TABLE_NUM_STATIC];
|
||||
}
|
||||
}
|
||||
|
||||
int stub_get_count(void)
|
||||
{
|
||||
return ARRAY_SIZE(public_stubs) + num_dynamic_stubs;
|
||||
}
|
||||
|
||||
#endif // !defined(STATIC_DISPATCH_ONLY)
|
||||
|
||||
/**
|
||||
* Return the slot of a stub.
|
||||
*/
|
||||
int
|
||||
stub_get_slot(const struct mapi_stub *stub)
|
||||
{
|
||||
return stub->slot;
|
||||
return ARRAY_LEN(public_stubs) + num_dynamic_stubs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the address of a stub.
|
||||
*/
|
||||
mapi_func
|
||||
stub_get_addr(const struct mapi_stub *stub)
|
||||
stub_get_addr(int index)
|
||||
{
|
||||
assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC);
|
||||
if (stub->addr != NULL)
|
||||
{
|
||||
return stub->addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = stub - public_stubs;
|
||||
return entry_get_public(index);
|
||||
}
|
||||
return entry_get_public(index);
|
||||
}
|
||||
#endif // !defined(STATIC_DISPATCH_ONLY)
|
||||
|
||||
static int stub_allow_override(void)
|
||||
{
|
||||
|
@ -255,26 +219,20 @@ static void stubFinishPatch(void)
|
|||
|
||||
static void stubRestoreFuncsInternal(void)
|
||||
{
|
||||
int i, slot;
|
||||
const struct mapi_stub *stub;
|
||||
int i;
|
||||
|
||||
assert(stub_allow_override());
|
||||
|
||||
for (stub = public_stubs, i = 0;
|
||||
i < ARRAY_SIZE(public_stubs);
|
||||
stub++, i++) {
|
||||
slot = (stub->slot == -1) ? MAPI_LAST_SLOT : stub->slot;
|
||||
entry_generate_default_code((char *)stub_get_addr(stub), slot);
|
||||
for (i = 0; i < ARRAY_LEN(public_stubs); i++) {
|
||||
entry_generate_default_code((char *)entry_get_public(i), public_stubs[i].slot);
|
||||
}
|
||||
|
||||
#if !defined(STATIC_DISPATCH_ONLY)
|
||||
for (stub = dynamic_stubs, i = 0;
|
||||
i < num_dynamic_stubs;
|
||||
stub++, i++) {
|
||||
slot = (stub->slot == -1) ? MAPI_LAST_SLOT : stub->slot;
|
||||
entry_generate_default_code((char *)stub_get_addr(stub), slot);
|
||||
for (i=0; i<num_dynamic_stubs; i++) {
|
||||
int slot = ARRAY_LEN(public_stubs) + i;
|
||||
entry_generate_default_code((char *)entry_get_public(slot), slot);
|
||||
}
|
||||
#endif // !defined(STATIC_DISPATCH_ONLY)
|
||||
#endif
|
||||
}
|
||||
|
||||
static GLboolean stubRestoreFuncs(void)
|
||||
|
@ -296,20 +254,20 @@ static void stubAbortPatch(void)
|
|||
|
||||
static GLboolean stubGetPatchOffset(const char *name, void **writePtr, const void **execPtr)
|
||||
{
|
||||
const struct mapi_stub *stub;
|
||||
int index;
|
||||
void *writeAddr = NULL;
|
||||
const void *execAddr = NULL;
|
||||
|
||||
stub = stub_find_public(name);
|
||||
index = stub_find_public(name);
|
||||
|
||||
#if !defined(STATIC_DISPATCH_ONLY)
|
||||
if (!stub) {
|
||||
stub = stub_find_dynamic(name, 0);
|
||||
if (index < 0) {
|
||||
index = stub_find_dynamic(name, 0);
|
||||
}
|
||||
#endif // !defined(STATIC_DISPATCH_ONLY)
|
||||
|
||||
if (stub) {
|
||||
mapi_func addr = stub_get_addr(stub);
|
||||
if (index >= 0) {
|
||||
mapi_func addr = entry_get_public(index);
|
||||
if (addr != NULL) {
|
||||
entry_get_patch_addresses(addr, &writeAddr, &execAddr);
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#include "entry.h"
|
||||
#include "glapi.h"
|
||||
|
||||
struct mapi_stub;
|
||||
|
||||
#if !defined(STATIC_DISPATCH_ONLY)
|
||||
|
||||
/**
|
||||
|
@ -43,23 +41,17 @@ struct mapi_stub;
|
|||
*/
|
||||
void stub_cleanup_dynamic(void);
|
||||
|
||||
const struct mapi_stub *
|
||||
int
|
||||
stub_find_public(const char *name);
|
||||
|
||||
struct mapi_stub *
|
||||
int
|
||||
stub_find_dynamic(const char *name, int generate);
|
||||
|
||||
const struct mapi_stub *
|
||||
stub_find_by_slot(int slot);
|
||||
|
||||
const char *
|
||||
stub_get_name(const struct mapi_stub *stub);
|
||||
|
||||
int
|
||||
stub_get_slot(const struct mapi_stub *stub);
|
||||
stub_get_name(int index);
|
||||
|
||||
mapi_func
|
||||
stub_get_addr(const struct mapi_stub *stub);
|
||||
stub_get_addr(int index);
|
||||
|
||||
int stub_get_count(void);
|
||||
#endif // !defined(STATIC_DISPATCH_ONLY)
|
||||
|
|
|
@ -132,7 +132,7 @@ def generate_public_stubs(functions):
|
|||
|
||||
text += "static const struct mapi_stub public_stubs[] = {\n"
|
||||
for func in functions:
|
||||
text += " { \"%s\", %d, NULL },\n" % (func.name, func.slot)
|
||||
text += " { \"%s\", %d },\n" % (func.name, func.slot)
|
||||
text += "};\n"
|
||||
text += "#undef MAPI_TMP_PUBLIC_STUBS\n"
|
||||
text += "#endif /* MAPI_TMP_PUBLIC_STUBS */\n"
|
||||
|
|
Loading…
Reference in a new issue