1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 2010 LunarG Inc.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the "Software"),
8848b8605Smrg * to deal in the Software without restriction, including without limitation
9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
11848b8605Smrg * Software is furnished to do so, subject to the following conditions:
12848b8605Smrg *
13848b8605Smrg * The above copyright notice and this permission notice shall be included
14848b8605Smrg * in all copies or substantial portions of the Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22848b8605Smrg * DEALINGS IN THE SOFTWARE.
23848b8605Smrg *
24848b8605Smrg * Authors:
25848b8605Smrg *    Chia-I Wu <olv@lunarg.com>
26848b8605Smrg */
27848b8605Smrg
28b8e80941Smrg#ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY
29b8e80941Smrg#define HIDDEN __attribute__((visibility("hidden")))
30b8e80941Smrg#else
31b8e80941Smrg#define HIDDEN
32b8e80941Smrg#endif
33848b8605Smrg
34848b8605Smrg#define X86_ENTRY_SIZE 32
35848b8605Smrg
36848b8605Smrg__asm__(".text\n"
37848b8605Smrg        ".balign 32\n"
38848b8605Smrg        "x86_entry_start:");
39848b8605Smrg
40848b8605Smrg#define STUB_ASM_ENTRY(func)        \
41848b8605Smrg   ".globl " func "\n"              \
42848b8605Smrg   ".type " func ", @function\n"    \
43848b8605Smrg   ".balign 32\n"                   \
44848b8605Smrg   func ":"
45848b8605Smrg
46848b8605Smrg#define STUB_ASM_CODE(slot)         \
47848b8605Smrg   "movl " ENTRY_CURRENT_TABLE ", %eax\n\t" \
48848b8605Smrg   "testl %eax, %eax\n\t"           \
49848b8605Smrg   "je 1f\n\t"                      \
50848b8605Smrg   "jmp *(4 * " slot ")(%eax)\n"    \
51848b8605Smrg   "1:\n\t"                         \
52848b8605Smrg   "call " ENTRY_CURRENT_TABLE_GET "\n\t" \
53848b8605Smrg   "jmp *(4 * " slot ")(%eax)"
54848b8605Smrg
55848b8605Smrg#define MAPI_TMP_STUB_ASM_GCC
56848b8605Smrg#include "mapi_tmp.h"
57848b8605Smrg
58848b8605Smrg#ifndef MAPI_MODE_BRIDGE
59848b8605Smrg
60848b8605Smrg__asm__(".balign 32\n"
61848b8605Smrg        "x86_entry_end:");
62848b8605Smrg
63848b8605Smrg#include <string.h>
64848b8605Smrg#include "u_execmem.h"
65848b8605Smrg
66b8e80941Smrgextern const char x86_entry_start[] HIDDEN;
67b8e80941Smrgextern const char x86_entry_end[] HIDDEN;
68848b8605Smrg
69848b8605Smrgvoid
70848b8605Smrgentry_patch_public(void)
71848b8605Smrg{
72848b8605Smrg}
73848b8605Smrg
74848b8605Smrgmapi_func
75848b8605Smrgentry_get_public(int slot)
76848b8605Smrg{
77848b8605Smrg   return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE);
78848b8605Smrg}
79848b8605Smrg
80848b8605Smrgvoid
81848b8605Smrgentry_patch(mapi_func entry, int slot)
82848b8605Smrg{
83848b8605Smrg   char *code = (char *) entry;
84848b8605Smrg
85848b8605Smrg   *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func);
86848b8605Smrg   *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func);
87848b8605Smrg}
88848b8605Smrg
89848b8605Smrgmapi_func
90848b8605Smrgentry_generate(int slot)
91848b8605Smrg{
92848b8605Smrg   const char *code_templ = x86_entry_end - X86_ENTRY_SIZE;
93848b8605Smrg   void *code;
94848b8605Smrg   mapi_func entry;
95848b8605Smrg
96848b8605Smrg   code = u_execmem_alloc(X86_ENTRY_SIZE);
97848b8605Smrg   if (!code)
98848b8605Smrg      return NULL;
99848b8605Smrg
100848b8605Smrg   memcpy(code, code_templ, X86_ENTRY_SIZE);
101848b8605Smrg   entry = (mapi_func) code;
102848b8605Smrg   entry_patch(entry, slot);
103848b8605Smrg
104848b8605Smrg   return entry;
105848b8605Smrg}
106848b8605Smrg
107848b8605Smrg#endif /* MAPI_MODE_BRIDGE */
108