mipself.em revision 1.6 1 1.1 christos # This shell script emits a C file. -*- C -*-
2 1.6 christos # Copyright (C) 2004-2018 Free Software Foundation, Inc.
3 1.1 christos #
4 1.1 christos # This file is part of the GNU Binutils.
5 1.1 christos #
6 1.1 christos # This program is free software; you can redistribute it and/or modify
7 1.1 christos # it under the terms of the GNU General Public License as published by
8 1.1 christos # the Free Software Foundation; either version 3 of the License, or
9 1.1 christos # (at your option) any later version.
10 1.1 christos #
11 1.1 christos # This program is distributed in the hope that it will be useful,
12 1.1 christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos # GNU General Public License for more details.
15 1.1 christos #
16 1.1 christos # You should have received a copy of the GNU General Public License
17 1.1 christos # along with this program; if not, write to the Free Software
18 1.1 christos # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 christos # MA 02110-1301, USA.
20 1.1 christos
21 1.1 christos fragment <<EOF
22 1.1 christos
23 1.1 christos #include "ldctor.h"
24 1.1 christos #include "elf/mips.h"
25 1.1 christos #include "elfxx-mips.h"
26 1.1 christos
27 1.1 christos #define is_mips_elf(bfd) \
28 1.1 christos (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
29 1.1 christos && elf_tdata (bfd) != NULL \
30 1.1 christos && elf_object_id (bfd) == MIPS_ELF_DATA)
31 1.1 christos
32 1.1 christos /* Fake input file for stubs. */
33 1.1 christos static lang_input_statement_type *stub_file;
34 1.1 christos static bfd *stub_bfd;
35 1.1 christos
36 1.3 christos static bfd_boolean insn32;
37 1.6 christos static bfd_boolean ignore_branch_isa;
38 1.3 christos
39 1.1 christos static void
40 1.1 christos mips_after_parse (void)
41 1.1 christos {
42 1.1 christos /* .gnu.hash and the MIPS ABI require .dynsym to be sorted in different
43 1.1 christos ways. .gnu.hash needs symbols to be grouped by hash code whereas the
44 1.1 christos MIPS ABI requires a mapping between the GOT and the symbol table. */
45 1.1 christos if (link_info.emit_gnu_hash)
46 1.1 christos {
47 1.6 christos einfo (_("%X%P: .gnu.hash is incompatible with the MIPS ABI\n"));
48 1.1 christos link_info.emit_hash = TRUE;
49 1.1 christos link_info.emit_gnu_hash = FALSE;
50 1.1 christos }
51 1.3 christos gld${EMULATION_NAME}_after_parse ();
52 1.1 christos }
53 1.1 christos
54 1.1 christos struct hook_stub_info
55 1.1 christos {
56 1.1 christos lang_statement_list_type add;
57 1.1 christos asection *input_section;
58 1.1 christos };
59 1.1 christos
60 1.1 christos /* Traverse the linker tree to find the spot where the stub goes. */
61 1.1 christos
62 1.1 christos static bfd_boolean
63 1.1 christos hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
64 1.1 christos {
65 1.1 christos lang_statement_union_type *l;
66 1.1 christos bfd_boolean ret;
67 1.1 christos
68 1.1 christos for (; (l = *lp) != NULL; lp = &l->header.next)
69 1.1 christos {
70 1.1 christos switch (l->header.type)
71 1.1 christos {
72 1.1 christos case lang_constructors_statement_enum:
73 1.1 christos ret = hook_in_stub (info, &constructor_list.head);
74 1.1 christos if (ret)
75 1.1 christos return ret;
76 1.1 christos break;
77 1.1 christos
78 1.1 christos case lang_output_section_statement_enum:
79 1.1 christos ret = hook_in_stub (info,
80 1.1 christos &l->output_section_statement.children.head);
81 1.1 christos if (ret)
82 1.1 christos return ret;
83 1.1 christos break;
84 1.1 christos
85 1.1 christos case lang_wild_statement_enum:
86 1.1 christos ret = hook_in_stub (info, &l->wild_statement.children.head);
87 1.1 christos if (ret)
88 1.1 christos return ret;
89 1.1 christos break;
90 1.1 christos
91 1.1 christos case lang_group_statement_enum:
92 1.1 christos ret = hook_in_stub (info, &l->group_statement.children.head);
93 1.1 christos if (ret)
94 1.1 christos return ret;
95 1.1 christos break;
96 1.1 christos
97 1.1 christos case lang_input_section_enum:
98 1.1 christos if (info->input_section == NULL
99 1.1 christos || l->input_section.section == info->input_section)
100 1.1 christos {
101 1.1 christos /* We've found our section. Insert the stub immediately
102 1.1 christos before its associated input section. */
103 1.1 christos *lp = info->add.head;
104 1.1 christos *(info->add.tail) = l;
105 1.1 christos return TRUE;
106 1.1 christos }
107 1.1 christos break;
108 1.1 christos
109 1.1 christos case lang_data_statement_enum:
110 1.1 christos case lang_reloc_statement_enum:
111 1.1 christos case lang_object_symbols_statement_enum:
112 1.1 christos case lang_output_statement_enum:
113 1.1 christos case lang_target_statement_enum:
114 1.1 christos case lang_input_statement_enum:
115 1.1 christos case lang_assignment_statement_enum:
116 1.1 christos case lang_padding_statement_enum:
117 1.1 christos case lang_address_statement_enum:
118 1.1 christos case lang_fill_statement_enum:
119 1.1 christos break;
120 1.1 christos
121 1.1 christos default:
122 1.1 christos FAIL ();
123 1.1 christos break;
124 1.1 christos }
125 1.1 christos }
126 1.1 christos return FALSE;
127 1.1 christos }
128 1.1 christos
129 1.1 christos /* Create a new stub section called STUB_SEC_NAME and arrange for it to
130 1.1 christos be linked in OUTPUT_SECTION. The section should go at the beginning of
131 1.1 christos OUTPUT_SECTION if INPUT_SECTION is null, otherwise it must go immediately
132 1.1 christos before INPUT_SECTION. */
133 1.1 christos
134 1.1 christos static asection *
135 1.1 christos mips_add_stub_section (const char *stub_sec_name, asection *input_section,
136 1.1 christos asection *output_section)
137 1.1 christos {
138 1.1 christos asection *stub_sec;
139 1.1 christos flagword flags;
140 1.1 christos lang_output_section_statement_type *os;
141 1.1 christos struct hook_stub_info info;
142 1.1 christos
143 1.1 christos /* PR 12845: If the input section has been garbage collected it will
144 1.1 christos not have its output section set to *ABS*. */
145 1.1 christos if (bfd_is_abs_section (output_section))
146 1.1 christos return NULL;
147 1.1 christos
148 1.1 christos /* Create the stub file, if we haven't already. */
149 1.1 christos if (stub_file == NULL)
150 1.1 christos {
151 1.1 christos stub_file = lang_add_input_file ("linker stubs",
152 1.1 christos lang_input_file_is_fake_enum,
153 1.1 christos NULL);
154 1.1 christos stub_bfd = bfd_create ("linker stubs", link_info.output_bfd);
155 1.1 christos if (stub_bfd == NULL
156 1.1 christos || !bfd_set_arch_mach (stub_bfd,
157 1.1 christos bfd_get_arch (link_info.output_bfd),
158 1.1 christos bfd_get_mach (link_info.output_bfd)))
159 1.1 christos {
160 1.6 christos einfo (_("%F%P: can not create BFD: %E\n"));
161 1.1 christos return NULL;
162 1.1 christos }
163 1.1 christos stub_bfd->flags |= BFD_LINKER_CREATED;
164 1.1 christos stub_file->the_bfd = stub_bfd;
165 1.1 christos ldlang_add_file (stub_file);
166 1.1 christos }
167 1.1 christos
168 1.1 christos /* Create the section. */
169 1.1 christos stub_sec = bfd_make_section_anyway (stub_bfd, stub_sec_name);
170 1.1 christos if (stub_sec == NULL)
171 1.1 christos goto err_ret;
172 1.1 christos
173 1.1 christos /* Set the flags. */
174 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
175 1.1 christos | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
176 1.1 christos if (!bfd_set_section_flags (stub_bfd, stub_sec, flags))
177 1.1 christos goto err_ret;
178 1.1 christos
179 1.3 christos os = lang_output_section_get (output_section);
180 1.1 christos
181 1.1 christos /* Initialize a statement list that contains only the new statement. */
182 1.1 christos lang_list_init (&info.add);
183 1.1 christos lang_add_section (&info.add, stub_sec, NULL, os);
184 1.1 christos if (info.add.head == NULL)
185 1.1 christos goto err_ret;
186 1.1 christos
187 1.1 christos /* Insert the new statement in the appropriate place. */
188 1.1 christos info.input_section = input_section;
189 1.1 christos if (hook_in_stub (&info, &os->children.head))
190 1.1 christos return stub_sec;
191 1.1 christos
192 1.1 christos err_ret:
193 1.6 christos einfo (_("%X%P: can not make stub section: %E\n"));
194 1.1 christos return NULL;
195 1.1 christos }
196 1.1 christos
197 1.1 christos /* This is called before the input files are opened. */
198 1.1 christos
199 1.1 christos static void
200 1.1 christos mips_create_output_section_statements (void)
201 1.1 christos {
202 1.3 christos struct elf_link_hash_table *htab;
203 1.3 christos
204 1.3 christos htab = elf_hash_table (&link_info);
205 1.3 christos if (is_elf_hash_table (htab) && is_mips_elf (link_info.output_bfd))
206 1.6 christos _bfd_mips_elf_linker_flags (&link_info, insn32, ignore_branch_isa);
207 1.3 christos
208 1.1 christos if (is_mips_elf (link_info.output_bfd))
209 1.1 christos _bfd_mips_elf_init_stubs (&link_info, mips_add_stub_section);
210 1.1 christos }
211 1.1 christos
212 1.1 christos /* This is called after we have merged the private data of the input bfds. */
213 1.1 christos
214 1.1 christos static void
215 1.1 christos mips_before_allocation (void)
216 1.1 christos {
217 1.6 christos if (is_mips_elf (link_info.output_bfd))
218 1.6 christos {
219 1.6 christos flagword flags;
220 1.1 christos
221 1.6 christos flags = elf_elfheader (link_info.output_bfd)->e_flags;
222 1.6 christos if (!bfd_link_pic (&link_info)
223 1.6 christos && !link_info.nocopyreloc
224 1.6 christos && (flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
225 1.6 christos _bfd_mips_elf_use_plts_and_copy_relocs (&link_info);
226 1.6 christos }
227 1.1 christos
228 1.1 christos gld${EMULATION_NAME}_before_allocation ();
229 1.1 christos }
230 1.1 christos
231 1.1 christos /* Avoid processing the fake stub_file in vercheck, stat_needed and
232 1.1 christos check_needed routines. */
233 1.1 christos
234 1.1 christos static void (*real_func) (lang_input_statement_type *);
235 1.1 christos
236 1.1 christos static void mips_for_each_input_file_wrapper (lang_input_statement_type *l)
237 1.1 christos {
238 1.1 christos if (l != stub_file)
239 1.1 christos (*real_func) (l);
240 1.1 christos }
241 1.1 christos
242 1.1 christos static void
243 1.1 christos mips_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
244 1.1 christos {
245 1.1 christos real_func = func;
246 1.1 christos lang_for_each_input_file (&mips_for_each_input_file_wrapper);
247 1.1 christos }
248 1.1 christos
249 1.1 christos #define lang_for_each_input_file mips_lang_for_each_input_file
250 1.1 christos
251 1.1 christos EOF
252 1.1 christos
253 1.3 christos # Define some shell vars to insert bits of code into the standard elf
254 1.3 christos # parse_args and list_options functions.
255 1.3 christos #
256 1.3 christos PARSE_AND_LIST_PROLOGUE='
257 1.5 christos enum
258 1.5 christos {
259 1.5 christos OPTION_INSN32 = 301,
260 1.6 christos OPTION_NO_INSN32,
261 1.6 christos OPTION_IGNORE_BRANCH_ISA,
262 1.6 christos OPTION_NO_IGNORE_BRANCH_ISA
263 1.5 christos };
264 1.3 christos '
265 1.3 christos
266 1.3 christos PARSE_AND_LIST_LONGOPTS='
267 1.3 christos { "insn32", no_argument, NULL, OPTION_INSN32 },
268 1.3 christos { "no-insn32", no_argument, NULL, OPTION_NO_INSN32 },
269 1.6 christos { "ignore-branch-isa", no_argument, NULL, OPTION_IGNORE_BRANCH_ISA },
270 1.6 christos { "no-ignore-branch-isa", no_argument, NULL, OPTION_NO_IGNORE_BRANCH_ISA },
271 1.3 christos '
272 1.3 christos
273 1.3 christos PARSE_AND_LIST_OPTIONS='
274 1.3 christos fprintf (file, _("\
275 1.3 christos --insn32 Only generate 32-bit microMIPS instructions\n"
276 1.3 christos ));
277 1.3 christos fprintf (file, _("\
278 1.3 christos --no-insn32 Generate all microMIPS instructions\n"
279 1.3 christos ));
280 1.6 christos fprintf (file, _("\
281 1.6 christos --ignore-branch-isa Accept invalid branch relocations requiring\n\
282 1.6 christos an ISA mode switch\n"
283 1.6 christos ));
284 1.6 christos fprintf (file, _("\
285 1.6 christos --no-ignore-branch-isa Reject invalid branch relocations requiring\n\
286 1.6 christos an ISA mode switch\n"
287 1.6 christos ));
288 1.3 christos '
289 1.3 christos
290 1.3 christos PARSE_AND_LIST_ARGS_CASES='
291 1.3 christos case OPTION_INSN32:
292 1.3 christos insn32 = TRUE;
293 1.3 christos break;
294 1.3 christos
295 1.3 christos case OPTION_NO_INSN32:
296 1.3 christos insn32 = FALSE;
297 1.3 christos break;
298 1.6 christos
299 1.6 christos case OPTION_IGNORE_BRANCH_ISA:
300 1.6 christos ignore_branch_isa = TRUE;
301 1.6 christos break;
302 1.6 christos
303 1.6 christos case OPTION_NO_IGNORE_BRANCH_ISA:
304 1.6 christos ignore_branch_isa = FALSE;
305 1.6 christos break;
306 1.3 christos '
307 1.3 christos
308 1.1 christos LDEMUL_AFTER_PARSE=mips_after_parse
309 1.1 christos LDEMUL_BEFORE_ALLOCATION=mips_before_allocation
310 1.1 christos LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=mips_create_output_section_statements
311