mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-28 11:43:36 +08:00
a3b60e4588
Some unaligned watchpoints were currently missed. On old kernels as specified in kernel RFE: aarch64: ptrace: BAS: Support any contiguous range (edit) https://sourceware.org/bugzilla/show_bug.cgi?id=20207 after this patch some other unaligned watchpoints will get reported as false positives. With new kernels all the watchpoints should work exactly. There may be a regresion that it now less merges watchpoints so that with multiple overlapping watchpoints it may run out of the 4 hardware watchpoint registers. But as discussed in the original thread GDB needs some generic watchpoints merging framework to be used by all the target specific code. Even current FSF GDB code does not merge it perfectly. Also with the more precise watchpoints one can technically merge them less. And I do not think it matters too much to improve mergeability only for old kernels. Still even on new kernels some better merging logic would make sense. There remains one issue: kernel-4.15.14-300.fc27.armv7hl FAIL: gdb.base/watchpoint-unaligned.exp: continue FAIL: gdb.base/watchpoint-unaligned.exp: continue (gdb) continue Continuing. Unexpected error setting watchpoint: Invalid argument. (gdb) FAIL: gdb.base/watchpoint-unaligned.exp: continue But that looks as a kernel bug to me. (1) It is not a regression by this patch. (2) It is unrelated to this patch. gdb/ChangeLog 2018-05-04 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> PR breakpoints/19806 and support for PR external/20207. * NEWS: Mention Aarch64 watchpoint improvements. * aarch64-linux-nat.c (aarch64_linux_stopped_data_address): Fix missed watchpoints and PR external/20207 watchpoints. * nat/aarch64-linux-hw-point.c (kernel_supports_any_contiguous_range): New. (aarch64_watchpoint_offset): New. (aarch64_watchpoint_length): Support PR external/20207 watchpoints. (aarch64_point_encode_ctrl_reg): New parameter offset, new asserts. (aarch64_point_is_aligned): Support PR external/20207 watchpoints. (aarch64_align_watchpoint): New parameters aligned_offset_p and next_addr_orig_p. Support PR external/20207 watchpoints. (aarch64_downgrade_regs): New. (aarch64_dr_state_insert_one_point): New parameters offset and addr_orig. (aarch64_dr_state_remove_one_point): Likewise. (aarch64_handle_breakpoint): Update caller. (aarch64_handle_aligned_watchpoint): Likewise. (aarch64_handle_unaligned_watchpoint): Support addr_orig and aligned_offset. (aarch64_linux_set_debug_regs): Remove const from state. Call aarch64_downgrade_regs. (aarch64_show_debug_reg_state): Print also dr_addr_orig_wp. * nat/aarch64-linux-hw-point.h (DR_CONTROL_LENGTH): Rename to ... (DR_CONTROL_MASK): ... this. (struct aarch64_debug_reg_state): New field dr_addr_orig_wp. (unsigned int aarch64_watchpoint_offset): New prototype. (aarch64_linux_set_debug_regs): Remove const from state. * utils.c (align_up, align_down): Move to ... * common/common-utils.c (align_up, align_down): ... here. * utils.h (align_up, align_down): Move to ... * common/common-utils.h (align_up, align_down): ... here. gdb/gdbserver/ChangeLog 2018-05-04 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> * linux-aarch64-low.c (aarch64_stopped_data_address): Likewise. gdb/testsuite/ChangeLog 2018-05-04 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> PR breakpoints/19806 and support for PR external/20207. * gdb.base/watchpoint-unaligned.c: New file. * gdb.base/watchpoint-unaligned.exp: New file.
187 lines
5.9 KiB
C++
187 lines
5.9 KiB
C++
/* Shared general utility routines for GDB, the GNU debugger.
|
|
|
|
Copyright (C) 1986-2018 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/>. */
|
|
|
|
#ifndef COMMON_UTILS_H
|
|
#define COMMON_UTILS_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "poison.h"
|
|
|
|
/* If possible, define FUNCTION_NAME, a macro containing the name of
|
|
the function being defined. Since this macro may not always be
|
|
defined, all uses must be protected by appropriate macro definition
|
|
checks (Eg: "#ifdef FUNCTION_NAME").
|
|
|
|
Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
|
|
which contains the name of the function currently being defined.
|
|
This is broken in G++ before version 2.6.
|
|
C9x has a similar variable called __func__, but prefer the GCC one since
|
|
it demangles C++ function names. */
|
|
#if (GCC_VERSION >= 2004)
|
|
#define FUNCTION_NAME __PRETTY_FUNCTION__
|
|
#else
|
|
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
|
#define FUNCTION_NAME __func__ /* ARI: func */
|
|
#endif
|
|
#endif
|
|
|
|
/* xmalloc(), xrealloc() and xcalloc() have already been declared in
|
|
"libiberty.h". */
|
|
|
|
/* Like xmalloc, but zero the memory. */
|
|
void *xzalloc (size_t);
|
|
|
|
template <typename T>
|
|
static void
|
|
xfree (T *ptr)
|
|
{
|
|
static_assert (IsFreeable<T>::value, "Trying to use xfree with a non-POD \
|
|
data type. Use operator delete instead.");
|
|
|
|
if (ptr != NULL)
|
|
free (ptr); /* ARI: free */
|
|
}
|
|
|
|
|
|
/* Like asprintf and vasprintf, but return the string, throw an error
|
|
if no memory. */
|
|
char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
|
|
char *xstrvprintf (const char *format, va_list ap)
|
|
ATTRIBUTE_PRINTF (1, 0);
|
|
|
|
/* Like snprintf, but throw an error if the output buffer is too small. */
|
|
int xsnprintf (char *str, size_t size, const char *format, ...)
|
|
ATTRIBUTE_PRINTF (3, 4);
|
|
|
|
/* Returns a std::string built from a printf-style format string. */
|
|
std::string string_printf (const char* fmt, ...)
|
|
ATTRIBUTE_PRINTF (1, 2);
|
|
|
|
/* Like string_printf, but takes a va_list. */
|
|
std::string string_vprintf (const char* fmt, va_list args)
|
|
ATTRIBUTE_PRINTF (1, 0);
|
|
|
|
/* Like string_printf, but appends to DEST instead of returning a new
|
|
std::string. */
|
|
void string_appendf (std::string &dest, const char* fmt, ...)
|
|
ATTRIBUTE_PRINTF (2, 3);
|
|
|
|
/* Like string_appendf, but takes a va_list. */
|
|
void string_vappendf (std::string &dest, const char* fmt, va_list args)
|
|
ATTRIBUTE_PRINTF (2, 0);
|
|
|
|
/* Make a copy of the string at PTR with LEN characters
|
|
(and add a null character at the end in the copy).
|
|
Uses malloc to get the space. Returns the address of the copy. */
|
|
|
|
char *savestring (const char *ptr, size_t len);
|
|
|
|
/* The strerror() function can return NULL for errno values that are
|
|
out of range. Provide a "safe" version that always returns a
|
|
printable string. */
|
|
|
|
extern char *safe_strerror (int);
|
|
|
|
/* Return non-zero if the start of STRING matches PATTERN, zero
|
|
otherwise. */
|
|
|
|
static inline int
|
|
startswith (const char *string, const char *pattern)
|
|
{
|
|
return strncmp (string, pattern, strlen (pattern)) == 0;
|
|
}
|
|
|
|
ULONGEST strtoulst (const char *num, const char **trailer, int base);
|
|
|
|
/* Skip leading whitespace characters in INP, returning an updated
|
|
pointer. If INP is NULL, return NULL. */
|
|
|
|
extern char *skip_spaces (char *inp);
|
|
|
|
/* A const-correct version of the above. */
|
|
|
|
extern const char *skip_spaces (const char *inp);
|
|
|
|
/* Skip leading non-whitespace characters in INP, returning an updated
|
|
pointer. If INP is NULL, return NULL. */
|
|
|
|
extern char *skip_to_space (char *inp);
|
|
|
|
/* A const-correct version of the above. */
|
|
|
|
extern const char *skip_to_space (const char *inp);
|
|
|
|
/* Assumes that V is an argv for a program, and iterates through
|
|
freeing all the elements. */
|
|
extern void free_vector_argv (std::vector<char *> &v);
|
|
|
|
/* Given a vector of arguments ARGV, return a string equivalent to
|
|
joining all the arguments with a whitespace separating them. */
|
|
extern std::string stringify_argv (const std::vector<char *> &argv);
|
|
|
|
/* Return true if VALUE is in [LOW, HIGH]. */
|
|
|
|
template <typename T>
|
|
static bool
|
|
in_inclusive_range (T value, T low, T high)
|
|
{
|
|
return value >= low && value <= high;
|
|
}
|
|
|
|
/* Return true if the file NAME exists and is a regular file.
|
|
If the result is false then *ERRNO_PTR is set to a useful value assuming
|
|
we're expecting a regular file. */
|
|
extern bool is_regular_file (const char *name, int *errno_ptr);
|
|
|
|
/* Ensure that V is aligned to an N byte boundary (B's assumed to be a
|
|
power of 2). Round up/down when necessary. Examples of correct
|
|
use include:
|
|
|
|
addr = align_up (addr, 8); -- VALUE needs 8 byte alignment
|
|
write_memory (addr, value, len);
|
|
addr += len;
|
|
|
|
and:
|
|
|
|
sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned
|
|
write_memory (sp, value, len);
|
|
|
|
Note that uses such as:
|
|
|
|
write_memory (addr, value, len);
|
|
addr += align_up (len, 8);
|
|
|
|
and:
|
|
|
|
sp -= align_up (len, 8);
|
|
write_memory (sp, value, len);
|
|
|
|
are typically not correct as they don't ensure that the address (SP
|
|
or ADDR) is correctly aligned (relying on previous alignment to
|
|
keep things right). This is also why the methods are called
|
|
"align_..." instead of "round_..." as the latter reads better with
|
|
this incorrect coding style. */
|
|
|
|
extern ULONGEST align_up (ULONGEST v, int n);
|
|
extern ULONGEST align_down (ULONGEST v, int n);
|
|
|
|
#endif
|