PATCH: PR ld/4590: String merging breaks ia64 linker
H. J. Lu
hjl@lucon.org
Wed Jun 13 05:36:00 GMT 2007
More information about the Binutils mailing list
Wed Jun 13 05:36:00 GMT 2007
- Previous message (by thread): PATCH: PR ld/4590: String merging breaks ia64 linker
- Next message (by thread): PATCH: PR ld/4590: String merging breaks ia64 linker
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Tue, Jun 12, 2007 at 07:18:31PM +0200, Andreas Schwab wrote: > "H. J. Lu" <hjl@lucon.org> writes: > > > On Tue, Jun 12, 2007 at 04:02:00PM +0200, Andreas Schwab wrote: > >> "H. J. Lu" <hjl@lucon.org> writes: > >> > >> > Please try this one. > >> > > >> > Thanks. > >> > > >> > H.J. > >> > ----- > >> > 2007-06-12 H.J. Lu <hongjiu.lu@intel.com> > >> > > >> > PR ld/4590 > >> > * elfxx-ia64.c (sort_dyn_sym_info): Take a new argument for > >> > string merge. Keep the valid got_offset when removing > >> > duplicated entries for string merge > >> > (get_dyn_sym_info): Initialize the got_offset field to -1. > >> > Update call to sort_dyn_sym_info. > >> > (elfNN_ia64_relocate_section): Set addend_merged if the > >> > addend is merged with another one. Call sort_dyn_sym_info > >> > to sort array of addend and remove duplicates. > >> > >> Still getting the same assertion failures. > >> > > > > Can you try this one? > > This works for me. > Try this one. sort_dyn_sym_info is highly optimized. I hope I get it right this time. The idea is to always make got_offset valid for the current addend. H.J. ---- bfd/ 2007-06-12 H.J. Lu <hongjiu.lu@intel.com> PR ld/4590 * elfxx-ia64.c (sort_dyn_sym_info): Keep the valid got_offset when removing duplicated entries. (get_dyn_sym_info): Initialize the got_offset field to -1. Update call to sort_dyn_sym_info. (elfNN_ia64_relocate_section): Call sort_dyn_sym_info to sort array of addend and remove duplicates. --- binutils/bfd/elfxx-ia64.c.merge 2007-06-12 18:37:38.000000000 -0700 +++ binutils/bfd/elfxx-ia64.c 2007-06-12 22:31:50.000000000 -0700 @@ -2235,18 +2235,25 @@ static unsigned int sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info, unsigned int count) { - bfd_vma curr, prev; - unsigned int i, dup, diff, dest, src, len; + bfd_vma curr, prev, got_offset; + unsigned int i, kept, dup, diff, dest, src, len; qsort (info, count, sizeof (*info), addend_compare); /* Find the first duplicate. */ prev = info [0].addend; + got_offset = info [0].got_offset; for (i = 1; i < count; i++) { curr = info [i].addend; if (curr == prev) - break; + { + /* For duplicates, make sure that got_offset is valid. */ + if (got_offset == (bfd_vma) -1) + got_offset = info [i].got_offset; + break; + } + got_offset = info [i].got_offset; prev = curr; } @@ -2257,15 +2264,31 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn dest = i++; while (i < count) { + /* Make sure that KEPT has a valid got_offset. */ + kept = dest - 1; + if (got_offset != (bfd_vma) -1) + info [kept].got_offset = got_offset; + curr = info [i].addend; + got_offset = info [i].got_offset; /* Move a block of elements whose first one is different from the previous. */ if (curr == prev) { for (src = i + 1; src < count; src++) - if (info [src].addend != curr) - break; + { + if (info [src].addend != curr) + break; + /* For duplicates, make sure that got_offset is + valid. */ + if (got_offset == (bfd_vma) -1) + got_offset = info [src].got_offset; + } + + /* Make sure that KEPT has a valid got_offset. */ + if (got_offset != (bfd_vma) -1) + info [kept].got_offset = got_offset; } else src = i; @@ -2273,37 +2296,69 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn if (src >= count) break; - /* Find the next duplicate. */ + /* Find the next duplicate. SRC will be kept. */ prev = info [src].addend; + got_offset = info [src].got_offset; for (dup = src + 1; dup < count; dup++) { curr = info [dup].addend; if (curr == prev) - break; + { + /* Make sure that got_offset is valid. */ + if (got_offset == (bfd_vma) -1) + got_offset = info [dup].got_offset; + break; + } prev = curr; + got_offset = info [dup].got_offset; } /* How much to move. */ len = dup - src; i = dup + 1; + /* Make sure that DUP - 1 has a valid got_offset. */ + if (got_offset != (bfd_vma) -1) + info [dup - 1].got_offset = got_offset; + if (len == 1 && dup < count) { /* If we only move 1 element, we combine it with the next - one. Find the next different one. */ + one. We will keep DUP instead of SRC. Make sure that + DUP has a valid got_offset. */ + if (got_offset != (bfd_vma) -1) + info [dup].got_offset = got_offset; + + /* Find the next different one. */ for (diff = dup + 1, src++; diff < count; diff++, src++) - if (info [diff].addend != curr) - break; + { + if (info [diff].addend != curr) + break; + /* Make sure that got_offset is valid. */ + if (got_offset == (bfd_vma) -1) + got_offset = info [diff].got_offset; + } + + if (got_offset == (bfd_vma) -1) + info [diff - 1].got_offset = got_offset; if (diff < count) { - /* Find the next duplicate. */ + /* Find the next duplicate. DIFF will be kept. */ prev = info [diff].addend; + got_offset = info [diff].got_offset; for (dup = diff + 1; dup < count; dup++) { curr = info [dup].addend; if (curr == prev) - break; + { + /* For duplicates, make sure that got_offset + is valid. */ + if (got_offset == (bfd_vma) -1) + got_offset = info [diff].got_offset; + break; + } + got_offset = info [diff].got_offset; prev = curr; diff++; } @@ -2442,6 +2497,7 @@ has_space: /* Append the new one to the array. */ dyn_i = info + count; memset (dyn_i, 0, sizeof (*dyn_i)); + dyn_i->got_offset = (bfd_vma) -1; dyn_i->addend = addend; /* We increment count only since the new ones are unsorted and @@ -4652,9 +4708,15 @@ elfNN_ia64_relocate_section (output_bfd, - sym_sec->output_section->vma - sym_sec->output_offset; } - - qsort (loc_h->info, loc_h->count, - sizeof (*loc_h->info), addend_compare); + + /* We may have introduced duplicated entries. We need + to remove them properly. */ + count = sort_dyn_sym_info (loc_h->info, loc_h->count); + if (count != loc_h->count) + { + loc_h->count = count; + loc_h->sorted_count = count; + } loc_h->sec_merge_done = 1; }
- Previous message (by thread): PATCH: PR ld/4590: String merging breaks ia64 linker
- Next message (by thread): PATCH: PR ld/4590: String merging breaks ia64 linker
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list