]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/emultempl/ppc64elf.em
* genscripts.sh (LIB_PATH): For native targets, concatenate $libdir
[thirdparty/binutils-gdb.git] / ld / emultempl / ppc64elf.em
CommitLineData
1f808cd5
AM
1# This shell script emits a C file. -*- C -*-
2# Copyright 2002 Free Software Foundation, Inc.
3#
4# This file is part of GLD, the Gnu Linker.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20
21# This file is sourced from elf32.em, and defines extra powerpc64-elf
22# specific routines.
23#
24cat >>e${EMULATION_NAME}.c <<EOF
25
9c1d81c1 26#include "ldctor.h"
805fc799 27#include "libbfd.h"
1f808cd5
AM
28#include "elf64-ppc.h"
29
9c1d81c1
AM
30/* Fake input file for stubs. */
31static lang_input_statement_type *stub_file;
32
33/* Whether we need to call ppc_layout_sections_again. */
1f808cd5
AM
34static int need_laying_out = 0;
35
9c1d81c1
AM
36/* Maximum size of a group of input sections that can be handled by
37 one stub section. A value of +/-1 indicates the bfd back-end
38 should use a suitable default size. */
39static bfd_signed_vma group_size = 1;
40
41static void ppc_create_output_section_statements PARAMS ((void));
42static asection *ppc_add_stub_section PARAMS ((const char *, asection *));
43static void ppc_layout_sections_again PARAMS ((void));
1f808cd5 44static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
9c1d81c1
AM
45static void build_section_lists PARAMS ((lang_statement_union_type *));
46
47/* This is called before the input files are opened. We create a new
48 fake input file to hold the stub sections. */
49
50static void
51ppc_create_output_section_statements ()
52{
53 stub_file = lang_add_input_file ("linker stubs",
54 lang_input_file_is_fake_enum,
55 NULL);
56 stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
57 if (stub_file->the_bfd == NULL
58 || !bfd_set_arch_mach (stub_file->the_bfd,
59 bfd_get_arch (output_bfd),
60 bfd_get_mach (output_bfd)))
61 {
62 einfo ("%X%P: can not create BFD %E\n");
63 return;
64 }
65
66 ldlang_add_file (stub_file);
67}
68
69
70struct hook_stub_info
71{
72 lang_statement_list_type add;
73 asection *input_section;
74};
75
76/* Traverse the linker tree to find the spot where the stub goes. */
77
78static boolean hook_in_stub
79 PARAMS ((struct hook_stub_info *, lang_statement_union_type **));
80
81static boolean
82hook_in_stub (info, lp)
83 struct hook_stub_info *info;
84 lang_statement_union_type **lp;
85{
86 lang_statement_union_type *l;
87 boolean ret;
88
89 for (; (l = *lp) != NULL; lp = &l->header.next)
90 {
91 switch (l->header.type)
92 {
93 case lang_constructors_statement_enum:
94 ret = hook_in_stub (info, &constructor_list.head);
95 if (ret)
96 return ret;
97 break;
98
99 case lang_output_section_statement_enum:
100 ret = hook_in_stub (info,
101 &l->output_section_statement.children.head);
102 if (ret)
103 return ret;
104 break;
105
106 case lang_wild_statement_enum:
107 ret = hook_in_stub (info, &l->wild_statement.children.head);
108 if (ret)
109 return ret;
110 break;
111
112 case lang_group_statement_enum:
113 ret = hook_in_stub (info, &l->group_statement.children.head);
114 if (ret)
115 return ret;
116 break;
117
118 case lang_input_section_enum:
119 if (l->input_section.section == info->input_section)
120 {
121 /* We've found our section. Insert the stub immediately
122 before its associated input section. */
123 *lp = info->add.head;
124 *(info->add.tail) = l;
125 return true;
126 }
127 break;
128
129 case lang_data_statement_enum:
130 case lang_reloc_statement_enum:
131 case lang_object_symbols_statement_enum:
132 case lang_output_statement_enum:
133 case lang_target_statement_enum:
134 case lang_input_statement_enum:
135 case lang_assignment_statement_enum:
136 case lang_padding_statement_enum:
137 case lang_address_statement_enum:
138 case lang_fill_statement_enum:
139 break;
140
141 default:
142 FAIL ();
143 break;
144 }
145 }
146 return false;
147}
148
149
150/* Call-back for ppc64_elf_size_stubs. */
151
152/* Create a new stub section, and arrange for it to be linked
153 immediately before INPUT_SECTION. */
154
155static asection *
156ppc_add_stub_section (stub_sec_name, input_section)
157 const char *stub_sec_name;
158 asection *input_section;
159{
160 asection *stub_sec;
161 flagword flags;
162 asection *output_section;
163 const char *secname;
164 lang_output_section_statement_type *os;
165 struct hook_stub_info info;
166
167 stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_sec_name);
168 if (stub_sec == NULL)
169 goto err_ret;
170
171 flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
172 | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
173 if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
174 goto err_ret;
175
176 output_section = input_section->output_section;
177 secname = bfd_get_section_name (output_section->owner, output_section);
178 os = lang_output_section_find (secname);
179
180 info.input_section = input_section;
181 lang_list_init (&info.add);
182 lang_add_section (&info.add, stub_sec, os, stub_file);
183
184 if (info.add.head == NULL)
185 goto err_ret;
186
187 if (hook_in_stub (&info, &os->children.head))
188 return stub_sec;
189
190 err_ret:
191 einfo ("%X%P: can not make stub section: %E\n");
192 return NULL;
193}
194
195
196/* Another call-back for ppc64_elf_size_stubs. */
197
198static void
199ppc_layout_sections_again ()
200{
201 /* If we have changed sizes of the stub sections, then we need
202 to recalculate all the section offsets. This may mean we need to
203 add even more stubs. */
204 need_laying_out = 0;
205
206 lang_reset_memory_regions ();
207
208 /* Resize the sections. */
209 lang_size_sections (stat_ptr->head, abs_output_section,
210 &stat_ptr->head, 0, (bfd_vma) 0, NULL);
211
212 /* Recalculate TOC base. */
213 ldemul_after_allocation ();
214
215 /* Do the assignments again. */
216 lang_do_assignments (stat_ptr->head, abs_output_section,
217 (fill_type *) 0, (bfd_vma) 0);
218}
219
1f808cd5
AM
220
221/* Call the back-end function to set TOC base after we have placed all
222 the sections. */
223static void
224gld${EMULATION_NAME}_after_allocation ()
225{
805fc799
AM
226 if (!link_info.relocateable)
227 _bfd_set_gp_value (output_bfd, ppc64_elf_toc (output_bfd));
1f808cd5
AM
228}
229
9c1d81c1
AM
230
231static void
232build_section_lists (statement)
233 lang_statement_union_type *statement;
234{
235 if (statement->header.type == lang_input_section_enum
805fc799
AM
236 && !statement->input_section.ifile->just_syms_flag
237 && statement->input_section.section->output_section != NULL
238 && statement->input_section.section->output_section->owner == output_bfd)
9c1d81c1 239 {
805fc799 240 ppc64_elf_next_input_section (&link_info,
9c1d81c1
AM
241 statement->input_section.section);
242 }
243}
244
245/* Final emulation specific call. */
1f808cd5
AM
246
247static void
248gld${EMULATION_NAME}_finish ()
249{
9c1d81c1
AM
250 int ret;
251
1e281515
AM
252 /* e_entry on PowerPC64 points to the function descriptor for
253 _start. If _start is missing, default to the first function
254 descriptor in the .opd section. */
255 entry_section = ".opd";
256
1f808cd5
AM
257 /* If generating a relocatable output file, then we don't have any
258 stubs. */
259 if (link_info.relocateable)
260 return;
261
262 /* bfd_elf64_discard_info just plays with debugging sections,
263 ie. doesn't affect any code, so we can delay resizing the
264 sections. It's likely we'll resize everything in the process of
9c1d81c1 265 adding stubs. */
1f808cd5
AM
266 if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
267 need_laying_out = 1;
268
9c1d81c1
AM
269 ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
270 if (ret != 0)
1f808cd5 271 {
9c1d81c1
AM
272 if (ret < 0)
273 {
274 einfo ("%X%P: can not size stub section: %E\n");
275 return;
276 }
277
278 lang_for_each_statement (build_section_lists);
279
1f808cd5 280 /* Call into the BFD backend to do the real work. */
9c1d81c1
AM
281 if (!ppc64_elf_size_stubs (output_bfd,
282 stub_file->the_bfd,
283 &link_info,
284 group_size,
285 &ppc_add_stub_section,
286 &ppc_layout_sections_again))
1f808cd5
AM
287 {
288 einfo ("%X%P: can not size stub section: %E\n");
289 return;
290 }
9c1d81c1 291 }
1f808cd5 292
9c1d81c1
AM
293 if (need_laying_out)
294 ppc_layout_sections_again ();
1f808cd5 295
9c1d81c1
AM
296 if (stub_file->the_bfd->sections != NULL)
297 {
298 if (!ppc64_elf_build_stubs (&link_info))
299 einfo ("%X%P: can not build stubs: %E\n");
300 }
301}
1f808cd5 302
76dc39fe 303
9c1d81c1
AM
304/* Avoid processing the fake stub_file in vercheck, stat_needed and
305 check_needed routines. */
1f808cd5 306
9c1d81c1
AM
307static void ppc_for_each_input_file_wrapper
308 PARAMS ((lang_input_statement_type *));
309static void ppc_lang_for_each_input_file
310 PARAMS ((void (*) (lang_input_statement_type *)));
1f808cd5 311
9c1d81c1 312static void (*real_func) PARAMS ((lang_input_statement_type *));
1f808cd5 313
9c1d81c1
AM
314static void ppc_for_each_input_file_wrapper (l)
315 lang_input_statement_type *l;
316{
317 if (l != stub_file)
318 (*real_func) (l);
1f808cd5 319}
9c1d81c1
AM
320
321static void
322ppc_lang_for_each_input_file (func)
323 void (*func) PARAMS ((lang_input_statement_type *));
324{
325 real_func = func;
326 lang_for_each_input_file (&ppc_for_each_input_file_wrapper);
327}
328
329#define lang_for_each_input_file ppc_lang_for_each_input_file
330
1f808cd5
AM
331EOF
332
9c1d81c1
AM
333# Define some shell vars to insert bits of code into the standard elf
334# parse_args and list_options functions.
335#
336PARSE_AND_LIST_PROLOGUE='
337#define OPTION_STUBGROUP_SIZE 301
338'
339
340# The options are repeated below so that no abbreviations are allowed.
341# Otherwise -s matches stub-group-size
342PARSE_AND_LIST_LONGOPTS='
343 { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
344 { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
345'
346
347PARSE_AND_LIST_OPTIONS='
348 fprintf (file, _("\
349 --stub-group-size=N Maximum size of a group of input sections that can be\n\
350 handled by one stub section. A negative value\n\
351 locates all stubs before their branches (with a\n\
352 group size of -N), while a positive value allows\n\
353 two groups of input sections, one before, and one\n\
354 after each stub section. Values of +/-1 indicate\n\
355 the linker should choose suitable defaults.\n"
356 ));
357'
358
359PARSE_AND_LIST_ARGS_CASES='
360 case OPTION_STUBGROUP_SIZE:
361 {
362 const char *end;
363 group_size = bfd_scan_vma (optarg, &end, 0);
364 if (*end)
365 einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
366 }
367 break;
368'
369
1f808cd5
AM
370# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
371#
372LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
373LDEMUL_FINISH=gld${EMULATION_NAME}_finish
9c1d81c1 374LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements