#include "u_current.h"
/* C version of the public entries */
+#define MAPI_TMP_DEFINES
+#define MAPI_TMP_PUBLIC_DECLARES
#define MAPI_TMP_PUBLIC_ENTRIES
#include "mapi_tmp.h"
{
}
+mapi_func
+entry_get_public(int slot)
+{
+ /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */
+ return public_entries[slot];
+}
+
mapi_func
entry_generate(int slot)
{
#include "u_compiler.h"
#include "stub.h"
-/* declare public entries */
-#define MAPI_TMP_DEFINES
-#define MAPI_TMP_PUBLIC_DECLARES
-#include "mapi_tmp.h"
-
void
entry_patch_public(void);
+mapi_func
+entry_get_public(int slot);
+
mapi_func
entry_generate(int slot);
"movq u_current_table@GOTTPOFF(%rip), %rax\n\t"
"ret");
+__asm__(".balign 32\n"
+ "x86_64_entry_start:");
+
#define STUB_ASM_ENTRY(func) \
".globl " func "\n" \
".type " func ", @function\n" \
{
}
+mapi_func
+entry_get_public(int slot)
+{
+ extern char x86_64_entry_start[];
+ return (mapi_func) (x86_64_entry_start + slot * 32);
+}
+
void
entry_patch(mapi_func entry, int slot)
{
"ret");
#ifndef GLX_X86_READONLY_TEXT
-__asm__(".section wtext, \"awx\", @progbits\n"
- ".balign 16\n"
- "x86_entry_start:");
+__asm__(".section wtext, \"awx\", @progbits");
#endif /* GLX_X86_READONLY_TEXT */
+__asm__(".balign 16\n"
+ "x86_entry_start:");
+
#define STUB_ASM_ENTRY(func) \
".globl " func "\n" \
".type " func ", @function\n" \
#endif
}
+mapi_func
+entry_get_public(int slot)
+{
+ extern char x86_entry_start[];
+ return (mapi_func) (x86_entry_start + slot * 16);
+}
+
void
entry_patch(mapi_func entry, int slot)
{
#define X86_ENTRY_SIZE 32
-__asm__(".text");
+__asm__(".text\n"
+ ".balign 32\n"
+ "x86_entry_start:");
#define STUB_ASM_ENTRY(func) \
".globl " func "\n" \
{
}
+mapi_func
+entry_get_public(int slot)
+{
+ extern const char x86_entry_start[];
+ return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE);
+}
+
void
entry_patch(mapi_func entry, int slot)
{
return '\n\n'.join(dispatches)
+ def c_public_initializer(self, prefix):
+ """Return the initializer for public dispatch functions."""
+ names = []
+ for ent in self.entries:
+ if ent.alias:
+ continue
+
+ name = '%s(mapi_func) %s' % (self.indent,
+ self._c_function_call(ent, prefix))
+ names.append(name)
+
+ return ',\n'.join(names)
+
def c_stub_string_pool(self):
"""Return the string pool for use by stubs."""
# sort entries by their names
"""Return the initializer for struct mapi_stub array."""
stubs = []
for ent in self.entries_sorted_by_names:
- stubs.append('%s{ (mapi_func) %s, %d, (void *) %d }' % (
- self.indent, self._c_function_call(ent, prefix),
- ent.slot, pool_offsets[ent]))
+ stubs.append('%s{ (void *) %d, %d, NULL }' % (
+ self.indent, pool_offsets[ent], ent.slot))
return ',\n'.join(stubs)
print
print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
print self.c_public_dispatches(self.prefix_lib)
+ print
+ print 'static const mapi_func public_entries[] = {'
+ print self.c_public_initializer(self.prefix_lib)
+ print '};'
print '#undef MAPI_TMP_PUBLIC_ENTRIES'
print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
*/
#include <stdlib.h>
-#include <stddef.h> /* for offsetof */
#include <string.h>
#include <assert.h>
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
struct mapi_stub {
- mapi_func addr;
- int slot;
const void *name;
+ int slot;
+ mapi_func addr;
};
/* define public_string_pool and public_stubs */
mapi_func
stub_get_addr(const struct mapi_stub *stub)
{
- return stub->addr;
+ assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC);
+ return (stub->addr) ? stub->addr : entry_get_public(stub->slot);
}