Rev 5197 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5197 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* Intel 80386/80486-specific support for 32-bit ELF |
1 | /* Intel 80386/80486-specific support for 32-bit ELF |
2 | Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
- | |
3 | 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 |
- | |
4 | Free Software Foundation, Inc. |
2 | Copyright (C) 1993-2015 Free Software Foundation, Inc. |
Line 5... | Line 3... | ||
5 | 3 | ||
Line 6... | Line 4... | ||
6 | This file is part of BFD, the Binary File Descriptor library. |
4 | This file is part of BFD, the Binary File Descriptor library. |
7 | 5 | ||
Line 29... | Line 27... | ||
29 | #include "elf-vxworks.h" |
27 | #include "elf-vxworks.h" |
30 | #include "bfd_stdint.h" |
28 | #include "bfd_stdint.h" |
31 | #include "objalloc.h" |
29 | #include "objalloc.h" |
32 | #include "hashtab.h" |
30 | #include "hashtab.h" |
33 | #include "dwarf2.h" |
31 | #include "dwarf2.h" |
- | 32 | #include "opcode/i386.h" |
|
Line 34... | Line 33... | ||
34 | 33 | ||
35 | /* 386 uses REL relocations instead of RELA. */ |
34 | /* 386 uses REL relocations instead of RELA. */ |
Line 36... | Line 35... | ||
36 | #define USE_REL 1 |
35 | #define USE_REL 1 |
Line 37... | Line 36... | ||
37 | 36 | ||
38 | #include "elf/i386.h" |
37 | #include "elf/i386.h" |
39 | 38 | ||
40 | static reloc_howto_type elf_howto_table[]= |
39 | static reloc_howto_type elf_howto_table[]= |
41 | { |
40 | { |
42 | HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield, |
41 | HOWTO(R_386_NONE, 0, 3, 0, FALSE, 0, complain_overflow_dont, |
43 | bfd_elf_generic_reloc, "R_386_NONE", |
42 | bfd_elf_generic_reloc, "R_386_NONE", |
44 | TRUE, 0x00000000, 0x00000000, FALSE), |
43 | TRUE, 0x00000000, 0x00000000, FALSE), |
Line 146... | Line 145... | ||
146 | bfd_elf_generic_reloc, "R_386_TLS_DESC", |
145 | bfd_elf_generic_reloc, "R_386_TLS_DESC", |
147 | TRUE, 0xffffffff, 0xffffffff, FALSE), |
146 | TRUE, 0xffffffff, 0xffffffff, FALSE), |
148 | HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
147 | HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
149 | bfd_elf_generic_reloc, "R_386_IRELATIVE", |
148 | bfd_elf_generic_reloc, "R_386_IRELATIVE", |
150 | TRUE, 0xffffffff, 0xffffffff, FALSE), |
149 | TRUE, 0xffffffff, 0xffffffff, FALSE), |
- | 150 | HOWTO(R_386_GOT32X, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
|
- | 151 | bfd_elf_generic_reloc, "R_386_GOT32X", |
|
- | 152 | TRUE, 0xffffffff, 0xffffffff, FALSE), |
|
Line 151... | Line 153... | ||
151 | 153 | ||
152 | /* Another gap. */ |
154 | /* Another gap. */ |
153 | #define R_386_irelative (R_386_IRELATIVE + 1 - R_386_tls_offset) |
155 | #define R_386_ext2 (R_386_GOT32X + 1 - R_386_tls_offset) |
Line 154... | Line 156... | ||
154 | #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_irelative) |
156 | #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_ext2) |
155 | 157 | ||
156 | /* GNU extension to record C++ vtable hierarchy. */ |
158 | /* GNU extension to record C++ vtable hierarchy. */ |
157 | HOWTO (R_386_GNU_VTINHERIT, /* type */ |
159 | HOWTO (R_386_GNU_VTINHERIT, /* type */ |
Line 332... | Line 334... | ||
332 | 334 | ||
333 | case BFD_RELOC_386_IRELATIVE: |
335 | case BFD_RELOC_386_IRELATIVE: |
334 | TRACE ("BFD_RELOC_386_IRELATIVE"); |
336 | TRACE ("BFD_RELOC_386_IRELATIVE"); |
Line -... | Line 337... | ||
- | 337 | return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset]; |
|
- | 338 | ||
- | 339 | case BFD_RELOC_386_GOT32X: |
|
- | 340 | TRACE ("BFD_RELOC_386_GOT32X"); |
|
335 | return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset]; |
341 | return &elf_howto_table[R_386_GOT32X - R_386_tls_offset]; |
336 | 342 | ||
337 | case BFD_RELOC_VTABLE_INHERIT: |
343 | case BFD_RELOC_VTABLE_INHERIT: |
Line 338... | Line 344... | ||
338 | TRACE ("BFD_RELOC_VTABLE_INHERIT"); |
344 | TRACE ("BFD_RELOC_VTABLE_INHERIT"); |
Line 371... | Line 377... | ||
371 | 377 | ||
372 | if ((indx = r_type) >= R_386_standard |
378 | if ((indx = r_type) >= R_386_standard |
373 | && ((indx = r_type - R_386_ext_offset) - R_386_standard |
379 | && ((indx = r_type - R_386_ext_offset) - R_386_standard |
374 | >= R_386_ext - R_386_standard) |
380 | >= R_386_ext - R_386_standard) |
375 | && ((indx = r_type - R_386_tls_offset) - R_386_ext |
381 | && ((indx = r_type - R_386_tls_offset) - R_386_ext |
376 | >= R_386_irelative - R_386_ext) |
382 | >= R_386_ext2 - R_386_ext) |
377 | && ((indx = r_type - R_386_vt_offset) - R_386_irelative |
383 | && ((indx = r_type - R_386_vt_offset) - R_386_ext2 |
378 | >= R_386_vt - R_386_irelative)) |
384 | >= R_386_vt - R_386_ext2)) |
379 | { |
385 | { |
380 | (*_bfd_error_handler) (_("%B: invalid relocation type %d"), |
386 | (*_bfd_error_handler) (_("%B: invalid relocation type %d"), |
381 | abfd, (int) r_type); |
387 | abfd, (int) r_type); |
382 | indx = R_386_NONE; |
388 | indx = R_386_NONE; |
- | 389 | } |
|
383 | } |
390 | /* PR 17512: file: 0f67f69d. */ |
- | 391 | if (elf_howto_table [indx].type != r_type) |
|
384 | BFD_ASSERT (elf_howto_table [indx].type == r_type); |
392 | return NULL; |
385 | return &elf_howto_table[indx]; |
393 | return &elf_howto_table[indx]; |
Line 386... | Line 394... | ||
386 | } |
394 | } |
387 | 395 | ||
Line 580... | Line 588... | ||
580 | 0, 0, 0, 0, /* replaced with offset into relocation table. */ |
588 | 0, 0, 0, 0, /* replaced with offset into relocation table. */ |
581 | 0xe9, /* jmp relative */ |
589 | 0xe9, /* jmp relative */ |
582 | 0, 0, 0, 0 /* replaced with offset to start of .plt. */ |
590 | 0, 0, 0, 0 /* replaced with offset to start of .plt. */ |
583 | }; |
591 | }; |
Line -... | Line 592... | ||
- | 592 | ||
- | 593 | /* Entries in the GOT procedure linkage table look like this. */ |
|
- | 594 | ||
- | 595 | static const bfd_byte elf_i386_got_plt_entry[8] = |
|
- | 596 | { |
|
- | 597 | 0xff, 0x25, /* jmp indirect */ |
|
- | 598 | 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */ |
|
- | 599 | 0x66, 0x90 /* xchg %ax,%ax */ |
|
- | 600 | }; |
|
- | 601 | ||
- | 602 | /* Entries in the PIC GOT procedure linkage table look like this. */ |
|
- | 603 | ||
- | 604 | static const bfd_byte elf_i386_pic_got_plt_entry[8] = |
|
- | 605 | { |
|
- | 606 | 0xff, 0xa3, /* jmp *offset(%ebx) */ |
|
- | 607 | 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */ |
|
- | 608 | 0x66, 0x90 /* xchg %ax,%ax */ |
|
- | 609 | }; |
|
584 | 610 | ||
Line 585... | Line 611... | ||
585 | /* .eh_frame covering the .plt section. */ |
611 | /* .eh_frame covering the .plt section. */ |
586 | 612 | ||
587 | static const bfd_byte elf_i386_eh_frame_plt[] = |
613 | static const bfd_byte elf_i386_eh_frame_plt[] = |
Line 736... | Line 762... | ||
736 | ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type)) |
762 | ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type)) |
737 | #define GOT_TLS_GD_ANY_P(type) \ |
763 | #define GOT_TLS_GD_ANY_P(type) \ |
738 | (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type)) |
764 | (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type)) |
739 | unsigned char tls_type; |
765 | unsigned char tls_type; |
Line -... | Line 766... | ||
- | 766 | ||
- | 767 | /* Symbol is referenced by R_386_GOTOFF relocation. */ |
|
- | 768 | unsigned int gotoff_ref : 1; |
|
- | 769 | ||
- | 770 | /* Reference count of C/C++ function pointer relocations in read-write |
|
- | 771 | section which can be resolved at run-time. */ |
|
- | 772 | bfd_signed_vma func_pointer_refcount; |
|
- | 773 | ||
- | 774 | /* Information about the GOT PLT entry. Filled when there are both |
|
- | 775 | GOT and PLT relocations against the same function. */ |
|
- | 776 | union gotplt_union plt_got; |
|
740 | 777 | ||
741 | /* Offset of the GOTPLT entry reserved for the TLS descriptor, |
778 | /* Offset of the GOTPLT entry reserved for the TLS descriptor, |
742 | starting at the end of the jump table. */ |
779 | starting at the end of the jump table. */ |
743 | bfd_vma tlsdesc_got; |
780 | bfd_vma tlsdesc_got; |
Line 785... | Line 822... | ||
785 | 822 | ||
786 | /* Short-cuts to get to dynamic linker sections. */ |
823 | /* Short-cuts to get to dynamic linker sections. */ |
787 | asection *sdynbss; |
824 | asection *sdynbss; |
788 | asection *srelbss; |
825 | asection *srelbss; |
- | 826 | asection *plt_eh_frame; |
|
Line 789... | Line 827... | ||
789 | asection *plt_eh_frame; |
827 | asection *plt_got; |
790 | 828 | ||
791 | union |
829 | union |
792 | { |
830 | { |
Line 826... | Line 864... | ||
826 | #define elf_i386_hash_table(p) \ |
864 | #define elf_i386_hash_table(p) \ |
827 | (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ |
865 | (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ |
828 | == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL) |
866 | == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL) |
Line 829... | Line 867... | ||
829 | 867 | ||
830 | #define elf_i386_compute_jump_table_size(htab) \ |
868 | #define elf_i386_compute_jump_table_size(htab) \ |
Line 831... | Line 869... | ||
831 | ((htab)->next_tls_desc_index * 4) |
869 | ((htab)->elf.srelplt->reloc_count * 4) |
Line 832... | Line 870... | ||
832 | 870 | ||
833 | /* Create an entry in an i386 ELF linker hash table. */ |
871 | /* Create an entry in an i386 ELF linker hash table. */ |
Line 854... | Line 892... | ||
854 | struct elf_i386_link_hash_entry *eh; |
892 | struct elf_i386_link_hash_entry *eh; |
Line 855... | Line 893... | ||
855 | 893 | ||
856 | eh = (struct elf_i386_link_hash_entry *) entry; |
894 | eh = (struct elf_i386_link_hash_entry *) entry; |
857 | eh->dyn_relocs = NULL; |
895 | eh->dyn_relocs = NULL; |
- | 896 | eh->tls_type = GOT_UNKNOWN; |
|
- | 897 | eh->gotoff_ref = 0; |
|
- | 898 | eh->func_pointer_refcount = 0; |
|
858 | eh->tls_type = GOT_UNKNOWN; |
899 | eh->plt_got.offset = (bfd_vma) -1; |
859 | eh->tlsdesc_got = (bfd_vma) -1; |
900 | eh->tlsdesc_got = (bfd_vma) -1; |
Line 860... | Line 901... | ||
860 | } |
901 | } |
861 | 902 | ||
Line 922... | Line 963... | ||
922 | { |
963 | { |
923 | memset (ret, 0, sizeof (*ret)); |
964 | memset (ret, 0, sizeof (*ret)); |
924 | ret->elf.indx = sec->id; |
965 | ret->elf.indx = sec->id; |
925 | ret->elf.dynstr_index = ELF32_R_SYM (rel->r_info); |
966 | ret->elf.dynstr_index = ELF32_R_SYM (rel->r_info); |
926 | ret->elf.dynindx = -1; |
967 | ret->elf.dynindx = -1; |
- | 968 | ret->func_pointer_refcount = 0; |
|
- | 969 | ret->plt_got.offset = (bfd_vma) -1; |
|
927 | *slot = ret; |
970 | *slot = ret; |
928 | } |
971 | } |
929 | return &ret->elf; |
972 | return &ret->elf; |
930 | } |
973 | } |
Line -... | Line 974... | ||
- | 974 | ||
- | 975 | /* Destroy an i386 ELF linker hash table. */ |
|
- | 976 | ||
- | 977 | static void |
|
- | 978 | elf_i386_link_hash_table_free (bfd *obfd) |
|
- | 979 | { |
|
- | 980 | struct elf_i386_link_hash_table *htab |
|
- | 981 | = (struct elf_i386_link_hash_table *) obfd->link.hash; |
|
- | 982 | ||
- | 983 | if (htab->loc_hash_table) |
|
- | 984 | htab_delete (htab->loc_hash_table); |
|
- | 985 | if (htab->loc_hash_memory) |
|
- | 986 | objalloc_free ((struct objalloc *) htab->loc_hash_memory); |
|
- | 987 | _bfd_elf_link_hash_table_free (obfd); |
|
- | 988 | } |
|
931 | 989 | ||
Line 932... | Line 990... | ||
932 | /* Create an i386 ELF linker hash table. */ |
990 | /* Create an i386 ELF linker hash table. */ |
933 | 991 | ||
934 | static struct bfd_link_hash_table * |
992 | static struct bfd_link_hash_table * |
Line 955... | Line 1013... | ||
955 | elf_i386_local_htab_eq, |
1013 | elf_i386_local_htab_eq, |
956 | NULL); |
1014 | NULL); |
957 | ret->loc_hash_memory = objalloc_create (); |
1015 | ret->loc_hash_memory = objalloc_create (); |
958 | if (!ret->loc_hash_table || !ret->loc_hash_memory) |
1016 | if (!ret->loc_hash_table || !ret->loc_hash_memory) |
959 | { |
1017 | { |
960 | free (ret); |
1018 | elf_i386_link_hash_table_free (abfd); |
961 | return NULL; |
1019 | return NULL; |
962 | } |
1020 | } |
- | 1021 | ret->elf.root.hash_table_free = elf_i386_link_hash_table_free; |
|
Line 963... | Line 1022... | ||
963 | 1022 | ||
964 | return &ret->elf.root; |
1023 | return &ret->elf.root; |
Line 965... | Line -... | ||
965 | } |
- | |
966 | - | ||
967 | /* Destroy an i386 ELF linker hash table. */ |
- | |
968 | - | ||
969 | static void |
- | |
970 | elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash) |
- | |
971 | { |
- | |
972 | struct elf_i386_link_hash_table *htab |
- | |
973 | = (struct elf_i386_link_hash_table *) hash; |
- | |
974 | - | ||
975 | if (htab->loc_hash_table) |
- | |
976 | htab_delete (htab->loc_hash_table); |
- | |
977 | if (htab->loc_hash_memory) |
- | |
978 | objalloc_free ((struct objalloc *) htab->loc_hash_memory); |
- | |
979 | _bfd_elf_link_hash_table_free (hash); |
- | |
980 | } |
1024 | } |
981 | 1025 | ||
982 | /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and |
1026 | /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and |
Line 983... | Line 1027... | ||
983 | .rel.bss sections in DYNOBJ, and set up shortcuts to them in our |
1027 | .rel.bss sections in DYNOBJ, and set up shortcuts to them in our |
Line 994... | Line 1038... | ||
994 | htab = elf_i386_hash_table (info); |
1038 | htab = elf_i386_hash_table (info); |
995 | if (htab == NULL) |
1039 | if (htab == NULL) |
996 | return FALSE; |
1040 | return FALSE; |
Line 997... | Line 1041... | ||
997 | 1041 | ||
998 | htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); |
- | |
999 | if (!info->shared) |
- | |
1000 | htab->srelbss = bfd_get_linker_section (dynobj, ".rel.bss"); |
- | |
1001 | 1042 | htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); |
|
1002 | if (!htab->sdynbss |
- | |
1003 | || (!info->shared && !htab->srelbss)) |
1043 | if (!htab->sdynbss) |
Line -... | Line 1044... | ||
- | 1044 | abort (); |
|
- | 1045 | ||
- | 1046 | if (bfd_link_executable (info)) |
|
- | 1047 | { |
|
- | 1048 | /* Always allow copy relocs for building executables. */ |
|
- | 1049 | asection *s = bfd_get_linker_section (dynobj, ".rel.bss"); |
|
- | 1050 | if (s == NULL) |
|
- | 1051 | { |
|
- | 1052 | const struct elf_backend_data *bed = get_elf_backend_data (dynobj); |
|
- | 1053 | s = bfd_make_section_anyway_with_flags (dynobj, |
|
- | 1054 | ".rel.bss", |
|
- | 1055 | (bed->dynamic_sec_flags |
|
- | 1056 | | SEC_READONLY)); |
|
- | 1057 | if (s == NULL |
|
- | 1058 | || ! bfd_set_section_alignment (dynobj, s, |
|
- | 1059 | bed->s->log_file_align)) |
|
- | 1060 | return FALSE; |
|
- | 1061 | } |
|
- | 1062 | htab->srelbss = s; |
|
1004 | abort (); |
1063 | } |
1005 | 1064 | ||
1006 | if (get_elf_i386_backend_data (dynobj)->is_vxworks |
1065 | if (get_elf_i386_backend_data (dynobj)->is_vxworks |
1007 | && !elf_vxworks_create_dynamic_sections (dynobj, info, |
1066 | && !elf_vxworks_create_dynamic_sections (dynobj, info, |
Line 1073... | Line 1132... | ||
1073 | { |
1132 | { |
1074 | edir->tls_type = eind->tls_type; |
1133 | edir->tls_type = eind->tls_type; |
1075 | eind->tls_type = GOT_UNKNOWN; |
1134 | eind->tls_type = GOT_UNKNOWN; |
1076 | } |
1135 | } |
Line -... | Line 1136... | ||
- | 1136 | ||
- | 1137 | /* Copy gotoff_ref so that elf_i386_adjust_dynamic_symbol will |
|
- | 1138 | generate a R_386_COPY reloc. */ |
|
- | 1139 | edir->gotoff_ref |= eind->gotoff_ref; |
|
1077 | 1140 | ||
1078 | if (ELIMINATE_COPY_RELOCS |
1141 | if (ELIMINATE_COPY_RELOCS |
1079 | && ind->root.type != bfd_link_hash_indirect |
1142 | && ind->root.type != bfd_link_hash_indirect |
1080 | && dir->dynamic_adjusted) |
1143 | && dir->dynamic_adjusted) |
1081 | { |
1144 | { |
Line 1087... | Line 1150... | ||
1087 | dir->ref_regular_nonweak |= ind->ref_regular_nonweak; |
1150 | dir->ref_regular_nonweak |= ind->ref_regular_nonweak; |
1088 | dir->needs_plt |= ind->needs_plt; |
1151 | dir->needs_plt |= ind->needs_plt; |
1089 | dir->pointer_equality_needed |= ind->pointer_equality_needed; |
1152 | dir->pointer_equality_needed |= ind->pointer_equality_needed; |
1090 | } |
1153 | } |
1091 | else |
1154 | else |
- | 1155 | { |
|
- | 1156 | if (eind->func_pointer_refcount > 0) |
|
- | 1157 | { |
|
- | 1158 | edir->func_pointer_refcount += eind->func_pointer_refcount; |
|
- | 1159 | eind->func_pointer_refcount = 0; |
|
- | 1160 | } |
|
- | 1161 | ||
1092 | _bfd_elf_link_hash_copy_indirect (info, dir, ind); |
1162 | _bfd_elf_link_hash_copy_indirect (info, dir, ind); |
1093 | } |
1163 | } |
- | 1164 | } |
|
Line 1094... | Line 1165... | ||
1094 | 1165 | ||
1095 | /* Return TRUE if the TLS access code sequence support transition |
1166 | /* Return TRUE if the TLS access code sequence support transition |
Line 1096... | Line 1167... | ||
1096 | from R_TYPE. */ |
1167 | from R_TYPE. */ |
Line 1303... | Line 1374... | ||
1303 | case R_386_TLS_GOTDESC: |
1374 | case R_386_TLS_GOTDESC: |
1304 | case R_386_TLS_DESC_CALL: |
1375 | case R_386_TLS_DESC_CALL: |
1305 | case R_386_TLS_IE_32: |
1376 | case R_386_TLS_IE_32: |
1306 | case R_386_TLS_IE: |
1377 | case R_386_TLS_IE: |
1307 | case R_386_TLS_GOTIE: |
1378 | case R_386_TLS_GOTIE: |
1308 | if (info->executable) |
1379 | if (bfd_link_executable (info)) |
1309 | { |
1380 | { |
1310 | if (h == NULL) |
1381 | if (h == NULL) |
1311 | to_type = R_386_TLS_LE_32; |
1382 | to_type = R_386_TLS_LE_32; |
1312 | else if (from_type != R_386_TLS_IE |
1383 | else if (from_type != R_386_TLS_IE |
1313 | && from_type != R_386_TLS_GOTIE) |
1384 | && from_type != R_386_TLS_GOTIE) |
Line 1319... | Line 1390... | ||
1319 | TLS_TYPE. */ |
1390 | TLS_TYPE. */ |
1320 | if (contents != NULL) |
1391 | if (contents != NULL) |
1321 | { |
1392 | { |
1322 | unsigned int new_to_type = to_type; |
1393 | unsigned int new_to_type = to_type; |
Line 1323... | Line 1394... | ||
1323 | 1394 | ||
1324 | if (info->executable |
1395 | if (bfd_link_executable (info) |
1325 | && h != NULL |
1396 | && h != NULL |
1326 | && h->dynindx == -1 |
1397 | && h->dynindx == -1 |
1327 | && (tls_type & GOT_TLS_IE)) |
1398 | && (tls_type & GOT_TLS_IE)) |
Line 1345... | Line 1416... | ||
1345 | } |
1416 | } |
Line 1346... | Line 1417... | ||
1346 | 1417 | ||
Line 1347... | Line 1418... | ||
1347 | break; |
1418 | break; |
1348 | 1419 | ||
1349 | case R_386_TLS_LDM: |
1420 | case R_386_TLS_LDM: |
1350 | if (info->executable) |
1421 | if (bfd_link_executable (info)) |
Line 1351... | Line 1422... | ||
1351 | to_type = R_386_TLS_LE_32; |
1422 | to_type = R_386_TLS_LE_32; |
1352 | break; |
1423 | break; |
Line 1401... | Line 1472... | ||
1401 | 1472 | ||
1402 | *r_type = to_type; |
1473 | *r_type = to_type; |
1403 | return TRUE; |
1474 | return TRUE; |
Line -... | Line 1475... | ||
- | 1475 | } |
|
- | 1476 | ||
- | 1477 | /* Rename some of the generic section flags to better document how they |
|
- | 1478 | are used here. */ |
|
1404 | } |
1479 | #define need_convert_load sec_flg0 |
1405 | 1480 | ||
1406 | /* Look through the relocs for a section during the first phase, and |
1481 | /* Look through the relocs for a section during the first phase, and |
Line 1407... | Line 1482... | ||
1407 | calculate needed space in the global offset table, procedure linkage |
1482 | calculate needed space in the global offset table, procedure linkage |
Line 1417... | Line 1492... | ||
1417 | Elf_Internal_Shdr *symtab_hdr; |
1492 | Elf_Internal_Shdr *symtab_hdr; |
1418 | struct elf_link_hash_entry **sym_hashes; |
1493 | struct elf_link_hash_entry **sym_hashes; |
1419 | const Elf_Internal_Rela *rel; |
1494 | const Elf_Internal_Rela *rel; |
1420 | const Elf_Internal_Rela *rel_end; |
1495 | const Elf_Internal_Rela *rel_end; |
1421 | asection *sreloc; |
1496 | asection *sreloc; |
- | 1497 | bfd_boolean use_plt_got; |
|
Line 1422... | Line 1498... | ||
1422 | 1498 | ||
1423 | if (info->relocatable) |
1499 | if (bfd_link_relocatable (info)) |
Line 1424... | Line 1500... | ||
1424 | return TRUE; |
1500 | return TRUE; |
Line 1425... | Line 1501... | ||
1425 | 1501 | ||
1426 | BFD_ASSERT (is_i386_elf (abfd)); |
1502 | BFD_ASSERT (is_i386_elf (abfd)); |
1427 | 1503 | ||
Line -... | Line 1504... | ||
- | 1504 | htab = elf_i386_hash_table (info); |
|
- | 1505 | if (htab == NULL) |
|
- | 1506 | return FALSE; |
|
- | 1507 | ||
1428 | htab = elf_i386_hash_table (info); |
1508 | use_plt_got = (!get_elf_i386_backend_data (abfd)->is_vxworks |
1429 | if (htab == NULL) |
1509 | && (get_elf_i386_backend_data (abfd) |
Line 1430... | Line 1510... | ||
1430 | return FALSE; |
1510 | == &elf_i386_arch_bed)); |
Line 1438... | Line 1518... | ||
1438 | for (rel = relocs; rel < rel_end; rel++) |
1518 | for (rel = relocs; rel < rel_end; rel++) |
1439 | { |
1519 | { |
1440 | unsigned int r_type; |
1520 | unsigned int r_type; |
1441 | unsigned long r_symndx; |
1521 | unsigned long r_symndx; |
1442 | struct elf_link_hash_entry *h; |
1522 | struct elf_link_hash_entry *h; |
- | 1523 | struct elf_i386_link_hash_entry *eh; |
|
1443 | Elf_Internal_Sym *isym; |
1524 | Elf_Internal_Sym *isym; |
1444 | const char *name; |
1525 | const char *name; |
1445 | bfd_boolean size_reloc; |
1526 | bfd_boolean size_reloc; |
Line 1446... | Line 1527... | ||
1446 | 1527 | ||
Line 1487... | Line 1568... | ||
1487 | while (h->root.type == bfd_link_hash_indirect |
1568 | while (h->root.type == bfd_link_hash_indirect |
1488 | || h->root.type == bfd_link_hash_warning) |
1569 | || h->root.type == bfd_link_hash_warning) |
1489 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1570 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1490 | } |
1571 | } |
Line -... | Line 1572... | ||
- | 1572 | ||
1491 | 1573 | eh = (struct elf_i386_link_hash_entry *) h; |
|
1492 | if (h != NULL) |
1574 | if (h != NULL) |
1493 | { |
1575 | { |
1494 | /* Create the ifunc sections for static executables. If we |
1576 | /* Create the ifunc sections for static executables. If we |
1495 | never see an indirect function symbol nor we are building |
1577 | never see an indirect function symbol nor we are building |
Line 1498... | Line 1580... | ||
1498 | switch (r_type) |
1580 | switch (r_type) |
1499 | { |
1581 | { |
1500 | default: |
1582 | default: |
1501 | break; |
1583 | break; |
Line -... | Line 1584... | ||
- | 1584 | ||
- | 1585 | case R_386_GOTOFF: |
|
1502 | 1586 | eh->gotoff_ref = 1; |
|
1503 | case R_386_32: |
1587 | case R_386_32: |
1504 | case R_386_PC32: |
1588 | case R_386_PC32: |
1505 | case R_386_PLT32: |
1589 | case R_386_PLT32: |
1506 | case R_386_GOT32: |
1590 | case R_386_GOT32: |
1507 | case R_386_GOTOFF: |
1591 | case R_386_GOT32X: |
1508 | if (htab->elf.dynobj == NULL) |
1592 | if (htab->elf.dynobj == NULL) |
1509 | htab->elf.dynobj = abfd; |
1593 | htab->elf.dynobj = abfd; |
1510 | if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) |
1594 | if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) |
1511 | return FALSE; |
1595 | return FALSE; |
1512 | break; |
1596 | break; |
Line 1513... | Line 1597... | ||
1513 | } |
1597 | } |
1514 | 1598 | ||
1515 | /* It is referenced by a non-shared object. */ |
1599 | /* It is referenced by a non-shared object. */ |
- | 1600 | h->ref_regular = 1; |
|
- | 1601 | h->root.non_ir_ref = 1; |
|
- | 1602 | ||
- | 1603 | if (h->type == STT_GNU_IFUNC) |
|
1516 | h->ref_regular = 1; |
1604 | elf_tdata (info->output_bfd)->has_gnu_symbols |
Line 1517... | Line 1605... | ||
1517 | h->root.non_ir_ref = 1; |
1605 | |= elf_gnu_symbol_ifunc; |
1518 | } |
1606 | } |
1519 | 1607 | ||
Line 1551... | Line 1639... | ||
1551 | goto do_size; |
1639 | goto do_size; |
Line 1552... | Line 1640... | ||
1552 | 1640 | ||
1553 | case R_386_TLS_IE_32: |
1641 | case R_386_TLS_IE_32: |
1554 | case R_386_TLS_IE: |
1642 | case R_386_TLS_IE: |
1555 | case R_386_TLS_GOTIE: |
1643 | case R_386_TLS_GOTIE: |
1556 | if (!info->executable) |
1644 | if (!bfd_link_executable (info)) |
1557 | info->flags |= DF_STATIC_TLS; |
1645 | info->flags |= DF_STATIC_TLS; |
Line 1558... | Line 1646... | ||
1558 | /* Fall through */ |
1646 | /* Fall through */ |
- | 1647 | ||
1559 | 1648 | case R_386_GOT32: |
|
1560 | case R_386_GOT32: |
1649 | case R_386_GOT32X: |
1561 | case R_386_TLS_GD: |
1650 | case R_386_TLS_GD: |
1562 | case R_386_TLS_GOTDESC: |
1651 | case R_386_TLS_GOTDESC: |
1563 | case R_386_TLS_DESC_CALL: |
1652 | case R_386_TLS_DESC_CALL: |
1564 | /* This symbol requires a global offset table entry. */ |
1653 | /* This symbol requires a global offset table entry. */ |
Line 1565... | Line 1654... | ||
1565 | { |
1654 | { |
1566 | int tls_type, old_tls_type; |
1655 | int tls_type, old_tls_type; |
1567 | 1656 | ||
1568 | switch (r_type) |
1657 | switch (r_type) |
- | 1658 | { |
|
- | 1659 | default: |
|
- | 1660 | case R_386_GOT32: |
|
1569 | { |
1661 | case R_386_GOT32X: |
1570 | default: |
1662 | tls_type = GOT_NORMAL; |
1571 | case R_386_GOT32: tls_type = GOT_NORMAL; break; |
1663 | break; |
1572 | case R_386_TLS_GD: tls_type = GOT_TLS_GD; break; |
1664 | case R_386_TLS_GD: tls_type = GOT_TLS_GD; break; |
1573 | case R_386_TLS_GOTDESC: |
1665 | case R_386_TLS_GOTDESC: |
Line 1671... | Line 1763... | ||
1671 | break; |
1763 | break; |
1672 | /* Fall through */ |
1764 | /* Fall through */ |
Line 1673... | Line 1765... | ||
1673 | 1765 | ||
1674 | case R_386_TLS_LE_32: |
1766 | case R_386_TLS_LE_32: |
1675 | case R_386_TLS_LE: |
1767 | case R_386_TLS_LE: |
1676 | if (info->executable) |
1768 | if (bfd_link_executable (info)) |
1677 | break; |
1769 | break; |
1678 | info->flags |= DF_STATIC_TLS; |
1770 | info->flags |= DF_STATIC_TLS; |
Line 1679... | Line 1771... | ||
1679 | /* Fall through */ |
1771 | /* Fall through */ |
1680 | 1772 | ||
1681 | case R_386_32: |
1773 | case R_386_32: |
1682 | case R_386_PC32: |
1774 | case R_386_PC32: |
1683 | if (h != NULL && info->executable) |
1775 | if (h != NULL && bfd_link_executable (info)) |
1684 | { |
1776 | { |
1685 | /* If this reloc is in a read-only section, we might |
1777 | /* If this reloc is in a read-only section, we might |
1686 | need a copy reloc. We can't check reliably at this |
1778 | need a copy reloc. We can't check reliably at this |
Line 1691... | Line 1783... | ||
1691 | h->non_got_ref = 1; |
1783 | h->non_got_ref = 1; |
Line 1692... | Line 1784... | ||
1692 | 1784 | ||
1693 | /* We may need a .plt entry if the function this reloc |
1785 | /* We may need a .plt entry if the function this reloc |
1694 | refers to is in a shared lib. */ |
1786 | refers to is in a shared lib. */ |
1695 | h->plt.refcount += 1; |
1787 | h->plt.refcount += 1; |
- | 1788 | if (r_type == R_386_PC32) |
|
- | 1789 | { |
|
- | 1790 | /* Since something like ".long foo - ." may be used |
|
- | 1791 | as pointer, make sure that PLT is used if foo is |
|
- | 1792 | a function defined in a shared library. */ |
|
1696 | if (r_type != R_386_PC32) |
1793 | if ((sec->flags & SEC_CODE) == 0) |
1697 | h->pointer_equality_needed = 1; |
1794 | h->pointer_equality_needed = 1; |
- | 1795 | } |
|
- | 1796 | else |
|
- | 1797 | { |
|
- | 1798 | h->pointer_equality_needed = 1; |
|
- | 1799 | /* R_386_32 can be resolved at run-time. */ |
|
- | 1800 | if (r_type == R_386_32 |
|
- | 1801 | && (sec->flags & SEC_READONLY) == 0) |
|
- | 1802 | eh->func_pointer_refcount += 1; |
|
- | 1803 | } |
|
Line 1698... | Line 1804... | ||
1698 | } |
1804 | } |
1699 | 1805 | ||
1700 | size_reloc = FALSE; |
1806 | size_reloc = FALSE; |
1701 | do_size: |
1807 | do_size: |
Line 1718... | Line 1824... | ||
1718 | 1824 | ||
1719 | If on the other hand, we are creating an executable, we |
1825 | If on the other hand, we are creating an executable, we |
1720 | may need to keep relocations for symbols satisfied by a |
1826 | may need to keep relocations for symbols satisfied by a |
1721 | dynamic library if we manage to avoid copy relocs for the |
1827 | dynamic library if we manage to avoid copy relocs for the |
1722 | symbol. */ |
1828 | symbol. */ |
1723 | if ((info->shared |
1829 | if ((bfd_link_pic (info) |
1724 | && (sec->flags & SEC_ALLOC) != 0 |
1830 | && (sec->flags & SEC_ALLOC) != 0 |
1725 | && (r_type != R_386_PC32 |
1831 | && (r_type != R_386_PC32 |
1726 | || (h != NULL |
1832 | || (h != NULL |
1727 | && (! SYMBOLIC_BIND (info, h) |
1833 | && (! SYMBOLIC_BIND (info, h) |
1728 | || h->root.type == bfd_link_hash_defweak |
1834 | || h->root.type == bfd_link_hash_defweak |
1729 | || !h->def_regular)))) |
1835 | || !h->def_regular)))) |
1730 | || (ELIMINATE_COPY_RELOCS |
1836 | || (ELIMINATE_COPY_RELOCS |
1731 | && !info->shared |
1837 | && !bfd_link_pic (info) |
1732 | && (sec->flags & SEC_ALLOC) != 0 |
1838 | && (sec->flags & SEC_ALLOC) != 0 |
1733 | && h != NULL |
1839 | && h != NULL |
1734 | && (h->root.type == bfd_link_hash_defweak |
1840 | && (h->root.type == bfd_link_hash_defweak |
1735 | || !h->def_regular))) |
1841 | || !h->def_regular))) |
Line 1754... | Line 1860... | ||
1754 | 1860 | ||
1755 | /* If this is a global symbol, we count the number of |
1861 | /* If this is a global symbol, we count the number of |
1756 | relocations we need for this symbol. */ |
1862 | relocations we need for this symbol. */ |
1757 | if (h != NULL) |
1863 | if (h != NULL) |
1758 | { |
1864 | { |
1759 | head = &((struct elf_i386_link_hash_entry *) h)->dyn_relocs; |
1865 | head = &eh->dyn_relocs; |
1760 | } |
1866 | } |
1761 | else |
1867 | else |
1762 | { |
1868 | { |
1763 | /* Track dynamic relocs needed for local syms too. |
1869 | /* Track dynamic relocs needed for local syms too. |
Line 1818... | Line 1924... | ||
1818 | break; |
1924 | break; |
Line 1819... | Line 1925... | ||
1819 | 1925 | ||
1820 | default: |
1926 | default: |
1821 | break; |
1927 | break; |
- | 1928 | } |
|
- | 1929 | ||
- | 1930 | if (use_plt_got |
|
- | 1931 | && h != NULL |
|
- | 1932 | && h->plt.refcount > 0 |
|
- | 1933 | && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) |
|
- | 1934 | || h->got.refcount > 0) |
|
- | 1935 | && htab->plt_got == NULL) |
|
- | 1936 | { |
|
- | 1937 | /* Create the GOT procedure linkage table. */ |
|
- | 1938 | unsigned int plt_got_align; |
|
- | 1939 | const struct elf_backend_data *bed; |
|
- | 1940 | ||
- | 1941 | bed = get_elf_backend_data (info->output_bfd); |
|
- | 1942 | BFD_ASSERT (sizeof (elf_i386_got_plt_entry) == 8 |
|
- | 1943 | && (sizeof (elf_i386_got_plt_entry) |
|
- | 1944 | == sizeof (elf_i386_pic_got_plt_entry))); |
|
- | 1945 | plt_got_align = 3; |
|
- | 1946 | ||
- | 1947 | if (htab->elf.dynobj == NULL) |
|
- | 1948 | htab->elf.dynobj = abfd; |
|
- | 1949 | htab->plt_got |
|
- | 1950 | = bfd_make_section_anyway_with_flags (htab->elf.dynobj, |
|
- | 1951 | ".plt.got", |
|
- | 1952 | (bed->dynamic_sec_flags |
|
- | 1953 | | SEC_ALLOC |
|
- | 1954 | | SEC_CODE |
|
- | 1955 | | SEC_LOAD |
|
- | 1956 | | SEC_READONLY)); |
|
- | 1957 | if (htab->plt_got == NULL |
|
- | 1958 | || !bfd_set_section_alignment (htab->elf.dynobj, |
|
- | 1959 | htab->plt_got, |
|
- | 1960 | plt_got_align)) |
|
- | 1961 | return FALSE; |
|
- | 1962 | } |
|
- | 1963 | ||
- | 1964 | if ((r_type == R_386_GOT32 || r_type == R_386_GOT32X) |
|
- | 1965 | && (h == NULL || h->type != STT_GNU_IFUNC)) |
|
1822 | } |
1966 | sec->need_convert_load = 1; |
Line 1823... | Line 1967... | ||
1823 | } |
1967 | } |
1824 | 1968 | ||
Line 1858... | Line 2002... | ||
1858 | Elf_Internal_Shdr *symtab_hdr; |
2002 | Elf_Internal_Shdr *symtab_hdr; |
1859 | struct elf_link_hash_entry **sym_hashes; |
2003 | struct elf_link_hash_entry **sym_hashes; |
1860 | bfd_signed_vma *local_got_refcounts; |
2004 | bfd_signed_vma *local_got_refcounts; |
1861 | const Elf_Internal_Rela *rel, *relend; |
2005 | const Elf_Internal_Rela *rel, *relend; |
Line 1862... | Line 2006... | ||
1862 | 2006 | ||
1863 | if (info->relocatable) |
2007 | if (bfd_link_relocatable (info)) |
Line 1864... | Line 2008... | ||
1864 | return TRUE; |
2008 | return TRUE; |
1865 | 2009 | ||
1866 | htab = elf_i386_hash_table (info); |
2010 | htab = elf_i386_hash_table (info); |
Line 1941... | Line 2085... | ||
1941 | case R_386_TLS_DESC_CALL: |
2085 | case R_386_TLS_DESC_CALL: |
1942 | case R_386_TLS_IE_32: |
2086 | case R_386_TLS_IE_32: |
1943 | case R_386_TLS_IE: |
2087 | case R_386_TLS_IE: |
1944 | case R_386_TLS_GOTIE: |
2088 | case R_386_TLS_GOTIE: |
1945 | case R_386_GOT32: |
2089 | case R_386_GOT32: |
- | 2090 | case R_386_GOT32X: |
|
1946 | if (h != NULL) |
2091 | if (h != NULL) |
1947 | { |
2092 | { |
1948 | if (h->got.refcount > 0) |
2093 | if (h->got.refcount > 0) |
1949 | h->got.refcount -= 1; |
2094 | h->got.refcount -= 1; |
1950 | if (h->type == STT_GNU_IFUNC) |
2095 | if (h->type == STT_GNU_IFUNC) |
Line 1961... | Line 2106... | ||
1961 | break; |
2106 | break; |
Line 1962... | Line 2107... | ||
1962 | 2107 | ||
1963 | case R_386_32: |
2108 | case R_386_32: |
1964 | case R_386_PC32: |
2109 | case R_386_PC32: |
1965 | case R_386_SIZE32: |
2110 | case R_386_SIZE32: |
1966 | if (info->shared |
2111 | if (bfd_link_pic (info) |
1967 | && (h == NULL || h->type != STT_GNU_IFUNC)) |
2112 | && (h == NULL || h->type != STT_GNU_IFUNC)) |
1968 | break; |
2113 | break; |
Line 1969... | Line 2114... | ||
1969 | /* Fall through */ |
2114 | /* Fall through */ |
1970 | 2115 | ||
1971 | case R_386_PLT32: |
2116 | case R_386_PLT32: |
1972 | if (h != NULL) |
2117 | if (h != NULL) |
1973 | { |
2118 | { |
- | 2119 | if (h->plt.refcount > 0) |
|
- | 2120 | h->plt.refcount -= 1; |
|
- | 2121 | if (r_type == R_386_32 |
|
- | 2122 | && (sec->flags & SEC_READONLY) == 0) |
|
- | 2123 | { |
|
- | 2124 | struct elf_i386_link_hash_entry *eh |
|
- | 2125 | = (struct elf_i386_link_hash_entry *) h; |
|
- | 2126 | if (eh->func_pointer_refcount > 0) |
|
1974 | if (h->plt.refcount > 0) |
2127 | eh->func_pointer_refcount -= 1; |
1975 | h->plt.refcount -= 1; |
2128 | } |
Line 1976... | Line 2129... | ||
1976 | } |
2129 | } |
1977 | break; |
2130 | break; |
Line 2101... | Line 2254... | ||
2101 | 2254 | ||
2102 | /* If we are creating a shared library, we must presume that the |
2255 | /* If we are creating a shared library, we must presume that the |
2103 | only references to the symbol are via the global offset table. |
2256 | only references to the symbol are via the global offset table. |
2104 | For such cases we need not do anything here; the relocations will |
2257 | For such cases we need not do anything here; the relocations will |
2105 | be handled correctly by relocate_section. */ |
2258 | be handled correctly by relocate_section. */ |
2106 | if (info->shared) |
2259 | if (!bfd_link_executable (info)) |
Line 2107... | Line 2260... | ||
2107 | return TRUE; |
2260 | return TRUE; |
2108 | 2261 | ||
- | 2262 | /* If there are no references to this symbol that do not use the |
|
- | 2263 | GOT nor R_386_GOTOFF relocation, we don't need to generate a copy |
|
2109 | /* If there are no references to this symbol that do not use the |
2264 | reloc. */ |
2110 | GOT, we don't need to generate a copy reloc. */ |
2265 | eh = (struct elf_i386_link_hash_entry *) h; |
Line 2111... | Line 2266... | ||
2111 | if (!h->non_got_ref) |
2266 | if (!h->non_got_ref && !eh->gotoff_ref) |
2112 | return TRUE; |
2267 | return TRUE; |
2113 | 2268 | ||
Line 2120... | Line 2275... | ||
2120 | 2275 | ||
2121 | htab = elf_i386_hash_table (info); |
2276 | htab = elf_i386_hash_table (info); |
2122 | if (htab == NULL) |
2277 | if (htab == NULL) |
Line 2123... | Line 2278... | ||
2123 | return FALSE; |
2278 | return FALSE; |
2124 | 2279 | ||
- | 2280 | /* If there aren't any dynamic relocs in read-only sections nor |
|
2125 | /* If there aren't any dynamic relocs in read-only sections, then |
2281 | R_386_GOTOFF relocation, then we can keep the dynamic relocs and |
2126 | we can keep the dynamic relocs and avoid the copy reloc. This |
2282 | avoid the copy reloc. This doesn't work on VxWorks, where we can |
2127 | doesn't work on VxWorks, where we can not have dynamic relocations |
2283 | not have dynamic relocations (other than copy and jump slot |
- | 2284 | relocations) in an executable. */ |
|
2128 | (other than copy and jump slot relocations) in an executable. */ |
2285 | if (ELIMINATE_COPY_RELOCS |
2129 | if (ELIMINATE_COPY_RELOCS |
2286 | && !eh->gotoff_ref |
2130 | && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks) |
- | |
2131 | { |
2287 | && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks) |
2132 | eh = (struct elf_i386_link_hash_entry *) h; |
2288 | { |
2133 | for (p = eh->dyn_relocs; p != NULL; p = p->next) |
2289 | for (p = eh->dyn_relocs; p != NULL; p = p->next) |
2134 | { |
2290 | { |
2135 | s = p->sec->output_section; |
2291 | s = p->sec->output_section; |
Line 2163... | Line 2319... | ||
2163 | h->needs_copy = 1; |
2319 | h->needs_copy = 1; |
2164 | } |
2320 | } |
Line 2165... | Line 2321... | ||
2165 | 2321 | ||
Line 2166... | Line 2322... | ||
2166 | s = htab->sdynbss; |
2322 | s = htab->sdynbss; |
2167 | 2323 | ||
Line 2168... | Line 2324... | ||
2168 | return _bfd_elf_adjust_dynamic_copy (h, s); |
2324 | return _bfd_elf_adjust_dynamic_copy (info, h, s); |
2169 | } |
2325 | } |
Line 2190... | Line 2346... | ||
2190 | if (htab == NULL) |
2346 | if (htab == NULL) |
2191 | return FALSE; |
2347 | return FALSE; |
Line 2192... | Line 2348... | ||
2192 | 2348 | ||
Line -... | Line 2349... | ||
- | 2349 | plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd); |
|
- | 2350 | ||
- | 2351 | /* Clear the reference count of function pointer relocations if |
|
- | 2352 | symbol isn't a normal function. */ |
|
- | 2353 | if (h->type != STT_FUNC) |
|
- | 2354 | eh->func_pointer_refcount = 0; |
|
- | 2355 | ||
- | 2356 | /* We can't use the GOT PLT if pointer equality is needed since |
|
- | 2357 | finish_dynamic_symbol won't clear symbol value and the dynamic |
|
- | 2358 | linker won't update the GOT slot. We will get into an infinite |
|
- | 2359 | loop at run-time. */ |
|
- | 2360 | if (htab->plt_got != NULL |
|
- | 2361 | && h->type != STT_GNU_IFUNC |
|
- | 2362 | && !h->pointer_equality_needed |
|
- | 2363 | && h->plt.refcount > 0 |
|
- | 2364 | && h->got.refcount > 0) |
|
- | 2365 | { |
|
- | 2366 | /* Don't use the regular PLT if there are both GOT and GOTPLT |
|
- | 2367 | reloctions. */ |
|
- | 2368 | h->plt.offset = (bfd_vma) -1; |
|
- | 2369 | ||
- | 2370 | /* Use the GOT PLT. */ |
|
- | 2371 | eh->plt_got.refcount = 1; |
|
2193 | plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd); |
2372 | } |
2194 | 2373 | ||
2195 | /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it |
2374 | /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it |
2196 | here if it is defined and referenced in a non-shared object. */ |
2375 | here if it is defined and referenced in a non-shared object. */ |
2197 | if (h->type == STT_GNU_IFUNC |
2376 | if (h->type == STT_GNU_IFUNC |
2198 | && h->def_regular) |
2377 | && h->def_regular) |
2199 | return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs, |
2378 | return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs, |
- | 2379 | plt_entry_size, |
|
- | 2380 | plt_entry_size, 4); |
|
2200 | plt_entry_size, |
2381 | /* Don't create the PLT entry if there are only function pointer |
- | 2382 | relocations which can be resolved at run-time. */ |
|
2201 | plt_entry_size, 4); |
2383 | else if (htab->elf.dynamic_sections_created |
2202 | else if (htab->elf.dynamic_sections_created |
2384 | && (h->plt.refcount > eh->func_pointer_refcount |
- | 2385 | || eh->plt_got.refcount > 0)) |
|
- | 2386 | { |
|
- | 2387 | bfd_boolean use_plt_got; |
|
- | 2388 | ||
- | 2389 | /* Clear the reference count of function pointer relocations |
|
- | 2390 | if PLT is used. */ |
|
- | 2391 | eh->func_pointer_refcount = 0; |
|
- | 2392 | ||
- | 2393 | if ((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) |
|
- | 2394 | { |
|
- | 2395 | /* Don't use the regular PLT for DF_BIND_NOW. */ |
|
- | 2396 | h->plt.offset = (bfd_vma) -1; |
|
- | 2397 | ||
- | 2398 | /* Use the GOT PLT. */ |
|
- | 2399 | h->got.refcount = 1; |
|
- | 2400 | eh->plt_got.refcount = 1; |
|
- | 2401 | } |
|
- | 2402 | ||
2203 | && h->plt.refcount > 0) |
2403 | use_plt_got = eh->plt_got.refcount > 0; |
2204 | { |
2404 | |
2205 | /* Make sure this symbol is output as a dynamic symbol. |
2405 | /* Make sure this symbol is output as a dynamic symbol. |
2206 | Undefined weak syms won't yet be marked as dynamic. */ |
2406 | Undefined weak syms won't yet be marked as dynamic. */ |
2207 | if (h->dynindx == -1 |
2407 | if (h->dynindx == -1 |
2208 | && !h->forced_local) |
2408 | && !h->forced_local) |
2209 | { |
2409 | { |
2210 | if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
2410 | if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
Line 2211... | Line 2411... | ||
2211 | return FALSE; |
2411 | return FALSE; |
2212 | } |
2412 | } |
2213 | 2413 | ||
2214 | if (info->shared |
2414 | if (bfd_link_pic (info) |
- | 2415 | || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) |
|
Line 2215... | Line 2416... | ||
2215 | || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) |
2416 | { |
- | 2417 | asection *s = htab->elf.splt; |
|
2216 | { |
2418 | asection *got_s = htab->plt_got; |
2217 | asection *s = htab->elf.splt; |
2419 | |
2218 | 2420 | /* If this is the first .plt entry, make room for the special |
|
Line -... | Line 2421... | ||
- | 2421 | first entry. The .plt section is used by prelink to undo |
|
- | 2422 | prelinking for dynamic relocations. */ |
|
- | 2423 | if (s->size == 0) |
|
2219 | /* If this is the first .plt entry, make room for the special |
2424 | s->size = plt_entry_size; |
Line 2220... | Line 2425... | ||
2220 | first entry. */ |
2425 | |
2221 | if (s->size == 0) |
2426 | if (use_plt_got) |
2222 | s->size += plt_entry_size; |
2427 | eh->plt_got.offset = got_s->size; |
2223 | 2428 | else |
|
2224 | h->plt.offset = s->size; |
2429 | h->plt.offset = s->size; |
2225 | 2430 | ||
2226 | /* If this symbol is not defined in a regular file, and we are |
2431 | /* If this symbol is not defined in a regular file, and we are |
2227 | not generating a shared library, then set the symbol to this |
2432 | not generating a shared library, then set the symbol to this |
- | 2433 | location in the .plt. This is required to make function |
|
- | 2434 | pointers compare as equal between the normal executable and |
|
- | 2435 | the shared library. */ |
|
- | 2436 | if (! bfd_link_pic (info) |
|
- | 2437 | && !h->def_regular) |
|
- | 2438 | { |
|
- | 2439 | if (use_plt_got) |
|
- | 2440 | { |
|
- | 2441 | /* We need to make a call to the entry of the GOT PLT |
|
2228 | location in the .plt. This is required to make function |
2442 | instead of regular PLT entry. */ |
2229 | pointers compare as equal between the normal executable and |
2443 | h->root.u.def.section = got_s; |
2230 | the shared library. */ |
2444 | h->root.u.def.value = eh->plt_got.offset; |
- | 2445 | } |
|
Line 2231... | Line 2446... | ||
2231 | if (! info->shared |
2446 | else |
- | 2447 | { |
|
- | 2448 | h->root.u.def.section = s; |
|
- | 2449 | h->root.u.def.value = h->plt.offset; |
|
- | 2450 | } |
|
2232 | && !h->def_regular) |
2451 | } |
Line 2233... | Line 2452... | ||
2233 | { |
2452 | |
2234 | h->root.u.def.section = s; |
2453 | /* Make room for this entry. */ |
- | 2454 | if (use_plt_got) |
|
2235 | h->root.u.def.value = h->plt.offset; |
2455 | got_s->size += sizeof (elf_i386_got_plt_entry); |
Line 2236... | Line 2456... | ||
2236 | } |
2456 | else |
2237 | 2457 | { |
|
2238 | /* Make room for this entry. */ |
2458 | s->size += plt_entry_size; |
- | 2459 | ||
Line 2239... | Line 2460... | ||
2239 | s->size += plt_entry_size; |
2460 | /* We also need to make an entry in the .got.plt section, |
2240 | 2461 | which will be placed in the .got section by the linker |
|
2241 | /* We also need to make an entry in the .got.plt section, which |
2462 | script. */ |
2242 | will be placed in the .got section by the linker script. */ |
2463 | htab->elf.sgotplt->size += 4; |
2243 | htab->elf.sgotplt->size += 4; |
2464 | |
2244 | 2465 | /* We also need to make an entry in the .rel.plt section. */ |
|
Line 2282... | Line 2503... | ||
2282 | eh->tlsdesc_got = (bfd_vma) -1; |
2503 | eh->tlsdesc_got = (bfd_vma) -1; |
Line 2283... | Line 2504... | ||
2283 | 2504 | ||
2284 | /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary, |
2505 | /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary, |
2285 | make it a R_386_TLS_LE_32 requiring no TLS entry. */ |
2506 | make it a R_386_TLS_LE_32 requiring no TLS entry. */ |
2286 | if (h->got.refcount > 0 |
2507 | if (h->got.refcount > 0 |
2287 | && info->executable |
2508 | && bfd_link_executable (info) |
2288 | && h->dynindx == -1 |
2509 | && h->dynindx == -1 |
2289 | && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE)) |
2510 | && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE)) |
2290 | h->got.offset = (bfd_vma) -1; |
2511 | h->got.offset = (bfd_vma) -1; |
2291 | else if (h->got.refcount > 0) |
2512 | else if (h->got.refcount > 0) |
Line 2334... | Line 2555... | ||
2334 | else if (GOT_TLS_GD_P (tls_type)) |
2555 | else if (GOT_TLS_GD_P (tls_type)) |
2335 | htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel); |
2556 | htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel); |
2336 | else if (! GOT_TLS_GDESC_P (tls_type) |
2557 | else if (! GOT_TLS_GDESC_P (tls_type) |
2337 | && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
2558 | && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
2338 | || h->root.type != bfd_link_hash_undefweak) |
2559 | || h->root.type != bfd_link_hash_undefweak) |
2339 | && (info->shared |
2560 | && (bfd_link_pic (info) |
2340 | || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) |
2561 | || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) |
2341 | htab->elf.srelgot->size += sizeof (Elf32_External_Rel); |
2562 | htab->elf.srelgot->size += sizeof (Elf32_External_Rel); |
2342 | if (GOT_TLS_GDESC_P (tls_type)) |
2563 | if (GOT_TLS_GDESC_P (tls_type)) |
2343 | htab->elf.srelplt->size += sizeof (Elf32_External_Rel); |
2564 | htab->elf.srelplt->size += sizeof (Elf32_External_Rel); |
2344 | } |
2565 | } |
Line 2352... | Line 2573... | ||
2352 | dynamic pc-relative relocs against symbols which turn out to be |
2573 | dynamic pc-relative relocs against symbols which turn out to be |
2353 | defined in regular objects. For the normal shared case, discard |
2574 | defined in regular objects. For the normal shared case, discard |
2354 | space for pc-relative relocs that have become local due to symbol |
2575 | space for pc-relative relocs that have become local due to symbol |
2355 | visibility changes. */ |
2576 | visibility changes. */ |
Line 2356... | Line 2577... | ||
2356 | 2577 | ||
2357 | if (info->shared) |
2578 | if (bfd_link_pic (info)) |
2358 | { |
2579 | { |
2359 | /* The only reloc that uses pc_count is R_386_PC32, which will |
2580 | /* The only reloc that uses pc_count is R_386_PC32, which will |
2360 | appear on a call or on something like ".long foo - .". We |
2581 | appear on a call or on something like ".long foo - .". We |
2361 | want calls to protected symbols to resolve directly to the |
2582 | want calls to protected symbols to resolve directly to the |
Line 2409... | Line 2630... | ||
2409 | } |
2630 | } |
2410 | else if (ELIMINATE_COPY_RELOCS) |
2631 | else if (ELIMINATE_COPY_RELOCS) |
2411 | { |
2632 | { |
2412 | /* For the non-shared case, discard space for relocs against |
2633 | /* For the non-shared case, discard space for relocs against |
2413 | symbols which turn out to need copy relocs or are not |
2634 | symbols which turn out to need copy relocs or are not |
- | 2635 | dynamic. Keep dynamic relocations for run-time function |
|
2414 | dynamic. */ |
2636 | pointer initialization. */ |
Line 2415... | Line 2637... | ||
2415 | 2637 | ||
2416 | if (!h->non_got_ref |
2638 | if ((!h->non_got_ref || eh->func_pointer_refcount > 0) |
2417 | && ((h->def_dynamic |
2639 | && ((h->def_dynamic |
2418 | && !h->def_regular) |
2640 | && !h->def_regular) |
2419 | || (htab->elf.dynamic_sections_created |
2641 | || (htab->elf.dynamic_sections_created |
2420 | && (h->root.type == bfd_link_hash_undefweak |
2642 | && (h->root.type == bfd_link_hash_undefweak |
Line 2434... | Line 2656... | ||
2434 | if (h->dynindx != -1) |
2656 | if (h->dynindx != -1) |
2435 | goto keep; |
2657 | goto keep; |
2436 | } |
2658 | } |
Line 2437... | Line 2659... | ||
2437 | 2659 | ||
- | 2660 | eh->dyn_relocs = NULL; |
|
Line 2438... | Line 2661... | ||
2438 | eh->dyn_relocs = NULL; |
2661 | eh->func_pointer_refcount = 0; |
2439 | 2662 | ||
Line 2440... | Line 2663... | ||
2440 | keep: ; |
2663 | keep: ; |
Line 2494... | Line 2717... | ||
2494 | { |
2717 | { |
2495 | struct bfd_link_info *info = (struct bfd_link_info *) inf; |
2718 | struct bfd_link_info *info = (struct bfd_link_info *) inf; |
Line 2496... | Line 2719... | ||
2496 | 2719 | ||
Line 2497... | Line 2720... | ||
2497 | info->flags |= DF_TEXTREL; |
2720 | info->flags |= DF_TEXTREL; |
- | 2721 | ||
2498 | 2722 | if ((info->warn_shared_textrel && bfd_link_pic (info)) |
|
2499 | if (info->warn_shared_textrel && info->shared) |
2723 | || info->error_textrel) |
2500 | info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"), |
2724 | info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'\n"), |
Line 2501... | Line 2725... | ||
2501 | p->sec->owner, h->root.root.string, |
2725 | p->sec->owner, h->root.root.string, |
2502 | p->sec); |
2726 | p->sec); |
2503 | 2727 | ||
2504 | /* Not an error, just cut short the traversal. */ |
2728 | /* Not an error, just cut short the traversal. */ |
2505 | return FALSE; |
2729 | return FALSE; |
2506 | } |
2730 | } |
Line 2507... | Line 2731... | ||
2507 | } |
2731 | } |
2508 | return TRUE; |
2732 | return TRUE; |
2509 | } |
2733 | } |
2510 | 2734 | ||
- | 2735 | /* With the local symbol, foo, we convert |
|
- | 2736 | mov foo@GOT[(%reg1)], %reg2 |
|
- | 2737 | to |
|
2511 | /* Convert |
2738 | lea foo[@GOTOFF(%reg1)], %reg2 |
- | 2739 | and convert |
|
- | 2740 | call/jmp *foo@GOT[(%reg)] |
|
- | 2741 | to |
|
- | 2742 | nop call foo/jmp foo nop |
|
- | 2743 | When PIC is false, convert |
|
- | 2744 | test %reg1, foo@GOT[(%reg2)] |
|
- | 2745 | to |
|
- | 2746 | test $foo, %reg1 |
|
- | 2747 | and convert |
|
- | 2748 | binop foo@GOT[(%reg1)], %reg2 |
|
Line 2512... | Line 2749... | ||
2512 | mov foo@GOT(%reg), %reg |
2749 | to |
2513 | to |
2750 | binop $foo, %reg2 |
2514 | lea foo@GOTOFF(%reg), %reg |
2751 | where binop is one of adc, add, and, cmp, or, sbb, sub, xor |
2515 | with the local symbol, foo. */ |
2752 | instructions. */ |
2516 | 2753 | ||
2517 | static bfd_boolean |
2754 | static bfd_boolean |
2518 | elf_i386_convert_mov_to_lea (bfd *abfd, asection *sec, |
2755 | elf_i386_convert_load (bfd *abfd, asection *sec, |
Line 2529... | Line 2766... | ||
2529 | 2766 | ||
2530 | /* Don't even try to convert non-ELF outputs. */ |
2767 | /* Don't even try to convert non-ELF outputs. */ |
2531 | if (!is_elf_hash_table (link_info->hash)) |
2768 | if (!is_elf_hash_table (link_info->hash)) |
Line 2532... | Line 2769... | ||
2532 | return FALSE; |
2769 | return FALSE; |
2533 | 2770 | ||
2534 | /* Nothing to do if there are no codes, no relocations or no output. */ |
2771 | /* Nothing to do if there is no need or no output. */ |
2535 | if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC) |
2772 | if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC) |
2536 | || sec->reloc_count == 0 |
2773 | || sec->need_convert_load == 0 |
Line 2537... | Line 2774... | ||
2537 | || discarded_section (sec)) |
2774 | || bfd_is_abs_section (sec->output_section)) |
Line 2538... | Line 2775... | ||
2538 | return TRUE; |
2775 | return TRUE; |
Line 2565... | Line 2802... | ||
2565 | { |
2802 | { |
2566 | unsigned int r_type = ELF32_R_TYPE (irel->r_info); |
2803 | unsigned int r_type = ELF32_R_TYPE (irel->r_info); |
2567 | unsigned int r_symndx = ELF32_R_SYM (irel->r_info); |
2804 | unsigned int r_symndx = ELF32_R_SYM (irel->r_info); |
2568 | unsigned int indx; |
2805 | unsigned int indx; |
2569 | struct elf_link_hash_entry *h; |
2806 | struct elf_link_hash_entry *h; |
- | 2807 | unsigned int opcode; |
|
- | 2808 | unsigned int modrm; |
|
- | 2809 | bfd_vma roff; |
|
- | 2810 | bfd_boolean baseless; |
|
- | 2811 | Elf_Internal_Sym *isym; |
|
- | 2812 | unsigned int addend; |
|
- | 2813 | unsigned int nop; |
|
- | 2814 | bfd_vma nop_offset; |
|
Line 2570... | Line 2815... | ||
2570 | 2815 | ||
2571 | if (r_type != R_386_GOT32) |
2816 | if (r_type != R_386_GOT32 && r_type != R_386_GOT32X) |
Line -... | Line 2817... | ||
- | 2817 | continue; |
|
- | 2818 | ||
- | 2819 | roff = irel->r_offset; |
|
- | 2820 | if (roff < 2) |
|
- | 2821 | continue; |
|
- | 2822 | ||
- | 2823 | /* Addend for R_386_GOT32 and R_386_GOT32X relocations must be 0. */ |
|
- | 2824 | addend = bfd_get_32 (abfd, contents + roff); |
|
- | 2825 | if (addend != 0) |
|
- | 2826 | continue; |
|
- | 2827 | ||
- | 2828 | modrm = bfd_get_8 (abfd, contents + roff - 1); |
|
- | 2829 | baseless = (modrm & 0xc7) == 0x5; |
|
- | 2830 | ||
- | 2831 | if (r_type == R_386_GOT32X |
|
- | 2832 | && baseless |
|
- | 2833 | && bfd_link_pic (link_info)) |
|
- | 2834 | { |
|
2572 | continue; |
2835 | /* For PIC, disallow R_386_GOT32X without a base register |
- | 2836 | since we don't know what the GOT base is. Allow |
|
- | 2837 | R_386_GOT32 for existing object files. */ |
|
2573 | 2838 | const char *name; |
|
2574 | /* Get the symbol referred to by the reloc. */ |
2839 | |
- | 2840 | if (r_symndx < symtab_hdr->sh_info) |
|
- | 2841 | { |
|
- | 2842 | isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, |
|
- | 2843 | r_symndx); |
|
- | 2844 | name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); |
|
- | 2845 | } |
|
- | 2846 | else |
|
- | 2847 | { |
|
- | 2848 | indx = r_symndx - symtab_hdr->sh_info; |
|
- | 2849 | h = elf_sym_hashes (abfd)[indx]; |
|
- | 2850 | BFD_ASSERT (h != NULL); |
|
- | 2851 | name = h->root.root.string; |
|
2575 | if (r_symndx < symtab_hdr->sh_info) |
2852 | } |
- | 2853 | ||
- | 2854 | (*_bfd_error_handler) |
|
- | 2855 | (_("%B: direct GOT relocation R_386_GOT32X against `%s' without base register can not be used when making a shared object"), |
|
- | 2856 | abfd, name); |
|
Line -... | Line 2857... | ||
- | 2857 | goto error_return; |
|
- | 2858 | } |
|
- | 2859 | ||
- | 2860 | opcode = bfd_get_8 (abfd, contents + roff - 2); |
|
- | 2861 | ||
- | 2862 | /* It is OK to convert mov to lea. */ |
|
- | 2863 | if (opcode != 0x8b) |
|
- | 2864 | { |
|
- | 2865 | /* Only convert R_386_GOT32X relocation for call, jmp or |
|
- | 2866 | one of adc, add, and, cmp, or, sbb, sub, test, xor |
|
- | 2867 | instructions. */ |
|
- | 2868 | if (r_type != R_386_GOT32X) |
|
- | 2869 | continue; |
|
- | 2870 | ||
- | 2871 | /* It is OK to convert indirect branch to direct branch. It |
|
- | 2872 | is OK to convert adc, add, and, cmp, or, sbb, sub, test, |
|
- | 2873 | xor only when PIC is false. */ |
|
- | 2874 | if (opcode != 0xff && bfd_link_pic (link_info)) |
|
- | 2875 | continue; |
|
- | 2876 | } |
|
- | 2877 | ||
- | 2878 | /* Try to convert R_386_GOT32 and R_386_GOT32X. Get the symbol |
|
2576 | { |
2879 | referred to by the reloc. */ |
2577 | Elf_Internal_Sym *isym; |
2880 | if (r_symndx < symtab_hdr->sh_info) |
Line 2578... | Line 2881... | ||
2578 | 2881 | { |
|
2579 | isym = bfd_sym_from_r_symndx (&htab->sym_cache, |
2882 | isym = bfd_sym_from_r_symndx (&htab->sym_cache, |
2580 | abfd, r_symndx); |
- | |
2581 | - | ||
2582 | /* STT_GNU_IFUNC must keep R_386_GOT32 relocation. */ |
- | |
2583 | if (ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC |
- | |
2584 | && bfd_get_8 (input_bfd, |
- | |
2585 | contents + irel->r_offset - 2) == 0x8b) |
- | |
2586 | { |
- | |
2587 | bfd_put_8 (output_bfd, 0x8d, |
- | |
2588 | contents + irel->r_offset - 2); |
- | |
2589 | irel->r_info = ELF32_R_INFO (r_symndx, R_386_GOTOFF); |
- | |
2590 | if (local_got_refcounts != NULL |
- | |
2591 | && local_got_refcounts[r_symndx] > 0) |
- | |
2592 | local_got_refcounts[r_symndx] -= 1; |
2883 | abfd, r_symndx); |
- | 2884 | ||
- | 2885 | /* STT_GNU_IFUNC must keep GOT32 relocations. */ |
|
- | 2886 | if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) |
|
- | 2887 | continue; |
|
- | 2888 | ||
- | 2889 | h = NULL; |
|
- | 2890 | if (opcode == 0x0ff) |
|
- | 2891 | /* Convert "call/jmp *foo@GOT[(%reg)]". */ |
|
- | 2892 | goto convert_branch; |
|
- | 2893 | else |
|
2593 | changed_contents = TRUE; |
2894 | /* Convert "mov foo@GOT[(%reg1)], %reg2", |
Line 2594... | Line 2895... | ||
2594 | changed_relocs = TRUE; |
2895 | "test %reg1, foo@GOT(%reg2)" and |
2595 | } |
2896 | "binop foo@GOT[(%reg1)], %reg2". */ |
2596 | continue; |
2897 | goto convert_load; |
Line 2597... | Line 2898... | ||
2597 | } |
2898 | } |
2598 | 2899 | ||
2599 | indx = r_symndx - symtab_hdr->sh_info; |
2900 | indx = r_symndx - symtab_hdr->sh_info; |
Line 2600... | Line 2901... | ||
2600 | h = elf_sym_hashes (abfd)[indx]; |
2901 | h = elf_sym_hashes (abfd)[indx]; |
2601 | BFD_ASSERT (h != NULL); |
2902 | BFD_ASSERT (h != NULL); |
- | 2903 | ||
- | 2904 | while (h->root.type == bfd_link_hash_indirect |
|
2602 | 2905 | || h->root.type == bfd_link_hash_warning) |
|
- | 2906 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
|
- | 2907 | ||
2603 | while (h->root.type == bfd_link_hash_indirect |
2908 | /* STT_GNU_IFUNC must keep GOT32 relocations. */ |
2604 | || h->root.type == bfd_link_hash_warning) |
2909 | if (h->type == STT_GNU_IFUNC) |
2605 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
2910 | continue; |
- | 2911 | ||
- | 2912 | if (opcode == 0xff) |
|
- | 2913 | { |
|
- | 2914 | /* We have "call/jmp *foo@GOT[(%reg)]". */ |
|
- | 2915 | if ((h->root.type == bfd_link_hash_defined |
|
- | 2916 | || h->root.type == bfd_link_hash_defweak) |
|
- | 2917 | && SYMBOL_REFERENCES_LOCAL (link_info, h)) |
|
- | 2918 | { |
|
- | 2919 | /* The function is locally defined. */ |
|
- | 2920 | convert_branch: |
|
- | 2921 | /* Convert R_386_GOT32X to R_386_PC32. */ |
|
- | 2922 | if (modrm == 0x15 || (modrm & 0xf8) == 0x90) |
|
2606 | 2923 | { |
|
2607 | /* STT_GNU_IFUNC must keep R_386_GOT32 relocation. We also avoid |
2924 | /* Convert to "nop call foo". ADDR_PREFIX_OPCODE |
- | 2925 | is a nop prefix. */ |
|
- | 2926 | modrm = 0xe8; |
|
- | 2927 | nop = link_info->call_nop_byte; |
|
- | 2928 | if (link_info->call_nop_as_suffix) |
|
- | 2929 | { |
|
2608 | optimizing _DYNAMIC since ld.so may use its link-time address. */ |
2930 | nop_offset = roff + 3; |
- | 2931 | irel->r_offset -= 1; |
|
- | 2932 | } |
|
- | 2933 | else |
|
2609 | if (h->def_regular |
2934 | nop_offset = roff - 2; |
- | 2935 | } |
|
- | 2936 | else |
|
- | 2937 | { |
|
- | 2938 | /* Convert to "jmp foo nop". */ |
|
2610 | && h->type != STT_GNU_IFUNC |
2939 | modrm = 0xe9; |
- | 2940 | nop = NOP_OPCODE; |
|
- | 2941 | nop_offset = roff + 3; |
|
- | 2942 | irel->r_offset -= 1; |
|
2611 | && h != htab->elf.hdynamic |
2943 | } |
- | 2944 | ||
- | 2945 | bfd_put_8 (abfd, nop, contents + nop_offset); |
|
- | 2946 | bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1); |
|
2612 | && SYMBOL_REFERENCES_LOCAL (link_info, h) |
2947 | /* When converting to PC-relative relocation, we |
2613 | && bfd_get_8 (input_bfd, |
2948 | need to adjust addend by -4. */ |
- | 2949 | bfd_put_32 (abfd, -4, contents + irel->r_offset); |
|
- | 2950 | irel->r_info = ELF32_R_INFO (r_symndx, R_386_PC32); |
|
- | 2951 | ||
- | 2952 | if (h) |
|
- | 2953 | { |
|
- | 2954 | if (h->got.refcount > 0) |
|
- | 2955 | h->got.refcount -= 1; |
|
- | 2956 | } |
|
2614 | contents + irel->r_offset - 2) == 0x8b) |
2957 | else |
2615 | { |
2958 | { |
2616 | bfd_put_8 (output_bfd, 0x8d, |
2959 | if (local_got_refcounts != NULL |
2617 | contents + irel->r_offset - 2); |
2960 | && local_got_refcounts[r_symndx] > 0) |
- | 2961 | local_got_refcounts[r_symndx] -= 1; |
|
- | 2962 | } |
|
- | 2963 | ||
- | 2964 | changed_contents = TRUE; |
|
- | 2965 | changed_relocs = TRUE; |
|
- | 2966 | } |
|
- | 2967 | } |
|
- | 2968 | else |
|
- | 2969 | { |
|
- | 2970 | /* We have "mov foo@GOT[(%re1g)], %reg2", |
|
- | 2971 | "test %reg1, foo@GOT(%reg2)" and |
|
- | 2972 | "binop foo@GOT[(%reg1)], %reg2". |
|
- | 2973 | ||
- | 2974 | Avoid optimizing _DYNAMIC since ld.so may use its |
|
- | 2975 | link-time address. */ |
|
- | 2976 | if (h == htab->elf.hdynamic) |
|
- | 2977 | continue; |
|
- | 2978 | ||
- | 2979 | /* def_regular is set by an assignment in a linker script in |
|
- | 2980 | bfd_elf_record_link_assignment. */ |
|
- | 2981 | if ((h->def_regular |
|
- | 2982 | || h->root.type == bfd_link_hash_defined |
|
- | 2983 | || h->root.type == bfd_link_hash_defweak) |
|
- | 2984 | && SYMBOL_REFERENCES_LOCAL (link_info, h)) |
|
- | 2985 | { |
|
- | 2986 | convert_load: |
|
- | 2987 | if (opcode == 0x8b) |
|
- | 2988 | { |
|
- | 2989 | /* Convert "mov foo@GOT(%reg1), %reg2" to |
|
- | 2990 | "lea foo@GOTOFF(%reg1), %reg2". */ |
|
- | 2991 | if (r_type == R_386_GOT32X |
|
- | 2992 | && (baseless || !bfd_link_pic (link_info))) |
|
- | 2993 | { |
|
- | 2994 | r_type = R_386_32; |
|
- | 2995 | /* For R_386_32, convert |
|
- | 2996 | "lea foo@GOTOFF(%reg1), %reg2" to |
|
- | 2997 | "lea foo@GOT, %reg2". */ |
|
- | 2998 | if (!baseless) |
|
- | 2999 | { |
|
- | 3000 | modrm = 0x5 | (modrm & 0x38); |
|
- | 3001 | bfd_put_8 (abfd, modrm, contents + roff - 1); |
|
- | 3002 | } |
|
- | 3003 | } |
|
- | 3004 | else |
|
- | 3005 | r_type = R_386_GOTOFF; |
|
- | 3006 | opcode = 0x8d; |
|
- | 3007 | } |
|
- | 3008 | else |
|
- | 3009 | { |
|
- | 3010 | if (opcode == 0x85) |
|
- | 3011 | { |
|
- | 3012 | /* Convert "test %reg1, foo@GOT(%reg2)" to |
|
- | 3013 | "test $foo, %reg1". */ |
|
- | 3014 | modrm = 0xc0 | (modrm & 0x38) >> 3; |
|
- | 3015 | opcode = 0xf7; |
|
- | 3016 | } |
|
- | 3017 | else |
|
- | 3018 | { |
|
- | 3019 | /* Convert "binop foo@GOT(%reg1), %reg2" to |
|
- | 3020 | "binop $foo, %reg2". */ |
|
- | 3021 | modrm = (0xc0 |
|
- | 3022 | | (modrm & 0x38) >> 3 |
|
- | 3023 | | (opcode & 0x3c)); |
|
- | 3024 | opcode = 0x81; |
|
- | 3025 | } |
|
- | 3026 | bfd_put_8 (abfd, modrm, contents + roff - 1); |
|
- | 3027 | r_type = R_386_32; |
|
- | 3028 | } |
|
- | 3029 | ||
- | 3030 | bfd_put_8 (abfd, opcode, contents + roff - 2); |
|
- | 3031 | irel->r_info = ELF32_R_INFO (r_symndx, r_type); |
|
- | 3032 | ||
- | 3033 | if (h) |
|
- | 3034 | { |
|
- | 3035 | if (h->got.refcount > 0) |
|
- | 3036 | h->got.refcount -= 1; |
|
- | 3037 | } |
|
- | 3038 | else |
|
- | 3039 | { |
|
- | 3040 | if (local_got_refcounts != NULL |
|
- | 3041 | && local_got_refcounts[r_symndx] > 0) |
|
- | 3042 | local_got_refcounts[r_symndx] -= 1; |
|
Line 2618... | Line 3043... | ||
2618 | irel->r_info = ELF32_R_INFO (r_symndx, R_386_GOTOFF); |
3043 | } |
2619 | if (h->got.refcount > 0) |
3044 | |
2620 | h->got.refcount -= 1; |
3045 | changed_contents = TRUE; |
2621 | changed_contents = TRUE; |
3046 | changed_relocs = TRUE; |
Line 2674... | Line 3099... | ||
2674 | abort (); |
3099 | abort (); |
Line 2675... | Line 3100... | ||
2675 | 3100 | ||
2676 | if (htab->elf.dynamic_sections_created) |
3101 | if (htab->elf.dynamic_sections_created) |
2677 | { |
3102 | { |
2678 | /* Set the contents of the .interp section to the interpreter. */ |
3103 | /* Set the contents of the .interp section to the interpreter. */ |
2679 | if (info->executable) |
3104 | if (bfd_link_executable (info) && !info->nointerp) |
2680 | { |
3105 | { |
2681 | s = bfd_get_linker_section (dynobj, ".interp"); |
3106 | s = bfd_get_linker_section (dynobj, ".interp"); |
2682 | if (s == NULL) |
3107 | if (s == NULL) |
2683 | abort (); |
3108 | abort (); |
Line 2686... | Line 3111... | ||
2686 | } |
3111 | } |
2687 | } |
3112 | } |
Line 2688... | Line 3113... | ||
2688 | 3113 | ||
2689 | /* Set up .got offsets for local syms, and space for local dynamic |
3114 | /* Set up .got offsets for local syms, and space for local dynamic |
2690 | relocs. */ |
3115 | relocs. */ |
2691 | for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) |
3116 | for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) |
2692 | { |
3117 | { |
2693 | bfd_signed_vma *local_got; |
3118 | bfd_signed_vma *local_got; |
2694 | bfd_signed_vma *end_local_got; |
3119 | bfd_signed_vma *end_local_got; |
2695 | char *local_tls_type; |
3120 | char *local_tls_type; |
Line 2703... | Line 3128... | ||
2703 | 3128 | ||
2704 | for (s = ibfd->sections; s != NULL; s = s->next) |
3129 | for (s = ibfd->sections; s != NULL; s = s->next) |
2705 | { |
3130 | { |
Line 2706... | Line 3131... | ||
2706 | struct elf_dyn_relocs *p; |
3131 | struct elf_dyn_relocs *p; |
2707 | 3132 | ||
Line 2708... | Line 3133... | ||
2708 | if (!elf_i386_convert_mov_to_lea (ibfd, s, info)) |
3133 | if (!elf_i386_convert_load (ibfd, s, info)) |
2709 | return FALSE; |
3134 | return FALSE; |
2710 | 3135 | ||
Line 2734... | Line 3159... | ||
2734 | srel->size += p->count * sizeof (Elf32_External_Rel); |
3159 | srel->size += p->count * sizeof (Elf32_External_Rel); |
2735 | if ((p->sec->output_section->flags & SEC_READONLY) != 0 |
3160 | if ((p->sec->output_section->flags & SEC_READONLY) != 0 |
2736 | && (info->flags & DF_TEXTREL) == 0) |
3161 | && (info->flags & DF_TEXTREL) == 0) |
2737 | { |
3162 | { |
2738 | info->flags |= DF_TEXTREL; |
3163 | info->flags |= DF_TEXTREL; |
2739 | if (info->warn_shared_textrel && info->shared) |
3164 | if ((info->warn_shared_textrel && bfd_link_pic (info)) |
- | 3165 | || info->error_textrel) |
|
2740 | info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"), |
3166 | info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'\n"), |
2741 | p->sec->owner, p->sec); |
3167 | p->sec->owner, p->sec); |
2742 | } |
3168 | } |
2743 | } |
3169 | } |
2744 | } |
3170 | } |
2745 | } |
3171 | } |
Line 2775... | Line 3201... | ||
2775 | s->size += 4; |
3201 | s->size += 4; |
2776 | if (GOT_TLS_GD_P (*local_tls_type) |
3202 | if (GOT_TLS_GD_P (*local_tls_type) |
2777 | || *local_tls_type == GOT_TLS_IE_BOTH) |
3203 | || *local_tls_type == GOT_TLS_IE_BOTH) |
2778 | s->size += 4; |
3204 | s->size += 4; |
2779 | } |
3205 | } |
2780 | if (info->shared |
3206 | if (bfd_link_pic (info) |
2781 | || GOT_TLS_GD_ANY_P (*local_tls_type) |
3207 | || GOT_TLS_GD_ANY_P (*local_tls_type) |
2782 | || (*local_tls_type & GOT_TLS_IE)) |
3208 | || (*local_tls_type & GOT_TLS_IE)) |
2783 | { |
3209 | { |
2784 | if (*local_tls_type == GOT_TLS_IE_BOTH) |
3210 | if (*local_tls_type == GOT_TLS_IE_BOTH) |
2785 | srel->size += 2 * sizeof (Elf32_External_Rel); |
3211 | srel->size += 2 * sizeof (Elf32_External_Rel); |
Line 2883... | Line 3309... | ||
2883 | strip_section = FALSE; |
3309 | strip_section = FALSE; |
2884 | } |
3310 | } |
2885 | else if (s == htab->elf.sgotplt |
3311 | else if (s == htab->elf.sgotplt |
2886 | || s == htab->elf.iplt |
3312 | || s == htab->elf.iplt |
2887 | || s == htab->elf.igotplt |
3313 | || s == htab->elf.igotplt |
- | 3314 | || s == htab->plt_got |
|
2888 | || s == htab->plt_eh_frame |
3315 | || s == htab->plt_eh_frame |
2889 | || s == htab->sdynbss) |
3316 | || s == htab->sdynbss) |
2890 | { |
3317 | { |
2891 | /* Strip these too. */ |
3318 | /* Strip these too. */ |
2892 | } |
3319 | } |
Line 2953... | Line 3380... | ||
2953 | the .dynamic section. The DT_DEBUG entry is filled in by the |
3380 | the .dynamic section. The DT_DEBUG entry is filled in by the |
2954 | dynamic linker and used by the debugger. */ |
3381 | dynamic linker and used by the debugger. */ |
2955 | #define add_dynamic_entry(TAG, VAL) \ |
3382 | #define add_dynamic_entry(TAG, VAL) \ |
2956 | _bfd_elf_add_dynamic_entry (info, TAG, VAL) |
3383 | _bfd_elf_add_dynamic_entry (info, TAG, VAL) |
Line 2957... | Line 3384... | ||
2957 | 3384 | ||
2958 | if (info->executable) |
3385 | if (bfd_link_executable (info)) |
2959 | { |
3386 | { |
2960 | if (!add_dynamic_entry (DT_DEBUG, 0)) |
3387 | if (!add_dynamic_entry (DT_DEBUG, 0)) |
2961 | return FALSE; |
3388 | return FALSE; |
Line 2962... | Line 3389... | ||
2962 | } |
3389 | } |
2963 | 3390 | ||
- | 3391 | if (htab->elf.splt->size != 0) |
|
- | 3392 | { |
|
2964 | if (htab->elf.splt->size != 0) |
3393 | /* DT_PLTGOT is used by prelink even if there is no PLT |
- | 3394 | relocation. */ |
|
- | 3395 | if (!add_dynamic_entry (DT_PLTGOT, 0)) |
|
- | 3396 | return FALSE; |
|
- | 3397 | ||
2965 | { |
3398 | if (htab->elf.srelplt->size != 0) |
2966 | if (!add_dynamic_entry (DT_PLTGOT, 0) |
3399 | { |
2967 | || !add_dynamic_entry (DT_PLTRELSZ, 0) |
3400 | if (!add_dynamic_entry (DT_PLTRELSZ, 0) |
2968 | || !add_dynamic_entry (DT_PLTREL, DT_REL) |
3401 | || !add_dynamic_entry (DT_PLTREL, DT_REL) |
2969 | || !add_dynamic_entry (DT_JMPREL, 0)) |
3402 | || !add_dynamic_entry (DT_JMPREL, 0)) |
- | 3403 | return FALSE; |
|
Line 2970... | Line 3404... | ||
2970 | return FALSE; |
3404 | } |
2971 | } |
3405 | } |
2972 | 3406 | ||
2973 | if (relocs) |
3407 | if (relocs) |
Line 2983... | Line 3417... | ||
2983 | elf_link_hash_traverse (&htab->elf, |
3417 | elf_link_hash_traverse (&htab->elf, |
2984 | elf_i386_readonly_dynrelocs, info); |
3418 | elf_i386_readonly_dynrelocs, info); |
Line 2985... | Line 3419... | ||
2985 | 3419 | ||
2986 | if ((info->flags & DF_TEXTREL) != 0) |
3420 | if ((info->flags & DF_TEXTREL) != 0) |
- | 3421 | { |
|
- | 3422 | if ((elf_tdata (output_bfd)->has_gnu_symbols |
|
- | 3423 | & elf_gnu_symbol_ifunc) == elf_gnu_symbol_ifunc) |
|
- | 3424 | { |
|
- | 3425 | info->callbacks->einfo |
|
- | 3426 | (_("%P%X: read-only segment has dynamic IFUNC relocations; recompile with -fPIC\n")); |
|
- | 3427 | bfd_set_error (bfd_error_bad_value); |
|
- | 3428 | return FALSE; |
|
- | 3429 | } |
|
2987 | { |
3430 | |
2988 | if (!add_dynamic_entry (DT_TEXTREL, 0)) |
3431 | if (!add_dynamic_entry (DT_TEXTREL, 0)) |
2989 | return FALSE; |
3432 | return FALSE; |
2990 | } |
3433 | } |
2991 | } |
3434 | } |
Line 3032... | Line 3475... | ||
3032 | htab->tls_module_base = bh; |
3475 | htab->tls_module_base = bh; |
Line 3033... | Line 3476... | ||
3033 | 3476 | ||
3034 | tlsbase = (struct elf_link_hash_entry *)bh; |
3477 | tlsbase = (struct elf_link_hash_entry *)bh; |
3035 | tlsbase->def_regular = 1; |
3478 | tlsbase->def_regular = 1; |
- | 3479 | tlsbase->other = STV_HIDDEN; |
|
3036 | tlsbase->other = STV_HIDDEN; |
3480 | tlsbase->root.linker_def = 1; |
3037 | (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE); |
3481 | (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE); |
3038 | } |
3482 | } |
Line 3039... | Line 3483... | ||
3039 | } |
3483 | } |
Line 3084... | Line 3528... | ||
3084 | elf_i386_set_tls_module_base (struct bfd_link_info *info) |
3528 | elf_i386_set_tls_module_base (struct bfd_link_info *info) |
3085 | { |
3529 | { |
3086 | struct elf_i386_link_hash_table *htab; |
3530 | struct elf_i386_link_hash_table *htab; |
3087 | struct bfd_link_hash_entry *base; |
3531 | struct bfd_link_hash_entry *base; |
Line 3088... | Line 3532... | ||
3088 | 3532 | ||
3089 | if (!info->executable) |
3533 | if (!bfd_link_executable (info)) |
Line 3090... | Line 3534... | ||
3090 | return; |
3534 | return; |
3091 | 3535 | ||
3092 | htab = elf_i386_hash_table (info); |
3536 | htab = elf_i386_hash_table (info); |
Line 3148... | Line 3592... | ||
3148 | Elf_Internal_Shdr *symtab_hdr; |
3592 | Elf_Internal_Shdr *symtab_hdr; |
3149 | struct elf_link_hash_entry **sym_hashes; |
3593 | struct elf_link_hash_entry **sym_hashes; |
3150 | bfd_vma *local_got_offsets; |
3594 | bfd_vma *local_got_offsets; |
3151 | bfd_vma *local_tlsdesc_gotents; |
3595 | bfd_vma *local_tlsdesc_gotents; |
3152 | Elf_Internal_Rela *rel; |
3596 | Elf_Internal_Rela *rel; |
- | 3597 | Elf_Internal_Rela *wrel; |
|
3153 | Elf_Internal_Rela *relend; |
3598 | Elf_Internal_Rela *relend; |
3154 | bfd_boolean is_vxworks_tls; |
3599 | bfd_boolean is_vxworks_tls; |
3155 | unsigned plt_entry_size; |
3600 | unsigned plt_entry_size; |
Line 3156... | Line 3601... | ||
3156 | 3601 | ||
Line 3164... | Line 3609... | ||
3164 | local_got_offsets = elf_local_got_offsets (input_bfd); |
3609 | local_got_offsets = elf_local_got_offsets (input_bfd); |
3165 | local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd); |
3610 | local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd); |
3166 | /* We have to handle relocations in vxworks .tls_vars sections |
3611 | /* We have to handle relocations in vxworks .tls_vars sections |
3167 | specially, because the dynamic loader is 'weird'. */ |
3612 | specially, because the dynamic loader is 'weird'. */ |
3168 | is_vxworks_tls = (get_elf_i386_backend_data (output_bfd)->is_vxworks |
3613 | is_vxworks_tls = (get_elf_i386_backend_data (output_bfd)->is_vxworks |
3169 | && info->shared |
3614 | && bfd_link_pic (info) |
3170 | && !strcmp (input_section->output_section->name, |
3615 | && !strcmp (input_section->output_section->name, |
3171 | ".tls_vars")); |
3616 | ".tls_vars")); |
Line 3172... | Line 3617... | ||
3172 | 3617 | ||
Line 3173... | Line 3618... | ||
3173 | elf_i386_set_tls_module_base (info); |
3618 | elf_i386_set_tls_module_base (info); |
Line 3174... | Line 3619... | ||
3174 | 3619 | ||
3175 | plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd); |
3620 | plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd); |
3176 | 3621 | ||
3177 | rel = relocs; |
3622 | rel = wrel = relocs; |
3178 | relend = relocs + input_section->reloc_count; |
3623 | relend = relocs + input_section->reloc_count; |
3179 | for (; rel < relend; rel++) |
3624 | for (; rel < relend; wrel++, rel++) |
3180 | { |
3625 | { |
3181 | unsigned int r_type; |
3626 | unsigned int r_type; |
- | 3627 | reloc_howto_type *howto; |
|
3182 | reloc_howto_type *howto; |
3628 | unsigned long r_symndx; |
3183 | unsigned long r_symndx; |
3629 | struct elf_link_hash_entry *h; |
3184 | struct elf_link_hash_entry *h; |
3630 | struct elf_i386_link_hash_entry *eh; |
3185 | Elf_Internal_Sym *sym; |
3631 | Elf_Internal_Sym *sym; |
3186 | asection *sec; |
3632 | asection *sec; |
3187 | bfd_vma off, offplt; |
3633 | bfd_vma off, offplt, plt_offset; |
3188 | bfd_vma relocation; |
3634 | bfd_vma relocation; |
3189 | bfd_boolean unresolved_reloc; |
3635 | bfd_boolean unresolved_reloc; |
3190 | bfd_reloc_status_type r; |
3636 | bfd_reloc_status_type r; |
- | 3637 | unsigned int indx; |
|
Line 3191... | Line 3638... | ||
3191 | unsigned int indx; |
3638 | int tls_type; |
3192 | int tls_type; |
3639 | bfd_vma st_size; |
3193 | bfd_vma st_size; |
3640 | asection *resolved_plt; |
- | 3641 | ||
- | 3642 | r_type = ELF32_R_TYPE (rel->r_info); |
|
- | 3643 | if (r_type == R_386_GNU_VTINHERIT |
|
3194 | 3644 | || r_type == R_386_GNU_VTENTRY) |
|
- | 3645 | { |
|
Line 3195... | Line 3646... | ||
3195 | r_type = ELF32_R_TYPE (rel->r_info); |
3646 | if (wrel != rel) |
3196 | if (r_type == R_386_GNU_VTINHERIT |
3647 | *wrel = *rel; |
3197 | || r_type == R_386_GNU_VTENTRY) |
3648 | continue; |
3198 | continue; |
3649 | } |
3199 | 3650 | ||
3200 | if ((indx = r_type) >= R_386_standard |
3651 | if ((indx = r_type) >= R_386_standard |
3201 | && ((indx = r_type - R_386_ext_offset) - R_386_standard |
3652 | && ((indx = r_type - R_386_ext_offset) - R_386_standard |
3202 | >= R_386_ext - R_386_standard) |
3653 | >= R_386_ext - R_386_standard) |
3203 | && ((indx = r_type - R_386_tls_offset) - R_386_ext |
3654 | && ((indx = r_type - R_386_tls_offset) - R_386_ext |
3204 | >= R_386_irelative - R_386_ext)) |
3655 | >= R_386_ext2 - R_386_ext)) |
Line 3225... | Line 3676... | ||
3225 | + sym->st_value); |
3676 | + sym->st_value); |
3226 | st_size = sym->st_size; |
3677 | st_size = sym->st_size; |
Line 3227... | Line 3678... | ||
3227 | 3678 | ||
3228 | if (ELF_ST_TYPE (sym->st_info) == STT_SECTION |
3679 | if (ELF_ST_TYPE (sym->st_info) == STT_SECTION |
3229 | && ((sec->flags & SEC_MERGE) != 0 |
3680 | && ((sec->flags & SEC_MERGE) != 0 |
3230 | || (info->relocatable |
3681 | || (bfd_link_relocatable (info) |
3231 | && sec->output_offset != 0))) |
3682 | && sec->output_offset != 0))) |
3232 | { |
3683 | { |
3233 | bfd_vma addend; |
3684 | bfd_vma addend; |
Line 3261... | Line 3712... | ||
3261 | break; |
3712 | break; |
3262 | default: |
3713 | default: |
3263 | abort (); |
3714 | abort (); |
3264 | } |
3715 | } |
Line 3265... | Line 3716... | ||
3265 | 3716 | ||
3266 | if (info->relocatable) |
3717 | if (bfd_link_relocatable (info)) |
3267 | addend += sec->output_offset; |
3718 | addend += sec->output_offset; |
3268 | else |
3719 | else |
3269 | { |
3720 | { |
3270 | asection *msec = sec; |
3721 | asection *msec = sec; |
Line 3292... | Line 3743... | ||
3292 | addend -= 4; |
3743 | addend -= 4; |
3293 | bfd_put_32 (input_bfd, addend, where); |
3744 | bfd_put_32 (input_bfd, addend, where); |
3294 | break; |
3745 | break; |
3295 | } |
3746 | } |
3296 | } |
3747 | } |
3297 | else if (!info->relocatable |
3748 | else if (!bfd_link_relocatable (info) |
3298 | && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) |
3749 | && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) |
3299 | { |
3750 | { |
3300 | /* Relocate against local STT_GNU_IFUNC symbol. */ |
3751 | /* Relocate against local STT_GNU_IFUNC symbol. */ |
3301 | h = elf_i386_get_local_sym_hash (htab, input_bfd, rel, |
3752 | h = elf_i386_get_local_sym_hash (htab, input_bfd, rel, |
3302 | FALSE); |
3753 | FALSE); |
Line 3309... | Line 3760... | ||
3309 | } |
3760 | } |
3310 | } |
3761 | } |
3311 | else |
3762 | else |
3312 | { |
3763 | { |
3313 | bfd_boolean warned ATTRIBUTE_UNUSED; |
3764 | bfd_boolean warned ATTRIBUTE_UNUSED; |
- | 3765 | bfd_boolean ignored ATTRIBUTE_UNUSED; |
|
Line 3314... | Line 3766... | ||
3314 | 3766 | ||
3315 | RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
3767 | RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
3316 | r_symndx, symtab_hdr, sym_hashes, |
3768 | r_symndx, symtab_hdr, sym_hashes, |
3317 | h, sec, relocation, |
3769 | h, sec, relocation, |
3318 | unresolved_reloc, warned); |
3770 | unresolved_reloc, warned, ignored); |
3319 | st_size = h->size; |
3771 | st_size = h->size; |
Line 3320... | Line 3772... | ||
3320 | } |
3772 | } |
- | 3773 | ||
3321 | 3774 | if (sec != NULL && discarded_section (sec)) |
|
3322 | if (sec != NULL && discarded_section (sec)) |
3775 | { |
- | 3776 | _bfd_clear_contents (howto, input_bfd, input_section, |
|
- | 3777 | contents + rel->r_offset); |
|
- | 3778 | wrel->r_offset = rel->r_offset; |
|
- | 3779 | wrel->r_info = 0; |
|
- | 3780 | wrel->r_addend = 0; |
|
- | 3781 | ||
- | 3782 | /* For ld -r, remove relocations in debug sections against |
|
- | 3783 | sections defined in discarded sections. Not done for |
|
- | 3784 | eh_frame editing code expects to be present. */ |
|
- | 3785 | if (bfd_link_relocatable (info) |
|
- | 3786 | && (input_section->flags & SEC_DEBUGGING)) |
|
- | 3787 | wrel--; |
|
- | 3788 | ||
Line 3323... | Line 3789... | ||
3323 | RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
3789 | continue; |
- | 3790 | } |
|
- | 3791 | ||
- | 3792 | if (bfd_link_relocatable (info)) |
|
3324 | rel, 1, relend, howto, 0, contents); |
3793 | { |
- | 3794 | if (wrel != rel) |
|
Line 3325... | Line 3795... | ||
3325 | 3795 | *wrel = *rel; |
|
3326 | if (info->relocatable) |
3796 | continue; |
3327 | continue; |
3797 | } |
3328 | 3798 | ||
Line 3334... | Line 3804... | ||
3334 | { |
3804 | { |
3335 | asection *plt, *gotplt, *base_got; |
3805 | asection *plt, *gotplt, *base_got; |
3336 | bfd_vma plt_index; |
3806 | bfd_vma plt_index; |
3337 | const char *name; |
3807 | const char *name; |
Line 3338... | Line 3808... | ||
3338 | 3808 | ||
- | 3809 | if ((input_section->flags & SEC_ALLOC) == 0) |
|
- | 3810 | { |
|
- | 3811 | /* Dynamic relocs are not propagated for SEC_DEBUGGING |
|
- | 3812 | sections because such sections are not SEC_ALLOC and |
|
- | 3813 | thus ld.so will not process them. */ |
|
- | 3814 | if ((input_section->flags & SEC_DEBUGGING) != 0) |
|
- | 3815 | continue; |
|
- | 3816 | abort (); |
|
3339 | if ((input_section->flags & SEC_ALLOC) == 0 |
3817 | } |
3340 | || h->plt.offset == (bfd_vma) -1) |
3818 | else if (h->plt.offset == (bfd_vma) -1) |
Line 3341... | Line 3819... | ||
3341 | abort (); |
3819 | abort (); |
3342 | 3820 | ||
3343 | /* STT_GNU_IFUNC symbol must go through PLT. */ |
3821 | /* STT_GNU_IFUNC symbol must go through PLT. */ |
Line 3372... | Line 3850... | ||
3372 | return FALSE; |
3850 | return FALSE; |
Line 3373... | Line 3851... | ||
3373 | 3851 | ||
3374 | case R_386_32: |
3852 | case R_386_32: |
3375 | /* Generate dynamic relcoation only when there is a |
3853 | /* Generate dynamic relcoation only when there is a |
3376 | non-GOT reference in a shared object. */ |
3854 | non-GOT reference in a shared object. */ |
3377 | if (info->shared && h->non_got_ref) |
3855 | if (bfd_link_pic (info) && h->non_got_ref) |
3378 | { |
3856 | { |
3379 | Elf_Internal_Rela outrel; |
3857 | Elf_Internal_Rela outrel; |
3380 | asection *sreloc; |
3858 | asection *sreloc; |
Line 3394... | Line 3872... | ||
3394 | + input_section->output_offset |
3872 | + input_section->output_offset |
3395 | + offset); |
3873 | + offset); |
Line 3396... | Line 3874... | ||
3396 | 3874 | ||
3397 | if (h->dynindx == -1 |
3875 | if (h->dynindx == -1 |
3398 | || h->forced_local |
3876 | || h->forced_local |
3399 | || info->executable) |
3877 | || bfd_link_executable (info)) |
3400 | { |
3878 | { |
3401 | /* This symbol is resolved locally. */ |
3879 | /* This symbol is resolved locally. */ |
3402 | outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); |
3880 | outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); |
3403 | bfd_put_32 (output_bfd, |
3881 | bfd_put_32 (output_bfd, |
Line 3423... | Line 3901... | ||
3423 | case R_386_PC32: |
3901 | case R_386_PC32: |
3424 | case R_386_PLT32: |
3902 | case R_386_PLT32: |
3425 | goto do_relocation; |
3903 | goto do_relocation; |
Line 3426... | Line 3904... | ||
3426 | 3904 | ||
- | 3905 | case R_386_GOT32: |
|
3427 | case R_386_GOT32: |
3906 | case R_386_GOT32X: |
3428 | base_got = htab->elf.sgot; |
3907 | base_got = htab->elf.sgot; |
Line 3429... | Line 3908... | ||
3429 | off = h->got.offset; |
3908 | off = h->got.offset; |
3430 | 3909 | ||
Line 3497... | Line 3976... | ||
3497 | + gotplt->output_offset); |
3976 | + gotplt->output_offset); |
3498 | goto do_relocation; |
3977 | goto do_relocation; |
3499 | } |
3978 | } |
3500 | } |
3979 | } |
Line -... | Line 3980... | ||
- | 3980 | ||
3501 | 3981 | eh = (struct elf_i386_link_hash_entry *) h; |
|
3502 | switch (r_type) |
3982 | switch (r_type) |
- | 3983 | { |
|
- | 3984 | case R_386_GOT32X: |
|
- | 3985 | /* Avoid optimizing _DYNAMIC since ld.so may use its |
|
- | 3986 | link-time address. */ |
|
- | 3987 | if (h == htab->elf.hdynamic) |
|
- | 3988 | goto r_386_got32; |
|
- | 3989 | ||
- | 3990 | if (bfd_link_pic (info)) |
|
- | 3991 | { |
|
- | 3992 | /* It is OK to convert mov to lea and convert indirect |
|
- | 3993 | branch to direct branch. It is OK to convert adc, |
|
- | 3994 | add, and, cmp, or, sbb, sub, test, xor only when PIC |
|
- | 3995 | is false. */ |
|
- | 3996 | unsigned int opcode, addend; |
|
- | 3997 | addend = bfd_get_32 (input_bfd, contents + rel->r_offset); |
|
- | 3998 | if (addend != 0) |
|
- | 3999 | goto r_386_got32; |
|
- | 4000 | opcode = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); |
|
- | 4001 | if (opcode != 0x8b && opcode != 0xff) |
|
- | 4002 | goto r_386_got32; |
|
- | 4003 | } |
|
- | 4004 | ||
- | 4005 | /* Resolve "mov GOT[(%reg)], %reg", |
|
- | 4006 | "call/jmp *GOT[(%reg)]", "test %reg, foo@GOT[(%reg)]" |
|
- | 4007 | and "binop foo@GOT[(%reg)], %reg". */ |
|
- | 4008 | if (h == NULL |
|
- | 4009 | || (h->plt.offset == (bfd_vma) -1 |
|
- | 4010 | && h->got.offset == (bfd_vma) -1) |
|
- | 4011 | || htab->elf.sgotplt == NULL) |
|
- | 4012 | abort (); |
|
- | 4013 | ||
- | 4014 | offplt = (htab->elf.sgotplt->output_section->vma |
|
- | 4015 | + htab->elf.sgotplt->output_offset); |
|
- | 4016 | ||
- | 4017 | /* It is relative to .got.plt section. */ |
|
- | 4018 | if (h->got.offset != (bfd_vma) -1) |
|
- | 4019 | /* Use GOT entry. */ |
|
- | 4020 | relocation = (htab->elf.sgot->output_section->vma |
|
- | 4021 | + htab->elf.sgot->output_offset |
|
- | 4022 | + h->got.offset - offplt); |
|
- | 4023 | else |
|
- | 4024 | /* Use GOTPLT entry. */ |
|
- | 4025 | relocation = (h->plt.offset / plt_entry_size - 1 + 3) * 4; |
|
- | 4026 | ||
- | 4027 | if (!bfd_link_pic (info)) |
|
- | 4028 | { |
|
- | 4029 | /* If not PIC, add the .got.plt section address for |
|
- | 4030 | baseless addressing. */ |
|
- | 4031 | unsigned int modrm; |
|
- | 4032 | modrm = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); |
|
- | 4033 | if ((modrm & 0xc7) == 0x5) |
|
- | 4034 | relocation += offplt; |
|
- | 4035 | } |
|
- | 4036 | ||
- | 4037 | unresolved_reloc = FALSE; |
|
- | 4038 | break; |
|
3503 | { |
4039 | |
- | 4040 | case R_386_GOT32: |
|
3504 | case R_386_GOT32: |
4041 | r_386_got32: |
3505 | /* Relocation is to the entry for this symbol in the global |
4042 | /* Relocation is to the entry for this symbol in the global |
3506 | offset table. */ |
4043 | offset table. */ |
3507 | if (htab->elf.sgot == NULL) |
4044 | if (htab->elf.sgot == NULL) |
Line 3511... | Line 4048... | ||
3511 | { |
4048 | { |
3512 | bfd_boolean dyn; |
4049 | bfd_boolean dyn; |
Line 3513... | Line 4050... | ||
3513 | 4050 | ||
3514 | off = h->got.offset; |
4051 | off = h->got.offset; |
3515 | dyn = htab->elf.dynamic_sections_created; |
4052 | dyn = htab->elf.dynamic_sections_created; |
- | 4053 | if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, |
|
- | 4054 | bfd_link_pic (info), |
|
3516 | if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) |
4055 | h) |
3517 | || (info->shared |
4056 | || (bfd_link_pic (info) |
3518 | && SYMBOL_REFERENCES_LOCAL (info, h)) |
4057 | && SYMBOL_REFERENCES_LOCAL (info, h)) |
3519 | || (ELF_ST_VISIBILITY (h->other) |
4058 | || (ELF_ST_VISIBILITY (h->other) |
3520 | && h->root.type == bfd_link_hash_undefweak)) |
4059 | && h->root.type == bfd_link_hash_undefweak)) |
3521 | { |
4060 | { |
Line 3558... | Line 4097... | ||
3558 | else |
4097 | else |
3559 | { |
4098 | { |
3560 | bfd_put_32 (output_bfd, relocation, |
4099 | bfd_put_32 (output_bfd, relocation, |
3561 | htab->elf.sgot->contents + off); |
4100 | htab->elf.sgot->contents + off); |
Line 3562... | Line 4101... | ||
3562 | 4101 | ||
3563 | if (info->shared) |
4102 | if (bfd_link_pic (info)) |
3564 | { |
4103 | { |
3565 | asection *s; |
4104 | asection *s; |
Line 3566... | Line 4105... | ||
3566 | Elf_Internal_Rela outrel; |
4105 | Elf_Internal_Rela outrel; |
Line 3591... | Line 4130... | ||
3591 | 4130 | ||
3592 | case R_386_GOTOFF: |
4131 | case R_386_GOTOFF: |
3593 | /* Relocation is relative to the start of the global offset |
4132 | /* Relocation is relative to the start of the global offset |
Line 3594... | Line 4133... | ||
3594 | table. */ |
4133 | table. */ |
3595 | 4134 | ||
3596 | /* Check to make sure it isn't a protected function symbol |
4135 | /* Check to make sure it isn't a protected function or data |
3597 | for shared library since it may not be local when used |
4136 | symbol for shared library since it may not be local when |
3598 | as function address. We also need to make sure that a |
4137 | used as function address or with copy relocation. We also |
3599 | symbol is defined locally. */ |
4138 | need to make sure that a symbol is referenced locally. */ |
3600 | if (info->shared && h) |
4139 | if (!bfd_link_executable (info) && h) |
3601 | { |
4140 | { |
3602 | if (!h->def_regular) |
4141 | if (!h->def_regular) |
Line 3623... | Line 4162... | ||
3623 | (_("%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"), |
4162 | (_("%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"), |
3624 | input_bfd, v, h->root.root.string); |
4163 | input_bfd, v, h->root.root.string); |
3625 | bfd_set_error (bfd_error_bad_value); |
4164 | bfd_set_error (bfd_error_bad_value); |
3626 | return FALSE; |
4165 | return FALSE; |
3627 | } |
4166 | } |
3628 | else if (!info->executable |
4167 | else if (!SYMBOL_REFERENCES_LOCAL (info, h) |
3629 | && !SYMBOLIC_BIND (info, h) |
4168 | && (h->type == STT_FUNC |
3630 | && h->type == STT_FUNC |
4169 | || h->type == STT_OBJECT) |
3631 | && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) |
4170 | && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) |
3632 | { |
4171 | { |
3633 | (*_bfd_error_handler) |
4172 | (*_bfd_error_handler) |
3634 | (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"), |
4173 | (_("%B: relocation R_386_GOTOFF against protected %s `%s' can not be used when making a shared object"), |
- | 4174 | input_bfd, |
|
- | 4175 | h->type == STT_FUNC ? "function" : "data", |
|
3635 | input_bfd, h->root.root.string); |
4176 | h->root.root.string); |
3636 | bfd_set_error (bfd_error_bad_value); |
4177 | bfd_set_error (bfd_error_bad_value); |
3637 | return FALSE; |
4178 | return FALSE; |
3638 | } |
4179 | } |
3639 | } |
4180 | } |
Line 3661... | Line 4202... | ||
3661 | /* Resolve a PLT32 reloc against a local symbol directly, |
4202 | /* Resolve a PLT32 reloc against a local symbol directly, |
3662 | without using the procedure linkage table. */ |
4203 | without using the procedure linkage table. */ |
3663 | if (h == NULL) |
4204 | if (h == NULL) |
3664 | break; |
4205 | break; |
Line 3665... | Line 4206... | ||
3665 | 4206 | ||
- | 4207 | if ((h->plt.offset == (bfd_vma) -1 |
|
3666 | if (h->plt.offset == (bfd_vma) -1 |
4208 | && eh->plt_got.offset == (bfd_vma) -1) |
3667 | || htab->elf.splt == NULL) |
4209 | || htab->elf.splt == NULL) |
3668 | { |
4210 | { |
3669 | /* We didn't make a PLT entry for this symbol. This |
4211 | /* We didn't make a PLT entry for this symbol. This |
3670 | happens when statically linking PIC code, or when |
4212 | happens when statically linking PIC code, or when |
3671 | using -Bsymbolic. */ |
4213 | using -Bsymbolic. */ |
3672 | break; |
4214 | break; |
Line -... | Line 4215... | ||
- | 4215 | } |
|
- | 4216 | ||
- | 4217 | if (h->plt.offset != (bfd_vma) -1) |
|
- | 4218 | { |
|
- | 4219 | resolved_plt = htab->elf.splt; |
|
- | 4220 | plt_offset = h->plt.offset; |
|
- | 4221 | } |
|
- | 4222 | else |
|
- | 4223 | { |
|
- | 4224 | resolved_plt = htab->plt_got; |
|
- | 4225 | plt_offset = eh->plt_got.offset; |
|
3673 | } |
4226 | } |
3674 | 4227 | ||
3675 | relocation = (htab->elf.splt->output_section->vma |
4228 | relocation = (resolved_plt->output_section->vma |
3676 | + htab->elf.splt->output_offset |
4229 | + resolved_plt->output_offset |
3677 | + h->plt.offset); |
4230 | + plt_offset); |
Line 3678... | Line 4231... | ||
3678 | unresolved_reloc = FALSE; |
4231 | unresolved_reloc = FALSE; |
3679 | break; |
4232 | break; |
Line 3687... | Line 4240... | ||
3687 | case R_386_PC32: |
4240 | case R_386_PC32: |
3688 | if ((input_section->flags & SEC_ALLOC) == 0 |
4241 | if ((input_section->flags & SEC_ALLOC) == 0 |
3689 | || is_vxworks_tls) |
4242 | || is_vxworks_tls) |
3690 | break; |
4243 | break; |
Line -... | Line 4244... | ||
- | 4244 | ||
3691 | 4245 | /* Copy dynamic function pointer relocations. */ |
|
3692 | if ((info->shared |
4246 | if ((bfd_link_pic (info) |
3693 | && (h == NULL |
4247 | && (h == NULL |
3694 | || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
4248 | || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
3695 | || h->root.type != bfd_link_hash_undefweak) |
4249 | || h->root.type != bfd_link_hash_undefweak) |
3696 | && ((r_type != R_386_PC32 && r_type != R_386_SIZE32) |
4250 | && ((r_type != R_386_PC32 && r_type != R_386_SIZE32) |
3697 | || !SYMBOL_CALLS_LOCAL (info, h))) |
4251 | || !SYMBOL_CALLS_LOCAL (info, h))) |
3698 | || (ELIMINATE_COPY_RELOCS |
4252 | || (ELIMINATE_COPY_RELOCS |
3699 | && !info->shared |
4253 | && !bfd_link_pic (info) |
3700 | && h != NULL |
4254 | && h != NULL |
3701 | && h->dynindx != -1 |
4255 | && h->dynindx != -1 |
3702 | && !h->non_got_ref |
4256 | && (!h->non_got_ref || eh->func_pointer_refcount > 0) |
3703 | && ((h->def_dynamic |
4257 | && ((h->def_dynamic |
3704 | && !h->def_regular) |
4258 | && !h->def_regular) |
3705 | || h->root.type == bfd_link_hash_undefweak |
4259 | || h->root.type == bfd_link_hash_undefweak |
3706 | || h->root.type == bfd_link_hash_undefined))) |
4260 | || h->root.type == bfd_link_hash_undefined))) |
Line 3729... | Line 4283... | ||
3729 | if (skip) |
4283 | if (skip) |
3730 | memset (&outrel, 0, sizeof outrel); |
4284 | memset (&outrel, 0, sizeof outrel); |
3731 | else if (h != NULL |
4285 | else if (h != NULL |
3732 | && h->dynindx != -1 |
4286 | && h->dynindx != -1 |
3733 | && (r_type == R_386_PC32 |
4287 | && (r_type == R_386_PC32 |
3734 | || !info->shared |
4288 | || !bfd_link_pic (info) |
3735 | || !SYMBOLIC_BIND (info, h) |
4289 | || !SYMBOLIC_BIND (info, h) |
3736 | || !h->def_regular)) |
4290 | || !h->def_regular)) |
3737 | outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
4291 | outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
3738 | else |
4292 | else |
3739 | { |
4293 | { |
Line 3760... | Line 4314... | ||
3760 | continue; |
4314 | continue; |
3761 | } |
4315 | } |
3762 | break; |
4316 | break; |
Line 3763... | Line 4317... | ||
3763 | 4317 | ||
3764 | case R_386_TLS_IE: |
4318 | case R_386_TLS_IE: |
3765 | if (!info->executable) |
4319 | if (!bfd_link_executable (info)) |
3766 | { |
4320 | { |
3767 | Elf_Internal_Rela outrel; |
4321 | Elf_Internal_Rela outrel; |
Line 3768... | Line 4322... | ||
3768 | asection *sreloc; |
4322 | asection *sreloc; |
Line 3830... | Line 4384... | ||
3830 | } |
4384 | } |
3831 | bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation), |
4385 | bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation), |
3832 | contents + roff); |
4386 | contents + roff); |
3833 | /* Skip R_386_PC32/R_386_PLT32. */ |
4387 | /* Skip R_386_PC32/R_386_PLT32. */ |
3834 | rel++; |
4388 | rel++; |
- | 4389 | wrel++; |
|
3835 | continue; |
4390 | continue; |
3836 | } |
4391 | } |
3837 | else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC) |
4392 | else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC) |
3838 | { |
4393 | { |
3839 | /* GDesc -> LE transition. |
4394 | /* GDesc -> LE transition. |
Line 4169... | Line 4724... | ||
4169 | - htab->elf.sgotplt->output_section->vma |
4724 | - htab->elf.sgotplt->output_section->vma |
4170 | - htab->elf.sgotplt->output_offset, |
4725 | - htab->elf.sgotplt->output_offset, |
4171 | contents + roff + 8); |
4726 | contents + roff + 8); |
4172 | /* Skip R_386_PLT32. */ |
4727 | /* Skip R_386_PLT32. */ |
4173 | rel++; |
4728 | rel++; |
- | 4729 | wrel++; |
|
4174 | continue; |
4730 | continue; |
4175 | } |
4731 | } |
4176 | else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC) |
4732 | else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC) |
4177 | { |
4733 | { |
4178 | /* GDesc -> IE transition. |
4734 | /* GDesc -> IE transition. |
Line 4266... | Line 4822... | ||
4266 | BFD_ASSERT (r_type == R_386_TLS_LE_32); |
4822 | BFD_ASSERT (r_type == R_386_TLS_LE_32); |
4267 | memcpy (contents + rel->r_offset - 2, |
4823 | memcpy (contents + rel->r_offset - 2, |
4268 | "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11); |
4824 | "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11); |
4269 | /* Skip R_386_PC32/R_386_PLT32. */ |
4825 | /* Skip R_386_PC32/R_386_PLT32. */ |
4270 | rel++; |
4826 | rel++; |
- | 4827 | wrel++; |
|
4271 | continue; |
4828 | continue; |
4272 | } |
4829 | } |
Line 4273... | Line 4830... | ||
4273 | 4830 | ||
4274 | if (htab->elf.sgot == NULL) |
4831 | if (htab->elf.sgot == NULL) |
Line 4301... | Line 4858... | ||
4301 | - htab->elf.sgotplt->output_offset; |
4858 | - htab->elf.sgotplt->output_offset; |
4302 | unresolved_reloc = FALSE; |
4859 | unresolved_reloc = FALSE; |
4303 | break; |
4860 | break; |
Line 4304... | Line 4861... | ||
4304 | 4861 | ||
- | 4862 | case R_386_TLS_LDO_32: |
|
4305 | case R_386_TLS_LDO_32: |
4863 | if (!bfd_link_executable (info) |
4306 | if (!info->executable || (input_section->flags & SEC_CODE) == 0) |
4864 | || (input_section->flags & SEC_CODE) == 0) |
4307 | relocation -= elf_i386_dtpoff_base (info); |
4865 | relocation -= elf_i386_dtpoff_base (info); |
4308 | else |
4866 | else |
4309 | /* When converting LDO to LE, we must negate. */ |
4867 | /* When converting LDO to LE, we must negate. */ |
4310 | relocation = -elf_i386_tpoff (info, relocation); |
4868 | relocation = -elf_i386_tpoff (info, relocation); |
Line 4311... | Line 4869... | ||
4311 | break; |
4869 | break; |
4312 | 4870 | ||
4313 | case R_386_TLS_LE_32: |
4871 | case R_386_TLS_LE_32: |
4314 | case R_386_TLS_LE: |
4872 | case R_386_TLS_LE: |
4315 | if (!info->executable) |
4873 | if (!bfd_link_executable (info)) |
4316 | { |
4874 | { |
Line 4317... | Line 4875... | ||
4317 | Elf_Internal_Rela outrel; |
4875 | Elf_Internal_Rela outrel; |
Line 4406... | Line 4964... | ||
4406 | input_bfd, input_section, |
4964 | input_bfd, input_section, |
4407 | (long) rel->r_offset, name, (int) r); |
4965 | (long) rel->r_offset, name, (int) r); |
4408 | return FALSE; |
4966 | return FALSE; |
4409 | } |
4967 | } |
4410 | } |
4968 | } |
- | 4969 | ||
- | 4970 | if (wrel != rel) |
|
- | 4971 | *wrel = *rel; |
|
- | 4972 | } |
|
- | 4973 | ||
- | 4974 | if (wrel != rel) |
|
- | 4975 | { |
|
- | 4976 | Elf_Internal_Shdr *rel_hdr; |
|
- | 4977 | size_t deleted = rel - wrel; |
|
- | 4978 | ||
- | 4979 | rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); |
|
- | 4980 | rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; |
|
- | 4981 | if (rel_hdr->sh_size == 0) |
|
- | 4982 | { |
|
- | 4983 | /* It is too late to remove an empty reloc section. Leave |
|
- | 4984 | one NONE reloc. |
|
- | 4985 | ??? What is wrong with an empty section??? */ |
|
- | 4986 | rel_hdr->sh_size = rel_hdr->sh_entsize; |
|
- | 4987 | deleted -= 1; |
|
- | 4988 | } |
|
- | 4989 | rel_hdr = _bfd_elf_single_rel_hdr (input_section); |
|
- | 4990 | rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; |
|
- | 4991 | input_section->reloc_count -= deleted; |
|
4411 | } |
4992 | } |
Line 4412... | Line 4993... | ||
4412 | 4993 | ||
4413 | return TRUE; |
4994 | return TRUE; |
Line 4423... | Line 5004... | ||
4423 | Elf_Internal_Sym *sym) |
5004 | Elf_Internal_Sym *sym) |
4424 | { |
5005 | { |
4425 | struct elf_i386_link_hash_table *htab; |
5006 | struct elf_i386_link_hash_table *htab; |
4426 | unsigned plt_entry_size; |
5007 | unsigned plt_entry_size; |
4427 | const struct elf_i386_backend_data *abed; |
5008 | const struct elf_i386_backend_data *abed; |
- | 5009 | struct elf_i386_link_hash_entry *eh; |
|
Line 4428... | Line 5010... | ||
4428 | 5010 | ||
4429 | htab = elf_i386_hash_table (info); |
5011 | htab = elf_i386_hash_table (info); |
4430 | if (htab == NULL) |
5012 | if (htab == NULL) |
Line 4431... | Line 5013... | ||
4431 | return FALSE; |
5013 | return FALSE; |
4432 | 5014 | ||
Line -... | Line 5015... | ||
- | 5015 | abed = get_elf_i386_backend_data (output_bfd); |
|
- | 5016 | plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd); |
|
4433 | abed = get_elf_i386_backend_data (output_bfd); |
5017 | |
4434 | plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd); |
5018 | eh = (struct elf_i386_link_hash_entry *) h; |
4435 | 5019 | ||
4436 | if (h->plt.offset != (bfd_vma) -1) |
5020 | if (h->plt.offset != (bfd_vma) -1) |
4437 | { |
5021 | { |
Line 4458... | Line 5042... | ||
4458 | 5042 | ||
4459 | /* This symbol has an entry in the procedure linkage table. Set |
5043 | /* This symbol has an entry in the procedure linkage table. Set |
Line 4460... | Line 5044... | ||
4460 | it up. */ |
5044 | it up. */ |
4461 | 5045 | ||
4462 | if ((h->dynindx == -1 |
5046 | if ((h->dynindx == -1 |
4463 | && !((h->forced_local || info->executable) |
5047 | && !((h->forced_local || bfd_link_executable (info)) |
4464 | && h->def_regular |
5048 | && h->def_regular |
4465 | && h->type == STT_GNU_IFUNC)) |
5049 | && h->type == STT_GNU_IFUNC)) |
4466 | || plt == NULL |
5050 | || plt == NULL |
Line 4489... | Line 5073... | ||
4489 | got_offset = h->plt.offset / plt_entry_size; |
5073 | got_offset = h->plt.offset / plt_entry_size; |
4490 | got_offset = got_offset * 4; |
5074 | got_offset = got_offset * 4; |
4491 | } |
5075 | } |
Line 4492... | Line 5076... | ||
4492 | 5076 | ||
4493 | /* Fill in the entry in the procedure linkage table. */ |
5077 | /* Fill in the entry in the procedure linkage table. */ |
4494 | if (! info->shared) |
5078 | if (! bfd_link_pic (info)) |
4495 | { |
5079 | { |
4496 | memcpy (plt->contents + h->plt.offset, abed->plt->plt_entry, |
5080 | memcpy (plt->contents + h->plt.offset, abed->plt->plt_entry, |
4497 | abed->plt->plt_entry_size); |
5081 | abed->plt->plt_entry_size); |
4498 | bfd_put_32 (output_bfd, |
5082 | bfd_put_32 (output_bfd, |
Line 4511... | Line 5095... | ||
4511 | 5095 | ||
4512 | /* S: Current slot number (zero-based). */ |
5096 | /* S: Current slot number (zero-based). */ |
4513 | s = ((h->plt.offset - abed->plt->plt_entry_size) |
5097 | s = ((h->plt.offset - abed->plt->plt_entry_size) |
4514 | / abed->plt->plt_entry_size); |
5098 | / abed->plt->plt_entry_size); |
4515 | /* K: Number of relocations for PLTResolve. */ |
5099 | /* K: Number of relocations for PLTResolve. */ |
4516 | if (info->shared) |
5100 | if (bfd_link_pic (info)) |
4517 | k = PLTRESOLVE_RELOCS_SHLIB; |
5101 | k = PLTRESOLVE_RELOCS_SHLIB; |
4518 | else |
5102 | else |
4519 | k = PLTRESOLVE_RELOCS; |
5103 | k = PLTRESOLVE_RELOCS; |
4520 | /* Skip the PLTresolve relocations, and the relocations for |
5104 | /* Skip the PLTresolve relocations, and the relocations for |
Line 4559... | Line 5143... | ||
4559 | /* Fill in the entry in the .rel.plt section. */ |
5143 | /* Fill in the entry in the .rel.plt section. */ |
4560 | rel.r_offset = (gotplt->output_section->vma |
5144 | rel.r_offset = (gotplt->output_section->vma |
4561 | + gotplt->output_offset |
5145 | + gotplt->output_offset |
4562 | + got_offset); |
5146 | + got_offset); |
4563 | if (h->dynindx == -1 |
5147 | if (h->dynindx == -1 |
4564 | || ((info->executable |
5148 | || ((bfd_link_executable (info) |
4565 | || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) |
5149 | || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) |
4566 | && h->def_regular |
5150 | && h->def_regular |
4567 | && h->type == STT_GNU_IFUNC)) |
5151 | && h->type == STT_GNU_IFUNC)) |
4568 | { |
5152 | { |
4569 | /* If an STT_GNU_IFUNC symbol is locally defined, generate |
5153 | /* If an STT_GNU_IFUNC symbol is locally defined, generate |
Line 4595... | Line 5179... | ||
4595 | bfd_put_32 (output_bfd, - (h->plt.offset |
5179 | bfd_put_32 (output_bfd, - (h->plt.offset |
4596 | + abed->plt->plt_plt_offset + 4), |
5180 | + abed->plt->plt_plt_offset + 4), |
4597 | plt->contents + h->plt.offset |
5181 | plt->contents + h->plt.offset |
4598 | + abed->plt->plt_plt_offset); |
5182 | + abed->plt->plt_plt_offset); |
4599 | } |
5183 | } |
- | 5184 | } |
|
- | 5185 | else if (eh->plt_got.offset != (bfd_vma) -1) |
|
- | 5186 | { |
|
- | 5187 | bfd_vma got_offset, plt_offset; |
|
- | 5188 | asection *plt, *got, *gotplt; |
|
- | 5189 | const bfd_byte *got_plt_entry; |
|
- | 5190 | ||
- | 5191 | /* Offset of displacement of the indirect jump. */ |
|
- | 5192 | bfd_vma plt_got_offset = 2; |
|
- | 5193 | ||
- | 5194 | /* Set the entry in the GOT procedure linkage table. */ |
|
- | 5195 | plt = htab->plt_got; |
|
- | 5196 | got = htab->elf.sgot; |
|
- | 5197 | gotplt = htab->elf.sgotplt; |
|
- | 5198 | got_offset = h->got.offset; |
|
Line -... | Line 5199... | ||
- | 5199 | ||
- | 5200 | if (got_offset == (bfd_vma) -1 |
|
- | 5201 | || plt == NULL |
|
- | 5202 | || got == NULL |
|
- | 5203 | || gotplt == NULL) |
|
- | 5204 | abort (); |
|
- | 5205 | ||
- | 5206 | /* Fill in the entry in the GOT procedure linkage table. */ |
|
- | 5207 | if (! bfd_link_pic (info)) |
|
- | 5208 | { |
|
- | 5209 | got_plt_entry = elf_i386_got_plt_entry; |
|
- | 5210 | got_offset += got->output_section->vma + got->output_offset; |
|
- | 5211 | } |
|
- | 5212 | else |
|
- | 5213 | { |
|
- | 5214 | got_plt_entry = elf_i386_pic_got_plt_entry; |
|
- | 5215 | got_offset += (got->output_section->vma |
|
- | 5216 | + got->output_offset |
|
- | 5217 | - gotplt->output_section->vma |
|
- | 5218 | - gotplt->output_offset); |
|
- | 5219 | } |
|
- | 5220 | ||
- | 5221 | plt_offset = eh->plt_got.offset; |
|
- | 5222 | memcpy (plt->contents + plt_offset, got_plt_entry, |
|
- | 5223 | sizeof (elf_i386_got_plt_entry)); |
|
- | 5224 | bfd_put_32 (output_bfd, got_offset, |
|
- | 5225 | plt->contents + plt_offset + plt_got_offset); |
|
- | 5226 | } |
|
4600 | 5227 | ||
- | 5228 | if (!h->def_regular |
|
- | 5229 | && (h->plt.offset != (bfd_vma) -1 |
|
4601 | if (!h->def_regular) |
5230 | || eh->plt_got.offset != (bfd_vma) -1)) |
4602 | { |
5231 | { |
4603 | /* Mark the symbol as undefined, rather than as defined in |
5232 | /* Mark the symbol as undefined, rather than as defined in |
4604 | the .plt section. Leave the value if there were any |
5233 | the .plt section. Leave the value if there were any |
4605 | relocations where pointer equality matters (this is a clue |
5234 | relocations where pointer equality matters (this is a clue |
Line 4610... | Line 5239... | ||
4610 | shared libraries because of that. */ |
5239 | shared libraries because of that. */ |
4611 | sym->st_shndx = SHN_UNDEF; |
5240 | sym->st_shndx = SHN_UNDEF; |
4612 | if (!h->pointer_equality_needed) |
5241 | if (!h->pointer_equality_needed) |
4613 | sym->st_value = 0; |
5242 | sym->st_value = 0; |
4614 | } |
5243 | } |
4615 | } |
- | |
Line 4616... | Line 5244... | ||
4616 | 5244 | ||
4617 | if (h->got.offset != (bfd_vma) -1 |
5245 | if (h->got.offset != (bfd_vma) -1 |
4618 | && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type) |
5246 | && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type) |
4619 | && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0) |
5247 | && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0) |
Line 4636... | Line 5264... | ||
4636 | The entry in the global offset table will already have been |
5264 | The entry in the global offset table will already have been |
4637 | initialized in the relocate_section function. */ |
5265 | initialized in the relocate_section function. */ |
4638 | if (h->def_regular |
5266 | if (h->def_regular |
4639 | && h->type == STT_GNU_IFUNC) |
5267 | && h->type == STT_GNU_IFUNC) |
4640 | { |
5268 | { |
4641 | if (info->shared) |
5269 | if (bfd_link_pic (info)) |
4642 | { |
5270 | { |
4643 | /* Generate R_386_GLOB_DAT. */ |
5271 | /* Generate R_386_GLOB_DAT. */ |
4644 | goto do_glob_dat; |
5272 | goto do_glob_dat; |
4645 | } |
5273 | } |
4646 | else |
5274 | else |
Line 4659... | Line 5287... | ||
4659 | + plt->output_offset + h->plt.offset), |
5287 | + plt->output_offset + h->plt.offset), |
4660 | htab->elf.sgot->contents + h->got.offset); |
5288 | htab->elf.sgot->contents + h->got.offset); |
4661 | return TRUE; |
5289 | return TRUE; |
4662 | } |
5290 | } |
4663 | } |
5291 | } |
4664 | else if (info->shared |
5292 | else if (bfd_link_pic (info) |
4665 | && SYMBOL_REFERENCES_LOCAL (info, h)) |
5293 | && SYMBOL_REFERENCES_LOCAL (info, h)) |
4666 | { |
5294 | { |
4667 | BFD_ASSERT((h->got.offset & 1) != 0); |
5295 | BFD_ASSERT((h->got.offset & 1) != 0); |
4668 | rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); |
5296 | rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); |
4669 | } |
5297 | } |
Line 4718... | Line 5346... | ||
4718 | 5346 | ||
4719 | /* Used to decide how to sort relocs in an optimal manner for the |
5347 | /* Used to decide how to sort relocs in an optimal manner for the |
Line 4720... | Line 5348... | ||
4720 | dynamic linker, before writing them out. */ |
5348 | dynamic linker, before writing them out. */ |
4721 | 5349 | ||
4722 | static enum elf_reloc_type_class |
5350 | static enum elf_reloc_type_class |
4723 | elf_i386_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, |
5351 | elf_i386_reloc_type_class (const struct bfd_link_info *info, |
4724 | const asection *rel_sec ATTRIBUTE_UNUSED, |
5352 | const asection *rel_sec ATTRIBUTE_UNUSED, |
- | 5353 | const Elf_Internal_Rela *rela) |
|
- | 5354 | { |
|
- | 5355 | bfd *abfd = info->output_bfd; |
|
- | 5356 | const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
|
- | 5357 | struct elf_link_hash_table *htab = elf_hash_table (info); |
|
- | 5358 | unsigned long r_symndx = ELF32_R_SYM (rela->r_info); |
|
- | 5359 | Elf_Internal_Sym sym; |
|
- | 5360 | ||
- | 5361 | if (htab->dynsym == NULL |
|
- | 5362 | || !bed->s->swap_symbol_in (abfd, |
|
- | 5363 | (htab->dynsym->contents |
|
- | 5364 | + r_symndx * sizeof (Elf32_External_Sym)), |
|
- | 5365 | 0, &sym)) |
|
- | 5366 | abort (); |
|
- | 5367 | ||
- | 5368 | /* Check relocation against STT_GNU_IFUNC symbol. */ |
|
- | 5369 | if (ELF32_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) |
|
4725 | const Elf_Internal_Rela *rela) |
5370 | return reloc_class_ifunc; |
4726 | { |
5371 | |
4727 | switch (ELF32_R_TYPE (rela->r_info)) |
5372 | switch (ELF32_R_TYPE (rela->r_info)) |
4728 | { |
5373 | { |
4729 | case R_386_RELATIVE: |
5374 | case R_386_RELATIVE: |
Line 4825... | Line 5470... | ||
4825 | } |
5470 | } |
Line 4826... | Line 5471... | ||
4826 | 5471 | ||
4827 | /* Fill in the first entry in the procedure linkage table. */ |
5472 | /* Fill in the first entry in the procedure linkage table. */ |
4828 | if (htab->elf.splt && htab->elf.splt->size > 0) |
5473 | if (htab->elf.splt && htab->elf.splt->size > 0) |
4829 | { |
5474 | { |
4830 | if (info->shared) |
5475 | if (bfd_link_pic (info)) |
4831 | { |
5476 | { |
4832 | memcpy (htab->elf.splt->contents, abed->plt->pic_plt0_entry, |
5477 | memcpy (htab->elf.splt->contents, abed->plt->pic_plt0_entry, |
4833 | abed->plt->plt0_entry_size); |
5478 | abed->plt->plt0_entry_size); |
4834 | memset (htab->elf.splt->contents + abed->plt->plt0_entry_size, |
5479 | memset (htab->elf.splt->contents + abed->plt->plt0_entry_size, |
Line 4883... | Line 5528... | ||
4883 | really seem like the right value. */ |
5528 | really seem like the right value. */ |
4884 | elf_section_data (htab->elf.splt->output_section) |
5529 | elf_section_data (htab->elf.splt->output_section) |
4885 | ->this_hdr.sh_entsize = 4; |
5530 | ->this_hdr.sh_entsize = 4; |
Line 4886... | Line 5531... | ||
4886 | 5531 | ||
4887 | /* Correct the .rel.plt.unloaded relocations. */ |
5532 | /* Correct the .rel.plt.unloaded relocations. */ |
4888 | if (abed->is_vxworks && !info->shared) |
5533 | if (abed->is_vxworks && !bfd_link_pic (info)) |
4889 | { |
5534 | { |
4890 | int num_plts = (htab->elf.splt->size |
5535 | int num_plts = (htab->elf.splt->size |
4891 | / abed->plt->plt_entry_size) - 1; |
5536 | / abed->plt->plt_entry_size) - 1; |
Line 4892... | Line 5537... | ||
4892 | unsigned char *p; |
5537 | unsigned char *p; |
4893 | 5538 | ||
4894 | p = htab->srelplt2->contents; |
5539 | p = htab->srelplt2->contents; |
4895 | if (info->shared) |
5540 | if (bfd_link_pic (info)) |
4896 | p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel); |
5541 | p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel); |
Line 4897... | Line 5542... | ||
4897 | else |
5542 | else |
Line 4974... | Line 5619... | ||
4974 | info); |
5619 | info); |
Line 4975... | Line 5620... | ||
4975 | 5620 | ||
4976 | return TRUE; |
5621 | return TRUE; |
Line 4977... | Line -... | ||
4977 | } |
- | |
4978 | 5622 | } |
|
Line 4979... | Line 5623... | ||
4979 | /* Return address for Ith PLT stub in section PLT, for relocation REL |
5623 | |
4980 | or (bfd_vma) -1 if it should not be included. */ |
5624 | /* Return an array of PLT entry symbol values. */ |
- | 5625 | ||
- | 5626 | static bfd_vma * |
|
- | 5627 | elf_i386_get_plt_sym_val (bfd *abfd, asymbol **dynsyms, asection *plt, |
|
- | 5628 | asection *relplt) |
|
- | 5629 | { |
|
- | 5630 | bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); |
|
- | 5631 | arelent *p; |
|
- | 5632 | long count, i; |
|
- | 5633 | bfd_vma *plt_sym_val; |
|
- | 5634 | bfd_vma plt_offset; |
|
- | 5635 | bfd_byte *plt_contents; |
|
- | 5636 | const struct elf_i386_backend_data *bed |
|
- | 5637 | = get_elf_i386_backend_data (abfd); |
|
- | 5638 | Elf_Internal_Shdr *hdr; |
|
- | 5639 | ||
- | 5640 | /* Get the .plt section contents. */ |
|
- | 5641 | plt_contents = (bfd_byte *) bfd_malloc (plt->size); |
|
- | 5642 | if (plt_contents == NULL) |
|
- | 5643 | return NULL; |
|
- | 5644 | if (!bfd_get_section_contents (abfd, (asection *) plt, |
|
- | 5645 | plt_contents, 0, plt->size)) |
|
- | 5646 | { |
|
- | 5647 | bad_return: |
|
- | 5648 | free (plt_contents); |
|
- | 5649 | return NULL; |
|
- | 5650 | } |
|
- | 5651 | ||
- | 5652 | slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; |
|
- | 5653 | if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE)) |
|
- | 5654 | goto bad_return; |
|
- | 5655 | ||
- | 5656 | hdr = &elf_section_data (relplt)->this_hdr; |
|
- | 5657 | count = relplt->size / hdr->sh_entsize; |
|
- | 5658 | ||
- | 5659 | plt_sym_val = (bfd_vma *) bfd_malloc (sizeof (bfd_vma) * count); |
|
- | 5660 | if (plt_sym_val == NULL) |
|
- | 5661 | goto bad_return; |
|
- | 5662 | ||
- | 5663 | for (i = 0; i < count; i++) |
|
- | 5664 | plt_sym_val[i] = -1; |
|
- | 5665 | ||
- | 5666 | plt_offset = bed->plt->plt_entry_size; |
|
- | 5667 | p = relplt->relocation; |
|
- | 5668 | for (i = 0; i < count; i++, p++) |
|
- | 5669 | { |
|
- | 5670 | long reloc_index; |
|
- | 5671 | ||
- | 5672 | /* Skip unknown relocation. PR 17512: file: bc9d6cf5. */ |
|
4981 | 5673 | if (p->howto == NULL) |
|
- | 5674 | continue; |
|
- | 5675 | ||
- | 5676 | if (p->howto->type != R_386_JUMP_SLOT |
|
- | 5677 | && p->howto->type != R_386_IRELATIVE) |
|
- | 5678 | continue; |
|
- | 5679 | ||
- | 5680 | reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset |
|
- | 5681 | + bed->plt->plt_reloc_offset)); |
|
- | 5682 | reloc_index /= sizeof (Elf32_External_Rel); |
|
- | 5683 | if (reloc_index >= count) |
|
- | 5684 | abort (); |
|
- | 5685 | plt_sym_val[reloc_index] = plt->vma + plt_offset; |
|
- | 5686 | plt_offset += bed->plt->plt_entry_size; |
|
- | 5687 | ||
- | 5688 | /* PR binutils/18437: Skip extra relocations in the .rel.plt |
|
- | 5689 | section. */ |
|
- | 5690 | if (plt_offset >= plt->size) |
|
- | 5691 | break; |
|
- | 5692 | } |
|
- | 5693 | ||
- | 5694 | free (plt_contents); |
|
- | 5695 | ||
- | 5696 | return plt_sym_val; |
|
- | 5697 | } |
|
- | 5698 | ||
- | 5699 | /* Similar to _bfd_elf_get_synthetic_symtab. */ |
|
- | 5700 | ||
- | 5701 | static long |
|
- | 5702 | elf_i386_get_synthetic_symtab (bfd *abfd, |
|
- | 5703 | long symcount, |
|
- | 5704 | asymbol **syms, |
|
4982 | static bfd_vma |
5705 | long dynsymcount, |
4983 | elf_i386_plt_sym_val (bfd_vma i, const asection *plt, |
5706 | asymbol **dynsyms, |
- | 5707 | asymbol **ret) |
|
- | 5708 | { |
|
- | 5709 | asection *plt = bfd_get_section_by_name (abfd, ".plt"); |
|
- | 5710 | return _bfd_elf_ifunc_get_synthetic_symtab (abfd, symcount, syms, |
|
4984 | const arelent *rel ATTRIBUTE_UNUSED) |
5711 | dynsymcount, dynsyms, ret, |
Line 4985... | Line 5712... | ||
4985 | { |
5712 | plt, |
Line 4986... | Line 5713... | ||
4986 | return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner); |
5713 | elf_i386_get_plt_sym_val); |
Line 5002... | Line 5729... | ||
5002 | /* Hook called by the linker routine which adds symbols from an object |
5729 | /* Hook called by the linker routine which adds symbols from an object |
5003 | file. */ |
5730 | file. */ |
Line 5004... | Line 5731... | ||
5004 | 5731 | ||
5005 | static bfd_boolean |
5732 | static bfd_boolean |
5006 | elf_i386_add_symbol_hook (bfd * abfd, |
5733 | elf_i386_add_symbol_hook (bfd * abfd, |
5007 | struct bfd_link_info * info ATTRIBUTE_UNUSED, |
5734 | struct bfd_link_info * info, |
5008 | Elf_Internal_Sym * sym, |
5735 | Elf_Internal_Sym * sym, |
5009 | const char ** namep ATTRIBUTE_UNUSED, |
5736 | const char ** namep ATTRIBUTE_UNUSED, |
5010 | flagword * flagsp ATTRIBUTE_UNUSED, |
5737 | flagword * flagsp ATTRIBUTE_UNUSED, |
5011 | asection ** secp ATTRIBUTE_UNUSED, |
5738 | asection ** secp ATTRIBUTE_UNUSED, |
5012 | bfd_vma * valp ATTRIBUTE_UNUSED) |
5739 | bfd_vma * valp ATTRIBUTE_UNUSED) |
- | 5740 | { |
|
5013 | { |
5741 | if (ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE |
5014 | if ((abfd->flags & DYNAMIC) == 0 |
5742 | && (abfd->flags & DYNAMIC) == 0 |
5015 | && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC |
5743 | && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour) |
5016 | || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)) |
5744 | elf_tdata (info->output_bfd)->has_gnu_symbols |
Line 5017... | Line 5745... | ||
5017 | elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE; |
5745 | |= elf_gnu_symbol_unique; |
5018 | 5746 | ||
Line 5019... | Line 5747... | ||
5019 | return TRUE; |
5747 | return TRUE; |
5020 | } |
5748 | } |
5021 | 5749 | ||
5022 | #define TARGET_LITTLE_SYM bfd_elf32_i386_vec |
5750 | #define TARGET_LITTLE_SYM i386_elf32_vec |
5023 | #define TARGET_LITTLE_NAME "elf32-i386" |
5751 | #define TARGET_LITTLE_NAME "elf32-i386" |
5024 | #define ELF_ARCH bfd_arch_i386 |
5752 | #define ELF_ARCH bfd_arch_i386 |
Line 5031... | Line 5759... | ||
5031 | #define elf_backend_want_got_plt 1 |
5759 | #define elf_backend_want_got_plt 1 |
5032 | #define elf_backend_plt_readonly 1 |
5760 | #define elf_backend_plt_readonly 1 |
5033 | #define elf_backend_want_plt_sym 0 |
5761 | #define elf_backend_want_plt_sym 0 |
5034 | #define elf_backend_got_header_size 12 |
5762 | #define elf_backend_got_header_size 12 |
5035 | #define elf_backend_plt_alignment 4 |
5763 | #define elf_backend_plt_alignment 4 |
- | 5764 | #define elf_backend_extern_protected_data 1 |
|
Line 5036... | Line 5765... | ||
5036 | 5765 | ||
5037 | /* Support RELA for objdump of prelink objects. */ |
5766 | /* Support RELA for objdump of prelink objects. */ |
5038 | #define elf_info_to_howto elf_i386_info_to_howto_rel |
5767 | #define elf_info_to_howto elf_i386_info_to_howto_rel |
Line 5039... | Line 5768... | ||
5039 | #define elf_info_to_howto_rel elf_i386_info_to_howto_rel |
5768 | #define elf_info_to_howto_rel elf_i386_info_to_howto_rel |
Line 5040... | Line 5769... | ||
5040 | 5769 | ||
5041 | #define bfd_elf32_mkobject elf_i386_mkobject |
5770 | #define bfd_elf32_mkobject elf_i386_mkobject |
5042 | - | ||
5043 | #define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name |
5771 | |
5044 | #define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create |
5772 | #define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name |
- | 5773 | #define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create |
|
Line 5045... | Line 5774... | ||
5045 | #define bfd_elf32_bfd_link_hash_table_free elf_i386_link_hash_table_free |
5774 | #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup |
5046 | #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup |
5775 | #define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup |
5047 | #define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup |
5776 | #define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab |
5048 | 5777 | ||
Line 5062... | Line 5791... | ||
5062 | #define elf_backend_relocate_section elf_i386_relocate_section |
5791 | #define elf_backend_relocate_section elf_i386_relocate_section |
5063 | #define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections |
5792 | #define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections |
5064 | #define elf_backend_always_size_sections elf_i386_always_size_sections |
5793 | #define elf_backend_always_size_sections elf_i386_always_size_sections |
5065 | #define elf_backend_omit_section_dynsym \ |
5794 | #define elf_backend_omit_section_dynsym \ |
5066 | ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) |
5795 | ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) |
5067 | #define elf_backend_plt_sym_val elf_i386_plt_sym_val |
- | |
5068 | #define elf_backend_hash_symbol elf_i386_hash_symbol |
5796 | #define elf_backend_hash_symbol elf_i386_hash_symbol |
5069 | #define elf_backend_add_symbol_hook elf_i386_add_symbol_hook |
5797 | #define elf_backend_add_symbol_hook elf_i386_add_symbol_hook |
5070 | #undef elf_backend_post_process_headers |
- | |
5071 | #define elf_backend_post_process_headers _bfd_elf_set_osabi |
- | |
Line 5072... | Line 5798... | ||
5072 | 5798 | ||
Line 5073... | Line 5799... | ||
5073 | #include "elf32-target.h" |
5799 | #include "elf32-target.h" |
Line 5074... | Line 5800... | ||
5074 | 5800 | ||
5075 | /* FreeBSD support. */ |
5801 | /* FreeBSD support. */ |
5076 | 5802 | ||
5077 | #undef TARGET_LITTLE_SYM |
5803 | #undef TARGET_LITTLE_SYM |
5078 | #define TARGET_LITTLE_SYM bfd_elf32_i386_freebsd_vec |
5804 | #define TARGET_LITTLE_SYM i386_elf32_fbsd_vec |
5079 | #undef TARGET_LITTLE_NAME |
5805 | #undef TARGET_LITTLE_NAME |
Line 5086... | Line 5812... | ||
5086 | executables and (for simplicity) also all other object files. */ |
5812 | executables and (for simplicity) also all other object files. */ |
Line 5087... | Line 5813... | ||
5087 | 5813 | ||
5088 | static void |
5814 | static void |
5089 | elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) |
5815 | elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) |
5090 | { |
5816 | { |
Line 5091... | Line 5817... | ||
5091 | _bfd_elf_set_osabi (abfd, info); |
5817 | _bfd_elf_post_process_headers (abfd, info); |
- | 5818 | ||
5092 | 5819 | #ifdef OLD_FREEBSD_ABI_LABEL |
|
- | 5820 | { |
|
5093 | #ifdef OLD_FREEBSD_ABI_LABEL |
5821 | /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ |
- | 5822 | Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); |
|
5094 | /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ |
5823 | memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); |
5095 | memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); |
5824 | } |
Line 5096... | Line 5825... | ||
5096 | #endif |
5825 | #endif |
5097 | } |
5826 | } |
Line 5106... | Line 5835... | ||
5106 | #include "elf32-target.h" |
5835 | #include "elf32-target.h" |
Line 5107... | Line 5836... | ||
5107 | 5836 | ||
Line 5108... | Line 5837... | ||
5108 | /* Solaris 2. */ |
5837 | /* Solaris 2. */ |
5109 | 5838 | ||
5110 | #undef TARGET_LITTLE_SYM |
5839 | #undef TARGET_LITTLE_SYM |
5111 | #define TARGET_LITTLE_SYM bfd_elf32_i386_sol2_vec |
5840 | #define TARGET_LITTLE_SYM i386_elf32_sol2_vec |
Line -... | Line 5841... | ||
- | 5841 | #undef TARGET_LITTLE_NAME |
|
- | 5842 | #define TARGET_LITTLE_NAME "elf32-i386-sol2" |
|
5112 | #undef TARGET_LITTLE_NAME |
5843 | |
5113 | #define TARGET_LITTLE_NAME "elf32-i386-sol2" |
5844 | #undef elf_backend_post_process_headers |
5114 | 5845 | ||
Line 5115... | Line 5846... | ||
5115 | /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE |
5846 | /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE |
Line 5131... | Line 5862... | ||
5131 | #undef elf_backend_want_plt_sym |
5862 | #undef elf_backend_want_plt_sym |
5132 | #define elf_backend_want_plt_sym 1 |
5863 | #define elf_backend_want_plt_sym 1 |
Line 5133... | Line 5864... | ||
5133 | 5864 | ||
Line -... | Line 5865... | ||
- | 5865 | #include "elf32-target.h" |
|
- | 5866 | ||
- | 5867 | /* Intel MCU support. */ |
|
- | 5868 | ||
- | 5869 | static bfd_boolean |
|
- | 5870 | elf32_iamcu_elf_object_p (bfd *abfd) |
|
- | 5871 | { |
|
- | 5872 | /* Set the right machine number for an IAMCU elf32 file. */ |
|
- | 5873 | bfd_default_set_arch_mach (abfd, bfd_arch_iamcu, bfd_mach_i386_iamcu); |
|
- | 5874 | return TRUE; |
|
- | 5875 | } |
|
- | 5876 | ||
- | 5877 | #undef TARGET_LITTLE_SYM |
|
- | 5878 | #define TARGET_LITTLE_SYM iamcu_elf32_vec |
|
- | 5879 | #undef TARGET_LITTLE_NAME |
|
- | 5880 | #define TARGET_LITTLE_NAME "elf32-iamcu" |
|
- | 5881 | #undef ELF_ARCH |
|
- | 5882 | #define ELF_ARCH bfd_arch_iamcu |
|
- | 5883 | ||
- | 5884 | #undef ELF_MACHINE_CODE |
|
- | 5885 | #define ELF_MACHINE_CODE EM_IAMCU |
|
- | 5886 | ||
- | 5887 | #undef ELF_OSABI |
|
- | 5888 | ||
- | 5889 | #undef elf32_bed |
|
- | 5890 | #define elf32_bed elf32_iamcu_bed |
|
- | 5891 | ||
- | 5892 | #undef elf_backend_object_p |
|
- | 5893 | #define elf_backend_object_p elf32_iamcu_elf_object_p |
|
- | 5894 | ||
- | 5895 | #undef elf_backend_static_tls_alignment |
|
- | 5896 | ||
- | 5897 | #undef elf_backend_want_plt_sym |
|
- | 5898 | #define elf_backend_want_plt_sym 0 |
|
- | 5899 | ||
- | 5900 | #include "elf32-target.h" |
|
- | 5901 | ||
- | 5902 | /* Restore defaults. */ |
|
- | 5903 | #undef ELF_ARCH |
|
- | 5904 | #define ELF_ARCH bfd_arch_i386 |
|
- | 5905 | #undef ELF_MACHINE_CODE |
|
5134 | #include "elf32-target.h" |
5906 | #define ELF_MACHINE_CODE EM_386 |
Line 5135... | Line 5907... | ||
5135 | 5907 | ||
5136 | /* Native Client support. */ |
5908 | /* Native Client support. */ |
5137 | 5909 | ||
5138 | #undef TARGET_LITTLE_SYM |
5910 | #undef TARGET_LITTLE_SYM |
5139 | #define TARGET_LITTLE_SYM bfd_elf32_i386_nacl_vec |
5911 | #define TARGET_LITTLE_SYM i386_elf32_nacl_vec |
5140 | #undef TARGET_LITTLE_NAME |
5912 | #undef TARGET_LITTLE_NAME |
Line 5148... | Line 5920... | ||
5148 | /* Restore defaults. */ |
5920 | /* Restore defaults. */ |
5149 | #undef ELF_OSABI |
5921 | #undef ELF_OSABI |
5150 | #undef elf_backend_want_plt_sym |
5922 | #undef elf_backend_want_plt_sym |
5151 | #define elf_backend_want_plt_sym 0 |
5923 | #define elf_backend_want_plt_sym 0 |
5152 | #undef elf_backend_post_process_headers |
5924 | #undef elf_backend_post_process_headers |
5153 | #define elf_backend_post_process_headers _bfd_elf_set_osabi |
- | |
5154 | #undef elf_backend_static_tls_alignment |
5925 | #undef elf_backend_static_tls_alignment |
Line 5155... | Line 5926... | ||
5155 | 5926 | ||
Line 5156... | Line 5927... | ||
5156 | /* NaCl uses substantially different PLT entries for the same effects. */ |
5927 | /* NaCl uses substantially different PLT entries for the same effects. */ |
Line 5324... | Line 6095... | ||
5324 | #undef elf_backend_final_write_processing |
6095 | #undef elf_backend_final_write_processing |
Line 5325... | Line 6096... | ||
5325 | 6096 | ||
Line 5326... | Line 6097... | ||
5326 | /* VxWorks support. */ |
6097 | /* VxWorks support. */ |
5327 | 6098 | ||
5328 | #undef TARGET_LITTLE_SYM |
6099 | #undef TARGET_LITTLE_SYM |
5329 | #define TARGET_LITTLE_SYM bfd_elf32_i386_vxworks_vec |
6100 | #define TARGET_LITTLE_SYM i386_elf32_vxworks_vec |
5330 | #undef TARGET_LITTLE_NAME |
6101 | #undef TARGET_LITTLE_NAME |
5331 | #define TARGET_LITTLE_NAME "elf32-i386-vxworks" |
6102 | #define TARGET_LITTLE_NAME "elf32-i386-vxworks" |
5332 | #undef ELF_OSABI |
6103 | #undef ELF_OSABI |
Line 5342... | Line 6113... | ||
5342 | 6113 | ||
5343 | #undef elf_backend_arch_data |
6114 | #undef elf_backend_arch_data |
Line 5344... | Line 6115... | ||
5344 | #define elf_backend_arch_data &elf_i386_vxworks_arch_bed |
6115 | #define elf_backend_arch_data &elf_i386_vxworks_arch_bed |
5345 | - | ||
5346 | #undef elf_backend_relocs_compatible |
6116 | |
5347 | #undef elf_backend_post_process_headers |
6117 | #undef elf_backend_relocs_compatible |
5348 | #undef elf_backend_add_symbol_hook |
6118 | #undef elf_backend_add_symbol_hook |
5349 | #define elf_backend_add_symbol_hook \ |
6119 | #define elf_backend_add_symbol_hook \ |
5350 | elf_vxworks_add_symbol_hook |
6120 | elf_vxworks_add_symbol_hook |