/* Target-dependent code for FreeBSD/i386.

   Copyright (C) 2003-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "gdbcore.h"
#include "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "i386-fbsd-tdep.h"
#include "gdbsupport/x86-xstate.h"

#include "i386-tdep.h"
#include "i387-tdep.h"
#include "fbsd-tdep.h"
#include "solib-svr4.h"
#include "inferior.h"

/* Support for signal handlers.  */

/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
   routine.  */

/* FreeBSD/i386 supports three different signal trampolines, one for
   versions before 4.0, a second for 4.x, and a third for 5.0 and
   later.  To complicate matters, FreeBSD/i386 binaries running under
   an amd64 kernel use a different set of trampolines.  These
   trampolines differ from the i386 kernel trampolines in that they
   omit a middle section that conditionally restores %gs.  */

static const gdb_byte i386fbsd_sigtramp_start[] =
{
  0x8d, 0x44, 0x24, 0x20,       /* lea     SIGF_UC(%esp),%eax */
  0x50				/* pushl   %eax */
};

static const gdb_byte i386fbsd_sigtramp_middle[] =
{
  0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00,
				/* testl   $PSL_VM,UC_EFLAGS(%eax) */
  0x75, 0x03,			/* jne	   +3 */
  0x8e, 0x68, 0x14		/* mov	   UC_GS(%eax),%gs */
};

static const gdb_byte i386fbsd_sigtramp_end[] =
{
  0xb8, 0xa1, 0x01, 0x00, 0x00, /* movl   $SYS_sigreturn,%eax */
  0x50,			/* pushl   %eax */
  0xcd, 0x80			/* int	   $0x80 */
};

static const gdb_byte i386fbsd_freebsd4_sigtramp_start[] =
{
  0x8d, 0x44, 0x24, 0x14,	/* lea	   SIGF_UC4(%esp),%eax */
  0x50				/* pushl   %eax */
};

static const gdb_byte i386fbsd_freebsd4_sigtramp_middle[] =
{
  0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00,
				/* testl   $PSL_VM,UC4_EFLAGS(%eax) */
  0x75, 0x03,			/* jne	   +3 */
  0x8e, 0x68, 0x14		/* mov	   UC4_GS(%eax),%gs */
};

static const gdb_byte i386fbsd_freebsd4_sigtramp_end[] =
{
  0xb8, 0x58, 0x01, 0x00, 0x00, /* movl    $344,%eax */
  0x50,			/* pushl   %eax */
  0xcd, 0x80			/* int	   $0x80 */
};

static const gdb_byte i386fbsd_osigtramp_start[] =
{
  0x8d, 0x44, 0x24, 0x14,	/* lea	   SIGF_SC(%esp),%eax */
  0x50				/* pushl   %eax */
};

static const gdb_byte i386fbsd_osigtramp_middle[] =
{
  0xf7, 0x40, 0x18, 0x00, 0x00, 0x02, 0x00,
				/* testl   $PSL_VM,SC_PS(%eax) */
  0x75, 0x03,			/* jne	   +3 */
  0x8e, 0x68, 0x44		/* mov	   SC_GS(%eax),%gs */
};

static const gdb_byte i386fbsd_osigtramp_end[] =
{
  0xb8, 0x67, 0x00, 0x00, 0x00, /* movl    $103,%eax */
  0x50,			/* pushl   %eax */
  0xcd, 0x80			/* int	   $0x80 */
};

/* The three different trampolines are all the same size.  */
gdb_static_assert (sizeof i386fbsd_sigtramp_start
		   == sizeof i386fbsd_freebsd4_sigtramp_start);
gdb_static_assert (sizeof i386fbsd_sigtramp_start
		   == sizeof i386fbsd_osigtramp_start);
gdb_static_assert (sizeof i386fbsd_sigtramp_middle
		   == sizeof i386fbsd_freebsd4_sigtramp_middle);
gdb_static_assert (sizeof i386fbsd_sigtramp_middle
		   == sizeof i386fbsd_osigtramp_middle);
