From 83125db9c48e29262b1d8c7e882ea820aac77ed4 Mon Sep 17 00:00:00 2001 From: kettenis Date: Mon, 9 Jan 2023 21:18:47 +0000 Subject: [PATCH] Change the __canonicalize_funcptr_for_compare() implementation to stop trying to read a branch instruction and decode it to extract the address of the ld.so resolver function. Instead, directly execute that branch instruction. This is effectively a C runtime ABI change. In order to cross this if you are building from source, make sure you install an updated ld.so first. ok deraadt@ --- gnu/gcc/gcc/config/pa/fptr.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/gnu/gcc/gcc/config/pa/fptr.c b/gnu/gcc/gcc/config/pa/fptr.c index af207a3b850..6949c46fb7b 100644 --- a/gnu/gcc/gcc/config/pa/fptr.c +++ b/gnu/gcc/gcc/config/pa/fptr.c @@ -96,33 +96,12 @@ __canonicalize_funcptr_for_compare (fptr_t fptr) as the result is invariant. */ if (!fixup) { - int i; - unsigned int *iptr; - - /* Find the first "bl" branch in the offset search list. This is a - call to fixup or a magic branch to fixup at the beginning of the - trampoline template. The fixup function does the actual runtime - resolution of function descriptors. We only look for "bl" branches - with a 17-bit pc-relative displacement. */ - for (i = 0; i < NOFFSETS; i++) - { - iptr = (unsigned int *) (got[-2] + fixup_branch_offset[i]); - if ((*iptr & 0xfc00e000) == 0xe8000000) - break; - } - - /* This should not happen... */ - if (i == NOFFSETS) - return ~0; - - /* Extract the 17-bit displacement from the instruction. */ - iptr += SIGN_EXTEND (GET_FIELD (*iptr, 19, 28) | - GET_FIELD (*iptr, 29, 29) << 10 | - GET_FIELD (*iptr, 11, 15) << 11 | - GET_FIELD (*iptr, 31, 31) << 16, 17); + /* On OpenBSD, we have a magic branch to fixup just before the + trampoline template. The fixup function does the actual + runtime resolution of function descriptors. */ /* Build a plabel for an indirect call to fixup. */ - fixup_plabel[0] = (unsigned int) iptr + 8; /* address of fixup */ + fixup_plabel[0] = got[-2] - 4; /* address of fixup */ fixup_plabel[1] = got[-1]; /* ltp for fixup */ fixup = (fixup_t) ((int) fixup_plabel | 3); } -- 2.20.1