PATCH: PR ld/4590: String merging breaks ia64 linker
H. J. Lu
hjl@lucon.org
Tue Jun 12 13:08:00 GMT 2007
More information about the Binutils mailing list
Tue Jun 12 13:08: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 01:52:52PM +0200, Andreas Schwab wrote: > > Here's another testcase: > > .section .rodata.str1.8,"aMS", 1 > .LC1: .string "foo" > .LC2: .string "foo" > .LC3: .string "bar" > .LC4: .string "bar" > .LC5: .string "bar" > .LC6: .string "bar" > .LC7: .string "baz" > .LC8: .string "baz" > .section .data.rel.local,"aw" > .quad .LC2 > .quad .LC4 > .quad .LC6 > .quad .LC7 > .section .rodata,"a" > .LC9: .string "mumble" > .balign 8 > .space 0x400000 > .text > addl r12=@ltoffx(.LC1),r1 ;; > addl r12=@ltoffx(.LC3),r1 ;; > addl r12=@ltoffx(.LC5),r1 ;; > addl r12=@ltoffx(.LC8),r1 ;; > addl r12=@ltoffx(.LC9),r1 ;; > > > not immediately clear which of them to pick. Ideally, all this merging > should already happen before relaxing, so that we don't allocate those > extra got entries and NONE relocations. > 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. --- binutils/bfd/elfxx-ia64.c.merge 2007-06-12 05:54:55.000000000 -0700 +++ binutils/bfd/elfxx-ia64.c 2007-06-12 06:03:05.000000000 -0700 @@ -2233,21 +2233,29 @@ addend_compare (const void *xp, const vo static unsigned int sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info, - unsigned int count) + unsigned int count, bfd_boolean merged) { bfd_vma curr, prev; - unsigned int i, dup, diff, dest, src, len; + unsigned int i, kept, dup, diff, dest, src, len; qsort (info, count, sizeof (*info), addend_compare); /* Find the first duplicate. */ - prev = info [0].addend; + kept = 0; + prev = info [kept].addend; for (i = 1; i < count; i++) { curr = info [i].addend; if (curr == prev) - break; + { + /* If a string is merged with another one, we need to make + sure that KEPT has a valid got_offset. */ + if (merged && info [kept].got_offset == (bfd_vma) -1) + info [kept].got_offset = info [i].got_offset; + break; + } prev = curr; + kept++; } /* Remove duplicates. */ @@ -2264,8 +2272,14 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn if (curr == prev) { for (src = i + 1; src < count; src++) - if (info [src].addend != curr) - break; + { + if (info [src].addend != curr) + break; + /* If a string is merged with another one, we need + to make sure that KEPT has a valid got_offset. */ + if (merged && info [kept].got_offset == (bfd_vma) -1) + info [kept].got_offset = info [src].got_offset; + } } else src = i; @@ -2273,13 +2287,19 @@ 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; for (dup = src + 1; dup < count; dup++) { curr = info [dup].addend; if (curr == prev) - break; + { + /* If a string is merged with another one, we keep + the valid got_offset in SRC. */ + if (merged && info [src].got_offset == (bfd_vma) -1) + info [src].got_offset = info [dup].got_offset; + break; + } prev = curr; } @@ -2290,20 +2310,40 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn 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 (merged && info [dup].got_offset == (bfd_vma) -1) + info [dup].got_offset = info [src].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; + /* DIFF will be kept. If a string is merged with + another one, we need to make sure that DIFF has + a valid got_offset. */ + if (merged && info [diff].got_offset == (bfd_vma) -1) + info [diff].got_offset = info [dup].got_offset; + } if (diff < count) { - /* Find the next duplicate. */ + /* Find the next duplicate. DIFF will be kept. */ prev = info [diff].addend; for (dup = diff + 1; dup < count; dup++) { curr = info [dup].addend; if (curr == prev) - break; + { + /* If a string is merged with another one, + we need to make sure that DIFF has a + valid got_offset. */ + if (merged + && info [diff].got_offset == (bfd_vma) -1) + info [diff].got_offset = info [dup].got_offset; + break; + } prev = curr; diff++; } @@ -2442,6 +2482,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 @@ -2454,7 +2495,7 @@ has_space: array isn't sorted. */ if (count != sorted_count) { - count = sort_dyn_sym_info (info, count); + count = sort_dyn_sym_info (info, count, FALSE); *count_p = count; *sorted_count_p = count; } @@ -4652,9 +4693,16 @@ 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, + TRUE); + 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