gdb_static_assert (sizeof i386fbsd_sigtramp_end
		   == sizeof i386fbsd_freebsd4_sigtramp_end);
gdb_static_assert (sizeof i386fbsd_sigtramp_end
		   == sizeof i386fbsd_osigtramp_end);

/* We assume that the middle is the largest chunk below.  */
gdb_static_assert (sizeof i386fbsd_sigtramp_middle
		   > sizeof i386fbsd_sigtramp_start);
gdb_static_assert (sizeof i386fbsd_sigtramp_middle
		   > sizeof i386fbsd_sigtramp_end);

static int
i386fbsd_sigtramp_p (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  gdb_byte buf[sizeof i386fbsd_sigtramp_middle];
  const gdb_byte *middle, *end;

  /* Look for a matching start.  */
  if (!safe_frame_unwind_memory (this_frame, pc,
				 {buf, sizeof i386fbsd_sigtramp_start}))
    return 0;
  if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start)
      == 0)
    {
      middle = i386fbsd_sigtramp_middle;
      end = i386fbsd_sigtramp_end;
    }
  else if (memcmp (buf, i386fbsd_freebsd4_sigtramp_start,
		   sizeof i386fbsd_freebsd4_sigtramp_start) == 0)
    {
      middle = i386fbsd_freebsd4_sigtramp_middle;
      end = i386fbsd_freebsd4_sigtramp_end;
    }
  else if (memcmp (buf, i386fbsd_osigtramp_start,
		   sizeof i386fbsd_osigtramp_start) == 0)
    {
      middle = i386fbsd_osigtramp_middle;
      end = i386fbsd_osigtramp_end;
    }
  else
    return 0;

  /* Since the end is shorter than the middle, check for a matching end
     next.  */
  pc += sizeof i386fbsd_sigtramp_start;
  if (!safe_frame_unwind_memory (this_frame, pc,
				 {buf, sizeof i386fbsd_sigtramp_end}))
    return 0;
  if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) == 0)
    return 1;

  /* If the end didn't match, check for a matching middle.  */
  if (!safe_frame_unwind_memory (this_frame, pc,
				 {buf, sizeof i386fbsd_sigtramp_middle}))
    return 0;
  if (memcmp (buf, middle, sizeof i386fbsd_sigtramp_middle) != 0)
    return 0;

  /* The middle matched, check for a matching end.  */
  pc += sizeof i386fbsd_sigtramp_middle;
  if (!safe_frame_unwind_memory (this_frame, pc,
				 {buf, sizeof i386fbsd_sigtramp_end}))
    return 0;
  if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) != 0)
    return 0;

  return 1;
}

/* FreeBSD 3.0-RELEASE or later.  */

/* From <machine/reg.h>.  */
static int i386fbsd_r_reg_offset[] =
{
  9 * 4, 8 * 4, 7 * 4, 6 * 4,	/* %eax, %ecx, %edx, %ebx */
  15 * 4, 4 * 4,		/* %esp, %ebp */
  3 * 4, 2 * 4,			/* %esi, %edi */
  12 * 4, 14 * 4,		/* %eip, %eflags */
  13 * 4, 16 * 4,		/* %cs, %ss */
  1 * 4, 0 * 4, -1, -1		/* %ds, %es, %fs, %gs */
};

/* Sigtramp routine location.  */
CORE_ADDR i386fbsd_sigtramp_start_addr;
CORE_ADDR i386fbsd_sigtramp_end_addr;

/* From <machine/signal.h>.  */
int i386fbsd_sc_reg_offset[] =
{
  8 + 14 * 4,			/* %eax */
  8 + 13 * 4,			/* %ecx */
  8 + 12 * 4,			/* %edx */
  8 + 11 * 4,			/* %ebx */
  8 + 0 * 4,                    /* %esp */
  8 + 1 * 4,                    /* %ebp */
  8 + 10 * 4,                   /* %esi */
  8 + 9 * 4,                    /* %edi */
  8 + 3 * 4,                    /* %eip */
  8 + 4 * 4,                    /* %eflags */
  8 + 7 * 4,                    /* %cs */
  8 + 8 * 4,                    /* %ss */
  8 + 6 * 4,                    /* %ds */
  8 + 5 * 4,                    /* %es */
  8 + 15 * 4,			/* %fs */
  8 + 16 * 4			/* %gs */
};

