diff mbox series

[PR,gdb/21695] Fix lost line info for symbol at addr zero

Message ID 1526393061-18039-1-git-send-email-omair.javaid@linaro.org
State New
Headers show
Series [PR,gdb/21695] Fix lost line info for symbol at addr zero | expand

Commit Message

Omair Javaid May 15, 2018, 2:04 p.m. UTC
This patch fixes a unique condition where GDB fails to provide line
information of symbol at address zero when code is compiled with text
address zero but loaded at an offset > 0.

For example lets compile following code snippet:

int main() {
  return 0;
}

gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c

Start gdb and run:

add-symbol-file file.out 0xffff0000
info line main

GDB will return error saying no line info is available for the symbol.

This is a direct consequence of the fix for PR 12528 where GDB tries to ignore
line table for a function which has been garbage collected by the linker.

As the garbage collected symbols are sent to address zero GDB assumes a symbol
actually placed at address zero as garbage collected.

This was fixed with an additional check address < lowpc. But when symbol is
loaded at an offset lowpc becomes lowpc + offset while no offset is added to
address rather final symbol address is calculated based on baseaddr and address
added together. So in case where symbols are loaded at an offset the condition
address < lowpc will always return true.

This patch fixes this by comparing address against a non offset lowpc.
This patch also adds a GDB test case to replicate this behavior.

gdb:

2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

	PR gdb/21695
	* dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.
	(dwarf_decode_lines_1): Adjust.

gdb/testsuite:

2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

	PR gdb/21695
	* gdb.base/infoline-reloc-main-from-zero.exp: New test.
	* gdb.base/infoline-reloc-main-from-zero.c: New file.
---
 gdb/dwarf2read.c                                   |  8 ++--
 .../gdb.base/infoline-reloc-main-from-zero.c       | 24 ++++++++++
 .../gdb.base/infoline-reloc-main-from-zero.exp     | 51 ++++++++++++++++++++++
 3 files changed, 79 insertions(+), 4 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c
 create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

-- 
2.7.4

Comments

Omair Javaid May 28, 2018, 10:49 a.m. UTC | #1
On 15 May 2018 at 19:04, Omair Javaid <omair.javaid@linaro.org> wrote:
> This patch fixes a unique condition where GDB fails to provide line

> information of symbol at address zero when code is compiled with text

> address zero but loaded at an offset > 0.

>

> For example lets compile following code snippet:

>

> int main() {

>   return 0;

> }

>

> gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c

>

> Start gdb and run:

>

> add-symbol-file file.out 0xffff0000

> info line main

>

> GDB will return error saying no line info is available for the symbol.

>

> This is a direct consequence of the fix for PR 12528 where GDB tries to ignore

> line table for a function which has been garbage collected by the linker.

>

> As the garbage collected symbols are sent to address zero GDB assumes a symbol

> actually placed at address zero as garbage collected.

>

> This was fixed with an additional check address < lowpc. But when symbol is

> loaded at an offset lowpc becomes lowpc + offset while no offset is added to

> address rather final symbol address is calculated based on baseaddr and address

> added together. So in case where symbols are loaded at an offset the condition

> address < lowpc will always return true.

>

> This patch fixes this by comparing address against a non offset lowpc.

> This patch also adds a GDB test case to replicate this behavior.

>

> gdb:

>

> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

>

>         PR gdb/21695

>         * dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.

>         (dwarf_decode_lines_1): Adjust.

>

> gdb/testsuite:

>

> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

>

>         PR gdb/21695

>         * gdb.base/infoline-reloc-main-from-zero.exp: New test.

>         * gdb.base/infoline-reloc-main-from-zero.c: New file.

> ---

>  gdb/dwarf2read.c                                   |  8 ++--

>  .../gdb.base/infoline-reloc-main-from-zero.c       | 24 ++++++++++

>  .../gdb.base/infoline-reloc-main-from-zero.exp     | 51 ++++++++++++++++++++++

