Blame gdb/x86-linux-nat.c

Packit Service 706eca
/* Native-dependent code for GNU/Linux x86 (i386 and x86-64).
Packit Service 706eca
Packit Service 706eca
   Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit Service 706eca
Packit Service 706eca
   This file is part of GDB.
Packit Service 706eca
Packit Service 706eca
   This program is free software; you can redistribute it and/or modify
Packit Service 706eca
   it under the terms of the GNU General Public License as published by
Packit Service 706eca
   the Free Software Foundation; either version 3 of the License, or
Packit Service 706eca
   (at your option) any later version.
Packit Service 706eca
Packit Service 706eca
   This program is distributed in the hope that it will be useful,
Packit Service 706eca
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 706eca
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 706eca
   GNU General Public License for more details.
Packit Service 706eca
Packit Service 706eca
   You should have received a copy of the GNU General Public License
Packit Service 706eca
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 706eca
Packit Service 706eca
#include "defs.h"
Packit Service 706eca
#include "inferior.h"
Packit Service 706eca
#include "elf/common.h"
Packit Service 706eca
#include "gdb_proc_service.h"
Packit Service 706eca
#include "nat/gdb_ptrace.h"
Packit Service 706eca
#include <sys/user.h>
Packit Service 706eca
#include <sys/procfs.h>
Packit Service 706eca
#include <sys/uio.h>
Packit Service 706eca
Packit Service 706eca
#include "x86-nat.h"
Packit Service 706eca
#ifndef __x86_64__
Packit Service 706eca
#include "i386-linux-nat.h"
Packit Service 706eca
#endif
Packit Service 706eca
#include "x86-linux-nat.h"
Packit Service 706eca
#include "i386-linux-tdep.h"
Packit Service 706eca
#ifdef __x86_64__
Packit Service 706eca
#include "amd64-linux-tdep.h"
Packit Service 706eca
#endif
Packit Service 706eca
#include "x86-xstate.h"
Packit Service 706eca
#include "nat/linux-btrace.h"
Packit Service 706eca
#include "nat/linux-nat.h"
Packit Service 706eca
#include "nat/x86-linux.h"
Packit Service 706eca
#include "nat/x86-linux-dregs.h"
Packit Service 706eca
#include "nat/linux-ptrace.h"
Packit Service 706eca
Packit Service 706eca
/* linux_nat_target::low_new_fork implementation.  */
Packit Service 706eca
Packit Service 706eca
void
Packit Service 706eca
x86_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
Packit Service 706eca
{
Packit Service 706eca
  pid_t parent_pid;
Packit Service 706eca
  struct x86_debug_reg_state *parent_state;
Packit Service 706eca
  struct x86_debug_reg_state *child_state;
Packit Service 706eca
Packit Service 706eca
  /* NULL means no watchpoint has ever been set in the parent.  In
Packit Service 706eca
     that case, there's nothing to do.  */
Packit Service 706eca
  if (parent->arch_private == NULL)
Packit Service 706eca
    return;
Packit Service 706eca
Packit Service 706eca
  /* Linux kernel before 2.6.33 commit
Packit Service 706eca
     72f674d203cd230426437cdcf7dd6f681dad8b0d
Packit Service 706eca
     will inherit hardware debug registers from parent
Packit Service 706eca
     on fork/vfork/clone.  Newer Linux kernels create such tasks with
Packit Service 706eca
     zeroed debug registers.
Packit Service 706eca
Packit Service 706eca
     GDB core assumes the child inherits the watchpoints/hw
Packit Service 706eca
     breakpoints of the parent, and will remove them all from the
Packit Service 706eca
     forked off process.  Copy the debug registers mirrors into the
Packit Service 706eca
     new process so that all breakpoints and watchpoints can be
Packit Service 706eca
     removed together.  The debug registers mirror will become zeroed
Packit Service 706eca
     in the end before detaching the forked off process, thus making
Packit Service 706eca
     this compatible with older Linux kernels too.  */
Packit Service 706eca
Packit Service 706eca
  parent_pid = parent->ptid.pid ();
Packit Service 706eca
  parent_state = x86_debug_reg_state (parent_pid);
Packit Service 706eca
  child_state = x86_debug_reg_state (child_pid);
Packit Service 706eca
  *child_state = *parent_state;
Packit Service 706eca
}
Packit Service 706eca

