summaryrefslogtreecommitdiffstats
path: root/libgcc
diff options
context:
space:
mode:
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-26 14:50:46 +0000
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-26 14:50:46 +0000
commitbd4c3e3fc062eba385a3c7197b78083f78bb77e2 (patch)
treed334606aee45429446eb33263ed5f3f6f42c5f7f /libgcc
parent1d16273100b3e69f15d331dc6b0c56d57a72d5c1 (diff)
downloadppe42-gcc-bd4c3e3fc062eba385a3c7197b78083f78bb77e2.tar.gz
ppe42-gcc-bd4c3e3fc062eba385a3c7197b78083f78bb77e2.zip
* config/pa/linux-unwind.h (pa32_read_access_ok): New function.
(pa32_fallback_frame_state): Use pa32_read_access_ok to check if memory read accesses are ok. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@216717 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/config/pa/linux-unwind.h34
2 files changed, 34 insertions, 6 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index e34db931564..7a3fda440f7 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-26 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/linux-unwind.h (pa32_read_access_ok): New function.
+ (pa32_fallback_frame_state): Use pa32_read_access_ok to check if
+ memory read accesses are ok.
+
2014-10-22 Georg-Johann Lay <avr@gjlay.de>
PR target/63223
diff --git a/libgcc/config/pa/linux-unwind.h b/libgcc/config/pa/linux-unwind.h
index 485f2d98e76..4a3cfffd19f 100644
--- a/libgcc/config/pa/linux-unwind.h
+++ b/libgcc/config/pa/linux-unwind.h
@@ -32,6 +32,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <signal.h>
#include <sys/ucontext.h>
+/* Return TRUE if read access to *P is allowed. */
+
+static inline long
+pa32_read_access_ok (void *p)
+{
+ long ret;
+
+ __asm__ ("proberi (%1),3,%0" : "=r" (ret) : "r" (p) :);
+ return ret;
+}
+
/* Unfortunately, because of various bugs and changes to the kernel,
we have several cases to deal with.
@@ -48,7 +59,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
tell us how to locate the sigcontext structure.
Note that with a 2.4 64-bit kernel, the signal context is not properly
- passed back to userspace so the unwind will not work correctly. */
+ passed back to userspace so the unwind will not work correctly.
+
+ There is also a bug in various glibc versions. The (CONTEXT)->ra
+ for the outermost frame is not marked as undefined, so we need to
+ check whether read access is allowed for all the accesses used in
+ searching for the signal trampoline. */
#define MD_FALLBACK_FRAME_STATE_FOR pa32_fallback_frame_state
@@ -73,14 +89,17 @@ pa32_fallback_frame_state (struct _Unwind_Context *context,
e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
08000240 nop */
- if (pc[0] == 0x34190000 || pc[0] == 0x34190002)
+ if (pa32_read_access_ok (pc)
+ && (pc[0] == 0x34190000 || pc[0] == 0x34190002))
off = 4*4;
- else if (pc[4] == 0x34190000 || pc[4] == 0x34190002)
+ else if (pa32_read_access_ok (&pc[4])
+ && (pc[4] == 0x34190000 || pc[4] == 0x34190002))
{
pc += 4;
off = 10 * 4;
}
- else if (pc[5] == 0x34190000 || pc[5] == 0x34190002)
+ else if (pa32_read_access_ok (&pc[5])
+ && (pc[5] == 0x34190000 || pc[5] == 0x34190002))
{
pc += 5;
off = 10 * 4;
@@ -96,13 +115,16 @@ pa32_fallback_frame_state (struct _Unwind_Context *context,
word boundary and we can then determine the frame offset. */
sp = (unsigned long)context->ra;
pc = (unsigned int *)sp;
- if ((pc[0] == 0x34190000 || pc[0] == 0x34190002) && (sp & 4))
+ if ((sp & 4)
+ && pa32_read_access_ok (pc)
+ && (pc[0] == 0x34190000 || pc[0] == 0x34190002))
off = 5 * 4;
else
return _URC_END_OF_STACK;
}
- if (pc[1] != 0x3414015a
+ if (!pa32_read_access_ok (&pc[3])
+ || pc[1] != 0x3414015a
|| pc[2] != 0xe4008200
|| pc[3] != 0x08000240)
return _URC_END_OF_STACK;
OpenPOWER on IntegriCloud