mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
268a13a5a3
This is the next patch in the ongoing series to move gdbsever to the top level. This patch just renames the "common" directory. The idea is to do this move in two parts: first rename the directory (this patch), then move the directory to the top. This approach makes the patches a bit more tractable. I chose the name "gdbsupport" for the directory. However, as this patch was largely written by sed, we could pick a new name without too much difficulty. Tested by the buildbot. gdb/ChangeLog 2019-07-09 Tom Tromey <tom@tromey.com> * contrib/ari/gdb_ari.sh: Change common to gdbsupport. * configure: Rebuild. * configure.ac: Change common to gdbsupport. * gdbsupport: Rename from common. * acinclude.m4: Change common to gdbsupport. * Makefile.in (CONFIG_SRC_SUBDIR, COMMON_SFILES) (HFILES_NO_SRCDIR, stamp-version, ALLDEPFILES): Change common to gdbsupport. * aarch64-tdep.c, ada-lang.c, ada-lang.h, agent.c, alloc.c, amd64-darwin-tdep.c, amd64-dicos-tdep.c, amd64-fbsd-nat.c, amd64-fbsd-tdep.c, amd64-linux-nat.c, amd64-linux-tdep.c, amd64-nbsd-tdep.c, amd64-obsd-tdep.c, amd64-sol2-tdep.c, amd64-tdep.c, amd64-windows-tdep.c, arch-utils.c, arch/aarch64-insn.c, arch/aarch64.c, arch/aarch64.h, arch/amd64.c, arch/amd64.h, arch/arm-get-next-pcs.c, arch/arm-linux.c, arch/arm.c, arch/i386.c, arch/i386.h, arch/ppc-linux-common.c, arch/riscv.c, arch/riscv.h, arch/tic6x.c, arm-tdep.c, auto-load.c, auxv.c, ax-gdb.c, ax-general.c, ax.h, breakpoint.c, breakpoint.h, btrace.c, btrace.h, build-id.c, build-id.h, c-lang.h, charset.c, charset.h, cli/cli-cmds.c, cli/cli-cmds.h, cli/cli-decode.c, cli/cli-dump.c, cli/cli-option.h, cli/cli-script.c, coff-pe-read.c, command.h, compile/compile-c-support.c, compile/compile-c.h, compile/compile-cplus-symbols.c, compile/compile-cplus-types.c, compile/compile-cplus.h, compile/compile-loc2c.c, compile/compile.c, completer.c, completer.h, contrib/ari/gdb_ari.sh, corefile.c, corelow.c, cp-support.c, cp-support.h, cp-valprint.c, csky-tdep.c, ctf.c, darwin-nat.c, debug.c, defs.h, disasm-selftests.c, disasm.c, disasm.h, dtrace-probe.c, dwarf-index-cache.c, dwarf-index-cache.h, dwarf-index-write.c, dwarf2-frame.c, dwarf2expr.c, dwarf2loc.c, dwarf2read.c, event-loop.c, event-top.c, exceptions.c, exec.c, extension.h, fbsd-nat.c, features/aarch64-core.c, features/aarch64-fpu.c, features/aarch64-pauth.c, features/aarch64-sve.c, features/i386/32bit-avx.c, features/i386/32bit-avx512.c, features/i386/32bit-core.c, features/i386/32bit-linux.c, features/i386/32bit-mpx.c, features/i386/32bit-pkeys.c, features/i386/32bit-segments.c, features/i386/32bit-sse.c, features/i386/64bit-avx.c, features/i386/64bit-avx512.c, features/i386/64bit-core.c, features/i386/64bit-linux.c, features/i386/64bit-mpx.c, features/i386/64bit-pkeys.c, features/i386/64bit-segments.c, features/i386/64bit-sse.c, features/i386/x32-core.c, features/riscv/32bit-cpu.c, features/riscv/32bit-csr.c, features/riscv/32bit-fpu.c, features/riscv/64bit-cpu.c, features/riscv/64bit-csr.c, features/riscv/64bit-fpu.c, features/tic6x-c6xp.c, features/tic6x-core.c, features/tic6x-gp.c, filename-seen-cache.h, findcmd.c, findvar.c, fork-child.c, gcore.c, gdb_bfd.c, gdb_bfd.h, gdb_proc_service.h, gdb_regex.c, gdb_select.h, gdb_usleep.c, gdbarch-selftests.c, gdbthread.h, gdbtypes.h, gnu-nat.c, go32-nat.c, guile/guile.c, guile/scm-ports.c, guile/scm-safe-call.c, guile/scm-type.c, i386-fbsd-nat.c, i386-fbsd-tdep.c, i386-go32-tdep.c, i386-linux-nat.c, i386-linux-tdep.c, i386-tdep.c, i387-tdep.c, ia64-libunwind-tdep.c, ia64-linux-nat.c, inf-child.c, inf-ptrace.c, infcall.c, infcall.h, infcmd.c, inferior-iter.h, inferior.c, inferior.h, inflow.c, inflow.h, infrun.c, infrun.h, inline-frame.c, language.h, linespec.c, linux-fork.c, linux-nat.c, linux-tdep.c, linux-thread-db.c, location.c, machoread.c, macrotab.h, main.c, maint.c, maint.h, memattr.c, memrange.h, mi/mi-cmd-break.h, mi/mi-cmd-env.c, mi/mi-cmd-stack.c, mi/mi-cmd-var.c, mi/mi-interp.c, mi/mi-main.c, mi/mi-parse.h, minsyms.c, mips-linux-tdep.c, namespace.h, nat/aarch64-linux-hw-point.c, nat/aarch64-linux-hw-point.h, nat/aarch64-linux.c, nat/aarch64-sve-linux-ptrace.c, nat/amd64-linux-siginfo.c, nat/fork-inferior.c, nat/linux-btrace.c, nat/linux-btrace.h, nat/linux-namespaces.c, nat/linux-nat.h, nat/linux-osdata.c, nat/linux-personality.c, nat/linux-procfs.c, nat/linux-ptrace.c, nat/linux-ptrace.h, nat/linux-waitpid.c, nat/mips-linux-watch.c, nat/mips-linux-watch.h, nat/ppc-linux.c, nat/x86-dregs.c, nat/x86-dregs.h, nat/x86-linux-dregs.c, nat/x86-linux.c, nto-procfs.c, nto-tdep.c, objfile-flags.h, objfiles.c, objfiles.h, obsd-nat.c, observable.h, osdata.c, p-valprint.c, parse.c, parser-defs.h, ppc-linux-nat.c, printcmd.c, probe.c, proc-api.c, procfs.c, producer.c, progspace.h, psymtab.h, python/py-framefilter.c, python/py-inferior.c, python/py-ref.h, python/py-type.c, python/python.c, record-btrace.c, record-full.c, record.c, record.h, regcache-dump.c, regcache.c, regcache.h, remote-fileio.c, remote-fileio.h, remote-sim.c, remote.c, riscv-tdep.c, rs6000-aix-tdep.c, rust-exp.y, s12z-tdep.c, selftest-arch.c, ser-base.c, ser-event.c, ser-pipe.c, ser-tcp.c, ser-unix.c, skip.c, solib-aix.c, solib-target.c, solib.c, source-cache.c, source.c, source.h, sparc-nat.c, spu-linux-nat.c, stack.c, stap-probe.c, symfile-add-flags.h, symfile.c, symfile.h, symtab.c, symtab.h, target-descriptions.c, target-descriptions.h, target-memory.c, target.c, target.h, target/waitstatus.c, target/waitstatus.h, thread-iter.h, thread.c, tilegx-tdep.c, top.c, top.h, tracefile-tfile.c, tracefile.c, tracepoint.c, tracepoint.h, tui/tui-io.c, ui-file.c, ui-out.h, unittests/array-view-selftests.c, unittests/child-path-selftests.c, unittests/cli-utils-selftests.c, unittests/common-utils-selftests.c, unittests/copy_bitwise-selftests.c, unittests/environ-selftests.c, unittests/format_pieces-selftests.c, unittests/function-view-selftests.c, unittests/lookup_name_info-selftests.c, unittests/memory-map-selftests.c, unittests/memrange-selftests.c, unittests/mkdir-recursive-selftests.c, unittests/observable-selftests.c, unittests/offset-type-selftests.c, unittests/optional-selftests.c, unittests/parse-connection-spec-selftests.c, unittests/ptid-selftests.c, unittests/rsp-low-selftests.c, unittests/scoped_fd-selftests.c, unittests/scoped_mmap-selftests.c, unittests/scoped_restore-selftests.c, unittests/string_view-selftests.c, unittests/style-selftests.c, unittests/tracepoint-selftests.c, unittests/unpack-selftests.c, unittests/utils-selftests.c, unittests/xml-utils-selftests.c, utils.c, utils.h, valarith.c, valops.c, valprint.c, value.c, value.h, varobj.c, varobj.h, windows-nat.c, x86-linux-nat.c, xml-support.c, xml-support.h, xml-tdesc.h, xstormy16-tdep.c, xtensa-linux-nat.c, dwarf2read.h: Change common to gdbsupport. gdb/gdbserver/ChangeLog 2019-07-09 Tom Tromey <tom@tromey.com> * configure: Rebuild. * configure.ac: Change common to gdbsupport. * acinclude.m4: Change common to gdbsupport. * Makefile.in (SFILES, OBS, GDBREPLAY_OBS, IPA_OBJS) (version-generated.c, gdbsupport/%-ipa.o, gdbsupport/%.o): Change common to gdbsupport. * ax.c, event-loop.c, fork-child.c, gdb_proc_service.h, gdbreplay.c, gdbthread.h, hostio-errno.c, hostio.c, i387-fp.c, inferiors.c, inferiors.h, linux-aarch64-tdesc-selftest.c, linux-amd64-ipa.c, linux-i386-ipa.c, linux-low.c, linux-tic6x-low.c, linux-x86-low.c, linux-x86-tdesc-selftest.c, linux-x86-tdesc.c, lynx-i386-low.c, lynx-low.c, mem-break.h, nto-x86-low.c, regcache.c, regcache.h, remote-utils.c, server.c, server.h, spu-low.c, symbol.c, target.h, tdesc.c, tdesc.h, thread-db.c, tracepoint.c, win32-i386-low.c, win32-low.c: Change common to gdbsupport.
350 lines
9.0 KiB
C
350 lines
9.0 KiB
C
/* Copyright (C) 2009-2019 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 "gdbsupport/common-defs.h"
|
|
#include "nat/gdb_ptrace.h"
|
|
#include "mips-linux-watch.h"
|
|
|
|
/* Assuming usable watch registers REGS, return the irw_mask of
|
|
register N. */
|
|
|
|
uint32_t
|
|
mips_linux_watch_get_irw_mask (struct pt_watch_regs *regs, int n)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
return regs->mips32.watch_masks[n] & IRW_MASK;
|
|
case pt_watch_style_mips64:
|
|
return regs->mips64.watch_masks[n] & IRW_MASK;
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Assuming usable watch registers REGS, return the reg_mask of
|
|
register N. */
|
|
|
|
static uint32_t
|
|
get_reg_mask (struct pt_watch_regs *regs, int n)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
return regs->mips32.watch_masks[n] & ~IRW_MASK;
|
|
case pt_watch_style_mips64:
|
|
return regs->mips64.watch_masks[n] & ~IRW_MASK;
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Assuming usable watch registers REGS, return the num_valid. */
|
|
|
|
uint32_t
|
|
mips_linux_watch_get_num_valid (struct pt_watch_regs *regs)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
return regs->mips32.num_valid;
|
|
case pt_watch_style_mips64:
|
|
return regs->mips64.num_valid;
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Assuming usable watch registers REGS, return the watchlo of
|
|
register N. */
|
|
|
|
CORE_ADDR
|
|
mips_linux_watch_get_watchlo (struct pt_watch_regs *regs, int n)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
return regs->mips32.watchlo[n];
|
|
case pt_watch_style_mips64:
|
|
return regs->mips64.watchlo[n];
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Assuming usable watch registers REGS, set watchlo of register N to
|
|
VALUE. */
|
|
|
|
void
|
|
mips_linux_watch_set_watchlo (struct pt_watch_regs *regs, int n,
|
|
CORE_ADDR value)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
/* The cast will never throw away bits as 64 bit addresses can
|
|
never be used on a 32 bit kernel. */
|
|
regs->mips32.watchlo[n] = (uint32_t) value;
|
|
break;
|
|
case pt_watch_style_mips64:
|
|
regs->mips64.watchlo[n] = value;
|
|
break;
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Assuming usable watch registers REGS, return the watchhi of
|
|
register N. */
|
|
|
|
uint32_t
|
|
mips_linux_watch_get_watchhi (struct pt_watch_regs *regs, int n)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
return regs->mips32.watchhi[n];
|
|
case pt_watch_style_mips64:
|
|
return regs->mips64.watchhi[n];
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Assuming usable watch registers REGS, set watchhi of register N to
|
|
VALUE. */
|
|
|
|
void
|
|
mips_linux_watch_set_watchhi (struct pt_watch_regs *regs, int n,
|
|
uint16_t value)
|
|
{
|
|
switch (regs->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
regs->mips32.watchhi[n] = value;
|
|
break;
|
|
case pt_watch_style_mips64:
|
|
regs->mips64.watchhi[n] = value;
|
|
break;
|
|
default:
|
|
internal_error (__FILE__, __LINE__,
|
|
_("Unrecognized watch register style"));
|
|
}
|
|
}
|
|
|
|
/* Read the watch registers of process LWPID and store it in
|
|
WATCH_READBACK. Save true to *WATCH_READBACK_VALID if watch
|
|
registers are valid. Return 1 if watch registers are usable.
|
|
Cached information is used unless FORCE is true. */
|
|
|
|
int
|
|
mips_linux_read_watch_registers (long lwpid,
|
|
struct pt_watch_regs *watch_readback,
|
|
int *watch_readback_valid, int force)
|
|
{
|
|
if (force || *watch_readback_valid == 0)
|
|
{
|
|
if (ptrace (PTRACE_GET_WATCH_REGS, lwpid, watch_readback, NULL) == -1)
|
|
{
|
|
*watch_readback_valid = -1;
|
|
return 0;
|
|
}
|
|
switch (watch_readback->style)
|
|
{
|
|
case pt_watch_style_mips32:
|
|
if (watch_readback->mips32.num_valid == 0)
|
|
{
|
|
*watch_readback_valid = -1;
|
|
return 0;
|
|
}
|
|
break;
|
|
case pt_watch_style_mips64:
|
|
if (watch_readback->mips64.num_valid == 0)
|
|
{
|
|
*watch_readback_valid = -1;
|
|
return 0;
|
|
}
|
|
break;
|
|
default:
|
|
*watch_readback_valid = -1;
|
|
return 0;
|
|
}
|
|
/* Watch registers appear to be usable. */
|
|
*watch_readback_valid = 1;
|
|
}
|
|
return (*watch_readback_valid == 1) ? 1 : 0;
|
|
}
|
|
|
|
/* Convert GDB's TYPE to an IRW mask. */
|
|
|
|
uint32_t
|
|
mips_linux_watch_type_to_irw (enum target_hw_bp_type type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case hw_write:
|
|
return W_MASK;
|
|
case hw_read:
|
|
return R_MASK;
|
|
case hw_access:
|
|
return (W_MASK | R_MASK);
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* Set any low order bits in MASK that are not set. */
|
|
|
|
static CORE_ADDR
|
|
fill_mask (CORE_ADDR mask)
|
|
{
|
|
CORE_ADDR f = 1;
|
|
|
|
while (f && f < mask)
|
|
{
|
|
mask |= f;
|
|
f <<= 1;
|
|
}
|
|
return mask;
|
|
}
|
|
|
|
/* Try to add a single watch to the specified registers REGS. The
|
|
address of added watch is ADDR, the length is LEN, and the mask
|
|
is IRW. Return 1 on success, 0 on failure. */
|
|
|
|
int
|
|
mips_linux_watch_try_one_watch (struct pt_watch_regs *regs,
|
|
CORE_ADDR addr, int len, uint32_t irw)
|
|
{
|
|
CORE_ADDR base_addr, last_byte, break_addr, segment_len;
|
|
CORE_ADDR mask_bits, t_low;
|
|
uint16_t t_hi;
|
|
int i, free_watches;
|
|
struct pt_watch_regs regs_copy;
|
|
|
|
if (len <= 0)
|
|
return 0;
|
|
|
|
last_byte = addr + len - 1;
|
|
mask_bits = fill_mask (addr ^ last_byte) | IRW_MASK;
|
|
base_addr = addr & ~mask_bits;
|
|
|
|
/* Check to see if it is covered by current registers. */
|
|
for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
|
|
{
|
|
t_low = mips_linux_watch_get_watchlo (regs, i);
|
|
if (t_low != 0 && irw == ((uint32_t) t_low & irw))
|
|
{
|
|
t_hi = mips_linux_watch_get_watchhi (regs, i) | IRW_MASK;
|
|
t_low &= ~(CORE_ADDR) t_hi;
|
|
if (addr >= t_low && last_byte <= (t_low + t_hi))
|
|
return 1;
|
|
}
|
|
}
|
|
/* Try to find an empty register. */
|
|
free_watches = 0;
|
|
for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
|
|
{
|
|
t_low = mips_linux_watch_get_watchlo (regs, i);
|
|
if (t_low == 0
|
|
&& irw == (mips_linux_watch_get_irw_mask (regs, i) & irw))
|
|
{
|
|
if (mask_bits <= (get_reg_mask (regs, i) | IRW_MASK))
|
|
{
|
|
/* It fits, we'll take it. */
|
|
mips_linux_watch_set_watchlo (regs, i, base_addr | irw);
|
|
mips_linux_watch_set_watchhi (regs, i, mask_bits & ~IRW_MASK);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
/* It doesn't fit, but has the proper IRW capabilities. */
|
|
free_watches++;
|
|
}
|
|
}
|
|
}
|
|
if (free_watches > 1)
|
|
{
|
|
/* Try to split it across several registers. */
|
|
regs_copy = *regs;
|
|
for (i = 0; i < mips_linux_watch_get_num_valid (®s_copy); i++)
|
|
{
|
|
t_low = mips_linux_watch_get_watchlo (®s_copy, i);
|
|
t_hi = get_reg_mask (®s_copy, i) | IRW_MASK;
|
|
if (t_low == 0 && irw == (t_hi & irw))
|
|
{
|
|
t_low = addr & ~(CORE_ADDR) t_hi;
|
|
break_addr = t_low + t_hi + 1;
|
|
if (break_addr >= addr + len)
|
|
segment_len = len;
|
|
else
|
|
segment_len = break_addr - addr;
|
|
mask_bits = fill_mask (addr ^ (addr + segment_len - 1));
|
|
mips_linux_watch_set_watchlo (®s_copy, i,
|
|
(addr & ~mask_bits) | irw);
|
|
mips_linux_watch_set_watchhi (®s_copy, i,
|
|
mask_bits & ~IRW_MASK);
|
|
if (break_addr >= addr + len)
|
|
{
|
|
*regs = regs_copy;
|
|
return 1;
|
|
}
|
|
len = addr + len - break_addr;
|
|
addr = break_addr;
|
|
}
|
|
}
|
|
}
|
|
/* It didn't fit anywhere, we failed. */
|
|
return 0;
|
|
}
|
|
|
|
/* Fill in the watch registers REGS with the currently cached
|
|
watches CURRENT_WATCHES. */
|
|
|
|
void
|
|
mips_linux_watch_populate_regs (struct mips_watchpoint *current_watches,
|
|
struct pt_watch_regs *regs)
|
|
{
|
|
struct mips_watchpoint *w;
|
|
int i;
|
|
|
|
/* Clear them out. */
|
|
for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
|
|
{
|
|
mips_linux_watch_set_watchlo (regs, i, 0);
|
|
mips_linux_watch_set_watchhi (regs, i, 0);
|
|
}
|
|
|
|
w = current_watches;
|
|
while (w)
|
|
{
|
|
uint32_t irw = mips_linux_watch_type_to_irw (w->type);
|
|
|
|
i = mips_linux_watch_try_one_watch (regs, w->addr, w->len, irw);
|
|
/* They must all fit, because we previously calculated that they
|
|
would. */
|
|
gdb_assert (i);
|
|
w = w->next;
|
|
}
|
|
}
|