Packit Service 706eca
Packit Service 706eca
x86_linux_nat_target::~x86_linux_nat_target ()
Packit Service 706eca
{
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
void
Packit Service 706eca
x86_linux_nat_target::post_startup_inferior (ptid_t ptid)
Packit Service 706eca
{
Packit Service 706eca
  x86_cleanup_dregs ();
Packit Service 706eca
  linux_nat_target::post_startup_inferior (ptid);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
#ifdef __x86_64__
Packit Service 706eca
/* Value of CS segment register:
Packit Service 706eca
     64bit process: 0x33
Packit Service 706eca
     32bit process: 0x23  */
Packit Service 706eca
#define AMD64_LINUX_USER64_CS 0x33
Packit Service 706eca
Packit Service 706eca
/* Value of DS segment register:
Packit Service 706eca
     LP64 process: 0x0
Packit Service 706eca
     X32 process: 0x2b  */
Packit Service 706eca
#define AMD64_LINUX_X32_DS 0x2b
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
/* Get Linux/x86 target description from running target.  */
Packit Service 706eca
Packit Service 706eca
const struct target_desc *
Packit Service 706eca
x86_linux_nat_target::read_description ()
Packit Service 706eca
{
Packit Service 706eca
  int tid;
Packit Service 706eca
  int is_64bit = 0;
Packit Service 706eca
#ifdef __x86_64__
Packit Service 706eca
  int is_x32;
Packit Service 706eca
#endif
Packit Service 706eca
  static uint64_t xcr0;
Packit Service 706eca
  uint64_t xcr0_features_bits;
Packit Service 706eca
Packit Service 706eca
  /* GNU/Linux LWP ID's are process ID's.  */
Packit Service 706eca
  tid = inferior_ptid.lwp ();
Packit Service 706eca
  if (tid == 0)
Packit Service 706eca
    tid = inferior_ptid.pid (); /* Not a threaded program.  */
Packit Service 706eca
Packit Service 706eca
#ifdef __x86_64__
Packit Service 706eca
  {
Packit Service 706eca
    unsigned long cs;
Packit Service 706eca
    unsigned long ds;
Packit Service 706eca
Packit Service 706eca
    /* Get CS register.  */
Packit Service 706eca
    errno = 0;
Packit Service 706eca
    cs = ptrace (PTRACE_PEEKUSER, tid,
Packit Service 706eca
		 offsetof (struct user_regs_struct, cs), 0);
Packit Service 706eca
    if (errno != 0)
Packit Service 706eca
      perror_with_name (_("Couldn't get CS register"));
Packit Service 706eca
Packit Service 706eca
    is_64bit = cs == AMD64_LINUX_USER64_CS;
Packit Service 706eca
Packit Service 706eca
    /* Get DS register.  */
Packit Service 706eca
    errno = 0;
Packit Service 706eca
    ds = ptrace (PTRACE_PEEKUSER, tid,
Packit Service 706eca
		 offsetof (struct user_regs_struct, ds), 0);
Packit Service 706eca
    if (errno != 0)
Packit Service 706eca
      perror_with_name (_("Couldn't get DS register"));
Packit Service 706eca
Packit Service 706eca
    is_x32 = ds == AMD64_LINUX_X32_DS;
Packit Service 706eca
Packit Service 706eca
    if (sizeof (void *) == 4 && is_64bit && !is_x32)
Packit Service 706eca
      error (_("Can't debug 64-bit process with 32-bit GDB"));
Packit Service 706eca
  }
Packit Service 706eca
#elif HAVE_PTRACE_GETFPXREGS
Packit Service 706eca
  if (have_ptrace_getfpxregs == -1)
Packit Service 706eca
    {
Packit Service 706eca
      elf_fpxregset_t fpxregs;
Packit Service 706eca
Packit Service 706eca
      if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0)
Packit Service 706eca
	{
Packit Service 706eca
	  have_ptrace_getfpxregs = 0;
Packit Service 706eca
	  have_ptrace_getregset = TRIBOOL_FALSE;
Packit Service 706eca
	  return i386_linux_read_description (X86_XSTATE_X87_MASK);
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
  if (have_ptrace_getregset == TRIBOOL_UNKNOWN)
Packit Service 706eca
    {
Packit Service 706eca
      uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))];
Packit Service 706eca
      struct iovec iov;
Packit Service 706eca
Packit Service 706eca
      iov.iov_base = xstateregs;
Packit Service 706eca
      iov.iov_len = sizeof (xstateregs);
Packit Service 706eca
Packit Service 706eca
      /* Check if PTRACE_GETREGSET works.  */
Packit Service 706eca
      if (ptrace (PTRACE_GETREGSET, tid,
Packit Service 706eca
		  (unsigned int) NT_X86_XSTATE, &iov) < 0)
Packit Service 706eca
	have_ptrace_getregset = TRIBOOL_FALSE;
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  have_ptrace_getregset = TRIBOOL_TRUE;
Packit Service 706eca
Packit Service 706eca
	  /* Get XCR0 from XSAVE extended state.  */
Packit Service 706eca
	  xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
Packit Service 706eca
			     / sizeof (uint64_t))];
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  /* Check the native XCR0 only if PTRACE_GETREGSET is available.  If
Packit Service 706eca
     PTRACE_GETREGSET is not available then set xcr0_features_bits to
Packit Service 706eca
     zero so that the "no-features" descriptions are returned by the
Packit Service 706eca
     switches below.  */
Packit Service 706eca
  if (have_ptrace_getregset == TRIBOOL_TRUE)
Packit Service 706eca
    xcr0_features_bits = xcr0 & X86_XSTATE_ALL_MASK;
Packit Service 706eca
  else
Packit Service 706eca
    xcr0_features_bits = 0;
Packit Service 706eca
Packit Service 706eca
  if (is_64bit)
Packit Service 706eca
    {
Packit Service 706eca
#ifdef __x86_64__
Packit Service 706eca
      return amd64_linux_read_description (xcr0_features_bits, is_x32);
Packit Service 706eca
#endif
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      const struct target_desc * tdesc
Packit Service 706eca
	= i386_linux_read_description (xcr0_features_bits);
Packit Service 706eca
Packit Service 706eca
      if (tdesc == NULL)
Packit Service 706eca
	tdesc = i386_linux_read_description (X86_XSTATE_SSE_MASK);
Packit Service 706eca
Packit Service 706eca
      return tdesc;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  gdb_assert_not_reached ("failed to return tdesc");
Packit Service 706eca
}
Packit Service 706eca

Packit Service 706eca
Packit Service 706eca
/* Enable branch tracing.  */
Packit Service 706eca
Packit Service 706eca
struct btrace_target_info *
Packit Service 706eca
x86_linux_nat_target::enable_btrace (ptid_t ptid,
Packit Service 706eca
				     const struct btrace_config *conf)
