[patch] workaround gcc46: prologue skip skips too far (PR 12435) #2
Doug Evans
dje@google.com
Thu Sep 8 17:31:00 GMT 2011
On Fri, Jul 22, 2011 at 2:58 PM, Jan Kratochvil
<jan.kratochvil@redhat.com> wrote:
> Hi,
>
> this is an improved patch of a former:
> [patch] workaround gcc46: prologue skip skips too far (PR 12435)
> http://sourceware.org/ml/gdb-patches/2011-03/msg01108.html
> cancel/FYI: Re: [patch] workaround gcc46: prologue skip skips too far (PR 12435)
> http://sourceware.org/ml/gdb-patches/2011-03/msg01123.html
>
> [...]
>
> I will update the code after FSF gcc gets fixed to minimize the workaround.
I realize this is checked in, but a couple of comments for maybe the
next patch for this.
> [...]
>
> --- a/gdb/amd64-tdep.c
> +++ b/gdb/amd64-tdep.c
> @@ -1902,6 +1902,9 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
> {
> struct amd64_frame_cache cache;
> CORE_ADDR pc;
> + struct symtab_and_line start_pc_sal, next_sal;
> + gdb_byte buf[4 + 8 * 7];
> + int offset, xmmreg;
>
> amd64_init_frame_cache (&cache);
> pc = amd64_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffLL,
> @@ -1909,7 +1912,71 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
> if (cache.frameless_p)
> return start_pc;
>
> - return pc;
> + /* GCC PR debug/48827 produced false prologue end:
> + 84 c0 test %al,%al
> + 74 23 je after
> + <-- here is 0 lines advance - the false prologue end marker.
> + 0f 29 85 70 ff ff ff movaps %xmm0,-0x90(%rbp)
> + 0f 29 4d 80 movaps %xmm1,-0x80(%rbp)
> + 0f 29 55 90 movaps %xmm2,-0x70(%rbp)
> + 0f 29 5d a0 movaps %xmm3,-0x60(%rbp)
> + 0f 29 65 b0 movaps %xmm4,-0x50(%rbp)
> + 0f 29 6d c0 movaps %xmm5,-0x40(%rbp)
> + 0f 29 75 d0 movaps %xmm6,-0x30(%rbp)
> + 0f 29 7d e0 movaps %xmm7,-0x20(%rbp)
> + after: */
> +
> + if (pc == start_pc)
> + return pc;
> +
> + start_pc_sal = find_pc_sect_line (start_pc, NULL, 0);
> + if (start_pc_sal.symtab == NULL
> + || !start_pc_sal.symtab->amd64_prologue_line_bug
> + || start_pc_sal.pc != start_pc || pc >= start_pc_sal.end)
> + return pc;
> +
> + next_sal = find_pc_sect_line (start_pc_sal.end, NULL, 0);
> + if (next_sal.line != start_pc_sal.line)
> + return pc;
> +
> + /* START_PC can be from overlayed memory, ignored here. */
> + if (target_read_memory (next_sal.pc - 4, buf, sizeof (buf)) != 0)
> + return pc;
> +
> + /* test %al,%al */
> + if (buf[0] != 0x84 || buf[1] != 0xc0)
> + return pc;
> + /* je AFTER */
> + if (buf[2] != 0x74)
> + return pc;
> +
> + offset = 4;
> + for (xmmreg = 0; xmmreg < 8; xmmreg++)
> + {
> + /* movaps %xmmreg?,-0x??(%rbp) */
> + if (buf[offset] != 0x0f || buf[offset + 1] != 0x29
> + || (buf[offset + 2] & 0b00111111) != (xmmreg << 3 | 0b101))
> + return pc;
> +
> + if ((buf[offset + 2] & 0b11000000) == 0b01000000)
> + {
> + /* 8-bit displacement. */
> + offset += 4;
> + }
> + else if ((buf[offset + 2] & 0b11000000) == 0b10000000)
> + {
> + /* 32-bit displacement. */
> + offset += 7;
> + }
> + else
> + return pc;
> + }
> +
> + /* je AFTER */
> + if (offset - 4 != buf[3])
> + return pc;
> +
> + return next_sal.end;
> }
These kinds of functions tend to grow and grow and become hard to maintain.
IWBN if all this new code is about a specific issue then tuck it away
in its own function.
[Or at least document both the start and end of it.]
> [...]
>
> --- a/gdb/symtab.h
> +++ b/gdb/symtab.h
> @@ -784,6 +784,11 @@ struct symtab
>
> unsigned int epilogue_unwind_valid : 1;
>
> + /* At least GCC 4.6.0 and 4.6.1 can produce invalid false prologue and marker
> + on amd64. This flag is set independently of the symtab arch. */
> +
> + unsigned amd64_prologue_line_bug : 1;
> +
> /* The macro table for this symtab. Like the blockvector, this
> may be shared between different symtabs --- and normally is for
> all the symtabs in a given compilation unit. */
I can hear the screams of pushback if a random net person wanted to
check in anything architecture specific to the architecture
independent part of gdb. :-)
More information about the Gdb-patches
mailing list