>  3 files changed, 79 insertions(+), 4 deletions(-)

>  create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

>  create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

>

> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c

> index 575d316..b171bb2 100644

> --- a/gdb/dwarf2read.c

> +++ b/gdb/dwarf2read.c

> @@ -20411,7 +20411,7 @@ public:

>       sequence.  */

>    void check_line_address (struct dwarf2_cu *cu,

>                            const gdb_byte *line_ptr,

> -                          CORE_ADDR lowpc, CORE_ADDR address);

> +                          CORE_ADDR lowpc_minus_base, CORE_ADDR address);

>

>    void handle_set_discriminator (unsigned int discriminator)

>    {

> @@ -20755,14 +20755,14 @@ lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,

>  void

>  lnp_state_machine::check_line_address (struct dwarf2_cu *cu,

>                                        const gdb_byte *line_ptr,

> -                                      CORE_ADDR lowpc, CORE_ADDR address)

> +                                      CORE_ADDR lowpc_minus_base, CORE_ADDR address)

>  {

>    /* If address < lowpc then it's not a usable value, it's outside the

>       pc range of the CU.  However, we restrict the test to only address

>       values of zero to preserve GDB's previous behaviour which is to

>       handle the specific case of a function being GC'd by the linker.  */

>

> -  if (address == 0 && address < lowpc)

> +  if (address == 0 && address < lowpc_minus_base)

>      {

>        /* This line table is for a function which has been

>          GCd by the linker.  Ignore it.  PR gdb/12528 */

> @@ -20857,7 +20857,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,

>                     line_ptr += bytes_read;

>

>                     state_machine.check_line_address (cu, line_ptr,

> -                                                     lowpc, address);

> +                                                     lowpc - baseaddr, address);

>                     state_machine.handle_set_address (baseaddr, address);

>                   }

>                   break;

> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> new file mode 100644

> index 0000000..8902051

> --- /dev/null

> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> @@ -0,0 +1,24 @@

> +/* This testcase is part of GDB, the GNU debugger.

> +

> +   Copyright 2011-2018 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/>.  */

> +

> +// Test case for PR gdb/21695

> +

> +int

> +main ()

> +{

> +  return 0;

> +}

> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> new file mode 100644

> index 0000000..68564688

> --- /dev/null

> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> @@ -0,0 +1,51 @@

> +# Copyright 2011-2018 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 file is part of the gdb testsuite

> +

> +#

> +# test running programs

> +#

> +

> +standard_testfile .c

> +

> +if [get_compiler_info] {

> +    return -1

> +}

> +

> +# Build executable with stripped startup code and text section starting at zero

> +

> +set opts {debug "additional_flags=-nostdlib -emain -Wl,-Ttext=0x00"}

> +

> +if {[build_executable $testfile.exp $testfile $srcfile $opts] == -1} {

> +    untested "failed to compile"

> +    return -1

> +}

> +

> +gdb_exit

> +gdb_start

> +gdb_reinitialize_dir $srcdir/$subdir

> +

> +# Load symbols at an offset 0xffff0000 using add-symbol-file

> +

> +gdb_test "add-symbol-file [standard_output_file ${testfile}] 0xffff000" \

> +    "Reading symbols from .*" \

> +    "add-symbol-file" \

> +    "add symbol table from file \".*\" at.*\\(y or n\\) " "y"

> +

> +# Check if we are able to read offset adjusted line information of main

> +

> +gdb_test "info line main" \

> +       "Line.*starts at address.*and ends at.*"

> --

> 2.7.4

>



Ping!
Omair Javaid June 12, 2018, 2:25 a.m. UTC | #2
On 28 May 2018 at 15:49, Omair Javaid <omair.javaid@linaro.org> wrote:
> On 15 May 2018 at 19:04, Omair Javaid <omair.javaid@linaro.org> wrote:

>> This patch fixes a unique condition where GDB fails to provide line

>> information of symbol at address zero when code is compiled with text

>> address zero but loaded at an offset > 0.

