From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Subject: --gc-section leftovers workaround.
Date: Wed, 28 Oct 2009 18:50:00 -0000 [thread overview]
Message-ID: <200910281851.01364.pedro@codesourcery.com> (raw)
With --gc-sections, gnu ld zeros out the start addresses of
unreferences FDEs, but leaves them behind. On targets where
addresses near 0 are valid, GDB can easily confuse these
leftovers for the valid FDEs, ending up with invalid debug
info loaded for such low addresses. Since this is a problem
that has beein in the field for a while, an FSF GDB
workaround seems appropriate, given that it is a simple
workaround --- give preference to FDEs that do not
start at zero when overlaps are detected.
Given that we now sort and bsearch FDEs, GDB is already giving
such preference as a side effect, but the code that discards
duplicate FDEs could be discarding the valid FDEs at 0, and
keep an FDE that should have been garbage collected. This patch
makes the overlap check explicit so as to avoid that. Tested on
arm-none-eabi where it fixed the problem, and on
x86_64-unknown-linux-gnu. Applied.
--
Pedro Alves
2009-10-28 Pedro Alves <pedro@codesourcery.com>
* dwarf2-frame.c (dwarf2_build_frame_info): Discard --gc-section
leftover FDEs.
---
gdb/dwarf2-frame.c | 44 +++++++++++++++++++++++++++++++-------------
1 file changed, 31 insertions(+), 13 deletions(-)
Index: src/gdb/dwarf2-frame.c
===================================================================
--- src.orig/gdb/dwarf2-frame.c 2009-10-23 19:05:16.000000000 +0100
+++ src/gdb/dwarf2-frame.c 2009-10-28 17:15:10.000000000 +0000
@@ -2101,7 +2101,8 @@ dwarf2_build_frame_info (struct objfile
if (fde_table.num_entries != 0)
{
struct dwarf2_fde_table *fde_table2;
- int i, j;
+ struct dwarf2_fde *fde_prev = NULL;
+ int i;
/* Prepare FDE table for lookups. */
qsort (fde_table.entries, fde_table.num_entries,
@@ -2110,22 +2111,39 @@ dwarf2_build_frame_info (struct objfile
/* Copy fde_table to obstack: it is needed at runtime. */
fde_table2 = (struct dwarf2_fde_table *)
obstack_alloc (&objfile->objfile_obstack, sizeof (*fde_table2));
+ fde_table2->num_entries = 0;
/* Since we'll be doing bsearch, squeeze out identical (except for
eh_frame_p) fde entries so bsearch result is predictable. */
- for (i = 0, j = 0; j < fde_table.num_entries; ++i)
- {
- const int k = j;
-
- obstack_grow (&objfile->objfile_obstack, &fde_table.entries[j],
- sizeof (fde_table.entries[0]));
- while (++j < fde_table.num_entries
- && (fde_table.entries[k]->initial_location
- == fde_table.entries[j]->initial_location))
- /* Skip. */;
- }
+ for (i = 0; i < fde_table.num_entries; i++)
+ {
+ struct dwarf2_fde *fde = fde_table.entries[i];
+
+ /* Check for leftovers from --gc-sections. The GNU linker
+ sets the relevant symbols to zero, but doesn't zero the
+ FDE *end* ranges because there's no relocation there.
+ It's (offset, length), not (start, end). On targets
+ where address zero is just another valid address this can
+ be a problem, since the FDEs appear to be non-empty in
+ the output --- we could pick out the wrong FDE. To work
+ around this, when overlaps are detected, we prefer FDEs
+ that do not start at zero. */
+ if (fde->initial_location == 0
+ && (i + 1) < fde_table.num_entries
+ && ((fde_table.entries[i + 1])->initial_location
+ < fde->initial_location + fde->address_range))
+ continue;
+
+ if (fde_prev != NULL
+ && fde_prev->initial_location == fde->initial_location)
+ continue;
+
+ obstack_grow (&objfile->objfile_obstack, &fde_table.entries[i],
+ sizeof (fde_table.entries[0]));
+ ++fde_table2->num_entries;
+ fde_prev = fde;
+ }
fde_table2->entries = obstack_finish (&objfile->objfile_obstack);
- fde_table2->num_entries = i;
set_objfile_data (objfile, dwarf2_frame_objfile_data, fde_table2);
/* Discard the original fde_table. */
next reply other threads:[~2009-10-28 18:50 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-28 18:50 Pedro Alves [this message]
2009-10-28 19:23 ` Paul Pluzhnikov
2009-10-28 19:35 ` Pedro Alves
2009-10-28 20:13 ` Paul Pluzhnikov
2009-10-28 20:20 ` Pedro Alves
2009-10-28 20:35 ` Paul Pluzhnikov
2009-10-28 20:55 ` Pedro Alves
2009-10-28 21:21 ` Paul Pluzhnikov
2009-10-28 19:29 ` Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200910281851.01364.pedro@codesourcery.com \
--to=pedro@codesourcery.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox