diff options
author | John David Anglin <danglin@gcc.gnu.org> | 2019-10-15 22:17:14 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2019-10-15 22:17:14 +0000 |
commit | 85093ac6c9f83d1b1206a21dcd0e243eacf69be9 (patch) | |
tree | 8271cf6e8b4e8e80bde508809a56f2e92ea0f770 | |
parent | 70a42a8559e8a73d8aef09c1d938833ffc811aaa (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | libgcc/config/pa/fptr.c | 16 |
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]; } |