View | Details | Raw Unified | Return to bug 157755 | Differences between
and this patch

Collapse All | Expand All

(-)b/gnu/usr.bin/gdb/arch/i386/Makefile (-1 / +20 lines)
Lines 9-15 LIBSRCS+= solib.c solib-svr4.c Link Here
9
LIBSRCS+= i386-tdep.c i386bsd-tdep.c i386fbsd-tdep-fixed.c i387-tdep.c
9
LIBSRCS+= i386-tdep.c i386bsd-tdep.c i386fbsd-tdep-fixed.c i387-tdep.c
10
10
11
nm.h:
11
nm.h:
12
	echo '#include "i386/nm-fbsd.h"' > ${.TARGET}
12
	echo '#ifndef GENSRCS_NM_H' > ${.TARGET}
13
	echo '#define GENSRCS_NM_H' >> ${.TARGET}
14
	echo '#include "i386/nm-fbsd.h"' >> ${.TARGET}
15
	echo '#undef I386_DR_LOW_SET_CONTROL' >> ${.TARGET}
16
	echo '#undef I386_DR_LOW_SET_ADDR' >> ${.TARGET}
17
	echo '#undef I386_DR_LOW_RESET_ADDR' >> ${.TARGET}
18
	echo '#undef I386_DR_LOW_GET_STATUS' >> ${.TARGET}
19
	echo '#define I386_DR_LOW_SET_CONTROL(c) \' >> ${.TARGET}
20
	echo '  fbsd_thread_dr_set_control (c)' >> ${.TARGET}
21
	echo 'void i386bsd_dr_set_control (unsigned long);' >> ${.TARGET}
22
	echo '#define I386_DR_LOW_SET_ADDR(r, v) \' >> ${.TARGET}
23
	echo '  fbsd_thread_dr_set_addr (r, v)' >> ${.TARGET}
24
	echo 'void fbsd_thread_dr_set_addr (int, CORE_ADDR);' >> ${.TARGET}
25
	echo '#define I386_DR_LOW_RESET_ADDR(r) \' >> ${.TARGET}
26
	echo '  fbsd_thread_dr_reset_addr (r)' >> ${.TARGET}
27
	echo 'void fbsd_thread_dr_reset_addr (int);' >> ${.TARGET}
28
	echo '#define I386_DR_LOW_GET_STATUS() \' >> ${.TARGET}
29
	echo '  fbsd_thread_dr_get_status ()' >> ${.TARGET}
30
	echo 'unsigned long fbsd_thread_dr_get_status (void);' >> ${.TARGET}
31
	echo '#endif /* GENSRCS_NM_H */' >> ${.TARGET}
13
32
14
tm.h:
33
tm.h:
15
	echo '#include "i386/tm-fbsd.h"' > ${.TARGET}
34
	echo '#include "i386/tm-fbsd.h"' > ${.TARGET}
(-)b/gnu/usr.bin/gdb/libgdb/fbsd-threads.c (+180 lines)
Lines 1797-1799 ps_linfo(struct ps_prochandle *ph, lwpid Link Here
1797
    return PS_ERR;
1797
    return PS_ERR;
1798
  return PS_OK;
1798
  return PS_OK;
1799
}
1799
}
1800
1801
1802
#if defined(HAVE_PT_GETDBREGS) && defined(I386_DR_LOW_SET_ADDR)
1803
/* Hardware watchpoint support based on i386bsd-nat.c: */
1804
/* Native-dependent code for modern i386 BSD's.
1805
   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
1806
1807
   This file is part of GDB.
1808
1809
   This program is free software; you can redistribute it and/or modify
1810
   it under the terms of the GNU General Public License as published by
1811
   the Free Software Foundation; either version 2 of the License, or
1812
   (at your option) any later version.
1813
1814
   This program is distributed in the hope that it will be useful,
1815
   but WITHOUT ANY WARRANTY; without even the implied warranty of
1816
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1817
   GNU General Public License for more details.
1818
1819
   You should have received a copy of the GNU General Public License
1820
   along with this program; if not, write to the Free Software
1821
   Foundation, Inc., 59 Temple Place - Suite 330,
1822
   Boston, MA 02111-1307, USA.  */
1823
1824
/*
1825
 * We need to add threads support because debug registers need to be
1826
 * set per LWP to implement hardware watchpoints.
1827
 * 
1828
 * We do not need to care user-level threads contexts for debug registers
1829
 * since they are not in mcontext.
1830
 */
1831
1832
/* Not all versions of FreeBSD/i386 that support the debug registers
1833
   have this macro.  */
