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:
parent
95e54da724
commit
5609a71e68
2 changed files with 117 additions and 33 deletions
|
@ -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
|
||||
|
|
132
bfd/dwarf2.c
132
bfd/dwarf2.c
|
@ -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++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue