1af69d88dSmrg/* 2af69d88dSmrg * Mesa 3-D graphics library 3af69d88dSmrg * 4af69d88dSmrg * Copyright (C) 2010 LunarG Inc. 5af69d88dSmrg * 6af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 7af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 8af69d88dSmrg * to deal in the Software without restriction, including without limitation 9af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 11af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 12af69d88dSmrg * 13af69d88dSmrg * The above copyright notice and this permission notice shall be included 14af69d88dSmrg * in all copies or substantial portions of the Software. 15af69d88dSmrg * 16af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22af69d88dSmrg * DEALINGS IN THE SOFTWARE. 23af69d88dSmrg * 24af69d88dSmrg * Authors: 25af69d88dSmrg * Chia-I Wu <olv@lunarg.com> 26af69d88dSmrg */ 27af69d88dSmrg 281463c08dSmrg#ifdef __CET__ 291463c08dSmrg#define ENDBR "endbr64\n\t" 301463c08dSmrg#else 311463c08dSmrg#define ENDBR 321463c08dSmrg#endif 331463c08dSmrg 347e995a2eSmrg#ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY 357e995a2eSmrg#define HIDDEN __attribute__((visibility("hidden"))) 367e995a2eSmrg#else 377e995a2eSmrg#define HIDDEN 387e995a2eSmrg#endif 39af69d88dSmrg 40af69d88dSmrg__asm__(".text\n" 41f1d7adeeStnn ".balign 64\n" 42af69d88dSmrg "x86_64_entry_start:"); 43af69d88dSmrg 44af69d88dSmrg#define STUB_ASM_ENTRY(func) \ 45af69d88dSmrg ".globl " func "\n" \ 46af69d88dSmrg ".type " func ", @function\n" \ 47f1d7adeeStnn ".balign 64\n" \ 48af69d88dSmrg func ":" 49af69d88dSmrg 507e995a2eSmrg#ifndef __ILP32__ 517e995a2eSmrg 52f1d7adeeStnn#if defined(__NetBSD__) 53af69d88dSmrg#define STUB_ASM_CODE(slot) \ 54af69d88dSmrg "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ 55af69d88dSmrg "movq %fs:(%rax), %r11\n\t" \ 56e81a0f50Smaya "testq %r11, %r11\n\t" \ 57f1d7adeeStnn "je 1f\n\t" \ 58f1d7adeeStnn "jmp *(8 * " slot ")(%r11)\n\t" \ 59f1d7adeeStnn "1:\n\t" \ 60f1d7adeeStnn "callq " ENTRY_CURRENT_TABLE_GET "@PLT\n\t" \ 61f1d7adeeStnn "jmp *(8 * " slot ")(%rax)" 62e81a0f50Smaya#else 63e81a0f50Smaya#define STUB_ASM_CODE(slot) \ 641463c08dSmrg ENDBR \ 65e81a0f50Smaya "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ 66e81a0f50Smaya "movq %fs:(%rax), %r11\n\t" \ 67e81a0f50Smaya "jmp *(8 * " slot ")(%r11)" 68e81a0f50Smaya#endif 69af69d88dSmrg 707e995a2eSmrg#else 717e995a2eSmrg 727e995a2eSmrg#define STUB_ASM_CODE(slot) \ 731463c08dSmrg ENDBR \ 747e995a2eSmrg "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ 757e995a2eSmrg "movl %fs:(%rax), %r11d\n\t" \ 767e995a2eSmrg "movl 4*" slot "(%r11d), %r11d\n\t" \ 777e995a2eSmrg "jmp *%r11" 787e995a2eSmrg 797e995a2eSmrg#endif 807e995a2eSmrg 81af69d88dSmrg#define MAPI_TMP_STUB_ASM_GCC 82af69d88dSmrg#include "mapi_tmp.h" 83af69d88dSmrg 84af69d88dSmrg#ifndef MAPI_MODE_BRIDGE 85af69d88dSmrg 86af69d88dSmrg#include <string.h> 87af69d88dSmrg#include "u_execmem.h" 88af69d88dSmrg 89af69d88dSmrgvoid 90af69d88dSmrgentry_patch_public(void) 91af69d88dSmrg{ 92af69d88dSmrg} 93af69d88dSmrg 947e995a2eSmrgextern char 957e995a2eSmrgx86_64_entry_start[] HIDDEN; 96af69d88dSmrg 97af69d88dSmrgmapi_func 98af69d88dSmrgentry_get_public(int slot) 99af69d88dSmrg{ 100f1d7adeeStnn return (mapi_func) (x86_64_entry_start + slot * 64); 101af69d88dSmrg} 102af69d88dSmrg 103af69d88dSmrgvoid 104af69d88dSmrgentry_patch(mapi_func entry, int slot) 105af69d88dSmrg{ 106af69d88dSmrg char *code = (char *) entry; 1077e995a2eSmrg int offset = 12; 1087e995a2eSmrg#ifdef __ILP32__ 1097e995a2eSmrg offset = 13; 1107e995a2eSmrg#endif 1117e995a2eSmrg *((unsigned int *) (code + offset)) = slot * sizeof(mapi_func); 112af69d88dSmrg} 113af69d88dSmrg 114af69d88dSmrgmapi_func 115af69d88dSmrgentry_generate(int slot) 116af69d88dSmrg{ 1177e995a2eSmrg const char code_templ[] = { 1187e995a2eSmrg#ifndef __ILP32__ 119af69d88dSmrg /* movq %fs:0, %r11 */ 120af69d88dSmrg 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, 121af69d88dSmrg /* jmp *0x1234(%r11) */ 122af69d88dSmrg 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00, 1237e995a2eSmrg#else 1247e995a2eSmrg /* movl %fs:0, %r11d */ 1257e995a2eSmrg 0x64, 0x44, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, 1267e995a2eSmrg /* movl 0x1234(%r11d), %r11d */ 1277e995a2eSmrg 0x67, 0x45, 0x8b, 0x9b, 0x34, 0x12, 0x00, 0x00, 1287e995a2eSmrg /* jmp *%r11 */ 1297e995a2eSmrg 0x41, 0xff, 0xe3, 1307e995a2eSmrg#endif 131af69d88dSmrg }; 1327e995a2eSmrg unsigned long long addr; 1337e995a2eSmrg char *code; 134af69d88dSmrg mapi_func entry; 135af69d88dSmrg 1367e995a2eSmrg __asm__("movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%%rip), %0" 1377e995a2eSmrg : "=r" (addr)); 138af69d88dSmrg if ((addr >> 32) != 0xffffffff) 139af69d88dSmrg return NULL; 140af69d88dSmrg addr &= 0xffffffff; 141af69d88dSmrg 142af69d88dSmrg code = u_execmem_alloc(sizeof(code_templ)); 143af69d88dSmrg if (!code) 144af69d88dSmrg return NULL; 145af69d88dSmrg 146af69d88dSmrg memcpy(code, code_templ, sizeof(code_templ)); 147af69d88dSmrg 148af69d88dSmrg *((unsigned int *) (code + 5)) = addr; 149af69d88dSmrg entry = (mapi_func) code; 150af69d88dSmrg entry_patch(entry, slot); 151af69d88dSmrg 152af69d88dSmrg return entry; 153af69d88dSmrg} 154af69d88dSmrg 155af69d88dSmrg#endif /* MAPI_MODE_BRIDGE */ 156