#!/bin/sh -e ## 201-hjl-bfd-ref-addr.dpatch ## ## DP: Description: Support DW_FORM_ref_addr in Dwarf 2 reader in linker. ## DP: Author: H.J. Lu ## DP: Upstream status: hjl post 2.17.50.0.18, PR ld/3191 ## DP: Original patch: bfd-ref_addr-6.patch if [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi [ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts patch_opts="${patch_opts:--f --no-backup-if-mismatch}" case "$1" in -patch) patch $patch_opts -p1 < $0;; -unpatch) patch $patch_opts -p1 -R < $0;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1;; esac exit 0 2006-09-29 H.J. Lu 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. @DPATCH@ diff -urNad binutils-2.18~cvs20070812~/bfd/dwarf2.c binutils-2.18~cvs20070812/bfd/dwarf2.c --- binutils-2.18~cvs20070812~/bfd/dwarf2.c 2007-07-26 10:31:03.000000000 +0200 +++ binutils-2.18~cvs20070812/bfd/dwarf2.c 2007-08-12 13:15:54.000000000 +0200 @@ -1710,16 +1710,30 @@ } 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; @@ -1745,7 +1759,7 @@ 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; @@ -1907,7 +1921,7 @@ 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: @@ -2876,6 +2890,11 @@ bfd *debug_bfd; 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; @@ -2909,9 +2928,28 @@ 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 (debug_bfd, 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 (debug_bfd, total_size); if (stash->info_ptr == NULL) @@ -2919,17 +2957,27 @@ stash->info_ptr_end = stash->info_ptr; - for (msec = find_debug_info (debug_bfd, NULL); + if (count > 1) + { + count--; + msecs = (asection **) bfd_malloc2 (count, sizeof (*msecs)); + } + + for (i = 0, msec = first_msec; msec; msec = find_debug_info (debug_bfd, 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 @@ -2939,9 +2987,27 @@ 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 (debug_bfd, first_msec); + msec; + msec = find_debug_info (debug_bfd, msec)) + msec->vma = 0; + } + } + BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size); - stash->sec = find_debug_info (debug_bfd, NULL); + stash->sec = first_msec; stash->sec_info_ptr = stash->info_ptr; stash->syms = symbols; stash->bfd = debug_bfd;