diff options
Diffstat (limited to 'gdb/amd64-tdep.c')
-rw-r--r-- | gdb/amd64-tdep.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 14be776..8f686d1 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -1910,43 +1910,37 @@ amd64_analyze_prologue (struct gdbarch *gdbarch, return pc; } -/* Return PC of first real instruction. */ +/* Work around false termination of prologue - GCC PR debug/48827. + + START_PC is the first instruction of a function, PC is its minimal already + determined advanced address. Function returns PC if it has nothing to do. + + 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: */ static CORE_ADDR -amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) +amd64_skip_xmm_prologue (CORE_ADDR pc, 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, - &cache); - if (cache.frameless_p) - return start_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 + || producer_is_gcc_ge_4 (start_pc_sal.symtab->producer) < 6 || start_pc_sal.pc != start_pc || pc >= start_pc_sal.end) return pc; @@ -1993,6 +1987,23 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) return next_sal.end; } + +/* Return PC of first real instruction. */ + +static CORE_ADDR +amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) +{ + struct amd64_frame_cache cache; + CORE_ADDR pc; + + amd64_init_frame_cache (&cache); + pc = amd64_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffLL, + &cache); + if (cache.frameless_p) + return start_pc; + + return amd64_skip_xmm_prologue (pc, start_pc); +} /* Normal frames. */ |