/* Get XSAVE extended state xcr0 from core dump.  */

uint64_t
i386fbsd_core_read_xcr0 (bfd *abfd)
{
  asection *xstate = bfd_get_section_by_name (abfd, ".reg-xstate");
  uint64_t xcr0;

  if (xstate)
    {
      size_t size = bfd_section_size (xstate);

      /* Check extended state size.  */
      if (size < X86_XSTATE_AVX_SIZE)
	xcr0 = X86_XSTATE_SSE_MASK;
      else
	{
	  char contents[8];

	  if (! bfd_get_section_contents (abfd, xstate, contents,
					  I386_FBSD_XSAVE_XCR0_OFFSET,
					  8))
	    {
	      warning (_("Couldn't read `xcr0' bytes from "
			 "`.reg-xstate' section in core file."));
	      return X86_XSTATE_SSE_MASK;
	    }

	  xcr0 = bfd_get_64 (abfd, contents);
	}
    }
  else
    xcr0 = X86_XSTATE_SSE_MASK;

  return xcr0;
}

/* Implement the core_read_description gdbarch method.  */

static const struct target_desc *
i386fbsd_core_read_description (struct gdbarch *gdbarch,
				struct target_ops *target,
				bfd *abfd)
{
  return i386_target_description (i386fbsd_core_read_xcr0 (abfd), true);
}

/* Similar to i386_supply_fpregset, but use XSAVE extended state.  */

static void
i386fbsd_supply_xstateregset (const struct regset *regset,
			      struct regcache *regcache, int regnum,
			      const void *xstateregs, size_t len)
{
  i387_supply_xsave (regcache, regnum, xstateregs);
}

/* Similar to i386_collect_fpregset, but use XSAVE extended state.  */

static void
i386fbsd_collect_xstateregset (const struct regset *regset,
			       const struct regcache *regcache,
			       int regnum, void *xstateregs, size_t len)
{
  i387_collect_xsave (regcache, regnum, xstateregs, 1);
}

/* Register set definitions.  */

static const struct regset i386fbsd_xstateregset =
  {
    NULL,
    i386fbsd_supply_xstateregset,
    i386fbsd_collect_xstateregset
  };

/* Iterate over core file register note sections.  */

static void
i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
				       iterate_over_regset_sections_cb *cb,
				       void *cb_data,
				       const struct regcache *regcache)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  cb (".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, &i386_gregset, NULL,
      cb_data);
  cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, &i386_fpregset,
      NULL, cb_data);

  if (tdep->xcr0 & X86_XSTATE_AVX)
    cb (".reg-xstate", X86_XSTATE_SIZE (tdep->xcr0),
	X86_XSTATE_SIZE (tdep->xcr0), &i386fbsd_xstateregset,
	"XSAVE extended state", cb_data);
}

/* Implement the get_thread_local_address gdbarch method.  */

static CORE_ADDR
i386fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
				   CORE_ADDR lm_addr, CORE_ADDR offset)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  struct regcache *regcache;

  if (tdep->fsbase_regnum == -1)
    error (_("Unable to fetch %%gsbase"));

  regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
				       ptid, gdbarch);

  target_fetch_registers (regcache, tdep->fsbase_regnum + 1);

  ULONGEST gsbase;
  if (regcache->cooked_read (tdep->fsbase_regnum + 1, &gsbase) != REG_VALID)
    error (_("Unable to fetch %%gsbase"));

  CORE_ADDR dtv_addr = gsbase + gdbarch_ptr_bit (gdbarch) / 8;
  return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
}

