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:
Alan Modra 2014-04-24 21:59:56 +09:30
parent aaca88efb4
commit 93ee1e3683
6 changed files with 220 additions and 150 deletions

View File

@ -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>
PR ld/16807

View File

@ -160,7 +160,7 @@ struct dwarf2_debug
bfd_vma *sec_vma;
/* Number of sections whose VMA we must adjust. */
unsigned int adjusted_section_count;
int adjusted_section_count;
/* Array of sections with adjusted VMA. */
struct adjusted_section *adjusted_sections;
@ -401,7 +401,7 @@ info_hash_table_newfunc (struct bfd_hash_entry *entry,
if (ret == NULL)
{
ret = (struct info_hash_entry *) bfd_hash_allocate (table,
sizeof (* ret));
sizeof (* ret));
if (ret == NULL)
return NULL;
}
@ -461,7 +461,7 @@ insert_info_hash_table (struct info_hash_table *hash_table,
return FALSE;
node = (struct info_list_node *) bfd_hash_allocate (&hash_table->base,
sizeof (*node));
sizeof (*node));
if (!node)
return FALSE;
@ -509,13 +509,13 @@ read_section (bfd * abfd,
if (! msec)
{
section_name = sec->compressed_name;
if (section_name != NULL)
msec = bfd_get_section_by_name (abfd, section_name);
if (section_name != NULL)
msec = bfd_get_section_by_name (abfd, section_name);
}
if (! msec)
{
(*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."),
sec->uncompressed_name);
sec->uncompressed_name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
@ -634,7 +634,7 @@ read_indirect_string (struct comp_unit * unit,
*bytes_read_ptr = unit->offset_size;
if (! read_section (unit->abfd, &stash->debug_sections[debug_str],
stash->syms, offset,
stash->syms, offset,
&stash->dwarf_str_buffer, &stash->dwarf_str_size))
return NULL;
@ -645,7 +645,7 @@ read_indirect_string (struct comp_unit * unit,
}
/* 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. */
static char *
@ -815,7 +815,7 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
bfd_size_type amt;
if (! read_section (abfd, &stash->debug_sections[debug_abbrev],
stash->syms, offset,
stash->syms, offset,
&stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size))
return NULL;
@ -1313,7 +1313,7 @@ add_line_info (struct line_info_table *table,
info->prev_line = table->lcl_head->prev_line;
table->lcl_head->prev_line = info;
if (address < seq->low_pc)
seq->low_pc = address;
seq->low_pc = address;
}
return TRUE;
}
@ -1504,21 +1504,21 @@ sort_line_sequences (struct line_info_table* table)
for (n = 1; n < table->num_sequences; n++)
{
if (sequences[n].low_pc < last_high_pc)
{
{
if (sequences[n].last_line->address <= last_high_pc)
/* Skip nested entries. */
continue;
/* Trim overlapping entries. */
sequences[n].low_pc = last_high_pc;
}
}
last_high_pc = sequences[n].last_line->address;
if (n > num_sequences)
{
/* Close up the gap. */
sequences[num_sequences].low_pc = sequences[n].low_pc;
sequences[num_sequences].last_line = sequences[n].last_line;
}
{
/* Close up the gap. */
sequences[num_sequences].low_pc = sequences[n].low_pc;
sequences[num_sequences].last_line = sequences[n].last_line;
}
num_sequences++;
}
@ -1544,7 +1544,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
bfd_size_type amt;
if (! read_section (abfd, &stash->debug_sections[debug_line],
stash->syms, unit->line_offset,
stash->syms, unit->line_offset,
&stash->dwarf_line_buffer, &stash->dwarf_line_size))
return NULL;
@ -1737,7 +1737,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
if (!add_line_info (table, address, op_index, filename,
line, column, discriminator, 0))
goto line_fail;
discriminator = 0;
discriminator = 0;
if (address < low_pc)
low_pc = address;
if (address > high_pc)
@ -1758,7 +1758,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
if (!add_line_info (table, address, op_index, filename, line,
column, discriminator, end_sequence))
goto line_fail;
discriminator = 0;
discriminator = 0;
if (address < low_pc)
low_pc = address;
if (address > high_pc)
@ -1799,7 +1799,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
break;
case DW_LNE_set_discriminator:
discriminator =
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
break;
case DW_LNE_HP_source_file_correlation:
@ -1819,7 +1819,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
if (!add_line_info (table, address, op_index,
filename, line, column, discriminator, 0))
goto line_fail;
discriminator = 0;
discriminator = 0;
if (address < low_pc)
low_pc = address;
if (address > high_pc)
@ -1948,20 +1948,20 @@ lookup_address_in_line_info_table (struct line_info_table *table,
{
/* Note: seq->last_line should be a descendingly sorted list. */
for (each_line = seq->last_line;
each_line;
each_line = each_line->prev_line)
if (addr >= each_line->address)
break;
each_line;
each_line = each_line->prev_line)
if (addr >= each_line->address)
break;
if (each_line
&& !(each_line->end_sequence || each_line == seq->last_line))
{
*filename_ptr = each_line->filename;
*linenumber_ptr = each_line->line;
if (discriminator_ptr)
*discriminator_ptr = each_line->discriminator;
return seq->last_line->address - seq->low_pc;
}
&& !(each_line->end_sequence || each_line == seq->last_line))
{
*filename_ptr = each_line->filename;
*linenumber_ptr = each_line->line;
if (discriminator_ptr)
*discriminator_ptr = each_line->discriminator;
return seq->last_line->address - seq->low_pc;
}
}
*filename_ptr = NULL;
@ -1975,7 +1975,7 @@ read_debug_ranges (struct comp_unit *unit)
{
struct dwarf2_debug *stash = unit->stash;
return read_section (unit->abfd, &stash->debug_sections[debug_ranges],
stash->syms, 0,
stash->syms, 0,
&stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size);
}
@ -2946,7 +2946,7 @@ comp_unit_hash_info (struct dwarf2_debug *stash,
static asection *
find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
asection *after_sec)
asection *after_sec)
{
asection *msec;
const char *look;
@ -2990,12 +2990,36 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
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. */
static void
unset_sections (struct dwarf2_debug *stash)
{
unsigned int i;
int i;
struct adjusted_section *p;
i = stash->adjusted_section_count;
@ -3004,14 +3028,23 @@ unset_sections (struct dwarf2_debug *stash)
p->section->vma = 0;
}
/* Set unique VMAs for loadable and DWARF sections in ABFD and save
VMAs in STASH for unset_sections. */
/* Set VMAs for allocated and .debug_info sections in ORIG_BFD, a
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
place_sections (bfd *abfd, struct dwarf2_debug *stash)
place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
{
bfd *abfd;
struct adjusted_section *p;
unsigned int i;
int i;
const char *debug_info_name;
if (stash->adjusted_section_count != 0)
{
@ -3019,109 +3052,109 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
p = stash->adjusted_sections;
for (; i > 0; i--, p++)
p->section->vma = p->adj_vma;
return TRUE;
}
else
debug_info_name = stash->debug_sections[debug_info].uncompressed_name;
i = 0;
abfd = orig_bfd;
while (1)
{
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;
i = 0;
for (sect = abfd->sections; sect != NULL; sect = sect->next)
{
bfd_size_type sz;
int is_debug_info;
if ((sect->output_section != NULL
&& sect->output_section != sect)
&& sect->output_section != sect
&& (sect->flags & SEC_DEBUGGING) == 0)
|| sect->vma != 0)
continue;
/* We need to adjust the VMAs of any .debug_info sections.
Skip compressed ones, since no relocations could target
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;
is_debug_info = (strcmp (sect->name, debug_info_name) == 0
|| CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
if (!is_debug_info && (sect->flags & SEC_LOAD) == 0)
continue;
sz = sect->rawsize ? sect->rawsize : sect->size;
if (sz == 0)
if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
&& !is_debug_info)
continue;
i++;
}
if (i <= 1)
return TRUE;
if (abfd == stash->bfd_ptr)
break;
abfd = stash->bfd_ptr;
}
amt = i * sizeof (struct adjusted_section);
p = (struct adjusted_section *) bfd_alloc (abfd, amt);
if (! p)
if (i <= 1)
stash->adjusted_section_count = -1;
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;
stash->adjusted_sections = p;
stash->adjusted_section_count = i;
for (sect = abfd->sections; sect != NULL; sect = sect->next)
abfd = orig_bfd;
while (1)
{
bfd_size_type sz;
int is_debug_info;
asection *sect;
if ((sect->output_section != NULL
&& sect->output_section != sect)
|| sect->vma != 0)
continue;
/* We need to adjust the VMAs of any .debug_info sections.
Skip compressed ones, since no relocations could target
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)
continue;
sz = sect->rawsize ? sect->rawsize : sect->size;
if (sz == 0)
continue;
p->section = sect;
if (is_debug_info)
for (sect = abfd->sections; sect != NULL; sect = sect->next)
{
BFD_ASSERT (sect->alignment_power == 0);
sect->vma = last_dwarf;
last_dwarf += sz;
}
else if (last_vma != 0)
{
/* Align the new address to the current section
alignment. */
last_vma = ((last_vma
+ ~((bfd_vma) -1 << sect->alignment_power))
& ((bfd_vma) -1 << sect->alignment_power));
sect->vma = last_vma;
last_vma += sect->vma + sz;
}
else
last_vma += sect->vma + sz;
bfd_size_type sz;
int is_debug_info;
p->adj_vma = sect->vma;
if ((sect->output_section != NULL
&& sect->output_section != sect
&& (sect->flags & SEC_DEBUGGING) == 0)
|| sect->vma != 0)
continue;
p++;
is_debug_info = (strcmp (sect->name, debug_info_name) == 0
|| CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
&& !is_debug_info)
continue;
sz = sect->rawsize ? sect->rawsize : sect->size;
if (is_debug_info)
{
BFD_ASSERT (sect->alignment_power == 0);
sect->vma = last_dwarf;
last_dwarf += sz;
}
else
{
/* Align the new address to the current section
alignment. */
last_vma = ((last_vma
+ ~((bfd_vma) -1 << sect->alignment_power))
& ((bfd_vma) -1 << sect->alignment_power));
sect->vma = last_vma;
last_vma += sz;
}
p->section = sect;
p->adj_vma = sect->vma;
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;
}
@ -3407,9 +3440,10 @@ section_vma_same (const bfd *abfd, const struct dwarf2_debug *stash)
bfd_boolean
_bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
const struct dwarf_debug_section *debug_sections,
asymbol **symbols,
void **pinfo)
const struct dwarf_debug_section *debug_sections,
asymbol **symbols,
void **pinfo,
bfd_boolean do_place)
{
bfd_size_type amt = sizeof (struct dwarf2_debug);
bfd_size_type total_size;
@ -3418,8 +3452,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
if (stash != NULL)
{
if (stash->syms == symbols
&& section_vma_same (abfd, stash))
if (section_vma_same (abfd, stash))
return TRUE;
_bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
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
|| ! bfd_check_format (debug_bfd, bfd_object)
|| (msec = find_debug_info (debug_bfd,
debug_sections, NULL)) == NULL)
debug_sections, NULL)) == NULL
|| !bfd_generic_link_read_symbols (debug_bfd))
{
if (debug_bfd)
bfd_close (debug_bfd);
@ -3463,10 +3497,17 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
free (debug_filename);
return FALSE;
}
symbols = bfd_get_outsymbols (debug_bfd);
stash->syms = symbols;
stash->close_on_cleanup = TRUE;
}
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
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
@ -3540,7 +3581,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
static bfd_boolean
find_line (bfd *abfd,
const struct dwarf_debug_section *debug_sections,
const struct dwarf_debug_section *debug_sections,
asection *section,
bfd_vma offset,
asymbol *symbol,
@ -3574,20 +3615,13 @@ find_line (bfd *abfd,
if (discriminator_ptr)
*discriminator_ptr = 0;
if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL,
debug_sections, symbols, pinfo))
if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL, debug_sections,
symbols, pinfo,
(abfd->flags & (EXEC_P | DYNAMIC)) == 0))
return FALSE;
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
&& offset == 0
&& functionname_ptr == NULL
@ -3801,7 +3835,7 @@ find_line (bfd *abfd,
== stash->sec->size)
{
stash->sec = find_debug_info (stash->bfd_ptr, debug_sections,
stash->sec);
stash->sec);
stash->sec_info_ptr = stash->info_ptr;
}
@ -3822,20 +3856,20 @@ find_line (bfd *abfd,
bfd_boolean
_bfd_dwarf2_find_nearest_line (bfd *abfd,
const struct dwarf_debug_section *debug_sections,
const struct dwarf_debug_section *debug_sections,
asection *section,
asymbol **symbols,
bfd_vma offset,
const char **filename_ptr,
const char **functionname_ptr,
unsigned int *linenumber_ptr,
unsigned int *discriminator_ptr,
unsigned int *discriminator_ptr,
unsigned int addr_size,
void **pinfo)
{
return find_line (abfd, debug_sections, section, offset, NULL, symbols,
filename_ptr, functionname_ptr, linenumber_ptr,
discriminator_ptr, addr_size, pinfo);
filename_ptr, functionname_ptr, linenumber_ptr,
discriminator_ptr, addr_size, pinfo);
}
/* The DWARF2 version of find_line.
@ -3847,13 +3881,13 @@ _bfd_dwarf2_find_line (bfd *abfd,
asymbol *symbol,
const char **filename_ptr,
unsigned int *linenumber_ptr,
unsigned int *discriminator_ptr,
unsigned int *discriminator_ptr,
unsigned int addr_size,
void **pinfo)
{
return find_line (abfd, dwarf_debug_sections, NULL, 0, symbol, symbols,
filename_ptr, NULL, linenumber_ptr, discriminator_ptr,
addr_size, pinfo);
filename_ptr, NULL, linenumber_ptr, discriminator_ptr,
addr_size, pinfo);
}
bfd_boolean
@ -3962,6 +3996,8 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
free (stash->alt_dwarf_info_buffer);
if (stash->sec_vma)
free (stash->sec_vma);
if (stash->adjusted_sections)
free (stash->adjusted_sections);
if (stash->alt_bfd_ptr)
bfd_close (stash->alt_bfd_ptr);
}

View File

@ -560,7 +560,8 @@ extern bfd_boolean _bfd_dwarf2_find_inliner_info
/* Read DWARF 2 debugging information. */
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. */
extern void _bfd_dwarf2_cleanup_debug_info

View File

@ -565,7 +565,8 @@ extern bfd_boolean _bfd_dwarf2_find_inliner_info
/* Read DWARF 2 debugging information. */
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. */
extern void _bfd_dwarf2_cleanup_debug_info

View File

@ -5660,7 +5660,8 @@ bfd_mach_o_find_nearest_line (bfd *abfd,
break;
if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
dwarf_debug_sections, symbols,
&mdata->dwarf2_find_line_info))
&mdata->dwarf2_find_line_info,
FALSE))
return FALSE;
}
break;

View File

@ -106,6 +106,22 @@ struct saved_offsets
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
simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
asection *section,
@ -220,15 +236,6 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
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.sections = malloc (sizeof (*saved_offsets.sections)
* saved_offsets.section_count);