fptr.c (_dl_read_access_allowed): Change argument to unsigned int.

* config/pa/fptr.c (_dl_read_access_allowed): Change argument to
	unsigned int.  Adjust callers.
	(__canonicalize_funcptr_for_compare): Change plabel type to volatile
	unsigned int *.  Load relocation offset before function pointer.
	Add barrier to ensure ordering.

From-SVN: r277015
This commit is contained in:
John David Anglin 2019-10-15 22:17:14 +00:00
parent 70a42a8559
commit 85093ac6c9
2 changed files with 18 additions and 6 deletions

View File

@ -1,3 +1,11 @@
2019-10-15 John David Anglin <danglin@gcc.gnu.org>
* config/pa/fptr.c (_dl_read_access_allowed): Change argument to
unsigned int. Adjust callers.
(__canonicalize_funcptr_for_compare): Change plabel type to volatile
unsigned int *. Load relocation offset before function pointer.
Add barrier to ensure ordering.
2019-10-12 John David Anglin <danglin@gcc.gnu.org> 2019-10-12 John David Anglin <danglin@gcc.gnu.org>
* config/pa/lib2funcs.S (__gcc_plt_call): Load branch target to %r21. * config/pa/lib2funcs.S (__gcc_plt_call): Load branch target to %r21.

View File

@ -53,7 +53,7 @@ typedef int (*fixup_t) (struct link_map *, unsigned int);
extern unsigned int _GLOBAL_OFFSET_TABLE_; extern unsigned int _GLOBAL_OFFSET_TABLE_;
static inline int static inline int
_dl_read_access_allowed (unsigned int *addr) _dl_read_access_allowed (unsigned int addr)
{ {
int result; int result;
@ -79,7 +79,8 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
{ {
static unsigned int fixup_plabel[2] __attribute__((used)); static unsigned int fixup_plabel[2] __attribute__((used));
fixup_t fixup; fixup_t fixup;
unsigned int *got, *iptr, *plabel; volatile unsigned int *plabel;
unsigned int *got, *iptr, reloc_offset;
int i; 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
@ -94,17 +95,20 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
to the entry of the PLT stub just before the global offset table. to the entry of the PLT stub just before the global offset table.
The second word in the plabel contains the relocation offset for the The second word in the plabel contains the relocation offset for the
function. */ function. */
plabel = (unsigned int *) ((unsigned int) fptr & ~3); plabel = (volatile unsigned int *) ((unsigned int) fptr & ~3);
if (!_dl_read_access_allowed (plabel)) if (!_dl_read_access_allowed ((unsigned int)plabel))
return (unsigned int) fptr; return (unsigned int) fptr;
/* Load first word of candidate descriptor. It should be a pointer /* Load first word of candidate descriptor. It should be a pointer
with word alignment and point to memory that can be read. */ with word alignment and point to memory that can be read. */
got = (unsigned int *) plabel[0]; got = (unsigned int *) plabel[0];
if (((unsigned int) got & 3) != 0 if (((unsigned int) got & 3) != 0
|| !_dl_read_access_allowed (got)) || !_dl_read_access_allowed ((unsigned int)got))
return (unsigned int) fptr; return (unsigned int) fptr;
/* We need to load the relocation offset before the function address. */
reloc_offset = plabel[1];
__sync_synchronize();
got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB); got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB);
/* Return the address of the function if the plabel has been resolved. */ /* Return the address of the function if the plabel has been resolved. */
@ -140,7 +144,7 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
/* 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], reloc_offset);
return plabel[0]; return plabel[0];
} }