47
46
/* define public_string_pool and public_stubs */
48
47
#define MAPI_TMP_PUBLIC_STUBS
49
48
#include "mapi_tmp.h"
51
static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
52
static int num_dynamic_stubs;
53
static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC;
56
51
stub_init_once(void)
66
61
const struct mapi_stub *stub = (const struct mapi_stub *) elem;
67
62
const char *stub_name;
69
stub_name = &public_string_pool[(size_t) stub->name];
64
stub_name = &public_string_pool[stub->name_offset];
71
66
return strcmp(name, stub_name);
81
76
ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare);
87
static struct mapi_stub *
88
stub_add_dynamic(const char *name)
90
struct mapi_stub *stub;
93
idx = num_dynamic_stubs;
94
/* minus 1 to make sure we can never reach the last slot */
95
if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1)
98
stub = &dynamic_stubs[idx];
100
/* dispatch to the last slot, which is reserved for no-op */
101
stub->addr = entry_generate(
102
MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1);
106
stub->name = (const void *) strdup(name);
107
/* to be fixed later */
110
num_dynamic_stubs = idx + 1;
116
* Return the dynamic stub with the given name. If no such stub exists and
117
* generate is true, a new stub is generated.
120
stub_find_dynamic(const char *name, int generate)
122
static simple_mtx_t dynamic_mutex = SIMPLE_MTX_INITIALIZER;
123
struct mapi_stub *stub = NULL;
126
simple_mtx_lock(&dynamic_mutex);
129
assert(!stub_find_public(name));
131
count = num_dynamic_stubs;
132
for (i = 0; i < count; i++) {
133
if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) {
134
stub = &dynamic_stubs[i];
139
/* generate a dynamic stub */
140
if (generate && !stub)
141
stub = stub_add_dynamic(name);
143
simple_mtx_unlock(&dynamic_mutex);
148
80
static const struct mapi_stub *
149
81
search_table_by_slot(const struct mapi_stub *table, size_t num_entries,
163
95
const struct mapi_stub *stub =
164
96
search_table_by_slot(public_stubs, ARRAY_SIZE(public_stubs), slot);
167
return search_table_by_slot(dynamic_stubs, num_dynamic_stubs, slot);
171
stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias)
181
slot = next_dynamic_slot++;
183
entry_patch(stub->addr, slot);
191
104
stub_get_name(const struct mapi_stub *stub)
195
if (stub >= public_stubs &&
196
stub < public_stubs + ARRAY_SIZE(public_stubs))
197
name = &public_string_pool[(size_t) stub->name];
199
name = (const char *) stub->name;
106
return &public_string_pool[stub->name_offset];
217
122
stub_get_addr(const struct mapi_stub *stub)
219
assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC);
220
return (stub->addr) ? stub->addr : entry_get_public(stub->slot);
124
return entry_get_public(stub->slot);