2007-06-19  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.

ld/testsuite/

2007-06-19  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/4590
	* ld-ia64/merge1.d: New.
	* ld-ia64/merge1.s: Likewise.
	* ld-ia64/merge2.d: Likewise.
	* ld-ia64/merge2.s: Likewise.
	* ld-ia64/merge3.d: Likewise.
	* ld-ia64/merge3.s: Likewise.
	* ld-ia64/merge4.d: Likewise.
	* ld-ia64/merge4.s: Likewise.
	* ld-ia64/merge5.d: Likewise.
	* ld-ia64/merge5.s: Likewise.
This commit is contained in:
H.J. Lu 2007-06-19 13:05:55 +00:00
parent 30ff741fa7
commit 293a012441
13 changed files with 266 additions and 17 deletions

View File

@ -1,3 +1,13 @@
2007-06-19 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.
2007-06-18 H.J. Lu <hongjiu.lu@intel.com>
* libpei.h (_bfd_XXi_final_link_postscript): Remove

View File

@ -2234,37 +2234,62 @@ 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;
}
/* We may move a block of elements to here. */
dest = i++;
/* Remove duplicates. */
if (i < count)
{
/* We need to move a block of elements to here. */
dest = i++;
while (i < count)
{
/* For duplicates, make sure that the kept one 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 the kept one has a valid got_offset. */
if (got_offset != (bfd_vma) -1)
info [kept].got_offset = got_offset;
}
else
src = i;
@ -2272,13 +2297,25 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
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;
/* For duplicates, make sure that the kept one has
a valid got_offset. */
if (got_offset != (bfd_vma) -1)
info [dup - 1].got_offset = got_offset;
break;
}
got_offset = info [dup].got_offset;
prev = curr;
}
@ -2289,20 +2326,41 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
if (len == 1 && dup < count)
{
/* If we only move 1 element, we combine it with the next
one. Find the next different one. */
one. There must be at least a duplicate. 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;
}
/* Makre sure that the last duplicated one has an valid
offset. */
BFD_ASSERT (curr == prev);
if (got_offset != (bfd_vma) -1)
info [diff - 1].got_offset = got_offset;
if (diff < count)
{
/* Find the next duplicate. */
/* Find the next duplicate. Track the current valid
offset. */
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 [dup].got_offset;
break;
}
got_offset = info [dup].got_offset;
prev = curr;
diff++;
}
@ -2319,6 +2377,19 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
count = dest;
}
else
{
/* When we get here, either there is no duplicate at all or
the only duplicate is the last element. */
if (dest < count)
{
/* If the last element is a duplicate, make sure that the
kept one has a valid got_offset. We also update count. */
if (got_offset != (bfd_vma) -1)
info [dest - 1].got_offset = got_offset;
count = dest;
}
}
return count;
}
@ -2441,6 +2512,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
@ -4651,9 +4723,15 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
- 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;
}

View File

@ -1,3 +1,17 @@
2007-06-19 H.J. Lu <hongjiu.lu@intel.com>
PR ld/4590
* ld-ia64/merge1.d: New.
* ld-ia64/merge1.s: Likewise.
* ld-ia64/merge2.d: Likewise.
* ld-ia64/merge2.s: Likewise.
* ld-ia64/merge3.d: Likewise.
* ld-ia64/merge3.s: Likewise.
* ld-ia64/merge4.d: Likewise.
* ld-ia64/merge4.s: Likewise.
* ld-ia64/merge5.d: Likewise.
* ld-ia64/merge5.s: Likewise.
2007-06-18 Andreas Schwab <schwab@suse.de>
* ld-scripts/cross3.t: Add .opd section.

View File

@ -0,0 +1,10 @@
#source: merge1.s
#as: -x
#ld: -shared
#objdump: -d
#...
0+1e0 <.text>:
[ ]*[a-f0-9]+: 0b 60 80 02 00 24 \[MMI\] addl r12=32,r1;;
[ ]*[a-f0-9]+: c0 c0 04 00 48 00 addl r12=24,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;

View File

@ -0,0 +1,12 @@
.section .rodata.str1.8,"aMS", 1
.LC1: .string "foo"
.LC2: .string "foo"
.section .data.rel.local,"aw"
.quad .LC2
.section .rodata,"a"
.LC3: .string "bar"
.balign 8
.space 0x400000
.text
addl r12=@ltoffx(.LC1),r1 ;;
addl r12=@ltoffx(.LC3),r1 ;;