Packit Service 706eca
{
Packit Service 706eca
  struct btrace_target_info *tinfo = nullptr;
Packit Service 706eca
  TRY
Packit Service 706eca
    {
Packit Service 706eca
      tinfo = linux_enable_btrace (ptid, conf);
Packit Service 706eca
    }
Packit Service 706eca
  CATCH (exception, RETURN_MASK_ERROR)
Packit Service 706eca
    {
Packit Service 706eca
      error (_("Could not enable branch tracing for %s: %s"),
Packit Service 706eca
	     target_pid_to_str (ptid), exception.message);
Packit Service 706eca
    }
Packit Service 706eca
  END_CATCH
Packit Service 706eca
Packit Service 706eca
  return tinfo;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Disable branch tracing.  */
Packit Service 706eca
Packit Service 706eca
void
Packit Service 706eca
x86_linux_nat_target::disable_btrace (struct btrace_target_info *tinfo)
Packit Service 706eca
{
Packit Service 706eca
  enum btrace_error errcode = linux_disable_btrace (tinfo);
Packit Service 706eca
Packit Service 706eca
  if (errcode != BTRACE_ERR_NONE)
Packit Service 706eca
    error (_("Could not disable branch tracing."));
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Teardown branch tracing.  */
Packit Service 706eca
Packit Service 706eca
void
Packit Service 706eca
x86_linux_nat_target::teardown_btrace (struct btrace_target_info *tinfo)
Packit Service 706eca
{
Packit Service 706eca
  /* Ignore errors.  */
Packit Service 706eca
  linux_disable_btrace (tinfo);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
enum btrace_error
Packit Service 706eca
x86_linux_nat_target::read_btrace (struct btrace_data *data,
Packit Service 706eca
				   struct btrace_target_info *btinfo,
Packit Service 706eca
				   enum btrace_read_type type)
Packit Service 706eca
{
Packit Service 706eca
  return linux_read_btrace (data, btinfo, type);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* See to_btrace_conf in target.h.  */
Packit Service 706eca
Packit Service 706eca
const struct btrace_config *
Packit Service 706eca
x86_linux_nat_target::btrace_conf (const struct btrace_target_info *btinfo)
Packit Service 706eca
{
Packit Service 706eca
  return linux_btrace_conf (btinfo);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca

Packit Service 706eca
Packit Service 706eca
/* Helper for ps_get_thread_area.  Sets BASE_ADDR to a pointer to
Packit Service 706eca
   the thread local storage (or its descriptor) and returns PS_OK
Packit Service 706eca
   on success.  Returns PS_ERR on failure.  */
Packit Service 706eca
Packit Service 706eca
ps_err_e
Packit Service 706eca
x86_linux_get_thread_area (pid_t pid, void *addr, unsigned int *base_addr)
Packit Service 706eca
{
Packit Service 706eca
  /* NOTE: cagney/2003-08-26: The definition of this buffer is found
Packit Service 706eca
     in the kernel header <asm-i386/ldt.h>.  It, after padding, is 4 x
Packit Service 706eca
     4 byte integers in size: `entry_number', `base_addr', `limit',
Packit Service 706eca
     and a bunch of status bits.
Packit Service 706eca
Packit Service 706eca
     The values returned by this ptrace call should be part of the
Packit Service 706eca
     regcache buffer, and ps_get_thread_area should channel its
Packit Service 706eca
     request through the regcache.  That way remote targets could
Packit Service 706eca
     provide the value using the remote protocol and not this direct
Packit Service 706eca
     call.
Packit Service 706eca
Packit Service 706eca
     Is this function needed?  I'm guessing that the `base' is the
Packit Service 706eca
     address of a descriptor that libthread_db uses to find the
Packit Service 706eca
     thread local address base that GDB needs.  Perhaps that
Packit Service 706eca
     descriptor is defined by the ABI.  Anyway, given that
Packit Service 706eca
     libthread_db calls this function without prompting (gdb
Packit Service 706eca
     requesting tls base) I guess it needs info in there anyway.  */
Packit Service 706eca
  unsigned int desc[4];
Packit Service 706eca
Packit Service 706eca
  /* This code assumes that "int" is 32 bits and that
Packit Service 706eca
     GET_THREAD_AREA returns no more than 4 int values.  */
Packit Service 706eca
  gdb_assert (sizeof (int) == 4);
Packit Service 706eca
Packit Service 706eca
#ifndef PTRACE_GET_THREAD_AREA
Packit Service 706eca
#define PTRACE_GET_THREAD_AREA 25
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
  if (ptrace (PTRACE_GET_THREAD_AREA, pid, addr, &desc) < 0)
Packit Service 706eca
    return PS_ERR;
Packit Service 706eca
Packit Service 706eca
  *base_addr = desc[1];
Packit Service 706eca
  return PS_OK;
Packit Service 706eca
}
Packit Service 706eca

Packit Service 706eca
Packit Service 706eca
void
Packit Service 706eca
_initialize_x86_linux_nat ()
Packit Service 706eca
{
Packit Service 706eca
  /* Initialize the debug register function vectors.  */
Packit Service 706eca
  x86_dr_low.set_control = x86_linux_dr_set_control;
Packit Service 706eca
  x86_dr_low.set_addr = x86_linux_dr_set_addr;
Packit Service 706eca
  x86_dr_low.get_addr = x86_linux_dr_get_addr;
Packit Service 706eca
  x86_dr_low.get_status = x86_linux_dr_get_status;
Packit Service 706eca
  x86_dr_low.get_control = x86_linux_dr_get_control;
Packit Service 706eca
  x86_set_debug_register_length (sizeof (void *));
Packit Service 706eca
}