PR ld/3191

* dwarf2.c (struct adjusted_section): Renamed from struct
	loadable_section.
	(struct dwarf2_debug): Adjust for renaming.  Add version field.
	(read_attribute_value): Correctly handle DW_FORM_ref_addr for
	DWARF3.
	(find_abstract_instance_name): Pass a pointer to
	attribute instead of offset.  For DW_FORM_ref_addr, get the
	entry at the offset from the .debug_info section.
	(scan_unit_for_symbols): Update.
	(parse_comp_unit): Allow DWARF3.  Save the version.
	(unset_sections): Update for renaming.
	(place_sections): Likewise.  Set new VMAs for DWARF sections
	also.
This commit is contained in:
Daniel Jacobowitz 2008-09-08 21:58:29 +00:00
parent 95e54da724
commit 5609a71e68
2 changed files with 117 additions and 33 deletions

View file

@ -1,3 +1,21 @@
2008-09-08 H.J. Lu <hongjiu.lu@intel.com>
Daniel Jacobowitz <dan@codesourcery.com>
PR ld/3191
* dwarf2.c (struct adjusted_section): Renamed from struct
loadable_section.
(struct dwarf2_debug): Adjust for renaming. Add version field.
(read_attribute_value): Correctly handle DW_FORM_ref_addr for
DWARF3.
(find_abstract_instance_name): Pass a pointer to
attribute instead of offset. For DW_FORM_ref_addr, get the
entry at the offset from the .debug_info section.
(scan_unit_for_symbols): Update.
(parse_comp_unit): Allow DWARF3. Save the version.
(unset_sections): Update for renaming.
(place_sections): Likewise. Set new VMAs for DWARF sections
also.
2008-09-08 Tristan Gingold <gingold@adacore.com>
* configure.in: Update version to 2.19.50

View file