>>

>> For example lets compile following code snippet:

>>

>> int main() {

>>   return 0;

>> }

>>

>> gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c

>>

>> Start gdb and run:

>>

>> add-symbol-file file.out 0xffff0000

>> info line main

>>

>> GDB will return error saying no line info is available for the symbol.

>>

>> This is a direct consequence of the fix for PR 12528 where GDB tries to ignore

>> line table for a function which has been garbage collected by the linker.

>>

>> As the garbage collected symbols are sent to address zero GDB assumes a symbol

>> actually placed at address zero as garbage collected.

>>

>> This was fixed with an additional check address < lowpc. But when symbol is

>> loaded at an offset lowpc becomes lowpc + offset while no offset is added to

>> address rather final symbol address is calculated based on baseaddr and address

>> added together. So in case where symbols are loaded at an offset the condition

>> address < lowpc will always return true.

>>

>> This patch fixes this by comparing address against a non offset lowpc.

>> This patch also adds a GDB test case to replicate this behavior.

>>

>> gdb:

>>

>> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

>>

>>         PR gdb/21695

>>         * dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.

>>         (dwarf_decode_lines_1): Adjust.

>>

>> gdb/testsuite:

>>

>> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

>>

>>         PR gdb/21695

>>         * gdb.base/infoline-reloc-main-from-zero.exp: New test.

>>         * gdb.base/infoline-reloc-main-from-zero.c: New file.

>> ---

>>  gdb/dwarf2read.c                                   |  8 ++--

>>  .../gdb.base/infoline-reloc-main-from-zero.c       | 24 ++++++++++

>>  .../gdb.base/infoline-reloc-main-from-zero.exp     | 51 ++++++++++++++++++++++

>>  3 files changed, 79 insertions(+), 4 deletions(-)

>>  create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

>>  create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

>>

>> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c

>> index 575d316..b171bb2 100644

>> --- a/gdb/dwarf2read.c

>> +++ b/gdb/dwarf2read.c

>> @@ -20411,7 +20411,7 @@ public:

>>       sequence.  */

>>    void check_line_address (struct dwarf2_cu *cu,

>>                            const gdb_byte *line_ptr,

>> -                          CORE_ADDR lowpc, CORE_ADDR address);

>> +                          CORE_ADDR lowpc_minus_base, CORE_ADDR address);

>>

>>    void handle_set_discriminator (unsigned int discriminator)

>>    {

>> @@ -20755,14 +20755,14 @@ lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,

>>  void

>>  lnp_state_machine::check_line_address (struct dwarf2_cu *cu,

>>                                        const gdb_byte *line_ptr,

>> -                                      CORE_ADDR lowpc, CORE_ADDR address)

>> +                                      CORE_ADDR lowpc_minus_base, CORE_ADDR address)

>>  {

>>    /* If address < lowpc then it's not a usable value, it's outside the

>>       pc range of the CU.  However, we restrict the test to only address

>>       values of zero to preserve GDB's previous behaviour which is to

>>       handle the specific case of a function being GC'd by the linker.  */

>>

>> -  if (address == 0 && address < lowpc)

>> +  if (address == 0 && address < lowpc_minus_base)

>>      {

>>        /* This line table is for a function which has been

>>          GCd by the linker.  Ignore it.  PR gdb/12528 */

>> @@ -20857,7 +20857,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,

>>                     line_ptr += bytes_read;

>>

>>                     state_machine.check_line_address (cu, line_ptr,

>> -                                                     lowpc, address);

>> +                                                     lowpc - baseaddr, address);

>>                     state_machine.handle_set_address (baseaddr, address);

>>                   }

>>                   break;

>> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

>> new file mode 100644

>> index 0000000..8902051

>> --- /dev/null

>> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

>> @@ -0,0 +1,24 @@

>> +/* This testcase is part of GDB, the GNU debugger.

>> +

>> +   Copyright 2011-2018 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/>.  */

>> +

>> +// Test case for PR gdb/21695

