fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / binutils / ld / emultempl / hppaelf.em
blob93e88ad655a0a6dc9f9490fd9f39aa7795c104ae
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright 1991, 1993, 1994, 1997, 1999, 2000, 2001, 2002, 2003
3 #   Free Software Foundation, Inc.
5 # This file is part of GLD, the Gnu Linker.
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 # This file is sourced from elf32.em, and defines extra hppa-elf
23 # specific routines.
25 cat >>e${EMULATION_NAME}.c <<EOF
27 #include "ldctor.h"
28 #include "elf32-hppa.h"
31 /* Fake input file for stubs.  */
32 static lang_input_statement_type *stub_file;
34 /* Type of import/export stubs to build.  For a single sub-space model,
35    we can build smaller import stubs and there is no need for export
36    stubs.  */
37 static int multi_subspace = 0;
39 /* Whether we need to call hppa_layout_sections_again.  */
40 static int need_laying_out = 0;
42 /* Maximum size of a group of input sections that can be handled by
43    one stub section.  A value of +/-1 indicates the bfd back-end
44    should use a suitable default size.  */
45 static bfd_signed_vma group_size = 1;
47 /* Stops the linker merging .text sections on a relocatable link,
48    and adds millicode library to the list of input files.  */
50 static void
51 hppaelf_after_parse (void)
53   if (link_info.relocatable)
54     lang_add_unique (".text");
55 #if 0 /* Enable this once we split millicode stuff from libgcc.  */
56   else
57     lang_add_input_file ("milli",
58                          lang_input_file_is_l_enum,
59                          NULL);
60 #endif
63 /* This is called before the input files are opened.  We create a new
64    fake input file to hold the stub sections.  */
66 static void
67 hppaelf_create_output_section_statements (void)
69   extern const bfd_target bfd_elf32_hppa_linux_vec;
70   extern const bfd_target bfd_elf32_hppa_vec;
72   if (link_info.hash->creator != &bfd_elf32_hppa_linux_vec
73       && link_info.hash->creator != &bfd_elf32_hppa_vec)
74     return;
76   stub_file = lang_add_input_file ("linker stubs",
77                                    lang_input_file_is_fake_enum,
78                                    NULL);
79   stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
80   if (stub_file->the_bfd == NULL
81       || ! bfd_set_arch_mach (stub_file->the_bfd,
82                               bfd_get_arch (output_bfd),
83                               bfd_get_mach (output_bfd)))
84     {
85       einfo ("%X%P: can not create BFD %E\n");
86       return;
87     }
89   ldlang_add_file (stub_file);
93 struct hook_stub_info
95   lang_statement_list_type add;
96   asection *input_section;
99 /* Traverse the linker tree to find the spot where the stub goes.  */
101 static bfd_boolean
102 hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
104   lang_statement_union_type *l;
105   bfd_boolean ret;
107   for (; (l = *lp) != NULL; lp = &l->header.next)
108     {
109       switch (l->header.type)
110         {
111         case lang_constructors_statement_enum:
112           ret = hook_in_stub (info, &constructor_list.head);
113           if (ret)
114             return ret;
115           break;
117         case lang_output_section_statement_enum:
118           ret = hook_in_stub (info,
119                               &l->output_section_statement.children.head);
120           if (ret)
121             return ret;
122           break;
124         case lang_wild_statement_enum:
125           ret = hook_in_stub (info, &l->wild_statement.children.head);
126           if (ret)
127             return ret;
128           break;
130         case lang_group_statement_enum:
131           ret = hook_in_stub (info, &l->group_statement.children.head);
132           if (ret)
133             return ret;
134           break;
136         case lang_input_section_enum:
137           if (l->input_section.section == info->input_section)
138             {
139               /* We've found our section.  Insert the stub immediately
140                  before its associated input section.  */
141               *lp = info->add.head;
142               *(info->add.tail) = l;
143               return TRUE;
144             }
145           break;
147         case lang_data_statement_enum:
148         case lang_reloc_statement_enum:
149         case lang_object_symbols_statement_enum:
150         case lang_output_statement_enum:
151         case lang_target_statement_enum:
152         case lang_input_statement_enum:
153         case lang_assignment_statement_enum:
154         case lang_padding_statement_enum:
155         case lang_address_statement_enum:
156         case lang_fill_statement_enum:
157           break;
159         default:
160           FAIL ();
161           break;
162         }
163     }
164   return FALSE;
168 /* Call-back for elf32_hppa_size_stubs.  */
170 /* Create a new stub section, and arrange for it to be linked
171    immediately before INPUT_SECTION.  */
173 static asection *
174 hppaelf_add_stub_section (const char *stub_sec_name, asection *input_section)
176   asection *stub_sec;
177   flagword flags;
178   asection *output_section;
179   const char *secname;
180   lang_output_section_statement_type *os;
181   struct hook_stub_info info;
183   stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_sec_name);
184   if (stub_sec == NULL)
185     goto err_ret;
187   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
188            | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
189   if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
190     goto err_ret;
192   output_section = input_section->output_section;
193   secname = bfd_get_section_name (output_section->owner, output_section);
194   os = lang_output_section_find (secname);
196   info.input_section = input_section;
197   lang_list_init (&info.add);
198   lang_add_section (&info.add, stub_sec, os, stub_file);
200   if (info.add.head == NULL)
201     goto err_ret;
203   if (hook_in_stub (&info, &os->children.head))
204     return stub_sec;
206  err_ret:
207   einfo ("%X%P: can not make stub section: %E\n");
208   return NULL;
212 /* Another call-back for elf32_hppa_size_stubs.  */
214 static void
215 hppaelf_layout_sections_again (void)
217   /* If we have changed sizes of the stub sections, then we need
218      to recalculate all the section offsets.  This may mean we need to
219      add even more stubs.  */
220   need_laying_out = 0;
222   lang_reset_memory_regions ();
224   /* Resize the sections.  */
225   lang_size_sections (stat_ptr->head, abs_output_section,
226                       &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE);
228   /* Redo special stuff.  */
229   ldemul_after_allocation ();
231   /* Do the assignments again.  */
232   lang_do_assignments (stat_ptr->head, abs_output_section,
233                        (fill_type *) 0, (bfd_vma) 0);
237 static void
238 build_section_lists (lang_statement_union_type *statement)
240   if (statement->header.type == lang_input_section_enum
241       && !statement->input_section.ifile->just_syms_flag
242       && statement->input_section.section->output_section != NULL
243       && statement->input_section.section->output_section->owner == output_bfd)
244     {
245       elf32_hppa_next_input_section (&link_info,
246                                      statement->input_section.section);
247     }
251 /* Final emulation specific call.  For the PA we use this opportunity
252    to build linker stubs.  */
254 static void
255 gld${EMULATION_NAME}_finish (void)
257   /* bfd_elf_discard_info just plays with debugging sections,
258      ie. doesn't affect any code, so we can delay resizing the
259      sections.  It's likely we'll resize everything in the process of
260      adding stubs.  */
261   if (bfd_elf_discard_info (output_bfd, &link_info))
262     need_laying_out = 1;
264   /* If generating a relocatable output file, then we don't
265      have to examine the relocs.  */
266   if (stub_file != NULL && !link_info.relocatable)
267     {
268       int ret = elf32_hppa_setup_section_lists (output_bfd, &link_info);
270       if (ret != 0)
271         {
272           if (ret < 0)
273             {
274               einfo ("%X%P: can not size stub section: %E\n");
275               return;
276             }
278           lang_for_each_statement (build_section_lists);
280           /* Call into the BFD backend to do the real work.  */
281           if (! elf32_hppa_size_stubs (output_bfd,
282                                        stub_file->the_bfd,
283                                        &link_info,
284                                        multi_subspace,
285                                        group_size,
286                                        &hppaelf_add_stub_section,
287                                        &hppaelf_layout_sections_again))
288             {
289               einfo ("%X%P: can not size stub section: %E\n");
290               return;
291             }
292         }
293     }
295   if (need_laying_out)
296     hppaelf_layout_sections_again ();
298   if (! link_info.relocatable)
299     {
300       /* Set the global data pointer.  */
301       if (! elf32_hppa_set_gp (output_bfd, &link_info))
302         {
303           einfo ("%X%P: can not set gp\n");
304           return;
305         }
307       /* Now build the linker stubs.  */
308       if (stub_file != NULL && stub_file->the_bfd->sections != NULL)
309         {
310           if (! elf32_hppa_build_stubs (&link_info))
311             einfo ("%X%P: can not build stubs: %E\n");
312         }
313     }
317 /* Avoid processing the fake stub_file in vercheck, stat_needed and
318    check_needed routines.  */
320 static void (*real_func) (lang_input_statement_type *);
322 static void hppa_for_each_input_file_wrapper (lang_input_statement_type *l)
324   if (l != stub_file)
325     (*real_func) (l);
328 static void
329 hppa_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
331   real_func = func;
332   lang_for_each_input_file (&hppa_for_each_input_file_wrapper);
335 #define lang_for_each_input_file hppa_lang_for_each_input_file
339 # Define some shell vars to insert bits of code into the standard elf
340 # parse_args and list_options functions.
342 PARSE_AND_LIST_PROLOGUE='
343 #define OPTION_MULTI_SUBSPACE           301
344 #define OPTION_STUBGROUP_SIZE           (OPTION_MULTI_SUBSPACE + 1)
347 PARSE_AND_LIST_LONGOPTS='
348   { "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE },
349   { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
352 PARSE_AND_LIST_OPTIONS='
353   fprintf (file, _("\
354   --multi-subspace      Generate import and export stubs to support\n\
355                           multiple sub-space shared libraries\n"
356                    ));
357   fprintf (file, _("\
358   --stub-group-size=N   Maximum size of a group of input sections that can be\n\
359                           handled by one stub section.  A negative value\n\
360                           locates all stubs before their branches (with a\n\
361                           group size of -N), while a positive value allows\n\
362                           two groups of input sections, one before, and one\n\
363                           after each stub section.  Values of +/-1 indicate\n\
364                           the linker should choose suitable defaults.\n"
365                    ));
368 PARSE_AND_LIST_ARGS_CASES='
369     case OPTION_MULTI_SUBSPACE:
370       multi_subspace = 1;
371       break;
373     case OPTION_STUBGROUP_SIZE:
374       {
375         const char *end;
376         group_size = bfd_scan_vma (optarg, &end, 0);
377         if (*end)
378           einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
379       }
380       break;
383 # Put these extra hppaelf routines in ld_${EMULATION_NAME}_emulation
385 LDEMUL_AFTER_PARSE=hppaelf_after_parse
386 LDEMUL_FINISH=gld${EMULATION_NAME}_finish
387 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=hppaelf_create_output_section_statements