)]}'
{
  "commit": "1722f289eea6f3db2a82aa577aedc87d7a215ead",
  "tree": "8c12e55eec8f4ae06929672a1871e357dea92b90",
  "parents": [
    "b034bb38772a0e1c16153ee7c68b4206421548d0"
  ],
  "author": {
    "name": "Tom de Vries",
    "email": "tdevries@suse.de",
    "time": "Wed Jan 15 17:02:00 2025 +0100"
  },
  "committer": {
    "name": "Tom de Vries",
    "email": "tdevries@suse.de",
    "time": "Wed Jan 15 17:02:00 2025 +0100"
  },
  "message": "[gdb/tdep] Fix gdb.base/store.exp on s390x\n\nOn s390x-linux, I get:\n...\n(gdb) print l^M\n$29 \u003d 0^M\n(gdb) FAIL: gdb.base/store.exp: var doublest l; print old l, expecting -1\n...\n\nSo, we\u0027re in wack_doublest trying to print l, which is a copy of parameter u:\n...\n  register doublest l \u003d u, r \u003d v;\n...\nwhich does have the expected value:\n...\n(gdb) p u\n$1 \u003d -1\n...\nwhich is a long double, 16 bytes and looks like this:\n...\n(gdb) p /x u\n$3 \u003d 0xbfff0000000000000000000000000000\n...\n\nParameter u is passed in two registers:\n...\n \u003c2\u003e\u003c6a5\u003e: Abbrev Number: 15 (DW_TAG_formal_parameter)\n    \u003c6a6\u003e   DW_AT_name        : v\n    \u003c69e\u003e   DW_AT_location    : 6 byte block: 50 93 8 51 93 8 \\\n      (DW_OP_reg0 (r0); DW_OP_piece: 8; DW_OP_reg1 (r1); DW_OP_piece: 8)\n...\nand indeed we find the msw in r0 and the lsw in r1:\n...\n(gdb) p /x $r0\n$4 \u003d 0xbfff000000000000\n(gdb) p /x $r1\n$5 \u003d 0x0\n(gdb)\n...\n\nLikewise, variable l consists of two registers:\n...\n \u003c2\u003e\u003c6b5\u003e: Abbrev Number: 13 (DW_TAG_variable)\n    \u003c6b6\u003e   DW_AT_name        : l\n    \u003c6be\u003e   DW_AT_location    : 6 byte block: 68 93 8 69 93 8 \\\n      (DW_OP_reg24 (f8); DW_OP_piece: 8; DW_OP_reg25 (f10); DW_OP_piece: 8)\n...\nand we find the same values there:\n...\n(gdb) p /x $f8\n$6 \u003d 0xbfff000000000000\n(gdb) p /x $f10\n$7 \u003d 0x0\n...\n\nSo, we get the expected results when fetching the value from two gprs, but not\nwhen fetching the value from two fprs.\n\nWhen fetching the values from the two fprs, we stumble upon a particularity of\nthe DWARF register numbers as defined by the s390x ABI [1]: dwarf register 24\nmaps to both floating-point register f8 (8 bytes), and vector register v8\n(16 bytes).\n\nIn s390_dwarf_reg_to_regnum, it\u0027s determined which of the two is chosen, and\nif available vector registers are preferred over floating-point registers, so\nv8 is chosen, and used to fetch the value.\n\nSince the size of the DW_OP_piece is 8 bytes, and the register size is 16\nbytes, this bit in rw_pieced_value is activated:\n...\n\t\t    /* If the piece is located in a register, but does not\n\t\t       occupy the entire register, the placement of the piece\n\t\t       within that register is defined by the ABI. */\n\t\t    bits_to_skip\n\t\t      +\u003d 8 * gdbarch_dwarf2_reg_piece_offset (arch, gdb_regnum,\n\t\t\t\t\t\t\t      p-\u003esize / 8);\n...\nbut since the default implemention default_dwarf2_reg_piece_offset does not\nmatch the s390x ABI, we get the wrong answer.\n\nThis is a known problem, see FOSDEM 2018 presentation \"DWARF Pieces And Other\nDWARF Location Woes\" [2].\n\nFix this by adding s390_dwarf2_reg_piece_offset, roughly implementing the same\nlogic as in s390_value_from_register.\n\nTested on s390x-linux.\n\nApproved-By: Tom Tromey \u003ctom@tromey.com\u003e\n\n[1] https://github.com/IBM/s390x-abi\n[2] https://archive.fosdem.org/2018/schedule/event/dwarfpieces\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "36a70d8642cbd4c1b748fc86bf078187d4e37b2b",
      "old_mode": 33188,
      "old_path": "gdb/s390-tdep.c",
      "new_id": "6dc825b1707bd7bc6b2190139af1ef0ef9eefda3",
      "new_mode": 33188,
      "new_path": "gdb/s390-tdep.c"
    }
  ]
}
