[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