Home | History | Annotate | Download | only in mapi
      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 (at) 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 32\n"
     36         "x86_64_entry_start:");
     37 
     38 #define STUB_ASM_ENTRY(func)                             \
     39    ".globl " func "\n"                                   \
     40    ".type " func ", @function\n"                         \
     41    ".balign 32\n"                                        \
     42    func ":"
     43 
     44 #ifndef __ILP32__
     45 
     46 #define STUB_ASM_CODE(slot)                              \
     47    "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t"  \
     48    "movq %fs:(%rax), %r11\n\t"                           \
     49    "jmp *(8 * " slot ")(%r11)"
     50 
     51 #else
     52 
     53 #define STUB_ASM_CODE(slot)                              \
     54    "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t"  \
     55    "movl %fs:(%rax), %r11d\n\t"                          \
     56    "movl 4*" slot "(%r11d), %r11d\n\t"                   \
     57    "jmp *%r11"
     58 
     59 #endif
     60 
     61 #define MAPI_TMP_STUB_ASM_GCC
     62 #include "mapi_tmp.h"
     63 
     64 #ifndef MAPI_MODE_BRIDGE
     65 
     66 #include <string.h>
     67 #include "u_execmem.h"
     68 
     69 void
     70 entry_patch_public(void)
     71 {
     72 }
     73 
     74 extern char
     75 x86_64_entry_start[] HIDDEN;
     76 
     77 mapi_func
     78 entry_get_public(int slot)
     79 {
     80    return (mapi_func) (x86_64_entry_start + slot * 32);
     81 }
     82 
     83 void
     84 entry_patch(mapi_func entry, int slot)
     85 {
     86    char *code = (char *) entry;
     87    int offset = 12;
     88 #ifdef __ILP32__
     89    offset = 13;
     90 #endif
     91    *((unsigned int *) (code + offset)) = slot * sizeof(mapi_func);
     92 }
     93 
     94 mapi_func
     95 entry_generate(int slot)
     96 {
     97    const char code_templ[] = {
     98 #ifndef __ILP32__
     99       /* movq %fs:0, %r11 */
    100       0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00,
    101       /* jmp *0x1234(%r11) */
    102       0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00,
    103 #else
    104       /* movl %fs:0, %r11d */
    105       0x64, 0x44, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00,
    106       /* movl 0x1234(%r11d), %r11d */
    107       0x67, 0x45, 0x8b, 0x9b, 0x34, 0x12, 0x00, 0x00,
    108       /* jmp *%r11 */
    109       0x41, 0xff, 0xe3,
    110 #endif
    111    };
    112    unsigned long long addr;
    113    char *code;
    114    mapi_func entry;
    115 
    116    __asm__("movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%%rip), %0"
    117            : "=r" (addr));
    118    if ((addr >> 32) != 0xffffffff)
    119       return NULL;
    120    addr &= 0xffffffff;
    121 
    122    code = u_execmem_alloc(sizeof(code_templ));
    123    if (!code)
    124       return NULL;
    125 
    126    memcpy(code, code_templ, sizeof(code_templ));
    127 
    128    *((unsigned int *) (code + 5)) = addr;
    129    entry = (mapi_func) code;
    130    entry_patch(entry, slot);
    131 
    132    return entry;
    133 }
    134 
    135 #endif /* MAPI_MODE_BRIDGE */
    136