)]}'
{
  "commit": "cf16ab724a41e4cbaf723b5633d4e7b29f61372b",
  "tree": "0545a1c6dd04e5563fa6f32226128d2df0e8909b",
  "parents": [
    "f9b7cc0cd2a1699c5cb7d5b159c8392e6973663c"
  ],
  "author": {
    "name": "Tom de Vries",
    "email": "tdevries@suse.de",
    "time": "Tue Mar 12 17:08:18 2024 +0100"
  },
  "committer": {
    "name": "Tom de Vries",
    "email": "tdevries@suse.de",
    "time": "Tue Mar 12 17:08:18 2024 +0100"
  },
  "message": "[gdb/tdep] Fix gdb.base/watch-bitfields.exp on aarch64\n\nOn aarch64-linux, with test-case gdb.base/watch-bitfields.exp I run into:\n...\n(gdb) continue^M\nContinuing.^M\n^M\nHardware watchpoint 2: -location q.a^M\n^M\nOld value \u003d 1^M\nNew value \u003d 0^M\nmain () at watch-bitfields.c:42^M\n42        q.h--;^M\n(gdb) FAIL: $exp: -location watch against bitfields: q.e: 0-\u003e5: continue\n...\n\nIn a minimal form, if we step past line 37 which sets q.e, and we have a\nwatchpoint set on q.e, it triggers:\n...\n$ gdb -q -batch watch-bitfields -ex \"b 37\" -ex run -ex \"watch q.e\" -ex step\nBreakpoint 1 at 0x410204: file watch-bitfields.c, line 37.\n\nBreakpoint 1, main () at watch-bitfields.c:37\n37        q.e \u003d 5;\nHardware watchpoint 2: q.e\n\nHardware watchpoint 2: q.e\n\nOld value \u003d 0\nNew value \u003d 5\nmain () at /home/vries/gdb/src/gdb/testsuite/gdb.base/watch-bitfields.c:38\n38        q.f \u003d 6;\n...\n\nHowever, if we set in addition a watchpoint on q.a, the watchpoint on q.e\ndoesn\u0027t trigger.\n\nHow does this happen?\n\nBitfield q.a is just bit 0 of byte 0, and bitfield q.e is bit 4..7 of byte 1\nand bit 1 of byte 2.  So, watch q.a should watch byte 0, and watch q.e should\nwatch bytes 1 and 2.\n\nUsing \"maint set show-debug-regs on\" (and some more detailed debug prints) we\nget:\n...\nWP2: addr\u003d0x440028 (orig\u003d0x440029), ctrl\u003d0x000000d5, ref.count\u003d1\n  ctrl: enabled\u003d1, offset\u003d1, len\u003d2\nWP3: addr\u003d0x440028 (orig\u003d0x440028), ctrl\u003d0x00000035, ref.count\u003d1\n  ctrl: enabled\u003d1, offset\u003d0, len\u003d1\n...\nwhich matches that.\n\nWhen executing line 37, a hardware watchpoint trap triggers and we hit\naarch64_stopped_data_address with addr_trap \u003d\u003d 0x440028:\n...\n(gdb) p /x addr_trap\n$1 \u003d 0x440028\n....\nand since the loop in aarch64_stopped_data_address walks backward, we check\nWP3 first, which matches, and consequently target_stopped_by_watchpoint\nreturns true in watchpoints_triggered.\n\nLikewise for target_stopped_data_address, which also returns addr \u003d\u003d 0x440028.\nWatchpoints_triggered matches watchpoint q.a to that address, and sets\nwatch_triggered_yes.\n\nHowever, subsequently the value of q.a is checked, and it\u0027s the same value as\nbefore (becase the insn in line 37 didn\u0027t change q.a), so the watchpoint\nhardware trap is not reported to the user.\n\nThe problem originates from that fact that aarch64_stopped_data_address picked\nWP3 instead of WP2.\n\nThere\u0027s something we can do about this.  In the example above, both\ntarget_stopped_by_watchpoint and target_stopped_data_address returned true.\nInstead we can return true in target_stopped_by_watchpoint but false in\ntarget_stopped_data_address.  This lets watchpoints_triggered known that a\nwatchpoint was triggered, but we don\u0027t know where, and both watchpoints\nget set to watch_triggered_unknown.\n\nSubsequently, the values of both q.a and q.e are checked, and since q.e is not\nthe same value as before, the watchpoint hardware trap is reported to the user.\n\nNote that this works well for regular (write) watchpoints (watch command), but\nnot for read watchpoints (rwatch command), because for those no value is\nchecked.  Likewise for access watchpoints (awatch command).\n\nSo, fix this by:\n- passing a nullptr in aarch64_fbsd_nat_target::stopped_by_watchpoint and\n  aarch64_linux_nat_target::stopped_by_watchpoint to make clear we\u0027re not\n  interested in the stop address,\n- introducing a two-phase approach in aarch64_stopped_data_address, where:\n  - phase one handles access and read watchpoints, as before, and\n  - phase two handles write watchpoints, where multiple matches cause:\n    - return true if addr_p \u003d\u003d null, and\n    - return false if addr_p !\u003d null.\n\nTested on aarch64-linux.\n\nApproved-By: Luis Machado \u003cluis.machado@arm.com\u003e\n\nPR tdep/31214\nBug: https://sourceware.org/bugzilla/show_bug.cgi?id\u003d31214\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "d7aa819023b04f1f7c7cc6e473ca570c5bc56ccf",
      "old_mode": 33188,
      "old_path": "gdb/aarch64-fbsd-nat.c",
      "new_id": "89ed12bb8e57e4d5b974af2d625a64bc63645177",
      "new_mode": 33188,
      "new_path": "gdb/aarch64-fbsd-nat.c"
    },
    {
      "type": "modify",
      "old_id": "9dc45e1c1d96e7efa63143094d5736f2bc670e83",
      "old_mode": 33188,
      "old_path": "gdb/aarch64-linux-nat.c",
      "new_id": "cf7d5f8c6b14c532f43bf71e44cc51cc9ba118ea",
      "new_mode": 33188,
      "new_path": "gdb/aarch64-linux-nat.c"
    },
    {
      "type": "modify",
      "old_id": "2e8c0d801823ae056819bc3141c1667943ee494f",
      "old_mode": 33188,
      "old_path": "gdb/aarch64-nat.c",
      "new_id": "6c72a8d6d9f18d59693da45e784b54926fc21f17",
      "new_mode": 33188,
      "new_path": "gdb/aarch64-nat.c"
    },
    {
      "type": "modify",
      "old_id": "04674dea2a6e8214e60075687729b0ca64f84fd7",
      "old_mode": 33188,
      "old_path": "gdb/nat/aarch64-hw-point.c",
      "new_id": "08fd230b71f3146f295860362f514abe5777ed1a",
      "new_mode": 33188,
      "new_path": "gdb/nat/aarch64-hw-point.c"
    },
    {
      "type": "modify",
      "old_id": "70f71db752094cdd3614572f355cd3e24b50e373",
      "old_mode": 33188,
      "old_path": "gdb/nat/aarch64-hw-point.h",
      "new_id": "bdcca932e577ed5283f9f2c64f0a5d02c75dc8b5",
      "new_mode": 33188,
      "new_path": "gdb/nat/aarch64-hw-point.h"
    }
  ]
}
