aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2019-10-15 22:17:14 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2019-10-15 22:17:14 +0000
commit85093ac6c9f83d1b1206a21dcd0e243eacf69be9 (patch)
tree8271cf6e8b4e8e80bde508809a56f2e92ea0f770
parent70a42a8559e8a73d8aef09c1d938833ffc811aaa (diff)
downloadgcc-85093ac6c9f83d1b1206a21dcd0e243eacf69be9.zip
gcc-85093ac6c9f83d1b1206a21dcd0e243eacf69be9.tar.gz
gcc-85093ac6c9f83d1b1206a21dcd0e243eacf69be9.tar.bz2
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
-rw-r--r--libgcc/ChangeLog8
-rw-r--r--libgcc/config/pa/fptr.c16
2 files changed, 18 insertions, 6 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 4d2a32c..ed0e900 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -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>
* config/pa/lib2funcs.S (__gcc_plt_call): Load branch target to %r21.
diff --git a/libgcc/config/pa/fptr.c b/libgcc/config/pa/fptr.c
index 6cca747..9d2bb73 100644
--- a/libgcc/config/pa/fptr.c
+++ b/libgcc/config/pa/fptr.c
@@ -53,7 +53,7 @@ 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)
+_dl_read_access_allowed (unsigned int addr)
{
int result;
@@ -79,7 +79,8 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
{
static unsigned int fixup_plabel[2] __attribute__((used));
fixup_t fixup;
- unsigned int *got, *iptr, *plabel;
+ volatile unsigned int *plabel;
+ unsigned int *got, *iptr, reloc_offset;
int i;
/* -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.
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))
+ plabel = (volatile unsigned int *) ((unsigned int) fptr & ~3);
+ if (!_dl_read_access_allowed ((unsigned int)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))
+ || !_dl_read_access_allowed ((unsigned int)got))
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);
/* 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
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];
}