diff options
author | wschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-29 03:33:10 +0000 |
---|---|---|
committer | wschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-29 03:33:10 +0000 |
commit | afd2b95634aa2efdd3d49956929fc3336278c3ed (patch) | |
tree | c120873d10258dab0ff7f2e777e48a63a8f1b010 /libsanitizer | |
parent | 64ae10134da1c17b875cc78433616c6a4bfc8740 (diff) | |
download | gcc-afd2b95634aa2efdd3d49956929fc3336278c3ed.tar.gz |
2015-07-28 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR sanitizer/63927
* sanitizer_common/sanitizer_stacktrace.cc
(BufferedStackTrace::FastUnwindStack): Fix code for PowerPC to
find the link register at an offset of 16 from the base of the
caller's stack frame.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@226335 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer')
-rw-r--r-- | libsanitizer/ChangeLog | 8 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_stacktrace.cc | 11 |
2 files changed, 19 insertions, 0 deletions
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index 84147bfb2e5..94a9531497b 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,11 @@ +2015-07-28 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR sanitizer/63927 + * sanitizer_common/sanitizer_stacktrace.cc + (BufferedStackTrace::FastUnwindStack): Fix code for PowerPC to + find the link register at an offset of 16 from the base of the + caller's stack frame. + 2015-05-13 Michael Haubenwallner <michael.haubenwallner@ssi-schaefer.com> * Makefile.in: Regenerated with automake-1.11.6. diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc index 9b99b5bb201..a751da2f740 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc @@ -86,7 +86,18 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, while (IsValidFrame((uptr)frame, stack_top, bottom) && IsAligned((uptr)frame, sizeof(*frame)) && size < max_depth) { +#ifdef __powerpc__ + // PowerPC ABIs specify that the return address is saved at offset + // 16 of the *caller's* stack frame. Thus we must dereference the + // back chain to find the caller frame before extracting it. + uhwptr *caller_frame = (uhwptr*)frame[0]; + if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) || + !IsAligned((uptr)caller_frame, sizeof(uhwptr))) + break; + uhwptr pc1 = caller_frame[2]; +#else uhwptr pc1 = frame[1]; +#endif if (pc1 != pc) { trace_buffer[size++] = (uptr) pc1; } |