View File

@ -0,0 +1,10 @@
#source: merge2.s
#as: -x
#ld: -shared
#objdump: -d
#...
0+1e0 <.text>:
[ ]*[a-f0-9]+: 0b 60 80 02 00 24 \[MMI\] addl r12=32,r1;;
[ ]*[a-f0-9]+: c0 c0 04 00 48 00 addl r12=24,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;

View File

@ -0,0 +1,12 @@
.section .rodata.str1.8,"aMS", 1
.LC2: .string "foo"
.LC1: .string "foo"
.section .data.rel.local,"aw"
.quad .LC2
.section .rodata,"a"
.LC3: .string "bar"
.balign 8
.space 0x400000
.text
addl r12=@ltoffx(.LC1),r1 ;;
addl r12=@ltoffx(.LC3),r1 ;;

View File

@ -0,0 +1,13 @@
#source: merge3.s
#as: -x
#ld: -shared
#objdump: -d
#...
0+210 <.text>:
[ ]*[a-f0-9]+: 0b 60 80 02 00 24 \[MMI\] addl r12=32,r1;;
[ ]*[a-f0-9]+: c0 40 05 00 48 00 addl r12=40,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;
[ ]*[a-f0-9]+: 01 60 60 02 00 24 \[MII\] addl r12=24,r1
[ ]*[a-f0-9]+: 00 00 00 02 00 00 nop.i 0x0
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;

View File

@ -0,0 +1,16 @@
.section .rodata.str1.8,"aMS", 1
.LC1: .string "foo"
.LC2: .string "foo"
.LC3: .string "bar"
.LC4: .string "bar"
.section .data.rel.local,"aw"
.quad .LC2
.quad .LC3
.section .rodata,"a"
.LC5: .string "mumble"
.balign 8
.space 0x400000
.text
addl r12=@ltoffx(.LC1),r1 ;;
addl r12=@ltoffx(.LC4),r1 ;;
addl r12=@ltoffx(.LC5),r1 ;;

View File

@ -0,0 +1,13 @@
#source: merge4.s
#as: -x
#ld: -shared
#objdump: -d
#...
0+240 <.text>:
[ ]*[a-f0-9]+: 0b 60 80 02 00 24 \[MMI\] addl r12=32,r1;;
[ ]*[a-f0-9]+: c0 40 05 00 48 00 addl r12=40,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;
[ ]*[a-f0-9]+: 0b 60 c0 02 00 24 \[MMI\] addl r12=48,r1;;
[ ]*[a-f0-9]+: c0 c0 04 00 48 00 addl r12=24,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;

View File

@ -0,0 +1,21 @@
.section .rodata.str1.8,"aMS", 1
.LC1: .string "foo"
.LC2: .string "foo"
.LC3: .string "bar"
.LC4: .string "bar"
.LC5: .string "baz"
.LC6: .string "baz"
.section .data.rel.local,"aw"
.quad .LC2
.quad .LC4
.quad .LC5
.section .rodata,"a"
.LC7: .string "mumble"
.balign 8
.space 0x400000
.text
addl r12=@ltoffx(.LC1),r1 ;;
addl r12=@ltoffx(.LC3),r1 ;;
addl r12=@ltoffx(.LC6),r1 ;;
addl r12=@ltoffx(.LC7),r1 ;;

View File

@ -0,0 +1,16 @@
#source: merge5.s
#as: -x
#ld: -shared
#objdump: -d
#...
0+270 <.text>:
[ ]*[a-f0-9]+: 0b 60 80 02 00 24 \[MMI\] addl r12=32,r1;;
[ ]*[a-f0-9]+: c0 40 05 00 48 00 addl r12=40,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;
[ ]*[a-f0-9]+: 0b 60 a0 02 00 24 \[MMI\] addl r12=40,r1;;
[ ]*[a-f0-9]+: c0 c0 05 00 48 00 addl r12=56,r1
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;
[ ]*[a-f0-9]+: 01 60 60 02 00 24 \[MII\] addl r12=24,r1
[ ]*[a-f0-9]+: 00 00 00 02 00 00 nop.i 0x0
[ ]*[a-f0-9]+: 00 00 04 00 nop.i 0x0;;

View File

@ -0,0 +1,24 @@
.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 ;;