>> +

>> +int

>> +main ()

>> +{

>> +  return 0;

>> +}

>> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

>> new file mode 100644

>> index 0000000..68564688

>> --- /dev/null

>> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

>> @@ -0,0 +1,51 @@

>> +# Copyright 2011-2018 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 file is part of the gdb testsuite

>> +

>> +#

>> +# test running programs

>> +#

>> +

>> +standard_testfile .c

>> +

>> +if [get_compiler_info] {

>> +    return -1

>> +}

>> +

>> +# Build executable with stripped startup code and text section starting at zero

>> +

>> +set opts {debug "additional_flags=-nostdlib -emain -Wl,-Ttext=0x00"}

>> +

>> +if {[build_executable $testfile.exp $testfile $srcfile $opts] == -1} {

>> +    untested "failed to compile"

>> +    return -1

>> +}

>> +

>> +gdb_exit

>> +gdb_start

>> +gdb_reinitialize_dir $srcdir/$subdir

>> +

>> +# Load symbols at an offset 0xffff0000 using add-symbol-file

>> +

>> +gdb_test "add-symbol-file [standard_output_file ${testfile}] 0xffff000" \

>> +    "Reading symbols from .*" \

>> +    "add-symbol-file" \

>> +    "add symbol table from file \".*\" at.*\\(y or n\\) " "y"

>> +

>> +# Check if we are able to read offset adjusted line information of main

>> +

>> +gdb_test "info line main" \

>> +       "Line.*starts at address.*and ends at.*"

>> --

>> 2.7.4

>>

>

>

> Ping!


Ping!
Omair Javaid June 20, 2018, 7:53 a.m. UTC | #3
On Tue, 12 Jun 2018 at 07:25, Omair Javaid <omair.javaid@linaro.org> wrote:
>

> On 28 May 2018 at 15:49, Omair Javaid <omair.javaid@linaro.org> wrote:

> > On 15 May 2018 at 19:04, Omair Javaid <omair.javaid@linaro.org> wrote:

> >> This patch fixes a unique condition where GDB fails to provide line

> >> information of symbol at address zero when code is compiled with text

> >> address zero but loaded at an offset > 0.

> >>

> >> For example lets compile following code snippet:

> >>

> >> int main() {

> >>   return 0;

> >> }

> >>

> >> gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c

> >>

> >> Start gdb and run:

> >>

> >> add-symbol-file file.out 0xffff0000

> >> info line main

> >>

> >> GDB will return error saying no line info is available for the symbol.

> >>

> >> This is a direct consequence of the fix for PR 12528 where GDB tries to ignore

> >> line table for a function which has been garbage collected by the linker.

> >>

> >> As the garbage collected symbols are sent to address zero GDB assumes a symbol

> >> actually placed at address zero as garbage collected.

> >>

> >> This was fixed with an additional check address < lowpc. But when symbol is

> >> loaded at an offset lowpc becomes lowpc + offset while no offset is added to

> >> address rather final symbol address is calculated based on baseaddr and address

> >> added together. So in case where symbols are loaded at an offset the condition

> >> address < lowpc will always return true.

> >>

> >> This patch fixes this by comparing address against a non offset lowpc.

> >> This patch also adds a GDB test case to replicate this behavior.

> >>

> >> gdb:

> >>

> >> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

> >>

> >>         PR gdb/21695

> >>         * dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.

> >>         (dwarf_decode_lines_1): Adjust.

> >>

> >> gdb/testsuite:

> >>

> >> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

> >>

> >>         PR gdb/21695

> >>         * gdb.base/infoline-reloc-main-from-zero.exp: New test.

> >>         * gdb.base/infoline-reloc-main-from-zero.c: New file.

> >> ---

> >>  gdb/dwarf2read.c                                   |  8 ++--

> >>  .../gdb.base/infoline-reloc-main-from-zero.c       | 24 ++++++++++

> >>  .../gdb.base/infoline-reloc-main-from-zero.exp     | 51 ++++++++++++++++++++++

