fptr.c (_dl_read_access_allowed): New.

* config/pa/fptr.c (_dl_read_access_allowed): New.
	(__canonicalize_funcptr_for_compare): Use it.

From-SVN: r258310
This commit is contained in:
John David Anglin 2018-03-07 00:17:32 +00:00
parent c0423c3e71
commit 66a00b11a0
2 changed files with 25 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2018-03-06 John David Anglin <danglin@gcc.gnu.org>
* config/pa/fptr.c (_dl_read_access_allowed): New.
(__canonicalize_funcptr_for_compare): Use it.
2018-02-28 Jakub Jelinek <jakub@redhat.com>
PR debug/83917

View File

@ -52,6 +52,16 @@ typedef int (*fptr_t) (void);
typedef int (*fixup_t) (struct link_map *, unsigned int);
extern unsigned int _GLOBAL_OFFSET_TABLE_;
static inline int
_dl_read_access_allowed (unsigned int *addr)
{
int result;
asm ("proberi (%1),3,%0" : "=r" (result) : "r" (addr) : );
return result;
}
/* __canonicalize_funcptr_for_compare must be hidden so that it is not
placed in the dynamic symbol table. Like millicode functions, it
must be linked into all binaries in order access the got table of
@ -82,6 +92,16 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
The second word in the plabel contains the relocation offset for the
function. */
plabel = (unsigned int *) ((unsigned int) fptr & ~3);
if (!_dl_read_access_allowed (plabel))
return (unsigned int) fptr;
/* Load first word of candidate descriptor. It should be a pointer
with word alignment and point to memory that can be read. */
got = (unsigned int *) plabel[0];
if (((unsigned int) got & 3) != 0
|| !_dl_read_access_allowed (got))
return (unsigned int) fptr;
got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB);
/* Return the address of the function if the plabel has been resolved. */