static void
i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* Obviously FreeBSD is BSD-based.  */
  i386bsd_init_abi (info, gdbarch);

  /* FreeBSD has a different `struct reg', and reserves some space for
     its FPU emulator in `struct fpreg'.  */
  tdep->gregset_reg_offset = i386fbsd_r_reg_offset;
  tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd_r_reg_offset);
  tdep->sizeof_gregset = 18 * 4;
  tdep->sizeof_fpregset = 176;

  /* FreeBSD uses -freg-struct-return by default.  */
  tdep->struct_return = reg_struct_return;

  tdep->sigtramp_p = i386fbsd_sigtramp_p;

  /* FreeBSD uses a different memory layout.  */
  tdep->sigtramp_start = i386fbsd_sigtramp_start_addr;
  tdep->sigtramp_end = i386fbsd_sigtramp_end_addr;

  /* FreeBSD has a more complete `struct sigcontext'.  */
  tdep->sc_reg_offset = i386fbsd_sc_reg_offset;
  tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset);

  i386_elf_init_abi (info, gdbarch);

  /* FreeBSD uses SVR4-style shared libraries.  */
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
}

/* FreeBSD 4.0-RELEASE or later.  */

/* From <machine/reg.h>.  */
static int i386fbsd4_r_reg_offset[] =
{
  10 * 4, 9 * 4, 8 * 4, 7 * 4,	/* %eax, %ecx, %edx, %ebx */
  16 * 4, 5 * 4,		/* %esp, %ebp */
  4 * 4, 3 * 4,			/* %esi, %edi */
  13 * 4, 15 * 4,		/* %eip, %eflags */
  14 * 4, 17 * 4,		/* %cs, %ss */
  2 * 4, 1 * 4, 0 * 4, 18 * 4	/* %ds, %es, %fs, %gs */
};

/* From <machine/signal.h>.  */
int i386fbsd4_sc_reg_offset[] =
{
  20 + 11 * 4,			/* %eax */
  20 + 10 * 4,			/* %ecx */
  20 + 9 * 4,			/* %edx */
  20 + 8 * 4,			/* %ebx */
  20 + 17 * 4,			/* %esp */
  20 + 6 * 4,			/* %ebp */
  20 + 5 * 4,			/* %esi */
  20 + 4 * 4,			/* %edi */
  20 + 14 * 4,			/* %eip */
  20 + 16 * 4,			/* %eflags */
  20 + 15 * 4,			/* %cs */
  20 + 18 * 4,			/* %ss */
  20 + 3 * 4,			/* %ds */
  20 + 2 * 4,			/* %es */
  20 + 1 * 4,			/* %fs */
  20 + 0 * 4			/* %gs */
};

static void
i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* Generic FreeBSD support. */
  fbsd_init_abi (info, gdbarch);

  /* Inherit stuff from older releases.  We assume that FreeBSD
     4.0-RELEASE always uses ELF.  */
  i386fbsd_init_abi (info, gdbarch);

  /* FreeBSD 4.0 introduced a new `struct reg'.  */
  tdep->gregset_reg_offset = i386fbsd4_r_reg_offset;
  tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd4_r_reg_offset);
  tdep->sizeof_gregset = 19 * 4;

  /* FreeBSD 4.0 introduced a new `struct sigcontext'.  */
  tdep->sc_reg_offset = i386fbsd4_sc_reg_offset;
  tdep->sc_num_regs = ARRAY_SIZE (i386fbsd4_sc_reg_offset);

  tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;

  /* Iterate over core file register note sections.  */
  set_gdbarch_iterate_over_regset_sections
    (gdbarch, i386fbsd_iterate_over_regset_sections);

  set_gdbarch_core_read_description (gdbarch,
				     i386fbsd_core_read_description);

  set_gdbarch_fetch_tls_load_module_address (gdbarch,
					     svr4_fetch_objfile_link_map);
  set_gdbarch_get_thread_local_address (gdbarch,
					i386fbsd_get_thread_local_address);
}

void _initialize_i386fbsd_tdep ();
void
_initialize_i386fbsd_tdep ()
{
  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD,
			  i386fbsd4_init_abi);
}
