Re: [patch v4 01/13] disas: add precise instructions flag

Pedro Alves
2012-11-27T16:49:38Z

On 11/27/2012 10:48 AM, markus.t.metzger@intel.com wrote:
> From: Markus Metzger <markus.t.metzger@intel.com>
>
> When disassembling an address range with interleaved sources,

What you mean by interleaved? "disasm /m" ?

> the addresses that
> are being disassembled may not exactly match the specified range.

Is this another symptom of the issue that "disasm /m" sorts by
line number, rather than the much more reasonable sort-by-address,
which is IIRC what objdump does too?

> Addresses may be:
> - added after the specified range
> - omitted at the beginning of the specified range
>
> Add a new disassembly flag that fixes the above two cases.

It's much easier to evaluate such patches if we're shown examples of the
behavior you don't want, and of what the patch enables.

> 2012-11-27 Markus Metzger <markus.t.metzger@intel.com>
>
> * disasm.h: Add new flag DISASSEMBLY_PRECISE_INSN.
> * disasm.c (do_mixed_source_and_assembly): Adjust mle boundaries.
>
>
> ---
> gdb/disasm.c | 26 ++++++++++++++++++++++----
> gdb/disasm.h | 9 +++++----
> 2 files changed, 27 insertions(+), 8 deletions(-)
>
> diff --git a/gdb/disasm.c b/gdb/disasm.c
> index 25d87d7..2120add 100644
> --- a/gdb/disasm.c
> +++ b/gdb/disasm.c
> @@ -221,13 +221,22 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
>
> /* First, skip all the preceding functions. */
>
> - for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
> + /* If we want precise instructions, we only skip the line entries for which
> + the pc range between this and the next entry precedes the requested
> + instruction range. */
> + if (flags & DISASSEMBLY_PRECISE_INSN)
> + for (i = 0; i < nlines - 2 && le[i + 1].pc <= low; i++);
> + else
> + for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
>
> /* Now, copy all entries before the end of this function. */
>
> for (; i < nlines - 1 && le[i].pc < high; i++)
> {
> - if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
> + CORE_ADDR start = le[i].pc;
> + CORE_ADDR end = le[i + 1].pc;
> +
> + if (le[i].line == le[i + 1].line && start == end)
> continue; /* Ignore duplicates. */
>
> /* Skip any end-of-function markers. */
> @@ -237,8 +246,17 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
> mle[newlines].line = le[i].line;
> if (le[i].line > le[i + 1].line)
> out_of_order = 1;
> - mle[newlines].start_pc = le[i].pc;
> - mle[newlines].end_pc = le[i + 1].pc;
> +
> + /* If we want precise instructions, adjust the line ranges to only contain
> + instructions in the requested range. */
> + if (flags & DISASSEMBLY_PRECISE_INSN)
> + {
> + end = min (end, high);
> + start = max (start, low);
> + }
> +
> + mle[newlines].start_pc = start;
> + mle[newlines].end_pc = end;
> newlines++;
> }
>
> diff --git a/gdb/disasm.h b/gdb/disasm.h
> index a254642..a033b72 100644
> --- a/gdb/disasm.h
> +++ b/gdb/disasm.h
> @@ -19,10 +19,11 @@
> #ifndef DISASM_H
> #define DISASM_H
>
> -#define DISASSEMBLY_SOURCE (0x1 << 0)
> -#define DISASSEMBLY_RAW_INSN (0x1 << 1)
> -#define DISASSEMBLY_OMIT_FNAME (0x1 << 2)
> -#define DISASSEMBLY_FILENAME (0x1 << 3)
> +#define DISASSEMBLY_SOURCE (0x1 << 0)
> +#define DISASSEMBLY_RAW_INSN (0x1 << 1)
> +#define DISASSEMBLY_OMIT_FNAME (0x1 << 2)
> +#define DISASSEMBLY_FILENAME (0x1 << 3)
> +#define DISASSEMBLY_PRECISE_INSN (0x1 << 4)
>
> struct ui_out;
> struct ui_file;
>

--
Pedro Alves