@ -75,7 +75,7 @@ struct dwarf_block
bfd_byte *data;
};
struct loadable_section
struct adjusted_section
{
asection *section;
bfd_vma adj_vma;
@ -143,11 +143,11 @@ struct dwarf2_debug
use. */
struct funcinfo *inliner_chain;
/* Number of loadable sections. */
unsigned int loadable_section_count;
/* Number of sections whose VMA we must adjust. */
unsigned int adjusted_section_count;
/* Array of loadable sections. */
struct loadable_section *loadable_sections;
/* Array of sections with adjusted VMA. */
struct adjusted_section *adjusted_sections;
/* Number of times find_line is called. This is used in
the heuristic for enabling the info hash tables. */
@ -237,6 +237,9 @@ struct comp_unit
/* Pointer to dwarf2_debug structure. */
struct dwarf2_debug *stash;
/* DWARF format version for this unit - from unit header. */
int version;
/* Address size for this unit - from unit header. */
unsigned char addr_size;
@ -742,9 +745,20 @@ read_attribute_value (struct attribute *attr,
switch (form)
{
case DW_FORM_addr:
/* FIXME: DWARF3 draft says DW_FORM_ref_addr is offset_size. */
case DW_FORM_ref_addr:
/* DW_FORM_ref_addr is an address in DWARF2, and an offset in
DWARF3. */
if (unit->version == 3)
{
if (unit->offset_size == 4)
attr->u.val = read_4_bytes (unit->abfd, info_ptr);
else
attr->u.val = read_8_bytes (unit->abfd, info_ptr);
info_ptr += unit->offset_size;
break;
}
/* FALLTHROUGH */
case DW_FORM_addr:
attr->u.val = read_address (unit, info_ptr);
info_ptr += unit->addr_size;
break;
@ -1705,16 +1719,30 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
}
static char *
find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t die_ref)
find_abstract_instance_name (struct comp_unit *unit,
struct attribute *attr_ptr)
{
bfd *abfd = unit->abfd;
bfd_byte *info_ptr;
unsigned int abbrev_number, bytes_read, i;
struct abbrev_info *abbrev;
bfd_uint64_t die_ref = attr_ptr->u.val;
struct attribute attr;
char *name = 0;
info_ptr = unit->info_ptr_unit + die_ref;
/* DW_FORM_ref_addr can reference an entry in a different CU. It
is an offset from the .debug_info section, not the current CU. */
if (attr_ptr->form == DW_FORM_ref_addr)
{
/* We only support DW_FORM_ref_addr within the same file, so
any relocations should be resolved already. */
if (!die_ref)
abort ();
info_ptr = unit->stash->sec_info_ptr + die_ref;
}
else
info_ptr = unit->info_ptr_unit + die_ref;
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
@ -1740,7 +1768,7 @@ find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t die_ref)
name = attr.u.str;
break;
case DW_AT_specification:
name = find_abstract_instance_name (unit, attr.u.val);
name = find_abstract_instance_name (unit, &attr);
break;
case DW_AT_MIPS_linkage_name:
name = attr.u.str;
@ -1902,7 +1930,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
break;
case DW_AT_abstract_origin:
func->name = find_abstract_instance_name (unit, attr.u.val);
func->name = find_abstract_instance_name (unit, &attr);
break;
case DW_AT_name:
@ -2070,9 +2098,9 @@ parse_comp_unit (struct dwarf2_debug *stash,
addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
if (version != 2)
if (version != 2 && version != 3)
{
(*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."), version);
(*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 and 3 information."), version);
bfd_set_error (bfd_error_bad_value);
return 0;
}
@ -2120,6 +2148,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
amt = sizeof (struct comp_unit);
unit = bfd_zalloc (abfd, amt);
unit->abfd = abfd;
unit->version = version;
unit->addr_size = addr_size;
unit->offset_size = offset_size;
unit->abbrevs = abbrevs;
@ -2472,49 +2501,63 @@ find_debug_info (bfd *abfd, asection *after_sec)
return NULL;
}
/* Unset vmas for loadable sections in STASH. */
/* Unset vmas for adjusted sections in STASH. */
static void
unset_sections (struct dwarf2_debug *stash)
{
unsigned int i;
struct loadable_section *p;
struct adjusted_section *p;
i = stash->loadable_section_count;
p = stash->loadable_sections;
i = stash->adjusted_section_count;
p = stash->adjusted_sections;
for (; i > 0; i--, p++)
p->section->vma = 0;
}
/* Set unique vmas for loadable sections in ABFD and save vmas in
STASH for unset_sections. */
/* Set unique VMAs for loadable and DWARF sections in ABFD and save
VMAs in STASH for unset_sections. */
static bfd_boolean
place_sections (bfd *abfd, struct dwarf2_debug *stash)
{
struct loadable_section *p;
struct adjusted_section *p;
unsigned int i;
if (stash->loadable_section_count != 0)
if (stash->adjusted_section_count != 0)
{
i = stash->loadable_section_count;
p = stash->loadable_sections;
i = stash->adjusted_section_count;
p = stash->adjusted_sections;
for (; i > 0; i--, p++)
p->section->vma = p->adj_vma;
}
else
{
asection *sect;
bfd_vma last_vma = 0;
bfd_vma last_vma = 0, last_dwarf = 0;
bfd_size_type amt;
struct loadable_section *p;
struct adjusted_section *p;
i = 0;
for (sect = abfd->sections; sect != NULL; sect = sect->next)
{
bfd_size_type sz;
int is_debug_info;
if (sect->vma != 0 || (sect->flags & SEC_LOAD) == 0)
if (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, DWARF2_DEBUG_INFO) == 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;
@ -2524,19 +2567,33 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
i++;
}
amt = i * sizeof (struct loadable_section);
p = (struct loadable_section *) bfd_zalloc (abfd, amt);
amt = i * sizeof (struct adjusted_section);
p = (struct adjusted_section *) bfd_zalloc (abfd, amt);
if (! p)
return FALSE;
stash->loadable_sections = p;
stash->loadable_section_count = i;
stash->adjusted_sections = p;
stash->adjusted_section_count = i;
for (sect = abfd->sections; sect != NULL; sect = sect->next)
{
bfd_size_type sz;
int is_debug_info;
if (sect->vma != 0 || (sect->flags & SEC_LOAD) == 0)
if (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, DWARF2_DEBUG_INFO) == 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;
@ -2544,7 +2601,13 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
continue;
p->section = sect;
if (last_vma != 0)
if (is_debug_info)
{
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. */
@ -2552,9 +2615,12 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
+ ~((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;
p->adj_vma = sect->vma;
last_vma += sect->vma + sz;
p++;
}