From patchwork Mon Jul 20 05:19:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Evans X-Patchwork-Id: 7744 Received: (qmail 6522 invoked by alias); 20 Jul 2015 05:20:17 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 6511 invoked by uid 89); 20 Jul 2015 05:20:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_05, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f178.google.com Received: from mail-pd0-f178.google.com (HELO mail-pd0-f178.google.com) (209.85.192.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 20 Jul 2015 05:20:13 +0000 Received: by pdjr16 with SMTP id r16so98213661pdj.3 for ; Sun, 19 Jul 2015 22:20:12 -0700 (PDT) X-Received: by 10.70.34.171 with SMTP id a11mr55675630pdj.18.1437369611962; Sun, 19 Jul 2015 22:20:11 -0700 (PDT) Received: from sspiff.org (173-13-178-53-sfba.hfc.comcastbusiness.net. [173.13.178.53]) by smtp.gmail.com with ESMTPSA id j4sm19168332pdg.64.2015.07.19.22.20.09 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 19 Jul 2015 22:20:11 -0700 (PDT) Received: by sspiff.org (sSMTP sendmail emulation); Sun, 19 Jul 2015 22:19:21 -0700 From: Doug Evans To: gdb-patches@sourceware.org Subject: [PATCH] Rewrite mixed source/assembler disassembly Date: Sun, 19 Jul 2015 22:19:21 -0700 Message-ID: MIME-Version: 1.0 X-IsSubscribed: yes Hi. This is a patch I've wanted to write for a very long time. The current mixed source/assembler disassembly is not very usable. In the presence of multiple source files (inlined functions, etc.) it doesn't print usable output. In the presence of optimized code, trying to be source centric just doesn't work IMO. And with no optimization the before/after should be identical. One change I've made here is that I'm printing the source file in the output. This is critical when displaying inlined functions from another source file. If there's only one source file it's more a matter of taste. To keep things simple, this patch displays the source file name even if there's only one file. The other change I've made is to remove the blank line between assembly and the next source line. I'm ambivalent, what do you think? E.g., (gdb) disas /m main Dump of assembler code for function main: hello.c: <<<--- this is new 5 { 0x08048330 <+0>: push %ebp 0x08048331 <+1>: mov %esp,%ebp 0x08048333 <+3>: sub $0x8,%esp 0x08048336 <+6>: and $0xfffffff0,%esp 0x08048339 <+9>: sub $0x10,%esp 6 printf ("Hello.\n"); => 0x0804833c <+12>: movl $0x8048440,(%esp) 0x08048343 <+19>: call 0x8048284 7 return 0; 0x08048348 <+24>: mov $0x0,%eax 8 } 0x0804834d <+29>: leave 0x0804834e <+30>: ret I still need to test this with an MI frontend. 2015-07-19 Doug Evans * NEWS: Document change is mixed source/assembly output. * disasm.c: #include "source.h". (dis_line_entry) : New member. (dis_line_entry) : Delete members. (hash_dis_line_entry, eq_dis_line_entry): New functions. (allocate_dis_line_table): New functions. (maybe_add_dis_line_entry, line_has_code_p): New functions. (compare_lines): Delete. (dump_insns): New arg end_pc. All callers updated. (do_mixed_source_and_assembly): Rewrite. Delete arg nlines, le. Rename arg symtab to main_symtab. All callers updated. doc/ * gdb.texinfo (Machine Code): Update docs for mixed source/assembly disassembly. testsuite/ * gdb.mi/basics.c (main): Add comment. * gdb.mi/mi-cli.exp: Update. * gdb.mi/mi-disassemble.exp: Update. diff --git a/gdb/NEWS b/gdb/NEWS index 7ce9758..3222375 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -5,6 +5,10 @@ * Support for tracepoints on aarch64-linux was added in GDBserver. +* Mixed source disassembly output has been changed. + Disassembled instructions are now printed in program order, + and source for all relevant files are now printed. + *** Changes in GDB 7.10 * Support for process record-replay and reverse debugging on aarch64*-linux* diff --git a/gdb/disasm.c b/gdb/disasm.c index 483df01..1a6ae28 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -24,6 +24,7 @@ #include "disasm.h" #include "gdbcore.h" #include "dis-asm.h" +#include "source.h" /* Disassemble functions. FIXME: We should get rid of all the duplicate code in gdb that does @@ -36,11 +37,75 @@ struct dis_line_entry { + struct symtab *symtab; int line; - CORE_ADDR start_pc; - CORE_ADDR end_pc; }; +/* Hash function for dis_line_entry. */ + +static hashval_t +hash_dis_line_entry (const void *item) +{ + const struct dis_line_entry *dle = item; + + return htab_hash_pointer (dle->symtab) + dle->line; +} + +/* Equal function for dis_line_entry. */ + +static int +eq_dis_line_entry (const void *item_lhs, const void *item_rhs) +{ + const struct dis_line_entry *lhs = item_lhs; + const struct dis_line_entry *rhs = item_rhs; + + return (lhs->symtab == rhs->symtab + && lhs->line == rhs->line); +} + +/* Create the table to manage lines for mixed source/disassembly. */ + +static htab_t +allocate_dis_line_table (void) +{ + return htab_create_alloc (41, + hash_dis_line_entry, eq_dis_line_entry, + xfree, xcalloc, xfree); +} + +/* Add DLE to TABLE. + Returns 1 if added, 0 if already present. */ + +static void +maybe_add_dis_line_entry (htab_t table, struct symtab *symtab, int line) +{ + void **slot; + struct dis_line_entry dle, *dlep; + + dle.symtab = symtab; + dle.line = line; + slot = htab_find_slot (table, &dle, INSERT); + if (*slot == NULL) + { + dlep = XNEW (struct dis_line_entry); + dlep->symtab = symtab; + dlep->line = line; + *slot = dlep; + } +} + +/* Return non-zero if SYMTAB, LINE are in TABLE. */ + +static int +line_has_code_p (htab_t table, struct symtab *symtab, int line) +{ + struct dis_line_entry dle; + + dle.symtab = symtab; + dle.line = line; + return htab_find (table, &dle) != NULL; +} + /* Like target_read_memory, but slightly different parameters. */ static int dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, @@ -67,36 +132,11 @@ dis_asm_print_address (bfd_vma addr, struct disassemble_info *info) } static int -compare_lines (const void *mle1p, const void *mle2p) -{ - struct dis_line_entry *mle1, *mle2; - int val; - - mle1 = (struct dis_line_entry *) mle1p; - mle2 = (struct dis_line_entry *) mle2p; - - /* End of sequence markers have a line number of 0 but don't want to - be sorted to the head of the list, instead sort by PC. */ - if (mle1->line == 0 || mle2->line == 0) - { - val = mle1->start_pc - mle2->start_pc; - if (val == 0) - val = mle1->line - mle2->line; - } - else - { - val = mle1->line - mle2->line; - if (val == 0) - val = mle1->start_pc - mle2->start_pc; - } - return val; -} - -static int dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout, struct disassemble_info * di, CORE_ADDR low, CORE_ADDR high, - int how_many, int flags, struct ui_file *stb) + int how_many, int flags, struct ui_file *stb, + CORE_ADDR *end_pc) { int num_displayed = 0; CORE_ADDR pc; @@ -182,6 +222,9 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout, do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); } + + if (end_pc != NULL) + *end_pc = pc; return num_displayed; } @@ -192,10 +235,9 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout, static void do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout, - struct disassemble_info *di, int nlines, - struct linetable_entry *le, + struct disassemble_info *di, + struct symtab *main_symtab, CORE_ADDR low, CORE_ADDR high, - struct symtab *symtab, int how_many, int flags, struct ui_file *stb) { int newlines = 0; @@ -206,143 +248,169 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout, int next_line = 0; int num_displayed = 0; enum print_source_lines_flags psl_flags = 0; + struct cleanup *cleanups; struct cleanup *ui_out_chain; - struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0); - struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0); - - if (flags & DISASSEMBLY_FILENAME) - psl_flags |= PRINT_SOURCE_LINES_FILENAME; - - mle = (struct dis_line_entry *) alloca (nlines - * sizeof (struct dis_line_entry)); + struct cleanup *ui_out_tuple_chain; + struct cleanup *ui_out_list_chain; + CORE_ADDR pc; + struct symtab *last_symtab; + int last_line; + htab_t dis_line_table; - /* Copy linetable entries for this function into our data - structure, creating end_pc's and setting out_of_order as - appropriate. */ + gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL); - /* First, skip all the preceding functions. */ + /* First pass is to collect the list of all source files and lines. + We do this so that we can only print lines containing code once. + We try to print the source text leading up to the next instruction, + but if that text is for code that will be disassembled later, then + we'll want to defer printing it until later where it's used. */ - for (i = 0; i < nlines - 1 && le[i].pc < low; i++); + dis_line_table = allocate_dis_line_table (); + cleanups = make_cleanup_htab_delete (dis_line_table); - /* Now, copy all entries before the end of this function. */ + pc = low; - for (; i < nlines - 1 && le[i].pc < high; i++) + while (pc < high) { - if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc) - continue; /* Ignore duplicates. */ - - /* Skip any end-of-function markers. */ - if (le[i].line == 0) - continue; - - 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; - newlines++; - } + struct symtab_and_line sal; + int length; - /* If we're on the last line, and it's part of the function, - then we need to get the end pc in a special way. */ + sal = find_pc_line (pc, 0); + length = gdb_insn_length (gdbarch, pc); + pc += length; - if (i == nlines - 1 && le[i].pc < high) - { - mle[newlines].line = le[i].line; - mle[newlines].start_pc = le[i].pc; - sal = find_pc_line (le[i].pc, 0); - mle[newlines].end_pc = sal.end; - newlines++; + if (sal.symtab != NULL) + maybe_add_dis_line_entry (dis_line_table, sal.symtab, sal.line); } - /* Now, sort mle by line #s (and, then by addresses within - lines). */ - - if (out_of_order) - qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines); + /* Second pass prints the disassembly. */ - /* Now, for each line entry, emit the specified lines (unless - they have been emitted before), followed by the assembly code - for that line. */ + if (flags & DISASSEMBLY_FILENAME) + psl_flags |= PRINT_SOURCE_LINES_FILENAME; + ui_out_text (uiout, symtab_to_filename_for_display (main_symtab)); + ui_out_text (uiout, ":\n"); ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); - for (i = 0; i < newlines; i++) + ui_out_tuple_chain = make_cleanup (null_cleanup, NULL); + ui_out_list_chain = make_cleanup (null_cleanup, NULL); + + last_symtab = main_symtab; + last_line = 0; + pc = low; + + while (pc < high) { - /* Print out everything from next_line to the current line. */ - if (mle[i].line >= next_line) + struct linetable_entry *le = NULL; + struct symtab_and_line sal; + CORE_ADDR end_pc; + int start_preceding_line_to_display = 0; + int end_preceding_line_to_display = 0; + int new_line = 0; + + sal = find_pc_line (pc, 0); + + if (sal.symtab != last_symtab) { - if (next_line != 0) + /* New source file. */ + do_cleanups (ui_out_chain); + ui_out_text (uiout, symtab_to_filename_for_display (sal.symtab)); + ui_out_text (uiout, ":\n"); + ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, + "asm_insns"); + new_line = 1; + } + else + { + /* Same source file as last time. */ + if (sal.symtab != NULL) { - /* Just one line to print. */ - if (next_line == mle[i].line) + if (sal.line > last_line + 1 && last_line != 0) { - ui_out_tuple_chain - = make_cleanup_ui_out_tuple_begin_end (uiout, - "src_and_asm_line"); - print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags); + int l; + + /* Several preceding source lines. Print the trailing ones + not associated with code that we'll print later. */ + for (l = sal.line - 1; l > last_line; --l) + { + if (line_has_code_p (dis_line_table, sal.symtab, l)) + break; + } + if (l < sal.line - 1) + { + start_preceding_line_to_display = l + 1; + end_preceding_line_to_display = sal.line; + } } + if (sal.line != last_line) + new_line = 1; else { - /* Several source lines w/o asm instructions associated. */ - for (; next_line < mle[i].line; next_line++) - { - struct cleanup *ui_out_list_chain_line; - struct cleanup *ui_out_tuple_chain_line; - - ui_out_tuple_chain_line - = make_cleanup_ui_out_tuple_begin_end (uiout, - "src_and_asm_line"); - print_source_lines (symtab, next_line, next_line + 1, - psl_flags); - ui_out_list_chain_line - = make_cleanup_ui_out_list_begin_end (uiout, - "line_asm_insn"); - do_cleanups (ui_out_list_chain_line); - do_cleanups (ui_out_tuple_chain_line); - } - /* Print the last line and leave list open for - asm instructions to be added. */ - ui_out_tuple_chain + /* Same source line as last time. This can happen, depending + on the debug info. */ + } + } + } + + if (new_line) + { + if (sal.symtab == last_symtab) + { + do_cleanups (ui_out_list_chain); + do_cleanups (ui_out_tuple_chain); + } + if (start_preceding_line_to_display > 0) + { + /* Several source lines w/o asm instructions associated. */ + int l; + struct cleanup *ui_out_list_chain_line; + struct cleanup *ui_out_tuple_chain_line; + + gdb_assert (sal.symtab != NULL); + for (l = start_preceding_line_to_display; + l < end_preceding_line_to_display; + ++l) + { + ui_out_tuple_chain_line = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line"); - print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags); + print_source_lines (sal.symtab, l, l + 1, psl_flags); + ui_out_list_chain_line + = make_cleanup_ui_out_list_begin_end (uiout, + "line_asm_insn"); + do_cleanups (ui_out_list_chain_line); + do_cleanups (ui_out_tuple_chain_line); } } + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line"); + if (sal.symtab != NULL) + print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags); else - { - ui_out_tuple_chain - = make_cleanup_ui_out_tuple_begin_end (uiout, - "src_and_asm_line"); - print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags); - } - - next_line = mle[i].line + 1; + ui_out_text (uiout, _("--- no source info for this pc ---\n")); ui_out_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn"); } - num_displayed += dump_insns (gdbarch, uiout, di, - mle[i].start_pc, mle[i].end_pc, - how_many, flags, stb); + if (sal.end != 0) + end_pc = min (sal.end, high); + else + end_pc = pc + 1; + num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc, + how_many, flags, stb, &end_pc); + pc = end_pc; - /* When we've reached the end of the mle array, or we've seen the last - assembly range for this source line, close out the list/tuple. */ - if (i == (newlines - 1) || mle[i + 1].line > mle[i].line) - { - do_cleanups (ui_out_list_chain); - do_cleanups (ui_out_tuple_chain); - ui_out_tuple_chain = make_cleanup (null_cleanup, 0); - ui_out_list_chain = make_cleanup (null_cleanup, 0); - ui_out_text (uiout, "\n"); - } if (how_many >= 0 && num_displayed >= how_many) break; + + last_symtab = sal.symtab; + last_line = sal.line; } + do_cleanups (ui_out_chain); + do_cleanups (cleanups); } - static void do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout, struct disassemble_info * di, @@ -355,7 +423,7 @@ do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout, ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many, - flags, stb); + flags, stb, NULL); do_cleanups (ui_out_chain); } @@ -411,26 +479,21 @@ gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout, struct cleanup *cleanups = make_cleanup_ui_file_delete (stb); struct disassemble_info di = gdb_disassemble_info (gdbarch, stb); struct symtab *symtab; - struct linetable_entry *le = NULL; int nlines = -1; /* Assume symtab is valid for whole PC range. */ symtab = find_pc_line_symtab (low); if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL) - { - /* Convert the linetable to a bunch of my_line_entry's. */ - le = SYMTAB_LINETABLE (symtab)->item; - nlines = SYMTAB_LINETABLE (symtab)->nitems; - } + nlines = SYMTAB_LINETABLE (symtab)->nitems; if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0 || symtab == NULL || SYMTAB_LINETABLE (symtab) == NULL) do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb); else if (flags & DISASSEMBLY_SOURCE) - do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low, - high, symtab, how_many, flags, stb); + do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high, + how_many, flags, stb); do_cleanups (cleanups); gdb_flush (gdb_stdout); diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 9e2ecd1..8e6efb9 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -8082,20 +8082,19 @@ program is stopped just after function prologue: @smallexample (@value{GDBP}) disas /m main Dump of assembler code for function main: +hello.c: 5 @{ 0x08048330 <+0>: push %ebp 0x08048331 <+1>: mov %esp,%ebp 0x08048333 <+3>: sub $0x8,%esp 0x08048336 <+6>: and $0xfffffff0,%esp 0x08048339 <+9>: sub $0x10,%esp - 6 printf ("Hello.\n"); => 0x0804833c <+12>: movl $0x8048440,(%esp) 0x08048343 <+19>: call 0x8048284 - 7 return 0; -8 @} 0x08048348 <+24>: mov $0x0,%eax +8 @} 0x0804834d <+29>: leave 0x0804834e <+30>: ret diff --git a/gdb/testsuite/gdb.mi/basics.c b/gdb/testsuite/gdb.mi/basics.c index a7ce3e6..f5db825 100644 --- a/gdb/testsuite/gdb.mi/basics.c +++ b/gdb/testsuite/gdb.mi/basics.c @@ -59,7 +59,7 @@ void do_nothing (void) int main () { - callee1 (2, "A string argument.", 3.5); + callee1 (2, "A string argument.", 3.5); /* callee1-1 */ callee1 (2, "A string argument.", 3.5); do_nothing (); /* Hello, World! */ diff --git a/gdb/testsuite/gdb.mi/mi-cli.exp b/gdb/testsuite/gdb.mi/mi-cli.exp index 08c8f02..286d920 100644 --- a/gdb/testsuite/gdb.mi/mi-cli.exp +++ b/gdb/testsuite/gdb.mi/mi-cli.exp @@ -93,7 +93,7 @@ mi_gdb_test "-interpreter-exec console \"set listsize 1\"" \ # {.*\~"32[ \t(\\t)]*callee1.*\\n".*\^done } mi_gdb_test "-interpreter-exec console \"list\"" \ - ".*\~\"$line_main_body\[\\\\t \]*callee1.*;\\\\n\".*\\^done" \ + ".*\~\"$line_main_body\[\\\\t \]*callee1.*; /\\* callee1-1 \\*/\\\\n\".*\\^done" \ "-interpreter-exec console \"list\"" mi_execute_to "exec-continue" "breakpoint-hit" "callee4" "" ".*basics.c" $line_callee4_body \ diff --git a/gdb/testsuite/gdb.mi/mi-disassemble.exp b/gdb/testsuite/gdb.mi/mi-disassemble.exp index 4f5a352..7c9c8fd 100644 --- a/gdb/testsuite/gdb.mi/mi-disassemble.exp +++ b/gdb/testsuite/gdb.mi/mi-disassemble.exp @@ -116,6 +116,7 @@ proc test_disassembly_mixed {} { global decimal global fullname_syntax + set line_mixed_range [gdb_get_line_number "callee1-1"] set line_callee2_head [gdb_get_line_number "callee2 ("] set line_callee2_open_brace [expr $line_callee2_head + 1] @@ -128,12 +129,14 @@ proc test_disassembly_mixed {} { "002\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$line_callee2_open_brace\",file=\".*basics.c\",fullname=\"${fullname_syntax}basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"callee2\",offset=\"0\",inst=\".*\"\}.*\\\]\}.*,src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",fullname=\"${fullname_syntax}basics.c\",line_asm_insn=\\\[.*\{address=\"$hex\",func-name=\"callee2\",offset=\"$decimal\",inst=\".*\"\}\\\]\}\\\]" \ "data-disassemble file, line assembly mixed" - # - # In mixed mode, the lowest level of granularity is the source line. - # So we are going to get the disassembly for the source line at - # which we are now, even if we have specified that the range is only 2 insns. - # - mi_gdb_test "003-data-disassemble -s \$pc -e \"\$pc+4\" -- 1" \ + global expect_out + mi_gdb_test "-interpreter-exec console \"info line $line_mixed_range\"" \ + ".* starts at address ($hex) .* ends at ($hex).*\\^done" \ + "info line mixed-range" + set mixed_start $expect_out(3,string) + set mixed_end $expect_out(4,string) + + mi_gdb_test "003-data-disassemble -s $mixed_start -e $mixed_end -- 1" \ "003\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",fullname=\"${fullname_syntax}basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]\}\\\]" \ "data-disassemble range assembly mixed" } @@ -144,6 +147,7 @@ proc test_disassembly_mixed_with_opcodes {} { global decimal global fullname_syntax + set line_mixed_range [gdb_get_line_number "callee1-1"] set line_callee2_head [gdb_get_line_number "callee2 ("] set line_callee2_open_brace [expr $line_callee2_head + 1] @@ -156,12 +160,14 @@ proc test_disassembly_mixed_with_opcodes {} { "002\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$line_callee2_open_brace\",file=\".*basics.c\",fullname=\"${fullname_syntax}basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"callee2\",offset=\"0\",opcodes=\".*\",inst=\".*\"\}.*\\\]\}.*,src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",fullname=\"${fullname_syntax}basics.c\",line_asm_insn=\\\[.*\{address=\"$hex\",func-name=\"callee2\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}\\\]\}\\\]" \ "data-disassemble file, line assembly mixed with opcodes" - # - # In mixed mode, the lowest level of granularity is the source line. - # So we are going to get the disassembly for the source line at - # which we are now, even if we have specified that the range is only 2 insns. - # - mi_gdb_test "003-data-disassemble -s \$pc -e \"\$pc+4\" -- 3" \ + global expect_out + mi_gdb_test "-interpreter-exec console \"info line $line_mixed_range\"" \ + ".* starts at address ($hex) .* ends at ($hex).*\\^done" \ + "info line mixed-range with opcodes" + set mixed_start $expect_out(3,string) + set mixed_end $expect_out(4,string) + + mi_gdb_test "003-data-disassemble -s $mixed_start -e $mixed_end -- 3" \ "003\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",fullname=\"${fullname_syntax}basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}.*\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}\\\]\}\\\]" \ "data-disassemble range assembly mixed with opcodes" }