1834
#ifndef DBREG_DRX
1835
#define DBREG_DRX(d, x) ((&d->dr0)[x])
1836
#endif
1837
1838
static void
1839
fbsd_lwp_dr_set (lwpid_t lwpid, int regnum, unsigned long value)
1840
{
1841
  struct dbreg dbregs;
1842
1843
  if (ptrace (PT_GETDBREGS, lwpid,
1844
              (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
1845
    perror_with_name ("Couldn't get debug registers");
1846
1847
  /* For some mysterious reason, some of the reserved bits in the
1848
     debug control register get set.  Mask these off, otherwise the
1849
     ptrace call below will fail.  */
1850
  DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00);
1851
1852
  DBREG_DRX ((&dbregs), regnum) = value;
1853
1854
  if (ptrace (PT_SETDBREGS, lwpid,
1855
              (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
1856
    perror_with_name ("Couldn't write debug registers");
1857
}
1858
1859
struct dr_set_thr_arg {
1860
  int regnum;
1861
  unsigned long value;
1862
};
1863
1864
static int
1865
fbsd_thread_dr_set_callback (const td_thrhandle_t *th_p, void *data)
1866
{
1867
  struct dr_set_thr_arg *arg = data;
1868
  td_thrinfo_t ti;
1869
  td_err_e err;
1870
1871
  err = td_thr_get_info_p (th_p, &ti);
1872
  if (err != TD_OK)
1873
    error ("Cannot get thread info: %s", thread_db_err_str (err));
1874
1875
  /* Ignore zombie */
1876
  if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
1877
    return 0;
1878
1879
  fbsd_lwp_dr_set (ti.ti_lid, arg->regnum, arg->value);
1880
  return 0;
1881
}
1882
1883
static void
1884
fbsd_thread_dr_set (int regnum, unsigned long value)
1885
{
1886
  struct dr_set_thr_arg arg;
1887
  td_err_e err;
1888
1889
  arg.regnum = regnum;
1890
  arg.value = value;
1891
1892
  /* Iterating over LWPs is sufficient actually. */
1893
  err = td_ta_thr_iter_p (thread_agent, fbsd_thread_dr_set_callback, &arg,
1894
          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1895
          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1896
  if (err != TD_OK)
1897
    error ("Cannot set debug registers: %s", thread_db_err_str (err));
1898
}
1899
1900
void
1901
fbsd_thread_dr_set_control (unsigned long control)
1902
{
1903
  if (fbsd_thread_active)
1904
    fbsd_thread_dr_set (7, control);
1905
  else
1906
    fbsd_lwp_dr_set (GET_PID (inferior_ptid), 7, control);
1907
}
1908
1909
void
1910
fbsd_thread_dr_set_addr (int regnum, CORE_ADDR addr)
1911
{
1912
  gdb_assert (regnum >= 0 && regnum <= 4);
1913
1914
  if (fbsd_thread_active)
1915
    fbsd_thread_dr_set (regnum, addr);
1916
  else
1917
    fbsd_lwp_dr_set (GET_PID (inferior_ptid), regnum, addr);
1918
}
1919
1920
void
1921
fbsd_thread_dr_reset_addr (int regnum)
1922
{
1923
  gdb_assert (regnum >= 0 && regnum <= 4);
1924
1925
  if (fbsd_thread_active)
1926
    fbsd_thread_dr_set (regnum, 0);
1927
  else
1928
    fbsd_lwp_dr_set (GET_PID (inferior_ptid), regnum, 0);
1929
}
1930
1931
unsigned long
1932
fbsd_thread_dr_get_status (void)
1933
{
1934
  struct dbreg dbregs;
1935
  td_thrhandle_t th;
1936
  td_thrinfo_t ti;
1937
  td_err_e err;
1938
  lwpid_t lwpid;
1939
1940
  if (IS_THREAD (inferior_ptid))
1941
    {
1942
      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
1943
      if (err != TD_OK)
1944
        error ("Cannot find thread %d: Thread ID=%ld, %s",
1945
               pid_to_thread_id (inferior_ptid),           
1946
               GET_THREAD (inferior_ptid), thread_db_err_str (err));
1947
1948
      err = td_thr_get_info_p (&th, &ti);
1949
      if (err != TD_OK)
1950
        error ("Cannot get thread info: %s", thread_db_err_str (err));
1951
1952
      lwpid = ti.ti_lid;
1953
    }
1954
  else if (IS_LWP (inferior_ptid))
1955
    {
1956
      lwpid = GET_LWP (inferior_ptid);
1957
    }
1958
  else
1959
    {
1960
      lwpid = GET_PID (inferior_ptid);
1961
    }
1962
1963
  /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
1964
     ptrace call fails breaks debugging remote targets.  The correct
1965
     way to fix this is to add the hardware breakpoint and watchpoint
1966
     stuff to the target vector.  For now, just return zero if the
1967
     ptrace call fails.  */
1968
  if (ptrace (PT_GETDBREGS, GET_PID (inferior_ptid),
1969
              (PTRACE_ARG3_TYPE) & dbregs, 0) == -1)
1970
#if 0
1971
    perror_with_name ("Couldn't read debug registers");
1972
#else
1973
    return 0;
1974
#endif
1975
1976
  return DBREG_DRX ((&dbregs), 6);
1977
}
1978
1979
#endif /* PT_GETDBREGS && I386_DR_LOW_SET_ADDR */

Return to bug 157755