> >>  3 files changed, 79 insertions(+), 4 deletions(-)

> >>  create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> >>  create mode 100644 gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> >>

> >> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c

> >> index 575d316..b171bb2 100644

> >> --- a/gdb/dwarf2read.c

> >> +++ b/gdb/dwarf2read.c

> >> @@ -20411,7 +20411,7 @@ public:

> >>       sequence.  */

> >>    void check_line_address (struct dwarf2_cu *cu,

> >>                            const gdb_byte *line_ptr,

> >> -                          CORE_ADDR lowpc, CORE_ADDR address);

> >> +                          CORE_ADDR lowpc_minus_base, CORE_ADDR address);

> >>

> >>    void handle_set_discriminator (unsigned int discriminator)

> >>    {

> >> @@ -20755,14 +20755,14 @@ lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,

> >>  void

> >>  lnp_state_machine::check_line_address (struct dwarf2_cu *cu,

> >>                                        const gdb_byte *line_ptr,

> >> -                                      CORE_ADDR lowpc, CORE_ADDR address)

> >> +                                      CORE_ADDR lowpc_minus_base, CORE_ADDR address)

> >>  {

> >>    /* If address < lowpc then it's not a usable value, it's outside the

> >>       pc range of the CU.  However, we restrict the test to only address

> >>       values of zero to preserve GDB's previous behaviour which is to

> >>       handle the specific case of a function being GC'd by the linker.  */

> >>

> >> -  if (address == 0 && address < lowpc)

> >> +  if (address == 0 && address < lowpc_minus_base)

> >>      {

> >>        /* This line table is for a function which has been

> >>          GCd by the linker.  Ignore it.  PR gdb/12528 */

> >> @@ -20857,7 +20857,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,

> >>                     line_ptr += bytes_read;

> >>

> >>                     state_machine.check_line_address (cu, line_ptr,

> >> -                                                     lowpc, address);

> >> +                                                     lowpc - baseaddr, address);

> >>                     state_machine.handle_set_address (baseaddr, address);

> >>                   }

> >>                   break;

> >> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> >> new file mode 100644

> >> index 0000000..8902051

> >> --- /dev/null

> >> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> >> @@ -0,0 +1,24 @@

> >> +/* This testcase is part of GDB, the GNU debugger.

> >> +

> >> +   Copyright 2011-2018 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/>.  */

> >> +

> >> +// Test case for PR gdb/21695

> >> +

> >> +int

> >> +main ()

> >> +{

> >> +  return 0;

> >> +}

> >> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> >> new file mode 100644

> >> index 0000000..68564688

> >> --- /dev/null

> >> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> >> @@ -0,0 +1,51 @@

> >> +# Copyright 2011-2018 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 file is part of the gdb testsuite

> >> +

> >> +#

> >> +# test running programs

> >> +#

> >> +

> >> +standard_testfile .c

> >> +

> >> +if [get_compiler_info] {

> >> +    return -1

> >> +}

> >> +

> >> +# Build executable with stripped startup code and text section starting at zero

> >> +

> >> +set opts {debug "additional_flags=-nostdlib -emain -Wl,-Ttext=0x00"}

> >> +

> >> +if {[build_executable $testfile.exp $testfile $srcfile $opts] == -1} {

> >> +    untested "failed to compile"

> >> +    return -1

> >> +}

> >> +

> >> +gdb_exit

> >> +gdb_start

> >> +gdb_reinitialize_dir $srcdir/$subdir

> >> +

> >> +# Load symbols at an offset 0xffff0000 using add-symbol-file

> >> +

> >> +gdb_test "add-symbol-file [standard_output_file ${testfile}] 0xffff000" \

> >> +    "Reading symbols from .*" \

> >> +    "add-symbol-file" \

> >> +    "add symbol table from file \".*\" at.*\\(y or n\\) " "y"

> >> +

> >> +# Check if we are able to read offset adjusted line information of main

> >> +

