PR ld/14323
* elflink.c (elf_sort_symbol): Sort by size too. (elf_link_add_object_symbols <weakdefs>): Simplify binary search. Do not depend on ordering of symbol aliases. Match largest size.
This commit is contained in:
parent
2e515f7e37
commit
1416057852
@ -1,3 +1,10 @@
|
|||||||
|
2012-07-09 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR ld/14323
|
||||||
|
* elflink.c (elf_sort_symbol): Sort by size too.
|
||||||
|
(elf_link_add_object_symbols <weakdefs>): Simplify binary search.
|
||||||
|
Do not depend on ordering of symbol aliases. Match largest size.
|
||||||
|
|
||||||
2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
|
2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* elf.c (assign_section_numbers): Check if number of sections
|
* elf.c (assign_section_numbers): Check if number of sections
|
||||||
|
@ -3145,7 +3145,7 @@ on_needed_list (const char *soname, struct bfd_link_needed_list *needed)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort symbol by value and section. */
|
/* Sort symbol by value, section, and size. */
|
||||||
static int
|
static int
|
||||||
elf_sort_symbol (const void *arg1, const void *arg2)
|
elf_sort_symbol (const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
@ -3164,7 +3164,8 @@ elf_sort_symbol (const void *arg1, const void *arg2)
|
|||||||
if (sdiff != 0)
|
if (sdiff != 0)
|
||||||
return sdiff > 0 ? 1 : -1;
|
return sdiff > 0 ? 1 : -1;
|
||||||
}
|
}
|
||||||
return 0;
|
vdiff = h1->size - h2->size;
|
||||||
|
return vdiff == 0 ? 0 : vdiff > 0 ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is used to adjust offsets into .dynstr for
|
/* This function is used to adjust offsets into .dynstr for
|
||||||
@ -4726,7 +4727,6 @@ error_free_dyn:
|
|||||||
struct elf_link_hash_entry *hlook;
|
struct elf_link_hash_entry *hlook;
|
||||||
asection *slook;
|
asection *slook;
|
||||||
bfd_vma vlook;
|
bfd_vma vlook;
|
||||||
long ilook;
|
|
||||||
size_t i, j, idx;
|
size_t i, j, idx;
|
||||||
|
|
||||||
hlook = weaks;
|
hlook = weaks;
|
||||||
@ -4740,14 +4740,13 @@ error_free_dyn:
|
|||||||
slook = hlook->root.u.def.section;
|
slook = hlook->root.u.def.section;
|
||||||
vlook = hlook->root.u.def.value;
|
vlook = hlook->root.u.def.value;
|
||||||
|
|
||||||
ilook = -1;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
j = sym_count;
|
j = sym_count;
|
||||||
while (i < j)
|
while (i != j)
|
||||||
{
|
{
|
||||||
bfd_signed_vma vdiff;
|
bfd_signed_vma vdiff;
|
||||||
idx = (i + j) / 2;
|
idx = (i + j) / 2;
|
||||||
h = sorted_sym_hash [idx];
|
h = sorted_sym_hash[idx];
|
||||||
vdiff = vlook - h->root.u.def.value;
|
vdiff = vlook - h->root.u.def.value;
|
||||||
if (vdiff < 0)
|
if (vdiff < 0)
|
||||||
j = idx;
|
j = idx;
|
||||||
@ -4761,24 +4760,36 @@ error_free_dyn:
|
|||||||
else if (sdiff > 0)
|
else if (sdiff > 0)
|
||||||
i = idx + 1;
|
i = idx + 1;
|
||||||
else
|
else
|
||||||
{
|
break;
|
||||||
ilook = idx;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We didn't find a value/section match. */
|
/* We didn't find a value/section match. */
|
||||||
if (ilook == -1)
|
if (i == j)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i = ilook; i < sym_count; i++)
|
/* With multiple aliases, or when the weak symbol is already
|
||||||
|
strongly defined, we have multiple matching symbols and
|
||||||
|
the binary search above may land on any of them. Step
|
||||||
|
one past the matching symbol(s). */
|
||||||
|
while (++idx != j)
|
||||||
{
|
{
|
||||||
h = sorted_sym_hash [i];
|
h = sorted_sym_hash[idx];
|
||||||
|
if (h->root.u.def.section != slook
|
||||||
|
|| h->root.u.def.value != vlook)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now look back over the aliases. Since we sorted by size
|
||||||
|
as well as value and section, we'll choose the one with
|
||||||
|
the largest size. */
|
||||||
|
while (idx-- != i)
|
||||||
|
{
|
||||||
|
h = sorted_sym_hash[idx];
|
||||||
|
|
||||||
/* Stop if value or section doesn't match. */
|
/* Stop if value or section doesn't match. */
|
||||||
if (h->root.u.def.value != vlook
|
if (h->root.u.def.section != slook
|
||||||
|| h->root.u.def.section != slook)
|
|| h->root.u.def.value != vlook)
|
||||||
break;
|
break;
|
||||||
else if (h != hlook)
|
else if (h != hlook)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user