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 */ |