> >> +gdb_test "info line main" \

> >> +       "Line.*starts at address.*and ends at.*"

> >> --

> >> 2.7.4

> >>

> >

> >

> > Ping!

>

> Ping!


Ping!
Simon Marchi June 20, 2018, 4:12 p.m. UTC | #4
On 2018-05-15 10:04, Omair Javaid wrote:
> This patch fixes a unique condition where GDB fails to provide line

> information of symbol at address zero when code is compiled with text

> address zero but loaded at an offset > 0.

> 

> For example lets compile following code snippet:

> 

> int main() {

>   return 0;

> }

> 

> gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c

> 

> Start gdb and run:

> 

> add-symbol-file file.out 0xffff0000

> info line main

> 

> GDB will return error saying no line info is available for the symbol.

> 

> This is a direct consequence of the fix for PR 12528 where GDB tries to 

> ignore

> line table for a function which has been garbage collected by the 

> linker.

> 

> As the garbage collected symbols are sent to address zero GDB assumes a 

> symbol

> actually placed at address zero as garbage collected.

> 

> This was fixed with an additional check address < lowpc. But when 

> symbol is

> loaded at an offset lowpc becomes lowpc + offset while no offset is 

> added to

> address rather final symbol address is calculated based on baseaddr and 

> address

> added together. So in case where symbols are loaded at an offset the 

> condition

> address < lowpc will always return true.

> 

> This patch fixes this by comparing address against a non offset lowpc.

> This patch also adds a GDB test case to replicate this behavior.


Hi Omair,

Sorry for the wait.

I have tried your patch and see that it fixes the bug you report, but I 
am not sure I understand your explanation.  It sounds like we are 
comparing an unrelocated address with a relocated low_pc.  What your 
patch does is make sure we compare apples to apples, is that right?

I have added Tom Tromey in CC, he is currently playing with storing 
symbols relocated vs unrelocated, so maybe he knows better.  And maybe 
there's something in his pending patches that also touch this area.

> gdb:

> 

> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

> 

> 	PR gdb/21695

> 	* dwarf2read.c (lnp_state_machine::check_line_address): Update 

> declaration.

> 	(dwarf_decode_lines_1): Adjust.

> 

> gdb/testsuite:

> 

> 2018-05-15  Omair Javaid  <omair.javaid@linaro.org>

> 

> 	PR gdb/21695

> 	* gdb.base/infoline-reloc-main-from-zero.exp: New test.

> 	* gdb.base/infoline-reloc-main-from-zero.c: New file.

> ---

>  gdb/dwarf2read.c                                   |  8 ++--

>  .../gdb.base/infoline-reloc-main-from-zero.c       | 24 ++++++++++

>  .../gdb.base/infoline-reloc-main-from-zero.exp     | 51 

> ++++++++++++++++++++++

>  3 files changed, 79 insertions(+), 4 deletions(-)

>  create mode 100644 

> gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

>  create mode 100644 

> gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> 

> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c

> index 575d316..b171bb2 100644

> --- a/gdb/dwarf2read.c

> +++ b/gdb/dwarf2read.c

> @@ -20411,7 +20411,7 @@ public:

>       sequence.  */

>    void check_line_address (struct dwarf2_cu *cu,

>  			   const gdb_byte *line_ptr,

> -			   CORE_ADDR lowpc, CORE_ADDR address);

> +			   CORE_ADDR lowpc_minus_base, CORE_ADDR address);

> 

>    void handle_set_discriminator (unsigned int discriminator)

>    {

> @@ -20755,14 +20755,14 @@ lnp_state_machine::lnp_state_machine

> (gdbarch *arch, line_header *lh,

>  void

>  lnp_state_machine::check_line_address (struct dwarf2_cu *cu,

>  				       const gdb_byte *line_ptr,

> -				       CORE_ADDR lowpc, CORE_ADDR address)

> +				       CORE_ADDR lowpc_minus_base, CORE_ADDR address)


I would suggest naming this "unrelocated_lowpc".  Can you update the 
documentation of the method to describe that parameter?

>  {

>    /* If address < lowpc then it's not a usable value, it's outside the

>       pc range of the CU.  However, we restrict the test to only 

> address

>       values of zero to preserve GDB's previous behaviour which is to

>       handle the specific case of a function being GC'd by the linker.  

> */

> 

> -  if (address == 0 && address < lowpc)

> +  if (address == 0 && address < lowpc_minus_base)

>      {

>        /* This line table is for a function which has been

>  	 GCd by the linker.  Ignore it.  PR gdb/12528 */

> @@ -20857,7 +20857,7 @@ dwarf_decode_lines_1 (struct line_header *lh,

> struct dwarf2_cu *cu,

>  		    line_ptr += bytes_read;

> 

>  		    state_machine.check_line_address (cu, line_ptr,

> -						      lowpc, address);

> +						      lowpc - baseaddr, address);

>  		    state_machine.handle_set_address (baseaddr, address);

>  		  }

>  		  break;

> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> new file mode 100644

> index 0000000..8902051

> --- /dev/null

> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c

> @@ -0,0 +1,24 @@

> +/* This testcase is part of GDB, the GNU debugger.

> +

> +   Copyright 2011-2018 Free Software Foundation, Inc.


This should probably be just 2018.

> +

> +   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/>.  */

> +

> +// Test case for PR gdb/21695

> +

> +int

> +main ()

> +{

> +  return 0;

> +}

> diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> new file mode 100644

> index 0000000..68564688

> --- /dev/null

> +++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp

> @@ -0,0 +1,51 @@

> +# Copyright 2011-2018 Free Software Foundation, Inc.


Here too.

> +

> +# 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 file is part of the gdb testsuite

> +

> +#

> +# test running programs

> +#


Can you update this comment to reflect what this test does?

> +

> +standard_testfile .c

> +

> +if [get_compiler_info] {

> +    return -1

> +}

> +

> +# Build executable with stripped startup code and text section 

> starting at zero

> +

> +set opts {debug "additional_flags=-nostdlib -emain -Wl,-Ttext=0x00"}

> +

> +if {[build_executable $testfile.exp $testfile $srcfile $opts] == -1} {

> +    untested "failed to compile"

> +    return -1

> +}

> +

> +gdb_exit

> +gdb_start

> +gdb_reinitialize_dir $srcdir/$subdir


You can use clean_restart instead of these last 3 lines.

> +

> +# Load symbols at an offset 0xffff0000 using add-symbol-file

> +

> +gdb_test "add-symbol-file [standard_output_file ${testfile}] 

> 0xffff000" \


Use ${binfile} instead of [standard_output_file ${testfile}].

> +    "Reading symbols from .*" \

> +    "add-symbol-file" \

> +    "add symbol table from file \".*\" at.*\\(y or n\\) " "y"

> +

> +# Check if we are able to read offset adjusted line information of 

> main

> +

> +gdb_test "info line main" \

> +	"Line.*starts at address.*and ends at.*"


Thanks,

Simon
Tom Tromey June 21, 2018, 6:26 p.m. UTC | #5
>>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:


Simon> I have added Tom Tromey in CC, he is currently playing with storing
Simon> symbols relocated vs unrelocated, so maybe he knows better.  And maybe
Simon> there's something in his pending patches that also touch this area.

The patch seems reasonable to me.

I think it may touch the same code as my line table series, but that's
no big deal.  I'll rebase when the time comes.

>> +				       CORE_ADDR lowpc_minus_base, CORE_ADDR address)


Simon> I would suggest naming this "unrelocated_lowpc".  Can you update the
Simon> documentation of the method to describe that parameter?

Agreed.

>> /* If address < lowpc then it's not a usable value, it's outside the

>> pc range of the CU.  However, we restrict the test to only


This comment could also use an update, and it should be using upper-case
like "ADDRESS" and "LOWPC".

Tom
Omair Javaid June 25, 2018, 10:10 a.m. UTC | #6
On Thu, 21 Jun 2018 at 23:26, Tom Tromey <tom@tromey.com> wrote:
>

> >>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:

>

> Simon> I have added Tom Tromey in CC, he is currently playing with storing

> Simon> symbols relocated vs unrelocated, so maybe he knows better.  And maybe

> Simon> there's something in his pending patches that also touch this area.

>

> The patch seems reasonable to me.

>

> I think it may touch the same code as my line table series, but that's

> no big deal.  I'll rebase when the time comes.

>

> >> +                                   CORE_ADDR lowpc_minus_base, CORE_ADDR address)

>

> Simon> I would suggest naming this "unrelocated_lowpc".  Can you update the

> Simon> documentation of the method to describe that parameter?

>

> Agreed.

>

> >> /* If address < lowpc then it's not a usable value, it's outside the

> >> pc range of the CU.  However, we restrict the test to only

>

> This comment could also use an update, and it should be using upper-case

> like "ADDRESS" and "LOWPC".

>

> Tom

Thanks Tom and Simon for review. I will send an update after fixing
highlighted issues.
diff mbox series

Patch

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 575d316..b171bb2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -20411,7 +20411,7 @@  public:
      sequence.  */
   void check_line_address (struct dwarf2_cu *cu,
 			   const gdb_byte *line_ptr,
-			   CORE_ADDR lowpc, CORE_ADDR address);
+			   CORE_ADDR lowpc_minus_base, CORE_ADDR address);
 
   void handle_set_discriminator (unsigned int discriminator)
   {
@@ -20755,14 +20755,14 @@  lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,
 void
 lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
 				       const gdb_byte *line_ptr,
-				       CORE_ADDR lowpc, CORE_ADDR address)
+				       CORE_ADDR lowpc_minus_base, CORE_ADDR address)
 {
   /* If address < lowpc then it's not a usable value, it's outside the
      pc range of the CU.  However, we restrict the test to only address
      values of zero to preserve GDB's previous behaviour which is to
      handle the specific case of a function being GC'd by the linker.  */
 
-  if (address == 0 && address < lowpc)
+  if (address == 0 && address < lowpc_minus_base)
     {
       /* This line table is for a function which has been
 	 GCd by the linker.  Ignore it.  PR gdb/12528 */
@@ -20857,7 +20857,7 @@  dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 		    line_ptr += bytes_read;
 
 		    state_machine.check_line_address (cu, line_ptr,
-						      lowpc, address);
+						      lowpc - baseaddr, address);
 		    state_machine.handle_set_address (baseaddr, address);
 		  }
 		  break;
diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c
new file mode 100644
index 0000000..8902051
--- /dev/null
+++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c
@@ -0,0 +1,24 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011-2018 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/>.  */
+
+// Test case for PR gdb/21695
+
+int
+main ()
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp
new file mode 100644
index 0000000..68564688
--- /dev/null
+++ b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp
@@ -0,0 +1,51 @@ 
+# Copyright 2011-2018 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 file is part of the gdb testsuite
+
+#
+# test running programs
+#
+
+standard_testfile .c
+
+if [get_compiler_info] {
+    return -1
+}
+
+# Build executable with stripped startup code and text section starting at zero
+
+set opts {debug "additional_flags=-nostdlib -emain -Wl,-Ttext=0x00"}
+
+if {[build_executable $testfile.exp $testfile $srcfile $opts] == -1} {
+    untested "failed to compile"
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Load symbols at an offset 0xffff0000 using add-symbol-file
+
+gdb_test "add-symbol-file [standard_output_file ${testfile}] 0xffff000" \
+    "Reading symbols from .*" \
+    "add-symbol-file" \
+    "add symbol table from file \".*\" at.*\\(y or n\\) " "y"
+
+# Check if we are able to read offset adjusted line information of main
+    
+gdb_test "info line main" \
+	"Line.*starts at address.*and ends at.*"