GNU Binutils with patches for OS216
リビジョン | 9e9821ddd80c0d0b3dda54d34cc8867f256d4583 (tree) |
---|---|
日時 | 2017-04-25 06:37:12 |
作者 | H.J. Lu <hjl.tools@gmai...> |
コミッター | H.J. Lu |
x86-64: Force symbol dynamic if it isn't undefined weak
Force symbol dynamic if it isn't undefined weak. Generate relative
relocation for GOT reference against non-dynamic symbol in PIC to
avoid unnecessary dynamic symbols.
bfd/
* elf64-x86-64.c (elf_x86_64_link_hash_entry): Add
no_finish_dynamic_symbol.
(elf_x86_64_link_hash_newfunc): Set no_finish_dynamic_symbol to
0.
(elf_x86_64_allocate_dynrelocs): If a symbol isn't undefined
weak symbol, don't make it dynamic.
(elf_x86_64_relocate_section): If a symbol isn't dynamic in PIC,
set no_finish_dynamic_symbol and generate R_X86_64_RELATIVE
relocation for GOT reference.
(elf_x86_64_finish_dynamic_symbol): Abort if
no_finish_dynamic_symbol isn't 0.
ld/
* testsuite/ld-x86-64/no-plt.exp: Also check no-plt-1e.nd.
* testsuite/ld-x86-64/no-plt-1e.nd: New file.
@@ -1,5 +1,19 @@ | ||
1 | 1 | 2017-04-24 H.J. Lu <hongjiu.lu@intel.com> |
2 | 2 | |
3 | + * elf64-x86-64.c (elf_x86_64_link_hash_entry): Add | |
4 | + no_finish_dynamic_symbol. | |
5 | + (elf_x86_64_link_hash_newfunc): Set no_finish_dynamic_symbol to | |
6 | + 0. | |
7 | + (elf_x86_64_allocate_dynrelocs): If a symbol isn't undefined | |
8 | + weak symbol, don't make it dynamic. | |
9 | + (elf_x86_64_relocate_section): If a symbol isn't dynamic in PIC, | |
10 | + set no_finish_dynamic_symbol and generate R_X86_64_RELATIVE | |
11 | + relocation for GOT reference. | |
12 | + (elf_x86_64_finish_dynamic_symbol): Abort if | |
13 | + no_finish_dynamic_symbol isn't 0. | |
14 | + | |
15 | +2017-04-24 H.J. Lu <hongjiu.lu@intel.com> | |
16 | + | |
3 | 17 | PR ld/21402 |
4 | 18 | * elf32-i386.c (elf_i386_allocate_dynrelocs): If a symbol isn't |
5 | 19 | undefined weak symbol, don't make it dynamic. |
@@ -867,6 +867,9 @@ struct elf_x86_64_link_hash_entry | ||
867 | 867 | /* TRUE if symbol has non-GOT/non-PLT relocations in text sections. */ |
868 | 868 | unsigned int has_non_got_reloc : 1; |
869 | 869 | |
870 | + /* Don't call finish_dynamic_symbol on this symbol. */ | |
871 | + unsigned int no_finish_dynamic_symbol : 1; | |
872 | + | |
870 | 873 | /* 0: symbol isn't __tls_get_addr. |
871 | 874 | 1: symbol is __tls_get_addr. |
872 | 875 | 2: symbol is unknown. */ |
@@ -1022,6 +1025,7 @@ elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry, | ||
1022 | 1025 | eh->has_bnd_reloc = 0; |
1023 | 1026 | eh->has_got_reloc = 0; |
1024 | 1027 | eh->has_non_got_reloc = 0; |
1028 | + eh->no_finish_dynamic_symbol = 0; | |
1025 | 1029 | eh->tls_get_addr = 2; |
1026 | 1030 | eh->func_pointer_refcount = 0; |
1027 | 1031 | eh->plt_bnd.offset = (bfd_vma) -1; |
@@ -3218,7 +3222,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) | ||
3218 | 3222 | Undefined weak syms won't yet be marked as dynamic. */ |
3219 | 3223 | if (h->dynindx == -1 |
3220 | 3224 | && !h->forced_local |
3221 | - && !resolved_to_zero) | |
3225 | + && !resolved_to_zero | |
3226 | + && h->root.type == bfd_link_hash_undefweak) | |
3222 | 3227 | { |
3223 | 3228 | if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
3224 | 3229 | return FALSE; |
@@ -3338,7 +3343,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) | ||
3338 | 3343 | Undefined weak syms won't yet be marked as dynamic. */ |
3339 | 3344 | if (h->dynindx == -1 |
3340 | 3345 | && !h->forced_local |
3341 | - && !resolved_to_zero) | |
3346 | + && !resolved_to_zero | |
3347 | + && h->root.type == bfd_link_hash_undefweak) | |
3342 | 3348 | { |
3343 | 3349 | if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
3344 | 3350 | return FALSE; |
@@ -3475,6 +3481,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) | ||
3475 | 3481 | if (h->dynindx == -1 |
3476 | 3482 | && ! h->forced_local |
3477 | 3483 | && ! resolved_to_zero |
3484 | + && h->root.type == bfd_link_hash_undefweak | |
3478 | 3485 | && ! bfd_elf_link_record_dynamic_symbol (info, h)) |
3479 | 3486 | return FALSE; |
3480 | 3487 |
@@ -4270,6 +4277,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, | ||
4270 | 4277 | asection *base_got, *resolved_plt; |
4271 | 4278 | bfd_vma st_size; |
4272 | 4279 | bfd_boolean resolved_to_zero; |
4280 | + bfd_boolean relative_reloc; | |
4273 | 4281 | |
4274 | 4282 | r_type = ELF32_R_TYPE (rel->r_info); |
4275 | 4283 | if (r_type == (int) R_X86_64_GNU_VTINHERIT |
@@ -4637,6 +4645,7 @@ do_ifunc_pointer: | ||
4637 | 4645 | if (htab->elf.sgot == NULL) |
4638 | 4646 | abort (); |
4639 | 4647 | |
4648 | + relative_reloc = FALSE; | |
4640 | 4649 | if (h != NULL) |
4641 | 4650 | { |
4642 | 4651 | bfd_boolean dyn; |
@@ -4683,6 +4692,17 @@ do_ifunc_pointer: | ||
4683 | 4692 | /* Note that this is harmless for the GOTPLT64 case, |
4684 | 4693 | as -1 | 1 still is -1. */ |
4685 | 4694 | h->got.offset |= 1; |
4695 | + | |
4696 | + if (h->dynindx == -1 | |
4697 | + && !h->forced_local | |
4698 | + && h->root.type != bfd_link_hash_undefweak | |
4699 | + && bfd_link_pic (info)) | |
4700 | + { | |
4701 | + /* If this symbol isn't dynamic in PIC, | |
4702 | + generate R_X86_64_RELATIVE here. */ | |
4703 | + eh->no_finish_dynamic_symbol = 1; | |
4704 | + relative_reloc = TRUE; | |
4705 | + } | |
4686 | 4706 | } |
4687 | 4707 | } |
4688 | 4708 | else |
@@ -4704,30 +4724,32 @@ do_ifunc_pointer: | ||
4704 | 4724 | { |
4705 | 4725 | bfd_put_64 (output_bfd, relocation, |
4706 | 4726 | base_got->contents + off); |
4727 | + local_got_offsets[r_symndx] |= 1; | |
4707 | 4728 | |
4708 | 4729 | if (bfd_link_pic (info)) |
4709 | - { | |
4710 | - asection *s; | |
4711 | - Elf_Internal_Rela outrel; | |
4712 | - | |
4713 | - /* We need to generate a R_X86_64_RELATIVE reloc | |
4714 | - for the dynamic linker. */ | |
4715 | - s = htab->elf.srelgot; | |
4716 | - if (s == NULL) | |
4717 | - abort (); | |
4718 | - | |
4719 | - outrel.r_offset = (base_got->output_section->vma | |
4720 | - + base_got->output_offset | |
4721 | - + off); | |
4722 | - outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); | |
4723 | - outrel.r_addend = relocation; | |
4724 | - elf_append_rela (output_bfd, s, &outrel); | |
4725 | - } | |
4726 | - | |
4727 | - local_got_offsets[r_symndx] |= 1; | |
4730 | + relative_reloc = TRUE; | |
4728 | 4731 | } |
4729 | 4732 | } |
4730 | 4733 | |
4734 | + if (relative_reloc) | |
4735 | + { | |
4736 | + asection *s; | |
4737 | + Elf_Internal_Rela outrel; | |
4738 | + | |
4739 | + /* We need to generate a R_X86_64_RELATIVE reloc | |
4740 | + for the dynamic linker. */ | |
4741 | + s = htab->elf.srelgot; | |
4742 | + if (s == NULL) | |
4743 | + abort (); | |
4744 | + | |
4745 | + outrel.r_offset = (base_got->output_section->vma | |
4746 | + + base_got->output_offset | |
4747 | + + off); | |
4748 | + outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); | |
4749 | + outrel.r_addend = relocation; | |
4750 | + elf_append_rela (output_bfd, s, &outrel); | |
4751 | + } | |
4752 | + | |
4731 | 4753 | if (off >= (bfd_vma) -2) |
4732 | 4754 | abort (); |
4733 | 4755 |
@@ -5797,6 +5819,8 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, | ||
5797 | 5819 | : get_elf_x86_64_backend_data (output_bfd)); |
5798 | 5820 | |
5799 | 5821 | eh = (struct elf_x86_64_link_hash_entry *) h; |
5822 | + if (eh->no_finish_dynamic_symbol) | |
5823 | + abort (); | |
5800 | 5824 | |
5801 | 5825 | /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for |
5802 | 5826 | resolved undefined weak symbols in executable so that their |
@@ -1,5 +1,10 @@ | ||
1 | 1 | 2017-04-24 H.J. Lu <hongjiu.lu@intel.com> |
2 | 2 | |
3 | + * testsuite/ld-x86-64/no-plt.exp: Also check no-plt-1e.nd. | |
4 | + * testsuite/ld-x86-64/no-plt-1e.nd: New file. | |
5 | + | |
6 | +2017-04-24 H.J. Lu <hongjiu.lu@intel.com> | |
7 | + | |
3 | 8 | * testsuite/ld-i386/pr12570a.d: Skip for nacl targets. |
4 | 9 | * testsuite/ld-i386/pr12570b.d: Likewise. |
5 | 10 |
@@ -0,0 +1,7 @@ | ||
1 | +#nm: -g -D | |
2 | +#target: x86_64-*-* | |
3 | + | |
4 | +#failif | |
5 | +#... | |
6 | +[0-9]+ +T +func | |
7 | +#... |
@@ -111,7 +111,7 @@ run_cc_link_tests [list \ | ||
111 | 111 | tmpdir/no-plt-func1.o tmpdir/no-plt-extern1.o" \ |
112 | 112 | "" \ |
113 | 113 | {dummy.s} \ |
114 | - {{readelf -Wr no-plt-1e.rd} {objdump -dwrj.text no-plt-1e.dd}} \ | |
114 | + {{readelf -Wr no-plt-1e.rd} {nm -gD no-plt-1e.nd} {objdump -dwrj.text no-plt-1e.dd}} \ | |
115 | 115 | "no-plt-1e" \ |
116 | 116 | ] \ |
117 | 117 | [list \ |