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