summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorMaxim Kuvyrkov <maxim.kuvyrkov@linaro.org>2017-11-16 11:58:53 +0000
committerMaxim Kuvyrkov <maxim.kuvyrkov@linaro.org>2017-11-16 11:58:53 +0000
commit115902984185e7056652c58b2069d6253517c9b9 (patch)
treef62be0e56cd1e065ea16e2d1ce4e6011ff8b8300 /libgcc
parent76a2e9c7ffd7d7a426ab9c614c7845fe265c4fe7 (diff)
downloadgcc-115902984185e7056652c58b2069d6253517c9b9.tar.gz
Merge branches/gcc-7-branch rev 254792.
Change-Id: I67684002abf84c64d0e873a8044b211923c56499
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog18
-rw-r--r--libgcc/config/i386/freebsd-unwind.h43
-rw-r--r--libgcc/libgcc2.c3
3 files changed, 61 insertions, 3 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index aa1b04bec43..569963ba46e 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,21 @@
+2017-11-05 Andreas Tobler <andreast@gcc.gnu.org>
+
+ Backport from mainline
+ 2017-11-04 Andreas Tobler <andreast@gcc.gnu.org>
+
+ PR libgcc/82635
+ * config/i386/freebsd-unwind.h (MD_FALLBACK_FRAME_STATE_FOR): Use a
+ sysctl to determine whether we're in a trampoline.
+ Keep the pattern matching method for systems without
+ KERN_PROC_SIGTRAMP sysctl.
+
+2017-10-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/82274
+ * libgcc2.c (__mulvDI3): If both operands have
+ the same highpart of -1 and the topmost bit of lowpart is 0,
+ multiplication overflows even if both lowparts are 0.
+
2017-09-28 Krister Walfridsson <krister.walfridsson@gmail.com>
Backport from mainline
diff --git a/libgcc/config/i386/freebsd-unwind.h b/libgcc/config/i386/freebsd-unwind.h
index 0eec584a11e..a8e8edb993a 100644
--- a/libgcc/config/i386/freebsd-unwind.h
+++ b/libgcc/config/i386/freebsd-unwind.h
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <sys/types.h>
#include <signal.h>
+#include <unistd.h>
+#include <sys/sysctl.h>
#include <sys/ucontext.h>
+#include <sys/user.h>
#include <machine/sigframe.h>
#define REG_NAME(reg) sf_uc.uc_mcontext.mc_## reg
@@ -36,6 +39,38 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifdef __x86_64__
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_freebsd_fallback_frame_state
+#ifdef KERN_PROC_SIGTRAMP
+/* FreeBSD past 9.3 provides a kern.proc.sigtramp.<pid> sysctl that
+ returns the location of the signal trampoline. Use this to find
+ out whether we're in a trampoline.
+*/
+static int
+x86_64_outside_sigtramp_range (unsigned char *pc)
+{
+ static int sigtramp_range_determined = 0;
+ static unsigned char *sigtramp_start, *sigtramp_end;
+
+ if (sigtramp_range_determined == 0)
+ {
+ struct kinfo_sigtramp kst = {0};
+ size_t len = sizeof (kst);
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_SIGTRAMP, getpid() };
+
+ sigtramp_range_determined = 1;
+ if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
+ {
+ sigtramp_range_determined = 2;
+ sigtramp_start = kst.ksigtramp_start;
+ sigtramp_end = kst.ksigtramp_end;
+ }
+ }
+ if (sigtramp_range_determined < 2) /* sysctl failed if < 2 */
+ return 1;
+
+ return (pc < sigtramp_start || pc >= sigtramp_end);
+}
+#endif
+
static _Unwind_Reason_Code
x86_64_freebsd_fallback_frame_state
(struct _Unwind_Context *context, _Unwind_FrameState *fs)
@@ -43,6 +78,7 @@ x86_64_freebsd_fallback_frame_state
struct sigframe *sf;
long new_cfa;
+#ifndef KERN_PROC_SIGTRAMP
/* Prior to FreeBSD 9, the signal trampoline was located immediately
before the ps_strings. To support non-executable stacks on AMD64,
the sigtramp was moved to a shared page for FreeBSD 9. Unfortunately
@@ -62,12 +98,15 @@ x86_64_freebsd_fallback_frame_state
&& *(unsigned int *)(context->ra + 8) == 0x01a1c0c7
&& *(unsigned int *)(context->ra + 12) == 0x050f0000 ))
return _URC_END_OF_STACK;
+#else
+ if (x86_64_outside_sigtramp_range(context->ra))
+ return _URC_END_OF_STACK;
+#endif
sf = (struct sigframe *) context->cfa;
new_cfa = sf->REG_NAME(rsp);
fs->regs.cfa_how = CFA_REG_OFFSET;
- /* Register 7 is rsp */
- fs->regs.cfa_reg = 7;
+ fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
/* The SVR4 register numbering macros aren't usable in libgcc. */
diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c
index 5d3c69f16aa..83f865a04db 100644
--- a/libgcc/libgcc2.c
+++ b/libgcc/libgcc2.c
@@ -375,7 +375,8 @@ __mulvDI3 (DWtype u, DWtype v)
}
else
{
- if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
+ if ((uu.s.high & vv.s.high) == (Wtype) -1
+ && (uu.s.low | vv.s.low) != 0)
{
DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
* (UDWtype) (UWtype) vv.s.low};