[PATCH] Disassemble over end of line table sequence.
Andrew Burgess
aburgess@broadcom.com
Thu Jan 13 11:47:00 GMT 2011
Ping!
Could someone cast an eye over this please.
Thanks,
Andrew
On 15/12/2010 14:23, Andrew Burgess wrote:
> Within gdb we use line number 0 to mark the end of a sequence within the
> line number tables. When disassembling with source code we sort the
> lines based on the line number. As a result if a request is made to
> disassemble a range of addresses that includes an end of sequence marker
> the disassemble command will give an error rather than any sensible output.
>
> In the included test I request a disassembly for a range of addresses
> that spans a function boundary, currently this will fail. With the fix
> the disassembly I get back still does not quite cover the complete range
> of addresses requested, I am treating this problem as a separate issue
> to be fixed in a later patch, here I am only interested in ordering the
> lines correctly so that I get something sensible back rather than an error.
>
> Thanks,
>
> Andrew
>
>
>
> gdb/
>
> 2010-12-10 Andrew Burgess<aburgess@broadcom.com>
>
> * (compare_lines): Sort by pc for entries where the line
> number is 0, these are the end of sequence markers.
>
> gdb/testsuite/
>
> 2010-12-10 Andrew Burgess<aburgess@broadcom.com>
>
> * gdb.disasm/disasm-end-cu-1.c, gdb.disasm/disasm-end-cu-2.c,
> gdb.disasm/disasm-end-cu.exp: New test for disassembling
> over the boundary between two compilation units.
>
>
> diff --git a/gdb/disasm.c b/gdb/disasm.c
> index 9fa34a0..2259f3e 100644
> --- a/gdb/disasm.c
> +++ b/gdb/disasm.c
> @@ -77,12 +77,22 @@ compare_lines (const void *mle1p, const void *mle2p)
> mle1 = (struct dis_line_entry *) mle1p;
> mle2 = (struct dis_line_entry *) mle2p;
>
> - val = mle1->line - mle2->line;
> -
> - if (val != 0)
> - return val;
> + /* Work with end of sequence markers
> + where the line number is set to 0 */
> + 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 mle1->start_pc - mle2->start_pc;
> + return val;
> }
>
> static int
> diff --git a/gdb/testsuite/gdb.disasm/disasm-end-cu-1.c
> b/gdb/testsuite/gdb.disasm/disasm-end-cu-1.c
> new file mode 100644
> index 0000000..c031778
> --- /dev/null
> +++ b/gdb/testsuite/gdb.disasm/disasm-end-cu-1.c
> @@ -0,0 +1,14 @@
> +#include<stdio.h>
> +
> +void
> +dummy_1 ()
> +{
> + printf("In dummy_1 ()\n");
> +}
> +
> +int
> +main ()
> +{
> + printf("Hello World!\n");
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.disasm/disasm-end-cu-2.c
> b/gdb/testsuite/gdb.disasm/disasm-end-cu-2.c
> new file mode 100644
> index 0000000..7fddb87
> --- /dev/null
> +++ b/gdb/testsuite/gdb.disasm/disasm-end-cu-2.c
> @@ -0,0 +1,13 @@
> +#include<stdio.h>
> +
> +void
> +dummy_2 ()
> +{
> + printf("In dummy_2 ()\n");
> +}
> +
> +void
> +dummy_3 ()
> +{
> + printf("In dummy_3 ()\n");
> +}
> diff --git a/gdb/testsuite/gdb.disasm/disasm-end-cu.exp
> b/gdb/testsuite/gdb.disasm/disasm-end-cu.exp
> new file mode 100644
> index 0000000..fdbd179
> --- /dev/null
> +++ b/gdb/testsuite/gdb.disasm/disasm-end-cu.exp
> @@ -0,0 +1,70 @@
> +# Copyright 2010 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see<http://www.gnu.org/licenses/>.
> +
> +# This test can only be run on targets which support DWARF-2 and use gas.
> +# For now pick a sampling of likely targets.
> +if {![istarget *-*-linux*]
> +&& ![istarget *-*-gnu*]
> +&& ![istarget *-*-elf*]
> +&& ![istarget *-*-openbsd*]
> +&& ![istarget arm-*-eabi*]
> +&& ![istarget powerpc-*-eabi*]} {
> + return 0
> +}
> +
> +# This test tries to disassemble over the boundary between two compilation
> +# units displaying source lines. This checks that the disassemble routine
> +# can handle our use of line number 0 to mark the end of sequence.
> +
> +if { [prepare_for_testing disasm-end-cu.exp "disasm-end-cu"
> {disasm-end-cu-1.c disasm-end-cu-2.c} {debug}] } {
> + return -1
> +}
> +
> +if ![runto_main] {
> + return -1
> +}
> +
> +set main_addr [get_hexadecimal_valueof "&main" "0"]
> +set dummy_3_addr [get_hexadecimal_valueof "&dummy_3" "0"]
> +
> +if {$main_addr == 0 || $dummy_3_addr == 0 || $dummy_3_addr<= $main_addr} {
> + fail "Unable to extract required addresses, or addresses out of order"
> + return -1
> +}
> +
> +send_gdb "disassemble /m ${main_addr},${dummy_3_addr}\n"
> +gdb_expect {
> + -re "Dump of assembler code from ${main_addr} to
> ${dummy_3_addr}:\r\nEnd of assembler dump\." {
> + fail "No output from the disassemble command"
> + }
> +
> + -re "Line number 0 out of range;.* has $decimal lines\." {
> + fail "The disassemble command failed"
> + }
> +
> + -re "Dump of assembler code from ${main_addr} to
> ${dummy_3_addr}:\r\n.*main.*End of assembler dump\." {
> + pass "disassemble command returned some output"
> + }
> +
> + -re ".*$gdb_prompt $" {
> + fail "Unexpected output from disassemble command"
> + }
> +
> + timeout {
> + fail "(timeout) waiting for output of disassemble command"
> + }
> +}
> +
> +gdb_stop_suppressing_tests;
>
>
>
More information about the Gdb-patches
mailing list