mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 21:40:20 +01:00
mapi: Add and use entry_get_public.
Given a dispatch slot, entry_get_public returns the address of the corresponding public entry point. There may be more than one of them. But since they are all equivalent, it is fine to return any one of them. With entry_get_public, the address of any public entry point can be calculated at runtime when an assembly dispatcher is used. There is no need to have a mapping table in such case. This omits the unnecessary relocations from the binary.
This commit is contained in:
parent
897bff6773
commit
e6a7ef3ca6
7 changed files with 66 additions and 16 deletions
|
|
@ -42,6 +42,8 @@
|
|||
#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"
|
||||
|
||||
|
|
@ -50,6 +52,13 @@ entry_patch_public(void)
|
|||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,14 +32,12 @@
|
|||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ __asm__("x86_64_current_tls:\n\t"
|
|||
"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" \
|
||||
|
|
@ -71,6 +74,13 @@ entry_patch_public(void)
|
|||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,11 +54,12 @@ __asm__("x86_current_tls:\n\t"
|
|||
"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" \
|
||||
|
|
@ -101,6 +102,13 @@ entry_patch_public(void)
|
|||
#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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@
|
|||
|
||||
#define X86_ENTRY_SIZE 32
|
||||
|
||||
__asm__(".text");
|
||||
__asm__(".text\n"
|
||||
".balign 32\n"
|
||||
"x86_entry_start:");
|
||||
|
||||
#define STUB_ASM_ENTRY(func) \
|
||||
".globl " func "\n" \
|
||||
|
|
@ -60,6 +62,13 @@ entry_patch_public(void)
|
|||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -378,6 +378,19 @@ class ABIPrinter(object):
|
|||
|
||||
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
|
||||
|
|
@ -400,9 +413,8 @@ class ABIPrinter(object):
|
|||
"""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)
|
||||
|
||||
|
|
@ -526,6 +538,10 @@ class ABIPrinter(object):
|
|||
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 */'
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h> /* for offsetof */
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
|
@ -40,9 +39,9 @@
|
|||
#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 */
|
||||
|
|
@ -203,5 +202,6 @@ stub_get_slot(const struct mapi_stub *stub)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue