diff mbox

[aarch64] add unwind support for aarch64-*-freebsd*

Message ID 35429be2-c1f0-a119-f0c3-a27242c0f0b7@fgznet.ch
State New
Headers show

Commit Message

Andreas Tobler Feb. 16, 2017, 7:21 p.m. UTC
Hi all,

the attached patch adds unwind support for aarch64-*-freebsd*.

John used to catch unwind tests in ada.
So far it bootstraps and I see no regressions.

is this ok for trunk?

TIA,
Andreas

2017-02-16  John Marino  <gnugcc@marino.st>

	* config/aarch64/freebsd-unwind.h: New file.
	* config.host: Add aarch64-*-freebsd unwinder.

Comments

Andreas Tobler March 9, 2017, 12:50 p.m. UTC | #1
Ping!

TIA,
Andreas

On 16.02.17 20:21, Andreas Tobler wrote:
> Hi all,
>
> the attached patch adds unwind support for aarch64-*-freebsd*.
>
> John used to catch unwind tests in ada.
> So far it bootstraps and I see no regressions.
>
> is this ok for trunk?
>
> TIA,
> Andreas
>
> 2017-02-16  John Marino  <gnugcc@marino.st>
>
> 	* config/aarch64/freebsd-unwind.h: New file.
> 	* config.host: Add aarch64-*-freebsd unwinder.
>
Gerald Pfeifer March 9, 2017, 9:44 p.m. UTC | #2
On Thu, 9 Mar 2017, Andreas Tobler wrote:
> Ping!

Why are you pinging this, Andreas?  Are you seeking review to
make sure this is appropriate?

>> 2017-02-16  John Marino  <gnugcc@marino.st>
>> 
>> 	* config/aarch64/freebsd-unwind.h: New file.
>> 	* config.host: Add aarch64-*-freebsd unwinder.

I'm asking since this looks like a FreeBSD-related, in fact, 
FreeBSD-specific patch to me.

And MAINTAINERS has

  freebsd                 Andreas Tobler          <andreast@gcc.gnu.org>

so this is something you can approve yourself.

Gerald

PS: John, gnugcc is a bit like United US. :-)
Andreas Tobler March 9, 2017, 10:18 p.m. UTC | #3
On 09.03.17 22:44, Gerald Pfeifer wrote:
> On Thu, 9 Mar 2017, Andreas Tobler wrote:
>> Ping!
>
> Why are you pinging this, Andreas?  Are you seeking review to
> make sure this is appropriate?
>
>>> 2017-02-16  John Marino  <gnugcc@marino.st>
>>>
>>> 	* config/aarch64/freebsd-unwind.h: New file.
>>> 	* config.host: Add aarch64-*-freebsd unwinder.
>
> I'm asking since this looks like a FreeBSD-related, in fact,
> FreeBSD-specific patch to me.
>
> And MAINTAINERS has
>
>   freebsd                 Andreas Tobler          <andreast@gcc.gnu.org>
>
> so this is something you can approve yourself.

Basically yes, but I'm not sure how the planning and the freeze for 
trunk is. This is why ping.

Thanks,
Andreas
Gerald Pfeifer March 9, 2017, 10:34 p.m. UTC | #4
On Thu, 9 Mar 2017, Andreas Tobler wrote:
> Basically yes, but I'm not sure how the planning and the freeze for 
> trunk is. This is why ping.

If (since?) this can only affect FreeBSD, or really FreeBSD/aarch64, 
you are pretty much at liberty to make such a change. 

(We did not formally document this, but this is neither a tier 1 nor 
tier 2 platform, which gives you more leeway since, by definition, it 
cannot delay the release.)

Still, you break it, you get to fix it, or have people not like you. :-)

Gerald
diff mbox

Patch

Index: config.host
===================================================================
--- config.host	(revision 245512)
+++ config.host	(working copy)
@@ -340,7 +340,7 @@ 
 	extra_parts="$extra_parts crtfastmath.o"
 	tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
 	tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm"
-	md_unwind_header=aarch64/aarch64-unwind.h
+	md_unwind_header=aarch64/freebsd-unwind.h
 	;;
 aarch64*-*-linux*)
 	extra_parts="$extra_parts crtfastmath.o"
Index: config/aarch64/freebsd-unwind.h
===================================================================
--- config/aarch64/freebsd-unwind.h	(nonexistent)
+++ config/aarch64/freebsd-unwind.h	(working copy)
@@ -0,0 +1,108 @@ 
+/* DWARF2 EH unwinding support for FreeBSD/ARM64 (aarch64).
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   Contributed by John Marino <gnugcc@marino.st>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Identify a signal frame, and set the frame state data appropriately.
+   See unwind-dw2.c for the structs. */
+
+/* Always include AArch64 unwinder header file.  */
+#include "config/aarch64/aarch64-unwind.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/ucontext.h>
+#include <machine/frame.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+
+#define REG_NAME(reg)   mc_gpregs.gp_## reg
+#define XREG(num)       mc_gpregs.gp_x[num]
+#define DARC            __LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__
+
+#define MD_FALLBACK_FRAME_STATE_FOR aarch64_freebsd_fallback_frame_state
+
+static int
+aarch64_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);
+}
+
+static _Unwind_Reason_Code
+aarch64_freebsd_fallback_frame_state
+(struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  int n;
+  struct sigframe *sf;
+  mcontext_t *sc;
+  _Unwind_Ptr new_cfa;
+
+  if (aarch64_outside_sigtramp_range(context->ra))
+    return _URC_END_OF_STACK;
+
+  sf = (struct sigframe *) context->cfa;
+  sc = &sf->sf_uc.uc_mcontext;
+
+  new_cfa = (_Unwind_Ptr) sc;
+  fs->regs.cfa_how = CFA_REG_OFFSET;
+  fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
+  fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
+
+  for (n = 0; n < 32; n++)
+    fs->regs.reg[n].how = REG_SAVED_OFFSET;
+
+  for (n = 0; n < 30; n++)
+    fs->regs.reg[n].loc.offset = (_Unwind_Ptr) &(sc->XREG(n)) - new_cfa;
+
+  fs->regs.reg[30].loc.offset = (_Unwind_Ptr) &(sc->REG_NAME(lr)) - new_cfa;
+  fs->regs.reg[31].loc.offset = (_Unwind_Ptr) &(sc->REG_NAME(sp)) - new_cfa;
+
+  fs->regs.reg[DARC].how = REG_SAVED_OFFSET;
+  fs->regs.reg[DARC].loc.offset = (_Unwind_Ptr) &(sc->REG_NAME(elr)) - new_cfa;
+
+  fs->retaddr_column = DARC;
+  fs->signal_frame = 1;
+
+  return _URC_NO_REASON;
+}