diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2011-09-08 15:38:16 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2011-09-08 15:38:16 +0000 |
commit | 08711b9a36344df9e29be436d9f959324fff4f42 (patch) | |
tree | 5107fb8d69f110c93e06ce2ce356ee7d4229494a /gdb/amd64-tdep.c | |
parent | b2e7f004c75322ea75cc9326bc6c6f4b6577df7f (diff) | |
download | gdb-08711b9a36344df9e29be436d9f959324fff4f42.zip gdb-08711b9a36344df9e29be436d9f959324fff4f42.tar.gz gdb-08711b9a36344df9e29be436d9f959324fff4f42.tar.bz2 |
gdb/
PR breakpoints/12435
* amd64-tdep.c (amd64_skip_prologue): New variables start_pc_sal,
next_sal, buf, offset and xmmreg. Advance PC if it sees the PR.
* dwarf2read.c (process_full_comp_unit): Initialize
amd64_prologue_line_bug.
* symtab.h (struct symtab): New field amd64_prologue_line_bug.
gdb/testsuite/
PR breakpoints/12435
* gdb.arch/amd64-prologue-xmm.c: New file.
* gdb.arch/amd64-prologue-xmm.exp: New file.
* gdb.arch/amd64-prologue-xmm.s: New file.
Diffstat (limited to 'gdb/amd64-tdep.c')
-rw-r--r-- | gdb/amd64-tdep.c | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 051fb13..14be776 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -1917,6 +1917,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, @@ -1924,7 +1927,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; } |