| From 66482303f6d19f1e498b31626c3cbae75e44e957 Mon Sep 17 00:00:00 2001 |
| From: Lepton Wu <lepton@chromium.org> |
| Date: Mon, 22 Jun 2020 15:33:32 -0700 |
| Subject: [PATCH] mapi: x86: Fix dynamic entries in x86 tsd stubs. |
| |
| We need to update dynamic entries related code after updating |
| asm stubs. |
| |
| Fixes: 45206d7673a ("mapi: Adapted libglvnd x86 tsd changes") |
| Signed-off-by: Lepton Wu <lepton@chromium.org> |
| Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5598> |
| --- |
| src/mapi/entry_x86_tsd.h | 50 +++++++++++++++++++++++++++++++++------- |
| 1 file changed, 42 insertions(+), 8 deletions(-) |
| |
| diff --git a/src/mapi/entry_x86_tsd.h b/src/mapi/entry_x86_tsd.h |
| index 1cf3ea2964e..f5d9c41253f 100644 |
| --- a/src/mapi/entry_x86_tsd.h |
| +++ b/src/mapi/entry_x86_tsd.h |
| @@ -39,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) \ |
| @@ -49,11 +57,17 @@ __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) \ |
| + 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" \ |
| @@ -64,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" |
| @@ -74,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; |
| |
| @@ -95,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); |
| @@ -113,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; |
| -- |
| 2.28.0.163.g6104cc2f0b6-goog |
| |