)]}'
{
  "commit": "f9aa48dc545ef511e19f4dfab88a196b820fd2da",
  "tree": "e9c8208fc40ae0c9007260804dc84b7247b60f9c",
  "parents": [
    "55fc9233a835a87d1a9020a8c71c473b03fc4f72"
  ],
  "author": {
    "name": "Pawel Kupczak",
    "email": "pawel.kupczak@intel.com",
    "time": "Thu Aug 28 11:50:13 2025 +0000"
  },
  "committer": {
    "name": "Christina Schimpe",
    "email": "christina.schimpe@intel.com",
    "time": "Thu Sep 04 20:44:48 2025 +0000"
  },
  "message": "gdb, amd64: extend the amd64 prologue analyzer to skip register pushes\n\nA typical function\u0027s prologue can consist of setting up a frame pointer,\npushing registers onto the stack and allocating space on the stack.\nCurrent amd64 prologue analyzer would stop after the frame setup.\nThis patch allows GDB to skip past register pushes, while also improving\nunwinding pushed registers, for functions with a frame pointer, without\ndebug info and .cfi directives found in .eh_frame section that are used\nfor unwinding.  Skipping register pushes was also present for i386\ntargets before - the proposed changes are based on i386 implementation.\n\nIt also improves the unwinding even if .cfi directives are present,\nbecause GDB can only unwind a register if it has reached a corresponding\n.cfi directive, which won\u0027t be there before the pushes.\n\nAdditionally, at least gcc 11.4 and later by default doesn\u0027t emit\nnecessary debug info, which GDB would try to use to find prologue\u0027s end.\nIn that case, extended prologue analyzer would take effect.\n\nUsing C source listed below as an example, compiled with gcc 11.4.0:\n```\n\tint __attribute__ ((noinline))\n\tbar (int a)\n\t{\n\t    return a + a;\n\t}\n\n\tint __attribute__ ((noinline))\n\tfoo (int a, int b, int c, int d, int e)\n\t{\n\t    int x \u003d bar (a) + bar (b) + bar (c) + bar (d) + bar (e);\n\t    return x;\n\t}\n\n\tint\n\tmain (int argc, char **argv)\n\t{\n\t    return foo (1, 2, 3, 4, 5);\n\t}\n```\n\nCompiling with \"gcc -O1 -fno-omit-frame-pointer\n-fno-asynchronous-unwind-tables\", we get:\n```\n\t(gdb) b foo\n\tBreakpoint 1 at 0x1139\n\t(gdb) r\n\t...\n\tBreakpoint 1, 0x0000555555555139 in foo ()\n\t(gdb) disassemble\n\tDump of assembler code for function foo:\n\t   0x0000555555555131 \u003c+0\u003e:     endbr64\n\t   0x0000555555555135 \u003c+4\u003e:     push   %rbp\n\t   0x0000555555555136 \u003c+5\u003e:     mov    %rsp,%rbp\n\t\u003d\u003e 0x0000555555555139 \u003c+8\u003e:     push   %r15\n\t   0x000055555555513b \u003c+10\u003e:    push   %r14\n\t   0x000055555555513d \u003c+12\u003e:    push   %r13\n\t   0x000055555555513f \u003c+14\u003e:    push   %r12\n\t   0x0000555555555141 \u003c+16\u003e:    push   %rbx\n\t   0x0000555555555142 \u003c+17\u003e:    sub    $0x8,%rsp\n\t   0x0000555555555146 \u003c+21\u003e:    mov    %esi,%r15d\n\t...\n\t(gdb) ni\n\t0x000055555555513b in foo ()\n\t(gdb) p $r15\n\t$1 \u003d 140737354125376\n\t(gdb) p $r15\u003d1234\n\t$2 \u003d 1234\n\t(gdb) p $r15\n\t$3 \u003d 1234\n\t(gdb) up\n\t#1  0x00005555555551b7 in main ()\n\t(gdb) p $r15\n\t$4 \u003d 1234\n```\n\nWith the proposed changes, breakpoint gets past those register pushes:\n```\n\t(gdb) b foo\n\tBreakpoint 1 at 0x1142\n\t(gdb) r\n\t...\n\tBreakpoint 1, 0x0000555555555142 in foo ()\n\t(gdb) disassemble\n\tDump of assembler code for function foo:\n\t   0x0000555555555131 \u003c+0\u003e:     endbr64\n\t   0x0000555555555135 \u003c+4\u003e:     push   %rbp\n\t   0x0000555555555136 \u003c+5\u003e:     mov    %rsp,%rbp\n\t   0x0000555555555139 \u003c+8\u003e:     push   %r15\n\t   0x000055555555513b \u003c+10\u003e:    push   %r14\n\t   0x000055555555513d \u003c+12\u003e:    push   %r13\n\t   0x000055555555513f \u003c+14\u003e:    push   %r12\n\t   0x0000555555555141 \u003c+16\u003e:    push   %rbx\n\t\u003d\u003e 0x0000555555555142 \u003c+17\u003e:    sub    $0x8,%rsp\n\t   0x0000555555555146 \u003c+21\u003e:    mov    %esi,%r15d\n\t...\n```\n\nAlso, unwinding pushed registers now works:\n```\n\t...\n\tBreakpoint 1, 0x0000555555555142 in foo ()\n\t(gdb) disassemble\n\tDump of assembler code for function foo:\n\t   0x0000555555555131 \u003c+0\u003e:     endbr64\n\t   0x0000555555555135 \u003c+4\u003e:     push   %rbp\n\t   0x0000555555555136 \u003c+5\u003e:     mov    %rsp,%rbp\n\t   0x0000555555555139 \u003c+8\u003e:     push   %r15\n\t   0x0000555555555139 \u003c+8\u003e:     push   %r15\n\t   0x000055555555513b \u003c+10\u003e:    push   %r14\n\t   0x000055555555513d \u003c+12\u003e:    push   %r13\n\t   0x000055555555513f \u003c+14\u003e:    push   %r12\n\t   0x0000555555555141 \u003c+16\u003e:    push   %rbx\n\t\u003d\u003e 0x0000555555555142 \u003c+17\u003e:    sub    $0x8,%rsp\n\t   0x0000555555555146 \u003c+21\u003e:    mov    %esi,%r15d\n\t...\n\t(gdb) p $r15\n\t$1 \u003d 140737354125376\n\t(gdb) p $r15\u003d1234\n\t$2 \u003d 1234\n\t(gdb) p $r15\n\t$3 \u003d 1234\n\t(gdb) up\n\t#1  0x00005555555551b7 in main ()\n\t(gdb) p $r15\n\t$4 \u003d 140737354125376\n```\n\nAdditionally a new test was added to verify this behavior.\n\nReviewed-By: Guinevere Larsen \u003cguinevere@redhat.com\u003e\nApproved-By: Andrew Burgess \u003caburgess@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "916083457b67058dc5b3d9ffd3f340adff8f64cf",
      "old_mode": 33188,
      "old_path": "gdb/amd64-tdep.c",
      "new_id": "47eb2ec30260380df25c421cba3a699faa4fa64e",
      "new_mode": 33261,
      "new_path": "gdb/amd64-tdep.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "bcebfe873467930ab39dc54fbca81a9eb117b9f4",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-no-cfi.S"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "783ec3350c9fe1e5fd4e4db0348ffb28000181cf",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-offset.S"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "c5ef4f652126598f4231f1740608dc2009accfb3",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.S"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "1ce30b1761f07628d36a4bb1c9b61343bafa75f9",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "7ad0c60aa8153b8f94da3147a5884b73c19358b7",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.exp"
    }
  ]
}
