diff options
Diffstat (limited to 'lib/mesa/src/mapi/entry_x86_tsd.h')
-rw-r--r-- | lib/mesa/src/mapi/entry_x86_tsd.h | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/lib/mesa/src/mapi/entry_x86_tsd.h b/lib/mesa/src/mapi/entry_x86_tsd.h index 9526cdcef..f5d9c4125 100644 --- a/lib/mesa/src/mapi/entry_x86_tsd.h +++ b/lib/mesa/src/mapi/entry_x86_tsd.h @@ -25,6 +25,12 @@ * Chia-I Wu <olv@lunarg.com> */ +#ifdef __CET__ +#define ENDBR "endbr32\n\t" +#else +#define ENDBR +#endif + #ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY #define HIDDEN __attribute__((visibility("hidden"))) #else @@ -33,8 +39,16 @@ #define X86_ENTRY_SIZE 64 -__asm__(".text\n" - ".balign 32\n" +__asm__(".text\n"); + +__asm__("x86_got:\n\t" + "call 1f\n" + "1:\n\t" + "popl %eax\n\t" + "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t" + "ret"); + +__asm__(".balign 32\n" "x86_entry_start:"); #define STUB_ASM_ENTRY(func) \ @@ -43,11 +57,18 @@ __asm__(".text\n" ".balign 32\n" \ func ":" +#define LOC_BEGIN_SET_ECX +#define LOC_END_SET_ECX +#define LOC_END_JMP + #define STUB_ASM_CODE(slot) \ + ENDBR \ + LOC_BEGIN_SET_ECX \ "call 1f\n\t" \ "1:\n\t" \ "popl %ecx\n\t" \ "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx\n\t" \ + LOC_END_SET_ECX \ "movl " ENTRY_CURRENT_TABLE "@GOT(%ecx), %eax\n\t" \ "mov (%eax), %eax\n\t" \ "testl %eax, %eax\n\t" \ @@ -57,7 +78,8 @@ __asm__(".text\n" "call " ENTRY_CURRENT_TABLE_GET "@PLT\n\t" \ "popl %ebx\n\t" \ "1:\n\t" \ - "jmp *(4 * " slot ")(%eax)" + "jmp *(4 * " slot ")(%eax)\n\t" \ + LOC_END_JMP #define MAPI_TMP_STUB_ASM_GCC #include "mapi_tmp.h" @@ -67,9 +89,26 @@ __asm__(".text\n" __asm__(".balign 32\n" "x86_entry_end:"); +#undef LOC_BEGIN_SET_ECX +#undef LOC_END_SET_ECX +#undef LOC_END_JMP +#define LOC_BEGIN_SET_ECX "jmp set_ecx\n\t" +#define LOC_END_SET_ECX "set_ecx:movl $0x12345678, %ecx\n\tloc_end_set_ecx:\n\t" +#define LOC_END_JMP "loc_end_jmp:" + +/* Any number big enough works. This is to make sure the final + * jmp is a long jmp */ +__asm__(STUB_ASM_CODE("10000")); + +extern const char loc_end_set_ecx[] HIDDEN; +extern const char loc_end_jmp[] HIDDEN; + #include <string.h> #include "u_execmem.h" +extern unsigned long +x86_got(); + extern const char x86_entry_start[] HIDDEN; extern const char x86_entry_end[] HIDDEN; @@ -88,16 +127,15 @@ void entry_patch(mapi_func entry, int slot) { char *code = (char *) entry; - - *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func); - *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func); + int offset = loc_end_jmp - x86_entry_end - sizeof(unsigned long); + *((unsigned long *) (code + offset)) = slot * sizeof(mapi_func); } mapi_func entry_generate(int slot) { - const char *code_templ = x86_entry_end - X86_ENTRY_SIZE; - void *code; + const char *code_templ = x86_entry_end; + char *code; mapi_func entry; code = u_execmem_alloc(X86_ENTRY_SIZE); @@ -106,6 +144,9 @@ entry_generate(int slot) memcpy(code, code_templ, X86_ENTRY_SIZE); entry = (mapi_func) code; + int ecx_value_off = loc_end_set_ecx - x86_entry_end - sizeof(unsigned long); + *((unsigned long *) (code + ecx_value_off)) = x86_got(); + entry_patch(entry, slot); return entry; |