1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2010 LunarG Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Chia-I Wu <olv@lunarg.com> 26 */ 27 28#ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY 29#define HIDDEN __attribute__((visibility("hidden"))) 30#else 31#define HIDDEN 32#endif 33 34__asm__(".text\n" 35 ".balign 64\n" 36 "x86_64_entry_start:"); 37 38#define STUB_ASM_ENTRY(func) \ 39 ".globl " func "\n" \ 40 ".type " func ", @function\n" \ 41 ".balign 64\n" \ 42 func ":" 43 44#ifndef __ILP32__ 45 46#if defined(__NetBSD__) 47#define STUB_ASM_CODE(slot) \ 48 "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ 49 "movq %fs:(%rax), %r11\n\t" \ 50 "testq %r11, %r11\n\t" \ 51 "je 1f\n\t" \ 52 "jmp *(8 * " slot ")(%r11)\n\t" \ 53 "1:\n\t" \ 54 "callq " ENTRY_CURRENT_TABLE_GET "@PLT\n\t" \ 55 "jmp *(8 * " slot ")(%rax)" 56#else 57#define STUB_ASM_CODE(slot) \ 58 "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ 59 "movq %fs:(%rax), %r11\n\t" \ 60 "jmp *(8 * " slot ")(%r11)" 61#endif 62 63#else 64 65#define STUB_ASM_CODE(slot) \ 66 "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ 67 "movl %fs:(%rax), %r11d\n\t" \ 68 "movl 4*" slot "(%r11d), %r11d\n\t" \ 69 "jmp *%r11" 70 71#endif 72 73#define MAPI_TMP_STUB_ASM_GCC 74#include "mapi_tmp.h" 75 76#ifndef MAPI_MODE_BRIDGE 77 78#include <string.h> 79#include "u_execmem.h" 80 81void 82entry_patch_public(void) 83{ 84} 85 86extern char 87x86_64_entry_start[] HIDDEN; 88 89mapi_func 90entry_get_public(int slot) 91{ 92 return (mapi_func) (x86_64_entry_start + slot * 64); 93} 94 95void 96entry_patch(mapi_func entry, int slot) 97{ 98 char *code = (char *) entry; 99 int offset = 12; 100#ifdef __ILP32__ 101 offset = 13; 102#endif 103 *((unsigned int *) (code + offset)) = slot * sizeof(mapi_func); 104} 105 106mapi_func 107entry_generate(int slot) 108{ 109 const char code_templ[] = { 110#ifndef __ILP32__ 111 /* movq %fs:0, %r11 */ 112 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, 113 /* jmp *0x1234(%r11) */ 114 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00, 115#else 116 /* movl %fs:0, %r11d */ 117 0x64, 0x44, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, 118 /* movl 0x1234(%r11d), %r11d */ 119 0x67, 0x45, 0x8b, 0x9b, 0x34, 0x12, 0x00, 0x00, 120 /* jmp *%r11 */ 121 0x41, 0xff, 0xe3, 122#endif 123 }; 124 unsigned long long addr; 125 char *code; 126 mapi_func entry; 127 128 __asm__("movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%%rip), %0" 129 : "=r" (addr)); 130 if ((addr >> 32) != 0xffffffff) 131 return NULL; 132 addr &= 0xffffffff; 133 134 code = u_execmem_alloc(sizeof(code_templ)); 135 if (!code) 136 return NULL; 137 138 memcpy(code, code_templ, sizeof(code_templ)); 139 140 *((unsigned int *) (code + 5)) = addr; 141 entry = (mapi_func) code; 142 entry_patch(entry, slot); 143 144 return entry; 145} 146 147#endif /* MAPI_MODE_BRIDGE */ 148