+++ /dev/null
-2006-09-29 H.J. Lu <hongjiu.lu@intel.com>
-
- PR ld/3191
- * dwarf2.c (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): Updated.
- (_bfd_dwarf2_find_nearest_line): Adjust debug_info
- section vma when needed.
-
---- bfd/dwarf2.c.ref_addr 2006-09-21 13:55:25.000000000 -0700
-+++ bfd/dwarf2.c 2006-09-29 10:07:14.000000000 -0700
-@@ -1556,16 +1556,30 @@ lookup_symbol_in_variable_table (struct
- }
-
- 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)
-+ {
-+ /* FIXME: How to handle DW_FORM_ref_addr references an entry in
-+ a different file? */
-+ 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;
-
-@@ -1591,7 +1605,7 @@ find_abstract_instance_name (struct comp
- 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;
-@@ -1751,7 +1765,7 @@ scan_unit_for_symbols (struct comp_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:
-@@ -2375,6 +2389,11 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
- {
- bfd_size_type total_size;
- asection *msec;
-+ bfd_vma last_vma;
-+ bfd_size_type size;
-+ asection *first_msec;
-+ asection **msecs = NULL;
-+ unsigned int i, count;
-
- *pinfo = stash;
-
-@@ -2389,9 +2408,28 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
- Read them all in and produce one large stash. We do this in two
- passes - in the first pass we just accumulate the section sizes.
- In the second pass we read in the section's contents. The allows
-- us to avoid reallocing the data as we add sections to the stash. */
-+ us to avoid reallocing the data as we add sections to the stash.
-+
-+ We may need to adjust debug_info section vmas since we will
-+ concatenate them together. Otherwise relocations may be
-+ incorrect. */
-+ first_msec = msec;
-+ last_vma = 0;
-+ count = 0;
- for (total_size = 0; msec; msec = find_debug_info (abfd, msec))
-- total_size += msec->size;
-+ {
-+ size = msec->size;
-+ if (size == 0)
-+ continue;
-+
-+ total_size += size;
-+
-+ BFD_ASSERT (msec->vma == 0 && msec->alignment_power == 0);
-+
-+ msec->vma = last_vma;
-+ last_vma += size;
-+ count++;
-+ }
-
- stash->info_ptr = bfd_alloc (abfd, total_size);
- if (stash->info_ptr == NULL)
-@@ -2399,17 +2437,27 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
-
- stash->info_ptr_end = stash->info_ptr;
-
-- for (msec = find_debug_info (abfd, NULL);
-+ if (count > 1)
-+ {
-+ count--;
-+ msecs = (asection **) bfd_malloc2 (count, sizeof (*msecs));
-+ }
-+
-+ for (i = 0, msec = first_msec;
- msec;
- msec = find_debug_info (abfd, msec))
- {
-- bfd_size_type size;
- bfd_size_type start;
-
- size = msec->size;
- if (size == 0)
- continue;
-
-+ if (i && msecs)
-+ msecs [i - 1] = msec;
-+
-+ i++;
-+
- start = stash->info_ptr_end - stash->info_ptr;
-
- if ((bfd_simple_get_relocated_section_contents
-@@ -2419,9 +2467,27 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
- stash->info_ptr_end = stash->info_ptr + start + size;
- }
-
-+ /* Restore section vma. */
-+ if (count)
-+ {
-+ if (msecs)
-+ {
-+ for (i = 0; i < count; i++)
-+ msecs [i]->vma = 0;
-+ free (msecs);
-+ }
-+ else
-+ {
-+ for (msec = find_debug_info (abfd, first_msec);
-+ msec;
-+ msec = find_debug_info (abfd, msec))
-+ msec->vma = 0;
-+ }
-+ }
-+
- BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
-
-- stash->sec = find_debug_info (abfd, NULL);
-+ stash->sec = first_msec;
- stash->sec_info_ptr = stash->info_ptr;
- stash->syms = symbols;
- }