)]}'
{
  "commit": "c3efaf0afd9d37004c42cdfd3ce0c1bfa979c45e",
  "tree": "e2b3eb1907fa8a3ad718dd0179881bc6d69d3a18",
  "parents": [
    "e60a615dde5d6674a6488b74afe807a775551407"
  ],
  "author": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Mon Dec 12 14:05:22 2022 +0000"
  },
  "committer": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Fri Dec 16 13:51:08 2022 +0000"
  },
  "message": "gdb: fix crash when getting the value of a label symbol\n\nWhen the source program contains a goto label, it turns out it\u0027s\nactually pretty hard for a user to find out more about that label.\nFor example:\n\n  (gdb) p some_label\n  No symbol \"some_label\" in current context.\n  (gdb) disassemble some_label\n  No symbol \"some_label\" in current context.\n  (gdb) x/10i some_label\n  No symbol \"some_label\" in current context.\n  (gdb) break some_label\n  Breakpoint 2 at 0x401135: file /tmp/py-label-symbol-value.c, line 35.\n\nIn all cases, some_label is a goto label within the current frame.\nOnly placing a breakpoint on the label worked.\n\nThis all seems a little strange to me, it feels like asking about a\ngoto label would not be an unreasonable thing for a user to do.\n\nThis commit doesn\u0027t fix any of the above issues, I mention them just\nto provide a little context for why the following issue has probably\nnot been seen before.\n\nIt turns out there is one way a user can access the symbol for a goto\nlabel, through the Python API:\n\n  python frame \u003d gdb.selected_frame()\n  python frame_pc \u003d frame.pc()\n  python block \u003d gdb.current_progspace().block_for_pc(frame_pc)\n  python symbol,_ \u003d gdb.lookup_symbol(\u0027some_label\u0027, block, gdb.SYMBOL_LABEL_DOMAIN)\n  python print(str(symbol.value()))\n  ../../src/gdb/findvar.c:204: internal-error: store_typed_address: Assertion `type-\u003eis_pointer_or_reference ()\u0027 failed.\n\nThe problem is that label symbols are created using the\nbuiltin_core_addr type, which is a pure integer type.\n\nWhen GDB tries to fetch the value of a label symbol then we end up in\nfindvar.c, in the function language_defn::read_var_value, in the\nLOC_LABEL case.  From here store_typed_address is called to store the\naddress of the label into a value object with builtin_core_addr type.\n\nThe problem is that store_typed_address requires that the destination\ntype be a pointer or reference, which the builtin_core_addr type is\nnot.\n\nNow it\u0027s not clear what type a goto label address should have, but\nGCC has an extension that allows users to take the address of a goto\nlabel (using \u0026\u0026), in that case the result is of type \u0027void *\u0027.\n\nI propose that when we convert the CORE_ADDR value to a GDB value\nobject, we use builtin_func_ptr type instead of builtin_core_addr,\nthis means the result will be of type \u0027void (*) ()\u0027.  The benefit of\nthis approach is that when gdbarch_address_to_pointer is called the\ntarget type will be correctly identified as a pointer to code, which\nshould mean any architecture specific adjustments are done correctly.\n\nWe can then cast the new value to \u0027void *\u0027 type with a call to\nvalue_cast_pointer, this should not change the values bit\nrepresentation, but will just update the type.\n\nAfter this asking for the value of a label symbol works just fine:\n\n  (gdb) python print(str(symbol.value()))\n  0x401135 \u003cmain+35\u003e\n\nAnd the type is maybe what we\u0027d expect:\n\n  (gdb) python print(str(symbol.value().type))\n  void *\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "e609358df0897aab3773f42b5f01f3c55fcd0fea",
      "old_mode": 33188,
      "old_path": "gdb/findvar.c",
      "new_id": "a5e27035c1503ff20ef44029528b0268d0bba39f",
      "new_mode": 33188,
      "new_path": "gdb/findvar.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "94bdae6fd3044b39129809b067462792a5e2a9eb",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.python/py-label-symbol-value.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "44321e5f71d92b0d53277e718a0ad68a35497f39",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.python/py-label-symbol-value.exp"
    }
  ]
}
