Properly handle common symbol and weak function
bfd/ PR ld/14591 * elf-bfd.h (_bfd_elf_merge_symbol): Add an argument to return if the old symbol is weak. * elf32-sh-symbian.c (sh_symbian_relocate_section): Update _bfd_elf_merge_symbol call. * elflink.c (_bfd_elf_merge_symbol): Add an argument to return if the old symbol is weak. (_bfd_elf_add_default_symbol): Update _bfd_elf_merge_symbol call. (elf_link_add_object_symbols): Don't update symbol type from a weak definition. Update symbol type from a common symbol when overriding a weak symbol. ld/testsuite/ PR ld/14591 * ld-elf/comm-data.exp (run_ld_link_tests): Add comm-data3a and comm-data3b tests. * ld-ifunc/ifunc.exp (run_ld_link_exec_tests): New. * ld-elf/comm-data3.sd: New file. * ld-elf/comm-data3a.s: Likewise. * ld-elf/comm-data3b.s: Likewise. * ld-ifunc/ifunc-17a-i386.d: Likewise. * ld-ifunc/ifunc-17a-x86-64.d: Likewise. * ld-ifunc/ifunc-17a.s: Likewise. * ld-ifunc/ifunc-17b-i386.d: Likewise. * ld-ifunc/ifunc-17b-x86-64.d: Likewise. * ld-ifunc/ifunc-17b.s: Likewise. * ld-ifunc/ifunc-common-1.out: Likewise. * ld-ifunc/ifunc-common-1a.c: Likewise. * ld-ifunc/ifunc-common-1b.c: Likewise.
This commit is contained in:
parent
91b96a45e3
commit
37a9e49a28
@ -1,3 +1,20 @@
|
||||
2012-09-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/14591
|
||||
* elf-bfd.h (_bfd_elf_merge_symbol): Add an argument to return
|
||||
if the old symbol is weak.
|
||||
|
||||
* elf32-sh-symbian.c (sh_symbian_relocate_section): Update
|
||||
_bfd_elf_merge_symbol call.
|
||||
|
||||
* elflink.c (_bfd_elf_merge_symbol): Add an argument to return
|
||||
if the old symbol is weak.
|
||||
(_bfd_elf_add_default_symbol): Update _bfd_elf_merge_symbol
|
||||
call.
|
||||
(elf_link_add_object_symbols): Don't update symbol type from a
|
||||
weak definition. Update symbol type from a common symbol when
|
||||
overriding a weak symbol.
|
||||
|
||||
2012-09-17 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* elf32-i386.c (elf_i386_convert_mov_to_lea): Ignore discarded
|
||||
|
@ -1970,7 +1970,7 @@ extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
|
||||
|
||||
extern bfd_boolean _bfd_elf_merge_symbol
|
||||
(bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
|
||||
asection **, bfd_vma *, unsigned int *,
|
||||
asection **, bfd_vma *, bfd_boolean *, unsigned int *,
|
||||
struct elf_link_hash_entry **, bfd_boolean *,
|
||||
bfd_boolean *, bfd_boolean *, bfd_boolean *);
|
||||
|
||||
|
@ -497,7 +497,7 @@ sh_symbian_relocate_section (bfd * output_bfd,
|
||||
if (! _bfd_elf_merge_symbol (input_bfd, info,
|
||||
ptr->new_name, & new_sym,
|
||||
& psec, & new_value, NULL,
|
||||
& new_hash, & skip,
|
||||
NULL, & new_hash, & skip,
|
||||
& override, & type_change_ok,
|
||||
& size_change_ok))
|
||||
{
|
||||
|
@ -941,6 +941,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
|
||||
Elf_Internal_Sym *sym,
|
||||
asection **psec,
|
||||
bfd_vma *pvalue,
|
||||
bfd_boolean *pold_weak,
|
||||
unsigned int *pold_alignment,
|
||||
struct elf_link_hash_entry **sym_hash,
|
||||
bfd_boolean *skip,
|
||||
@ -1043,6 +1044,8 @@ _bfd_elf_merge_symbol (bfd *abfd,
|
||||
newweak = bind == STB_WEAK;
|
||||
oldweak = (h->root.type == bfd_link_hash_defweak
|
||||
|| h->root.type == bfd_link_hash_undefweak);
|
||||
if (pold_weak)
|
||||
*pold_weak = oldweak;
|
||||
|
||||
/* In cases involving weak versioned symbols, we may wind up trying
|
||||
to merge a symbol with itself. Catch that here, to avoid the
|
||||
@ -1665,7 +1668,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
|
||||
size_change_ok = FALSE;
|
||||
sec = *psec;
|
||||
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
|
||||
NULL, &hi, &skip, &override,
|
||||
NULL, NULL, &hi, &skip, &override,
|
||||
&type_change_ok, &size_change_ok))
|
||||
return FALSE;
|
||||
|
||||
@ -1774,7 +1777,7 @@ nondefault:
|
||||
size_change_ok = FALSE;
|
||||
sec = *psec;
|
||||
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
|
||||
NULL, &hi, &skip, &override,
|
||||
NULL, NULL, &hi, &skip, &override,
|
||||
&type_change_ok, &size_change_ok))
|
||||
return FALSE;
|
||||
|
||||
@ -3868,6 +3871,8 @@ error_free_dyn:
|
||||
bfd_boolean size_change_ok;
|
||||
bfd_boolean type_change_ok;
|
||||
bfd_boolean new_weakdef;
|
||||
bfd_boolean new_weak;
|
||||
bfd_boolean old_weak;
|
||||
bfd_boolean override;
|
||||
bfd_boolean common;
|
||||
unsigned int old_alignment;
|
||||
@ -4000,6 +4005,7 @@ error_free_dyn:
|
||||
|
||||
size_change_ok = FALSE;
|
||||
type_change_ok = bed->type_change_ok;
|
||||
old_weak = FALSE;
|
||||
old_alignment = 0;
|
||||
old_bfd = NULL;
|
||||
new_sec = sec;
|
||||
@ -4145,7 +4151,7 @@ error_free_dyn:
|
||||
}
|
||||
|
||||
if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
|
||||
&value, &old_alignment,
|
||||
&value, &old_weak, &old_alignment,
|
||||
sym_hash, &skip, &override,
|
||||
&type_change_ok, &size_change_ok))
|
||||
goto error_free_vers;
|
||||
@ -4207,10 +4213,11 @@ error_free_dyn:
|
||||
if (is_elf_hash_table (htab))
|
||||
h->unique_global = (flags & BSF_GNU_UNIQUE) != 0;
|
||||
|
||||
new_weak = (flags & BSF_WEAK) != 0;
|
||||
new_weakdef = FALSE;
|
||||
if (dynamic
|
||||
&& definition
|
||||
&& (flags & BSF_WEAK) != 0
|
||||
&& new_weak
|
||||
&& !bed->is_function_type (ELF_ST_TYPE (isym->st_info))
|
||||
&& is_elf_hash_table (htab)
|
||||
&& h->u.weakdef == NULL)
|
||||
@ -4339,7 +4346,9 @@ error_free_dyn:
|
||||
h->size = h->root.u.c.size;
|
||||
|
||||
if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
|
||||
&& (definition || h->type == STT_NOTYPE))
|
||||
&& ((definition && !new_weak)
|
||||
|| (old_weak && h->root.type == bfd_link_hash_common)
|
||||
|| h->type == STT_NOTYPE))
|
||||
{
|
||||
unsigned int type = ELF_ST_TYPE (isym->st_info);
|
||||
|
||||
|
@ -1,3 +1,24 @@
|
||||
2012-09-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/14591
|
||||
* ld-elf/comm-data.exp (run_ld_link_tests): Add comm-data3a and
|
||||
comm-data3b tests.
|
||||
|
||||
* ld-ifunc/ifunc.exp (run_ld_link_exec_tests): New.
|
||||
|
||||
* ld-elf/comm-data3.sd: New file.
|
||||
* ld-elf/comm-data3a.s: Likewise.
|
||||
* ld-elf/comm-data3b.s: Likewise.
|
||||
* ld-ifunc/ifunc-17a-i386.d: Likewise.
|
||||
* ld-ifunc/ifunc-17a-x86-64.d: Likewise.
|
||||
* ld-ifunc/ifunc-17a.s: Likewise.
|
||||
* ld-ifunc/ifunc-17b-i386.d: Likewise.
|
||||
* ld-ifunc/ifunc-17b-x86-64.d: Likewise.
|
||||
* ld-ifunc/ifunc-17b.s: Likewise.
|
||||
* ld-ifunc/ifunc-common-1.out: Likewise.
|
||||
* ld-ifunc/ifunc-common-1a.c: Likewise.
|
||||
* ld-ifunc/ifunc-common-1b.c: Likewise.
|
||||
|
||||
2012-09-17 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* ld-elf/shared.exp (build_cxx_tests): Move out the commented out
|
||||
|
@ -75,4 +75,24 @@ run_ld_link_tests [list \
|
||||
} \
|
||||
"comm-data" \
|
||||
] \
|
||||
[list \
|
||||
"$testname 3a" \
|
||||
"-static" \
|
||||
"" \
|
||||
{ comm-data3a.s comm-data3b.s } \
|
||||
{ \
|
||||
{ readelf -s comm-data3.sd } \
|
||||
} \
|
||||
"comm-data3a" \
|
||||
] \
|
||||
[list \
|
||||
"$testname 3b" \
|
||||
"-static" \
|
||||
"" \
|
||||
{ comm-data3b.s comm-data3a.s } \
|
||||
{ \
|
||||
{ readelf -s comm-data3.sd } \
|
||||
} \
|
||||
"comm-data3b" \
|
||||
] \
|
||||
]
|
||||
|
3
ld/testsuite/ld-elf/comm-data3.sd
Normal file
3
ld/testsuite/ld-elf/comm-data3.sd
Normal file
@ -0,0 +1,3 @@
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
11
ld/testsuite/ld-elf/comm-data3a.s
Normal file
11
ld/testsuite/ld-elf/comm-data3a.s
Normal file
@ -0,0 +1,11 @@
|
||||
.globl main
|
||||
.globl start
|
||||
.globl _start
|
||||
.globl __start
|
||||
.text
|
||||
main:
|
||||
start:
|
||||
_start:
|
||||
__start:
|
||||
.byte 0
|
||||
.common foo,4,4
|
6
ld/testsuite/ld-elf/comm-data3b.s
Normal file
6
ld/testsuite/ld-elf/comm-data3b.s
Normal file
@ -0,0 +1,6 @@
|
||||
.weak foo
|
||||
.type foo,%function
|
||||
.size foo,1
|
||||
.text
|
||||
foo:
|
||||
.byte 1
|
10
ld/testsuite/ld-ifunc/ifunc-17a-i386.d
Normal file
10
ld/testsuite/ld-ifunc/ifunc-17a-i386.d
Normal file
@ -0,0 +1,10 @@
|
||||
#source: ifunc-17a.s
|
||||
#source: ifunc-17b.s
|
||||
#ld: -static -m elf_i386
|
||||
#as: --32
|
||||
#readelf: -s --wide
|
||||
#target: x86_64-*-* i?86-*-*
|
||||
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
10
ld/testsuite/ld-ifunc/ifunc-17a-x86-64.d
Normal file
10
ld/testsuite/ld-ifunc/ifunc-17a-x86-64.d
Normal file
@ -0,0 +1,10 @@
|
||||
#source: ifunc-17a.s
|
||||
#source: ifunc-17b.s
|
||||
#ld: -static -m elf_x86_64
|
||||
#as: --64
|
||||
#readelf: -s --wide
|
||||
#target: x86_64-*-*
|
||||
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
11
ld/testsuite/ld-ifunc/ifunc-17a.s
Normal file
11
ld/testsuite/ld-ifunc/ifunc-17a.s
Normal file
@ -0,0 +1,11 @@
|
||||
.globl main
|
||||
.globl start
|
||||
.globl _start
|
||||
.globl __start
|
||||
.text
|
||||
main:
|
||||
start:
|
||||
_start:
|
||||
__start:
|
||||
.byte 0
|
||||
.common foo,4,4
|
10
ld/testsuite/ld-ifunc/ifunc-17b-i386.d
Normal file
10
ld/testsuite/ld-ifunc/ifunc-17b-i386.d
Normal file
@ -0,0 +1,10 @@
|
||||
#source: ifunc-17b.s
|
||||
#source: ifunc-17a.s
|
||||
#ld: -static -m elf_i386
|
||||
#as: --32
|
||||
#readelf: -s --wide
|
||||
#target: x86_64-*-* i?86-*-*
|
||||
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
10
ld/testsuite/ld-ifunc/ifunc-17b-x86-64.d
Normal file
10
ld/testsuite/ld-ifunc/ifunc-17b-x86-64.d
Normal file
@ -0,0 +1,10 @@
|
||||
#source: ifunc-17b.s
|
||||
#source: ifunc-17a.s
|
||||
#ld: -static -m elf_x86_64
|
||||
#as: --64
|
||||
#readelf: -s --wide
|
||||
#target: x86_64-*-*
|
||||
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
|
||||
#pass
|
6
ld/testsuite/ld-ifunc/ifunc-17b.s
Normal file
6
ld/testsuite/ld-ifunc/ifunc-17b.s
Normal file
@ -0,0 +1,6 @@
|
||||
.weak foo
|
||||
.type foo, %gnu_indirect_function
|
||||
.size foo,1
|
||||
.text
|
||||
foo:
|
||||
.byte 1
|
1
ld/testsuite/ld-ifunc/ifunc-common-1.out
Normal file
1
ld/testsuite/ld-ifunc/ifunc-common-1.out
Normal file
@ -0,0 +1 @@
|
||||
PASSED: 0
|
9
ld/testsuite/ld-ifunc/ifunc-common-1a.c
Normal file
9
ld/testsuite/ld-ifunc/ifunc-common-1a.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int foo;
|
||||
int
|
||||
main ()
|
||||
{
|
||||
printf ("PASSED: %d\n", foo);
|
||||
return 0;
|
||||
}
|
12
ld/testsuite/ld-ifunc/ifunc-common-1b.c
Normal file
12
ld/testsuite/ld-ifunc/ifunc-common-1b.c
Normal file
@ -0,0 +1,12 @@
|
||||
void alt (void) { }
|
||||
|
||||
void foo (void);
|
||||
void * foo_ifunc (void) __asm__ ("foo");
|
||||
__asm__(".type foo, %gnu_indirect_function");
|
||||
__asm__(".weak foo");
|
||||
|
||||
void *
|
||||
foo_ifunc (void)
|
||||
{
|
||||
return alt;
|
||||
}
|
@ -347,6 +347,27 @@ if { $verbose < 1 } {
|
||||
remote_file host delete "tmpdir/static_nonifunc_prog"
|
||||
}
|
||||
|
||||
run_ld_link_exec_tests [] [list \
|
||||
[list \
|
||||
"Common symbol override ifunc test 1a" \
|
||||
"-static" \
|
||||
"" \
|
||||
{ ifunc-common-1a.c ifunc-common-1b.c } \
|
||||
"ifunc-common-1a" \
|
||||
"ifunc-common-1.out" \
|
||||
"-g" \
|
||||
] \
|
||||
[list \
|
||||
"Common symbol override ifunc test 1b" \
|
||||
"-static" \
|
||||
"" \
|
||||
{ ifunc-common-1b.c ifunc-common-1a.c } \
|
||||
"ifunc-common-1b" \
|
||||
"ifunc-common-1.out" \
|
||||
"-g" \
|
||||
] \
|
||||
]
|
||||
|
||||
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
||||
foreach t $test_list {
|
||||
# We need to strip the ".d", but can leave the dirname.
|
||||
|
Loading…
Reference in New Issue
Block a user