From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 83201 invoked by alias); 26 Oct 2017 08:30:02 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 83121 invoked by uid 89); 26 Oct 2017 08:30:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=ham version=3.3.2 spammy=Watch, fired, nowadays, Hx-spam-relays-external:209.85.128.195 X-HELO: mail-wr0-f195.google.com Received: from mail-wr0-f195.google.com (HELO mail-wr0-f195.google.com) (209.85.128.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 26 Oct 2017 08:29:59 +0000 Received: by mail-wr0-f195.google.com with SMTP id y39so2366909wrd.4 for ; Thu, 26 Oct 2017 01:29:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=omhFYtlXlRNnN3bCjI3jHeT2EaqJptIUcsuE7WjiuxU=; b=AuqRuqCAESt0PtIm51wQOC5gzrkOLN5xw50TDPg570XWDuH1vMamdU6hVulMU4Cver 2GRVuY/71dJ9SS8Qw6u8/yv1N1+koaI/tqM2xj3CTeXYU3Sh8XkdK1hFhHzhqC2a63F1 h5pnHDvkzNqlu2z8wW7kAdaQZOPcBGMlRVoSzWSOHduyf7dC4h4okoeiLaazrNVfGAXe +2yEN/GsKcVgEFEFQb3rU82DsgVGCeNJqzFc2EDcECN67UnyJaztQt+0U0WsE8f5Ejvh HVhulGXapI1Cq2eJdnf0UExXYaAFXx2O+DEM0QnqNcoAr5wGBc2ToA+Gg5grh32h41UE OdIA== X-Gm-Message-State: AMCzsaWy5D39GLE1RbDjN3Q9NJ61AG8WuCIO+ClR2Heznoe/nTXeREy7 vKIV+guVQUaoFrOHTfI0/nRHdQ== X-Google-Smtp-Source: ABhQp+S0flYhUhv2p1btNQc5gcp/c26+a6V8ScVMJTAnwjwToqg2s4A++MLpk5XEuVm+2BXfnnn9lg== X-Received: by 10.223.167.76 with SMTP id e12mr4250741wrd.259.1509006597121; Thu, 26 Oct 2017 01:29:57 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (static.42.136.251.148.clients.your-server.de. [148.251.136.42]) by smtp.gmail.com with ESMTPSA id k19sm4058506wrg.32.2017.10.26.01.29.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 26 Oct 2017 01:29:56 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 3/3] [AArch64] Remove tag from address for watchpoint Date: Thu, 26 Oct 2017 08:30:00 -0000 Message-Id: <1509006590-9401-4-git-send-email-yao.qi@linaro.org> In-Reply-To: <1509006590-9401-1-git-send-email-yao.qi@linaro.org> References: <1509006590-9401-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes X-SW-Source: 2017-10/txt/msg00793.txt.bz2 Nowadays, GDB can't set watchpoint on tagged address, (gdb) p p2 $1 = (int *) 0xf000fffffffff474 (gdb) watch *((int *) 0xf000fffffffff474) Hardware watchpoint 2: *((int *) 0xf000fffffffff474) (gdb) c Continuing. main () at binutils-gdb/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c:45 45 void (*func_ptr) (void) = foo; Unexpected error setting hardware debug registers This patch is about setting watchpoint on a tagged address. Unlike breakpoint, watchpoint record the expression rather than the address, and when a watchpoint is fired, GDB checks the expression value changed instead of matching address, so we can mask the watchpoint address for aarch64, by adding a gdbarch method addr_tag_remove. gdb: 2017-10-25 Yao Qi * aarch64-linux-tdep.c (aarch64_linux_addr_tag_remove): New method. (aarch64_linux_init_abi): Install gdbarch method. * gdbarch.sh (addr_tag_remove): New gdbarch method. * gdbarch.c: Re-generated. * gdbarch.h: Re-generated. * breakpoint.c (update_watchpoint): gdb/testsuite: 2017-10-25 Yao Qi * gdb.arch/aarch64-tagged-pointer.exp: Add tests for watchpoint. --- gdb/aarch64-linux-tdep.c | 11 +++++++++++ gdb/breakpoint.c | 3 +-- gdb/gdbarch.c | 23 +++++++++++++++++++++++ gdb/gdbarch.h | 8 ++++++++ gdb/gdbarch.sh | 5 +++++ gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c | 1 + gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp | 14 ++++++++++++++ 7 files changed, 63 insertions(+), 2 deletions(-) diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index b6052ba..139f336 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -1001,6 +1001,15 @@ aarch64_linux_syscall_record (struct regcache *regcache, return 0; } +/* Implement the "addr_tag_remove" gdbarch method. */ + +static CORE_ADDR +aarch64_linux_addr_tag_remove (struct gdbarch *gdbarch, CORE_ADDR val) +{ + /* Ignore the top byte of virtual address. */ + return val & 0x0fffffffffffffffULL; +} + static void aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -1217,6 +1226,8 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_xml_syscall_file_name (gdbarch, "syscalls/aarch64-linux.xml"); set_gdbarch_get_syscall_number (gdbarch, aarch64_linux_get_syscall_number); + set_gdbarch_addr_tag_remove (gdbarch, aarch64_linux_addr_tag_remove); + /* Displaced stepping. */ set_gdbarch_max_insn_length (gdbarch, 4 * DISPLACED_MODIFIED_INSNS); set_gdbarch_displaced_step_copy_insn (gdbarch, diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index e16cfb6..16f03ff 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1894,8 +1894,7 @@ update_watchpoint (struct watchpoint *b, int reparse) loc->gdbarch = get_type_arch (value_type (v)); loc->pspace = frame_pspace; - loc->address = addr; - + loc->address = gdbarch_addr_tag_remove (loc->gdbarch, addr); if (bitsize != 0) { /* Just cover the bytes that make up the bitfield. */ diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 007392c..76574d4 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -259,6 +259,7 @@ struct gdbarch int frame_red_zone_size; gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr; gdbarch_addr_bits_remove_ftype *addr_bits_remove; + gdbarch_addr_tag_remove_ftype *addr_tag_remove; gdbarch_software_single_step_ftype *software_single_step; gdbarch_single_step_through_delay_ftype *single_step_through_delay; gdbarch_print_insn_ftype *print_insn; @@ -428,6 +429,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->stabs_argument_has_addr = default_stabs_argument_has_addr; gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity; gdbarch->addr_bits_remove = core_addr_identity; + gdbarch->addr_tag_remove = core_addr_identity; gdbarch->print_insn = default_print_insn; gdbarch->skip_trampoline_code = generic_skip_trampoline_code; gdbarch->skip_solib_resolver = generic_skip_solib_resolver; @@ -618,6 +620,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of stabs_argument_has_addr, invalid_p == 0 */ /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ /* Skip verify of addr_bits_remove, invalid_p == 0 */ + /* Skip verify of addr_tag_remove, invalid_p == 0 */ /* Skip verify of software_single_step, has predicate. */ /* Skip verify of single_step_through_delay, has predicate. */ /* Skip verify of print_insn, invalid_p == 0 */ @@ -737,6 +740,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: addr_bits_remove = <%s>\n", host_address_to_string (gdbarch->addr_bits_remove)); fprintf_unfiltered (file, + "gdbarch_dump: addr_tag_remove = <%s>\n", + host_address_to_string (gdbarch->addr_tag_remove)); + fprintf_unfiltered (file, "gdbarch_dump: gdbarch_address_class_name_to_type_flags_p() = %d\n", gdbarch_address_class_name_to_type_flags_p (gdbarch)); fprintf_unfiltered (file, @@ -3215,6 +3221,23 @@ set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch->addr_bits_remove = addr_bits_remove; } +CORE_ADDR +gdbarch_addr_tag_remove (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->addr_tag_remove != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_addr_tag_remove called\n"); + return gdbarch->addr_tag_remove (gdbarch, addr); +} + +void +set_gdbarch_addr_tag_remove (struct gdbarch *gdbarch, + gdbarch_addr_tag_remove_ftype addr_tag_remove) +{ + gdbarch->addr_tag_remove = addr_tag_remove; +} + int gdbarch_software_single_step_p (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index d2e6b6f..769c8fb 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -677,6 +677,14 @@ typedef CORE_ADDR (gdbarch_addr_bits_remove_ftype) (struct gdbarch *gdbarch, COR extern CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr); extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_bits_remove_ftype *addr_bits_remove); +/* On some machines, there are bits in address which are ignored by the + kernel, the hardeware, etc. They are called "tag", which can be + regarded as additional data associated with the address. */ + +typedef CORE_ADDR (gdbarch_addr_tag_remove_ftype) (struct gdbarch *gdbarch, CORE_ADDR addr); +extern CORE_ADDR gdbarch_addr_tag_remove (struct gdbarch *gdbarch, CORE_ADDR addr); +extern void set_gdbarch_addr_tag_remove (struct gdbarch *gdbarch, gdbarch_addr_tag_remove_ftype *addr_tag_remove); + /* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if the target needs software single step. An ISA method to implement it. diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 6459b12..1f673e7 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -621,6 +621,11 @@ m;CORE_ADDR;convert_from_func_ptr_addr;CORE_ADDR addr, struct target_ops *targ;a # possible it should be in TARGET_READ_PC instead). m;CORE_ADDR;addr_bits_remove;CORE_ADDR addr;addr;;core_addr_identity;;0 +# On some machines, there are bits in address which are ignored by the +# kernel, the hardeware, etc. They are called "tag", which can be +# regarded as additional data associated with the address. +m;CORE_ADDR;addr_tag_remove;CORE_ADDR addr;addr;;core_addr_identity;;0 + # FIXME/cagney/2001-01-18: This should be split in two. A target method that # indicates if the target needs software single step. An ISA method to # implement it. diff --git a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c index ec3574d..19395f5 100644 --- a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c +++ b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c @@ -54,4 +54,5 @@ main (void) } sp1->i = 8765; + i = 1; } diff --git a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp index 2a5b1eb..f38b876 100644 --- a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp +++ b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp @@ -90,3 +90,17 @@ foreach_with_prefix bptype {"hbreak" "break"} { gdb_test "up" "\\(\*func_ptr\\) \\(\\).*" "caller is *func_ptr" delete_breakpoints } + +gdb_test "down" +gdb_test "finish" +# Watch on tagged pointer. +gdb_test "watch *sp2" +gdb_test "continue" \ + "Continuing\\..*Hardware watchpoint \[0-9\]+.*" \ + "run until watchpoint on s1" +delete_breakpoints + +gdb_test "watch *p2" +gdb_test "continue" \ + "Continuing\\..*Hardware watchpoint \[0-9\]+.*" \ + "run until watchpoint on i" -- 1.9.1