fptr.c (__canonicalize_funcptr_for_compare): Remove code to initialize call to __dl_fixup once.
* config/pa/fptr.c (__canonicalize_funcptr_for_compare): Remove code to initialize call to __dl_fixup once. From-SVN: r231486
This commit is contained in:
parent
2f401a8f18
commit
787c102712
@ -1,3 +1,8 @@
|
|||||||
|
2015-12-09 John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
|
||||||
|
* config/pa/fptr.c (__canonicalize_funcptr_for_compare): Remove code
|
||||||
|
to initialize call to __dl_fixup once.
|
||||||
|
|
||||||
2015-12-04 Nick Clifton <nickc@redhat.com>
|
2015-12-04 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* config/msp430/mpy.c (__mulhi3): Use a faster algorithm.
|
* config/msp430/mpy.c (__mulhi3): Use a faster algorithm.
|
||||||
|
@ -64,10 +64,10 @@ unsigned int __canonicalize_funcptr_for_compare (fptr_t)
|
|||||||
unsigned int
|
unsigned int
|
||||||
__canonicalize_funcptr_for_compare (fptr_t fptr)
|
__canonicalize_funcptr_for_compare (fptr_t fptr)
|
||||||
{
|
{
|
||||||
static unsigned int fixup_plabel[2];
|
static unsigned int fixup_plabel[2] __attribute__((used));
|
||||||
static fixup_t fixup;
|
fixup_t fixup;
|
||||||
static unsigned int *init_fixup;
|
unsigned int *got, *iptr, *plabel;
|
||||||
unsigned int *plabel, *got;
|
int i;
|
||||||
|
|
||||||
/* -1 and page 0 are special. -1 is used in crtend to mark the end of
|
/* -1 and page 0 are special. -1 is used in crtend to mark the end of
|
||||||
a list of function pointers. Also return immediately if the plabel
|
a list of function pointers. Also return immediately if the plabel
|
||||||
@ -88,47 +88,33 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
|
|||||||
if (got != &_GLOBAL_OFFSET_TABLE_)
|
if (got != &_GLOBAL_OFFSET_TABLE_)
|
||||||
return plabel[0];
|
return plabel[0];
|
||||||
|
|
||||||
/* Initialize our plabel for calling fixup if we haven't done so already.
|
/* Find the first "bl" branch in the offset search list. This is a
|
||||||
We can't rely on static initialization so we check that any previous
|
call to _dl_fixup or a magic branch to fixup at the beginning of the
|
||||||
initialization was done for the current got address. This code needs
|
trampoline template. The fixup function does the actual runtime
|
||||||
to be thread safe but we don't have to be too careful as the result
|
resolution of function descriptors. We only look for "bl" branches
|
||||||
is invariant. */
|
with a 17-bit pc-relative displacement. */
|
||||||
if (init_fixup != got)
|
for (i = 0; i < NOFFSETS; i++)
|
||||||
{
|
{
|
||||||
int i;
|
iptr = (unsigned int *) (got[-2] + fixup_branch_offset[i]);
|
||||||
unsigned int *iptr;
|
if ((*iptr & 0xfc00e000) == 0xe8000000)
|
||||||
|
break;
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* Build a plabel for an indirect call to fixup. */
|
|
||||||
fixup_plabel[0] = (unsigned int) iptr + 8; /* address of fixup */
|
|
||||||
fixup_plabel[1] = got[-1]; /* ltp for fixup */
|
|
||||||
fixup = (fixup_t) ((int) fixup_plabel | 3);
|
|
||||||
|
|
||||||
/* Save address of the global offset table. */
|
|
||||||
init_fixup = got;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Build a plabel for an indirect call to _dl_fixup. */
|
||||||
|
fixup_plabel[0] = (unsigned int) iptr + 8; /* address of fixup */
|
||||||
|
fixup_plabel[1] = got[-1]; /* ltp for fixup */
|
||||||
|
fixup = (fixup_t) ((int) fixup_plabel | 3);
|
||||||
|
|
||||||
/* Call fixup to resolve the function address. got[1] contains the
|
/* Call fixup to resolve the function address. got[1] contains the
|
||||||
link_map pointer and plabel[1] the relocation offset. */
|
link_map pointer and plabel[1] the relocation offset. */
|
||||||
fixup ((struct link_map *) got[1], plabel[1]);
|
fixup ((struct link_map *) got[1], plabel[1]);
|
||||||
|
Loading…
Reference in New Issue
Block a user