diff options
author | Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org> | 2017-11-16 11:58:53 +0000 |
---|---|---|
committer | Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org> | 2017-11-16 11:58:53 +0000 |
commit | 115902984185e7056652c58b2069d6253517c9b9 (patch) | |
tree | f62be0e56cd1e065ea16e2d1ce4e6011ff8b8300 /libgcc | |
parent | 76a2e9c7ffd7d7a426ab9c614c7845fe265c4fe7 (diff) | |
download | gcc-115902984185e7056652c58b2069d6253517c9b9.tar.gz |
Merge branches/gcc-7-branch rev 254792.
Change-Id: I67684002abf84c64d0e873a8044b211923c56499
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 18 | ||||
-rw-r--r-- | libgcc/config/i386/freebsd-unwind.h | 43 | ||||
-rw-r--r-- | libgcc/libgcc2.c | 3 |
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}; |