| 1 | --- a/bfd/elf32-mips.c |
| 2 | +++ b/bfd/elf32-mips.c |
| 3 | @@ -1663,6 +1663,15 @@ static const struct ecoff_debug_swap mip |
| 4 | #define elf_backend_plt_readonly 1 |
| 5 | #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val |
| 6 | |
| 7 | +/* Most MIPS ELF files do not contain a traditional PLT; only VxWorks |
| 8 | + and non-PIC dynamic executables do. These settings only affect |
| 9 | + _bfd_elf_create_dynamic_sections, which is only called when we |
| 10 | + do want a traditional PLT. */ |
| 11 | +#undef elf_backend_want_plt_sym |
| 12 | +#define elf_backend_want_plt_sym 1 |
| 13 | +#undef elf_backend_plt_readonly |
| 14 | +#define elf_backend_plt_readonly 1 |
| 15 | + |
| 16 | #define elf_backend_discard_info _bfd_mips_elf_discard_info |
| 17 | #define elf_backend_ignore_discarded_relocs \ |
| 18 | _bfd_mips_elf_ignore_discarded_relocs |
| 19 | @@ -1686,6 +1695,8 @@ static const struct ecoff_debug_swap mip |
| 20 | #define bfd_elf32_bfd_print_private_bfd_data \ |
| 21 | _bfd_mips_elf_print_private_bfd_data |
| 22 | |
| 23 | +#define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val |
| 24 | + |
| 25 | /* Support for SGI-ish mips targets. */ |
| 26 | #define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec |
| 27 | #define TARGET_LITTLE_NAME "elf32-littlemips" |
| 28 | @@ -1789,6 +1800,7 @@ mips_vxworks_final_write_processing (bfd |
| 29 | #undef elf_backend_additional_program_headers |
| 30 | #undef elf_backend_modify_segment_map |
| 31 | #undef elf_backend_symbol_processing |
| 32 | +#undef elf_backend_plt_sym_val |
| 33 | /* NOTE: elf_backend_rela_normal is not defined for MIPS. */ |
| 34 | |
| 35 | #include "elf32-target.h" |
| 36 | --- a/bfd/elfxx-mips.c |
| 37 | +++ b/bfd/elfxx-mips.c |
| 38 | @@ -713,6 +713,11 @@ static bfd *reldyn_sorting_bfd; |
| 39 | /* Nonzero if ABFD is using NewABI conventions. */ |
| 40 | #define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd)) |
| 41 | |
| 42 | +/* Nonzero if ABFD is a non-PIC object. */ |
| 43 | +#define NON_PIC_P(abfd) \ |
| 44 | + (((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) == 0) \ |
| 45 | + && ((elf_elfheader (abfd)->e_flags & EF_MIPS_CPIC) == EF_MIPS_CPIC)) |
| 46 | + |
| 47 | /* The IRIX compatibility level we are striving for. */ |
| 48 | #define IRIX_COMPAT(abfd) \ |
| 49 | (get_elf_backend_data (abfd)->elf_backend_mips_irix_compat (abfd)) |
| 50 | @@ -725,6 +730,9 @@ static bfd *reldyn_sorting_bfd; |
| 51 | #define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \ |
| 52 | (NEWABI_P (abfd) ? ".MIPS.options" : ".options") |
| 53 | |
| 54 | +/* The name of the section holding non-PIC to PIC call stubs. */ |
| 55 | +#define NON_PIC_TO_PIC_STUB_SECTION_NAME ".MIPS.pic_stubs" |
| 56 | + |
| 57 | /* True if NAME is the recognized name of any SHT_MIPS_OPTIONS section. |
| 58 | Some IRIX system files do not use MIPS_ELF_OPTIONS_SECTION_NAME. */ |
| 59 | #define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \ |
| 60 | @@ -7686,7 +7694,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s |
| 61 | |
| 62 | /* We need a stub, not a plt entry for the undefined |
| 63 | function. But we record it as if it needs plt. See |
| 64 | - _bfd_elf_adjust_dynamic_symbol. */ |
| 65 | + _bfd_elf_adjust_dynamic_symbol. Note that these relocations |
| 66 | + are always used for PIC calls, even when using the new |
| 67 | + non-PIC ABI. */ |
| 68 | h->needs_plt = 1; |
| 69 | h->type = STT_FUNC; |
| 70 | } |
| 71 | @@ -7793,6 +7803,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s |
| 72 | case R_MIPS_32: |
| 73 | case R_MIPS_REL32: |
| 74 | case R_MIPS_64: |
| 75 | + if (h != NULL) |
| 76 | + h->non_got_ref = TRUE; |
| 77 | /* In VxWorks executables, references to external symbols |
| 78 | are handled using copy relocs or PLT stubs, so there's |
| 79 | no need to add a .rela.dyn entry for this relocation. */ |
| 80 | @@ -7848,11 +7860,21 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s |
| 81 | case R_MIPS_GPREL16: |
| 82 | case R_MIPS_LITERAL: |
| 83 | case R_MIPS_GPREL32: |
| 84 | + if (h != NULL |
| 85 | + && (r_type == R_MIPS_GPREL16 || r_type == R_MIPS_GPREL32)) |
| 86 | + h->non_got_ref = TRUE; |
| 87 | + |
| 88 | if (SGI_COMPAT (abfd)) |
| 89 | mips_elf_hash_table (info)->compact_rel_size += |
| 90 | sizeof (Elf32_External_crinfo); |
| 91 | break; |
| 92 | |
| 93 | + case R_MIPS_HI16: |
| 94 | + case R_MIPS_LO16: |
| 95 | + if (h != NULL && strcmp (h->root.root.string, "_gp_disp") != 0) |
| 96 | + h->non_got_ref = TRUE; |
| 97 | + break; |
| 98 | + |
| 99 | /* This relocation describes the C++ object vtable hierarchy. |
| 100 | Reconstruct it for later use during GC. */ |
| 101 | case R_MIPS_GNU_VTINHERIT: |
| 102 | @@ -7875,20 +7897,20 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s |
| 103 | |
| 104 | /* We must not create a stub for a symbol that has relocations |
| 105 | related to taking the function's address. This doesn't apply to |
| 106 | - VxWorks, where CALL relocs refer to a .got.plt entry instead of |
| 107 | - a normal .got entry. */ |
| 108 | + VxWorks or the non-PIC ABI, where CALL relocs refer to a |
| 109 | + .got.plt entry instead of a normal .got entry. */ |
| 110 | if (!htab->is_vxworks && h != NULL) |
| 111 | switch (r_type) |
| 112 | { |
| 113 | - default: |
| 114 | - ((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE; |
| 115 | - break; |
| 116 | case R_MIPS16_CALL16: |
| 117 | case R_MIPS_CALL16: |
| 118 | case R_MIPS_CALL_HI16: |
| 119 | case R_MIPS_CALL_LO16: |
| 120 | case R_MIPS_JALR: |
| 121 | break; |
| 122 | + default: |
| 123 | + ((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE; |
| 124 | + break; |
| 125 | } |
| 126 | |
| 127 | /* See if this reloc would need to refer to a MIPS16 hard-float stub, |
| 128 | @@ -12601,7 +12623,9 @@ _bfd_mips_elf_merge_private_bfd_data (bf |
| 129 | break; |
| 130 | } |
| 131 | } |
| 132 | - if (null_input_bfd) |
| 133 | + /* Dynamic objects normally have no sections, and do not reach |
| 134 | + here - but they might if used as DYNOBJ. */ |
| 135 | + if (null_input_bfd || (ibfd->flags & DYNAMIC) != 0) |
| 136 | return TRUE; |
| 137 | |
| 138 | ok = TRUE; |
| 139 | --- a/bfd/elfxx-mips.h |
| 140 | +++ b/bfd/elfxx-mips.h |
| 141 | @@ -64,6 +64,9 @@ extern bfd_boolean _bfd_mips_elf_finish_ |
| 142 | extern bfd_boolean _bfd_mips_vxworks_finish_dynamic_symbol |
| 143 | (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, |
| 144 | Elf_Internal_Sym *); |
| 145 | +extern bfd_boolean _bfd_mips_nonpic_finish_dynamic_symbol |
| 146 | + (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, |
| 147 | + Elf_Internal_Sym *); |
| 148 | extern bfd_boolean _bfd_mips_elf_finish_dynamic_sections |
| 149 | (bfd *, struct bfd_link_info *); |
| 150 | extern void _bfd_mips_elf_final_write_processing |
| 151 | @@ -158,6 +161,15 @@ gprel16_reloc_p (unsigned int r_type) |
| 152 | return r_type == R_MIPS_GPREL16 || r_type == R_MIPS16_GPREL; |
| 153 | } |
| 154 | |
| 155 | +extern bfd_vma _bfd_mips_elf_plt_sym_val |
| 156 | + (bfd_vma, const asection *, const arelent *); |
| 157 | +extern void _bfd_mips_elf_begin_write_processing |
| 158 | + (bfd *abfd, struct bfd_link_info *link_info); |
| 159 | +extern bfd_boolean bfd_mips_elf_maybe_create_non_pic_to_pic_stubs_section |
| 160 | + (struct bfd_link_info *); |
| 161 | +extern void _bfd_mips_post_process_headers |
| 162 | + (bfd *abfd, struct bfd_link_info *link_info); |
| 163 | + |
| 164 | #define elf_backend_common_definition _bfd_mips_elf_common_definition |
| 165 | #define elf_backend_name_local_section_symbols \ |
| 166 | _bfd_mips_elf_name_local_section_symbols |
| 167 | --- a/gas/config/tc-mips.c |
| 168 | +++ b/gas/config/tc-mips.c |
| 169 | @@ -1900,6 +1900,12 @@ md_begin (void) |
| 170 | as_bad (_("-G may not be used in position-independent code")); |
| 171 | g_switch_value = 0; |
| 172 | } |
| 173 | + else if (mips_abicalls) |
| 174 | + { |
| 175 | + if (g_switch_seen && g_switch_value != 0) |
| 176 | + as_bad (_("-G may not be used with abicalls")); |
| 177 | + g_switch_value = 0; |
| 178 | + } |
| 179 | |
| 180 | if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_arch)) |
| 181 | as_warn (_("Could not set architecture and machine")); |
| 182 | @@ -11270,6 +11276,7 @@ enum options |
| 183 | OPTION_PDR, |
| 184 | OPTION_NO_PDR, |
| 185 | OPTION_MVXWORKS_PIC, |
| 186 | + OPTION_NON_PIC_ABICALLS, |
| 187 | #endif /* OBJ_ELF */ |
| 188 | OPTION_END_OF_ENUM |
| 189 | }; |
| 190 | @@ -11377,6 +11384,7 @@ struct option md_longopts[] = |
| 191 | {"mpdr", no_argument, NULL, OPTION_PDR}, |
| 192 | {"mno-pdr", no_argument, NULL, OPTION_NO_PDR}, |
| 193 | {"mvxworks-pic", no_argument, NULL, OPTION_MVXWORKS_PIC}, |
| 194 | + {"mnon-pic-abicalls", no_argument, NULL, OPTION_NON_PIC_ABICALLS}, |
| 195 | #endif /* OBJ_ELF */ |
| 196 | |
| 197 | {NULL, no_argument, NULL, 0} |
| 198 | @@ -11825,6 +11833,11 @@ md_parse_option (int c, char *arg) |
| 199 | case OPTION_MVXWORKS_PIC: |
| 200 | mips_pic = VXWORKS_PIC; |
| 201 | break; |
| 202 | + |
| 203 | + case OPTION_NON_PIC_ABICALLS: |
| 204 | + mips_pic = NO_PIC; |
| 205 | + mips_abicalls = TRUE; |
| 206 | + break; |
| 207 | #endif /* OBJ_ELF */ |
| 208 | |
| 209 | default: |
| 210 | |