mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-13 02:45:02 +08:00
PR16867, linking object with separate debug file
This teaches the DWARF2 find_line functions how to deal with separate debug relocatable object files. Also fixes a major bug: When _bfd_dwarf2_slurp_debug_info was split out, place_sections ran after .debug_info was relocated. This defeated the whole purpose of place_sections. See the comment I added before place_sections. Fixes some minor bugs too: - place_sections didn't set VMA for alloc but non-load sections (bss). - zero size sections can have symbols, so they need their VMA set too. - last_vma was incorrectly adjusted. - my last change to place_sections left VMA unchanged for .debug_info when the linker has mapped input to output sections, but this is wrong since bfd_simple_get_relocated_section_contents unmaps debug sections. PR 16867 * dwarf2.c: Formatting. (struct dwarf2_debug): Make adjusted_section_count signed. (unset_sections): Make i signed. (set_debug_vma): New function. (place_sections): Handle separate debug object file. Set VMA on debug sections, even if they have an output section. Also set VMA on zero size sections, and non-load but alloc sections. Set adjusted_section_count to -1 when no section adjustment. Malloc adjusted_sections. Don't double last_vma. Transfer alloc section VMAs to separate debug file. (_bfd_dwarf2_cleanup_debug_info): Free adjusted_sections. (_bfd_dwarf2_slurp_debug_info): Add do_place parameter. Drop test on symbols being the same before using old stash. Read and use separate debug file symbols. Call place_sections. (find_line): Don't call place_sections here. * libbfd-in.h (_bfd_dwarf2_slurp_debug_info): Update proto. * libbfd.h: Regenerate. * mach-o.c (bfd_mach_o_find_nearest_line): Adjust _bfd_dwarf2_slurp_debug_info call. * simple.c (simple_save_output_info): Clarify comment.
This commit is contained in:
@ -1,3 +1,27 @@
|
|||||||
|
2014-04-24 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 16867
|
||||||
|
* dwarf2.c: Formatting.
|
||||||
|
(struct dwarf2_debug): Make adjusted_section_count signed.
|
||||||
|
(unset_sections): Make i signed.
|
||||||
|
(set_debug_vma): New function.
|
||||||
|
(place_sections): Handle separate debug object file. Set VMA
|
||||||
|
on debug sections, even if they have an output section. Also
|
||||||
|
set VMA on zero size sections, and non-load but alloc sections.
|
||||||
|
Set adjusted_section_count to -1 when no section adjustment.
|
||||||
|
Malloc adjusted_sections. Don't double last_vma. Transfer
|
||||||
|
alloc section VMAs to separate debug file.
|
||||||
|
(_bfd_dwarf2_cleanup_debug_info): Free adjusted_sections.
|
||||||
|
(_bfd_dwarf2_slurp_debug_info): Add do_place parameter. Drop
|
||||||
|
test on symbols being the same before using old stash. Read
|
||||||
|
and use separate debug file symbols. Call place_sections.
|
||||||
|
(find_line): Don't call place_sections here.
|
||||||
|
* libbfd-in.h (_bfd_dwarf2_slurp_debug_info): Update proto.
|
||||||
|
* libbfd.h: Regenerate.
|
||||||
|
* mach-o.c (bfd_mach_o_find_nearest_line): Adjust
|
||||||
|
_bfd_dwarf2_slurp_debug_info call.
|
||||||
|
* simple.c (simple_save_output_info): Clarify comment.
|
||||||
|
|
||||||
2014-04-24 Nick Clifton <nickc@redhat.com>
|
2014-04-24 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR ld/16807
|
PR ld/16807
|
||||||
|
170
bfd/dwarf2.c
170
bfd/dwarf2.c
@ -160,7 +160,7 @@ struct dwarf2_debug
|
|||||||
bfd_vma *sec_vma;
|
bfd_vma *sec_vma;
|
||||||
|
|
||||||
/* Number of sections whose VMA we must adjust. */
|
/* Number of sections whose VMA we must adjust. */
|
||||||
unsigned int adjusted_section_count;
|
int adjusted_section_count;
|
||||||
|
|
||||||
/* Array of sections with adjusted VMA. */
|
/* Array of sections with adjusted VMA. */
|
||||||
struct adjusted_section *adjusted_sections;
|
struct adjusted_section *adjusted_sections;
|
||||||
@ -645,7 +645,7 @@ read_indirect_string (struct comp_unit * unit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Like read_indirect_string but uses a .debug_str located in
|
/* Like read_indirect_string but uses a .debug_str located in
|
||||||
an alternate filepointed to by the .gnu_debuglink section.
|
an alternate file pointed to by the .gnu_debugaltlink section.
|
||||||
Used to impement DW_FORM_GNU_strp_alt. */
|
Used to impement DW_FORM_GNU_strp_alt. */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@ -2990,12 +2990,36 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Transfer VMAs from object file to separate debug file. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_debug_vma (bfd *orig_bfd, bfd *debug_bfd)
|
||||||
|
{
|
||||||
|
asection *s, *d;
|
||||||
|
|
||||||
|
for (s = orig_bfd->sections, d = debug_bfd->sections;
|
||||||
|
s != NULL && d != NULL;
|
||||||
|
s = s->next, d = d->next)
|
||||||
|
{
|
||||||
|
if ((d->flags & SEC_DEBUGGING) != 0)
|
||||||
|
break;
|
||||||
|
/* ??? Assumes 1-1 correspondence between sections in the
|
||||||
|
two files. */
|
||||||
|
if (strcmp (s->name, d->name) == 0)
|
||||||
|
{
|
||||||
|
d->output_section = s->output_section;
|
||||||
|
d->output_offset = s->output_offset;
|
||||||
|
d->vma = s->vma;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Unset vmas for adjusted sections in STASH. */
|
/* Unset vmas for adjusted sections in STASH. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unset_sections (struct dwarf2_debug *stash)
|
unset_sections (struct dwarf2_debug *stash)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
int i;
|
||||||
struct adjusted_section *p;
|
struct adjusted_section *p;
|
||||||
|
|
||||||
i = stash->adjusted_section_count;
|
i = stash->adjusted_section_count;
|
||||||
@ -3004,14 +3028,23 @@ unset_sections (struct dwarf2_debug *stash)
|
|||||||
p->section->vma = 0;
|
p->section->vma = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set unique VMAs for loadable and DWARF sections in ABFD and save
|
/* Set VMAs for allocated and .debug_info sections in ORIG_BFD, a
|
||||||
VMAs in STASH for unset_sections. */
|
relocatable object file. VMAs are normally all zero in relocatable
|
||||||
|
object files, so if we want to distinguish locations in sections by
|
||||||
|
address we need to set VMAs so the sections do not overlap. We
|
||||||
|
also set VMA on .debug_info so that when we have multiple
|
||||||
|
.debug_info sections (or the linkonce variant) they also do not
|
||||||
|
overlap. The multiple .debug_info sections make up a single
|
||||||
|
logical section. ??? We should probably do the same for other
|
||||||
|
debug sections. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
place_sections (bfd *abfd, struct dwarf2_debug *stash)
|
place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
|
||||||
{
|
{
|
||||||
|
bfd *abfd;
|
||||||
struct adjusted_section *p;
|
struct adjusted_section *p;
|
||||||
unsigned int i;
|
int i;
|
||||||
|
const char *debug_info_name;
|
||||||
|
|
||||||
if (stash->adjusted_section_count != 0)
|
if (stash->adjusted_section_count != 0)
|
||||||
{
|
{
|
||||||
@ -3019,91 +3052,86 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
|
|||||||
p = stash->adjusted_sections;
|
p = stash->adjusted_sections;
|
||||||
for (; i > 0; i--, p++)
|
for (; i > 0; i--, p++)
|
||||||
p->section->vma = p->adj_vma;
|
p->section->vma = p->adj_vma;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
asection *sect;
|
|
||||||
bfd_vma last_vma = 0, last_dwarf = 0;
|
|
||||||
bfd_size_type amt;
|
|
||||||
const char *debug_info_name;
|
|
||||||
|
|
||||||
debug_info_name = stash->debug_sections[debug_info].uncompressed_name;
|
debug_info_name = stash->debug_sections[debug_info].uncompressed_name;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
abfd = orig_bfd;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
asection *sect;
|
||||||
|
|
||||||
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
||||||
{
|
{
|
||||||
bfd_size_type sz;
|
|
||||||
int is_debug_info;
|
int is_debug_info;
|
||||||
|
|
||||||
if ((sect->output_section != NULL
|
if ((sect->output_section != NULL
|
||||||
&& sect->output_section != sect)
|
&& sect->output_section != sect
|
||||||
|
&& (sect->flags & SEC_DEBUGGING) == 0)
|
||||||
|| sect->vma != 0)
|
|| sect->vma != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We need to adjust the VMAs of any .debug_info sections.
|
is_debug_info = (strcmp (sect->name, debug_info_name) == 0
|
||||||
Skip compressed ones, since no relocations could target
|
|| CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
|
||||||
them - they should not appear in object files anyway. */
|
|
||||||
if (strcmp (sect->name, debug_info_name) == 0)
|
|
||||||
is_debug_info = 1;
|
|
||||||
else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO))
|
|
||||||
is_debug_info = 1;
|
|
||||||
else
|
|
||||||
is_debug_info = 0;
|
|
||||||
|
|
||||||
if (!is_debug_info && (sect->flags & SEC_LOAD) == 0)
|
if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
|
||||||
continue;
|
&& !is_debug_info)
|
||||||
|
|
||||||
sz = sect->rawsize ? sect->rawsize : sect->size;
|
|
||||||
if (sz == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i <= 1)
|
if (abfd == stash->bfd_ptr)
|
||||||
return TRUE;
|
break;
|
||||||
|
abfd = stash->bfd_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
amt = i * sizeof (struct adjusted_section);
|
if (i <= 1)
|
||||||
p = (struct adjusted_section *) bfd_alloc (abfd, amt);
|
stash->adjusted_section_count = -1;
|
||||||
if (! p)
|
else
|
||||||
|
{
|
||||||
|
bfd_vma last_vma = 0, last_dwarf = 0;
|
||||||
|
bfd_size_type amt = i * sizeof (struct adjusted_section);
|
||||||
|
|
||||||
|
p = (struct adjusted_section *) bfd_malloc (amt);
|
||||||
|
if (p == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
stash->adjusted_sections = p;
|
stash->adjusted_sections = p;
|
||||||
stash->adjusted_section_count = i;
|
stash->adjusted_section_count = i;
|
||||||
|
|
||||||
|
abfd = orig_bfd;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
asection *sect;
|
||||||
|
|
||||||
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
for (sect = abfd->sections; sect != NULL; sect = sect->next)
|
||||||
{
|
{
|
||||||
bfd_size_type sz;
|
bfd_size_type sz;
|
||||||
int is_debug_info;
|
int is_debug_info;
|
||||||
|
|
||||||
if ((sect->output_section != NULL
|
if ((sect->output_section != NULL
|
||||||
&& sect->output_section != sect)
|
&& sect->output_section != sect
|
||||||
|
&& (sect->flags & SEC_DEBUGGING) == 0)
|
||||||
|| sect->vma != 0)
|
|| sect->vma != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We need to adjust the VMAs of any .debug_info sections.
|
is_debug_info = (strcmp (sect->name, debug_info_name) == 0
|
||||||
Skip compressed ones, since no relocations could target
|
|| CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
|
||||||
them - they should not appear in object files anyway. */
|
|
||||||
if (strcmp (sect->name, debug_info_name) == 0)
|
|
||||||
is_debug_info = 1;
|
|
||||||
else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO))
|
|
||||||
is_debug_info = 1;
|
|
||||||
else
|
|
||||||
is_debug_info = 0;
|
|
||||||
|
|
||||||
if (!is_debug_info && (sect->flags & SEC_LOAD) == 0)
|
if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
|
||||||
|
&& !is_debug_info)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sz = sect->rawsize ? sect->rawsize : sect->size;
|
sz = sect->rawsize ? sect->rawsize : sect->size;
|
||||||
if (sz == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
p->section = sect;
|
|
||||||
if (is_debug_info)
|
if (is_debug_info)
|
||||||
{
|
{
|
||||||
BFD_ASSERT (sect->alignment_power == 0);
|
BFD_ASSERT (sect->alignment_power == 0);
|
||||||
sect->vma = last_dwarf;
|
sect->vma = last_dwarf;
|
||||||
last_dwarf += sz;
|
last_dwarf += sz;
|
||||||
}
|
}
|
||||||
else if (last_vma != 0)
|
else
|
||||||
{
|
{
|
||||||
/* Align the new address to the current section
|
/* Align the new address to the current section
|
||||||
alignment. */
|
alignment. */
|
||||||
@ -3111,16 +3139,21 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
|
|||||||
+ ~((bfd_vma) -1 << sect->alignment_power))
|
+ ~((bfd_vma) -1 << sect->alignment_power))
|
||||||
& ((bfd_vma) -1 << sect->alignment_power));
|
& ((bfd_vma) -1 << sect->alignment_power));
|
||||||
sect->vma = last_vma;
|
sect->vma = last_vma;
|
||||||
last_vma += sect->vma + sz;
|
last_vma += sz;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
last_vma += sect->vma + sz;
|
|
||||||
|
|
||||||
|
p->section = sect;
|
||||||
p->adj_vma = sect->vma;
|
p->adj_vma = sect->vma;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
if (abfd == stash->bfd_ptr)
|
||||||
|
break;
|
||||||
|
abfd = stash->bfd_ptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orig_bfd != stash->bfd_ptr)
|
||||||
|
set_debug_vma (orig_bfd, stash->bfd_ptr);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -3409,7 +3442,8 @@ bfd_boolean
|
|||||||
_bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
_bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
||||||
const struct dwarf_debug_section *debug_sections,
|
const struct dwarf_debug_section *debug_sections,
|
||||||
asymbol **symbols,
|
asymbol **symbols,
|
||||||
void **pinfo)
|
void **pinfo,
|
||||||
|
bfd_boolean do_place)
|
||||||
{
|
{
|
||||||
bfd_size_type amt = sizeof (struct dwarf2_debug);
|
bfd_size_type amt = sizeof (struct dwarf2_debug);
|
||||||
bfd_size_type total_size;
|
bfd_size_type total_size;
|
||||||
@ -3418,8 +3452,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
|||||||
|
|
||||||
if (stash != NULL)
|
if (stash != NULL)
|
||||||
{
|
{
|
||||||
if (stash->syms == symbols
|
if (section_vma_same (abfd, stash))
|
||||||
&& section_vma_same (abfd, stash))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
_bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
|
_bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
|
||||||
memset (stash, 0, amt);
|
memset (stash, 0, amt);
|
||||||
@ -3455,7 +3488,8 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
|||||||
if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
||||||
|| ! bfd_check_format (debug_bfd, bfd_object)
|
|| ! bfd_check_format (debug_bfd, bfd_object)
|
||||||
|| (msec = find_debug_info (debug_bfd,
|
|| (msec = find_debug_info (debug_bfd,
|
||||||
debug_sections, NULL)) == NULL)
|
debug_sections, NULL)) == NULL
|
||||||
|
|| !bfd_generic_link_read_symbols (debug_bfd))
|
||||||
{
|
{
|
||||||
if (debug_bfd)
|
if (debug_bfd)
|
||||||
bfd_close (debug_bfd);
|
bfd_close (debug_bfd);
|
||||||
@ -3463,10 +3497,17 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
|||||||
free (debug_filename);
|
free (debug_filename);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbols = bfd_get_outsymbols (debug_bfd);
|
||||||
|
stash->syms = symbols;
|
||||||
stash->close_on_cleanup = TRUE;
|
stash->close_on_cleanup = TRUE;
|
||||||
}
|
}
|
||||||
stash->bfd_ptr = debug_bfd;
|
stash->bfd_ptr = debug_bfd;
|
||||||
|
|
||||||
|
if (do_place
|
||||||
|
&& !place_sections (abfd, stash))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* There can be more than one DWARF2 info section in a BFD these
|
/* There can be more than one DWARF2 info section in a BFD these
|
||||||
days. First handle the easy case when there's only one. If
|
days. First handle the easy case when there's only one. If
|
||||||
there's more than one, try case two: none of the sections is
|
there's more than one, try case two: none of the sections is
|
||||||
@ -3574,20 +3615,13 @@ find_line (bfd *abfd,
|
|||||||
if (discriminator_ptr)
|
if (discriminator_ptr)
|
||||||
*discriminator_ptr = 0;
|
*discriminator_ptr = 0;
|
||||||
|
|
||||||
if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL,
|
if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL, debug_sections,
|
||||||
debug_sections, symbols, pinfo))
|
symbols, pinfo,
|
||||||
|
(abfd->flags & (EXEC_P | DYNAMIC)) == 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
stash = (struct dwarf2_debug *) *pinfo;
|
stash = (struct dwarf2_debug *) *pinfo;
|
||||||
|
|
||||||
/* In a relocatable file, 2 functions may have the same address.
|
|
||||||
We change the section vma so that they won't overlap. */
|
|
||||||
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
|
||||||
{
|
|
||||||
if (! place_sections (abfd, stash))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
do_line = (section == NULL
|
do_line = (section == NULL
|
||||||
&& offset == 0
|
&& offset == 0
|
||||||
&& functionname_ptr == NULL
|
&& functionname_ptr == NULL
|
||||||
@ -3962,6 +3996,8 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
|
|||||||
free (stash->alt_dwarf_info_buffer);
|
free (stash->alt_dwarf_info_buffer);
|
||||||
if (stash->sec_vma)
|
if (stash->sec_vma)
|
||||||
free (stash->sec_vma);
|
free (stash->sec_vma);
|
||||||
|
if (stash->adjusted_sections)
|
||||||
|
free (stash->adjusted_sections);
|
||||||
if (stash->alt_bfd_ptr)
|
if (stash->alt_bfd_ptr)
|
||||||
bfd_close (stash->alt_bfd_ptr);
|
bfd_close (stash->alt_bfd_ptr);
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,8 @@ extern bfd_boolean _bfd_dwarf2_find_inliner_info
|
|||||||
|
|
||||||
/* Read DWARF 2 debugging information. */
|
/* Read DWARF 2 debugging information. */
|
||||||
extern bfd_boolean _bfd_dwarf2_slurp_debug_info
|
extern bfd_boolean _bfd_dwarf2_slurp_debug_info
|
||||||
(bfd *, bfd *, const struct dwarf_debug_section *, asymbol **, void **);
|
(bfd *, bfd *, const struct dwarf_debug_section *, asymbol **, void **,
|
||||||
|
bfd_boolean);
|
||||||
|
|
||||||
/* Clean up the data used to handle DWARF 2 debugging information. */
|
/* Clean up the data used to handle DWARF 2 debugging information. */
|
||||||
extern void _bfd_dwarf2_cleanup_debug_info
|
extern void _bfd_dwarf2_cleanup_debug_info
|
||||||
|
@ -565,7 +565,8 @@ extern bfd_boolean _bfd_dwarf2_find_inliner_info
|
|||||||
|
|
||||||
/* Read DWARF 2 debugging information. */
|
/* Read DWARF 2 debugging information. */
|
||||||
extern bfd_boolean _bfd_dwarf2_slurp_debug_info
|
extern bfd_boolean _bfd_dwarf2_slurp_debug_info
|
||||||
(bfd *, bfd *, const struct dwarf_debug_section *, asymbol **, void **);
|
(bfd *, bfd *, const struct dwarf_debug_section *, asymbol **, void **,
|
||||||
|
bfd_boolean);
|
||||||
|
|
||||||
/* Clean up the data used to handle DWARF 2 debugging information. */
|
/* Clean up the data used to handle DWARF 2 debugging information. */
|
||||||
extern void _bfd_dwarf2_cleanup_debug_info
|
extern void _bfd_dwarf2_cleanup_debug_info
|
||||||
|
@ -5660,7 +5660,8 @@ bfd_mach_o_find_nearest_line (bfd *abfd,
|
|||||||
break;
|
break;
|
||||||
if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
|
if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
|
||||||
dwarf_debug_sections, symbols,
|
dwarf_debug_sections, symbols,
|
||||||
&mdata->dwarf2_find_line_info))
|
&mdata->dwarf2_find_line_info,
|
||||||
|
FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
25
bfd/simple.c
25
bfd/simple.c
@ -106,6 +106,22 @@ struct saved_offsets
|
|||||||
struct saved_output_info *sections;
|
struct saved_output_info *sections;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* The sections in ABFD may already have output sections and offsets
|
||||||
|
set if we are here during linking.
|
||||||
|
|
||||||
|
DWARF-2 specifies offsets into debug sections in many cases and
|
||||||
|
bfd_simple_get_relocated_section_contents is called to relocate
|
||||||
|
debug info for a single relocatable object file. So we want
|
||||||
|
offsets relative to that object file's sections, not offsets in the
|
||||||
|
output file. For that reason, reset a debug section->output_offset
|
||||||
|
to zero.
|
||||||
|
|
||||||
|
If not called during linking then set section->output_section to
|
||||||
|
point back to the input section, because output_section must not be
|
||||||
|
NULL when calling the relocation routines.
|
||||||
|
|
||||||
|
Save the original output offset and section to restore later. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
|
simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
|
||||||
asection *section,
|
asection *section,
|
||||||
@ -220,15 +236,6 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
|
|||||||
outbuf = data;
|
outbuf = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The sections in ABFD may already have output sections and offsets set.
|
|
||||||
Because this function is primarily for debug sections, and GCC uses the
|
|
||||||
knowledge that debug sections will generally have VMA 0 when emitting
|
|
||||||
relocations between DWARF-2 sections (which are supposed to be
|
|
||||||
section-relative offsets anyway), we need to reset the output offsets
|
|
||||||
to zero. We also need to arrange for section->output_section->vma plus
|
|
||||||
section->output_offset to equal section->vma, which we do by setting
|
|
||||||
section->output_section to point back to section. Save the original
|
|
||||||
output offset and output section to restore later. */
|
|
||||||
saved_offsets.section_count = abfd->section_count;
|
saved_offsets.section_count = abfd->section_count;
|
||||||
saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
|
saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
|
||||||
* saved_offsets.section_count);
|
* saved_offsets.section_count);
|
||||||
|
Reference in New Issue
Block a user