]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/binutils/ld/emultempl/avrelf.em
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / binutils / ld / emultempl / avrelf.em
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright 2006
3 #   Free Software Foundation, Inc.
4 #
5 # This file is part of GLD, the Gnu Linker.
6 #
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.
11 #
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.
16 #
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., 51 Franklin Street - Fifth Floor, Boston, 
20 # MA 02110-1301 USA.
21
22 # This file is sourced from elf32.em, and defines extra avr-elf
23 # specific routines.  It is used to generate the trampolines for the avr6
24 # family devices where one needs to address the issue that it is not possible
25 # to reach the whole program memory by using 16 bit pointers.
26
27 cat >>e${EMULATION_NAME}.c <<EOF
28
29 #include "elf32-avr.h"
30 #include "ldctor.h"
31
32 /* The fake file and it's corresponding section meant to hold 
33    the linker stubs if needed.  */
34
35 static lang_input_statement_type *stub_file;
36 static asection *avr_stub_section;
37
38 /* Variables set by the command-line parameters and transfered
39    to the bfd without use of global shared variables.  */
40
41 static bfd_boolean avr_no_stubs = FALSE;
42 static bfd_boolean avr_debug_relax = FALSE;
43 static bfd_boolean avr_debug_stubs = FALSE;
44 static bfd_boolean avr_replace_call_ret_sequences = TRUE;
45 static bfd_vma avr_pc_wrap_around = 0x10000000;
46
47 /* Transfers information to the bfd frontend.  */
48
49 static void
50 avr_elf_set_global_bfd_parameters (void)
51 {
52   elf32_avr_setup_params (& link_info,
53                           stub_file->the_bfd,
54                           avr_stub_section,
55                           avr_no_stubs,
56                           avr_debug_stubs,
57                           avr_debug_relax,
58                           avr_pc_wrap_around,
59                           avr_replace_call_ret_sequences);
60 }
61
62
63 /* Makes a conservative estimate of the trampoline section size that could
64    be corrected later on.  */
65
66 static void
67 avr_elf_${EMULATION_NAME}_before_allocation (void)
68 {
69   int ret;
70
71   gld${EMULATION_NAME}_before_allocation ();
72
73   /* We only need stubs for the avr6 family.  */
74   if (strcmp ("${EMULATION_NAME}","avr6"))
75     avr_no_stubs = TRUE;
76
77   avr_elf_set_global_bfd_parameters ();
78
79   /* If generating a relocatable output file, then
80      we don't  have to generate the trampolines.  */
81   if (link_info.relocatable)
82     avr_no_stubs = TRUE;
83
84   if (avr_no_stubs)
85     return;
86
87   ret = elf32_avr_setup_section_lists (output_bfd, &link_info);
88
89   if (ret < 0)
90     einfo ("%X%P: can not setup the input section list: %E\n");
91
92   if (ret <= 0)
93     return;
94
95   /* Call into the BFD backend to do the real "stub"-work.  */
96   if (! elf32_avr_size_stubs (output_bfd, &link_info, TRUE))
97     einfo ("%X%P: can not size stub section: %E\n");
98 }
99
100 /* This is called before the input files are opened.  We create a new
101    fake input file to hold the stub section and generate the section itself.  */
102
103 static void
104 avr_elf_create_output_section_statements (void)
105 {
106   flagword flags;
107
108   stub_file = lang_add_input_file ("linker stubs",
109                                    lang_input_file_is_fake_enum,
110                                    NULL);
111
112   stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
113   if (stub_file->the_bfd == NULL
114       || !bfd_set_arch_mach (stub_file->the_bfd,
115                              bfd_get_arch (output_bfd),
116                              bfd_get_mach (output_bfd)))
117     {
118       einfo ("%X%P: can not create stub BFD %E\n");
119       return;
120     }
121
122   /* Now we add the stub section.  */
123
124   avr_stub_section = bfd_make_section_anyway (stub_file->the_bfd,
125                                               ".trampolines");
126   if (avr_stub_section == NULL)
127     goto err_ret;
128   
129   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
130            | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
131   if (!bfd_set_section_flags (stub_file->the_bfd, avr_stub_section, flags))
132     goto err_ret;
133
134   avr_stub_section->alignment_power = 1;
135   
136   ldlang_add_file (stub_file);
137
138   return;
139
140   err_ret:
141    einfo ("%X%P: can not make stub section: %E\n");
142    return;
143 }
144
145 /* Re-calculates the size of the stubs so that we won't waste space.  */
146
147 static void
148 avr_elf_finish (void)
149
150   if (!avr_no_stubs)
151     {
152       /* Now build the linker stubs.  */
153       if (stub_file->the_bfd->sections != NULL)
154        {
155          /* Call again the trampoline analyzer to initialize the trampoline
156             stubs with the correct symbol addresses.  Since there could have
157             been relaxation, the symbol addresses that were found during
158             first call may no longer be correct.  */
159          if (!elf32_avr_size_stubs (output_bfd, &link_info, FALSE))
160            {
161              einfo ("%X%P: can not size stub section: %E\n");
162              return;
163            }
164
165          if (!elf32_avr_build_stubs (&link_info))
166            einfo ("%X%P: can not build stubs: %E\n");
167        }
168     }
169
170   gld${EMULATION_NAME}_finish ();
171 }
172
173
174 EOF
175
176
177 PARSE_AND_LIST_PROLOGUE='
178
179 #define OPTION_NO_CALL_RET_REPLACEMENT 301
180 #define OPTION_PMEM_WRAP_AROUND        302
181 #define OPTION_NO_STUBS                303
182 #define OPTION_DEBUG_STUBS             304
183 #define OPTION_DEBUG_RELAX             305
184 '
185
186 PARSE_AND_LIST_LONGOPTS='
187   { "no-call-ret-replacement", no_argument, 
188      NULL, OPTION_NO_CALL_RET_REPLACEMENT},
189   { "pmem-wrap-around", required_argument, 
190     NULL, OPTION_PMEM_WRAP_AROUND},
191   { "no-stubs", no_argument, 
192     NULL, OPTION_NO_STUBS},
193   { "debug-stubs", no_argument, 
194     NULL, OPTION_DEBUG_STUBS},
195   { "debug-relax", no_argument, 
196     NULL, OPTION_DEBUG_RELAX},
197 '
198
199 PARSE_AND_LIST_OPTIONS='
200   fprintf (file, _("     --pmem-wrap-around=<val> "
201                            "Make the linker relaxation machine assume that a\n"
202                    "                              "
203                            "program counter wrap-around occures at address\n"
204                    "                              "
205                            "<val>. Supported values are 8k, 16k, 32k and 64k.\n"));
206   fprintf (file, _("     --no-call-ret-replacement "
207                            "The relaxation machine normally will\n"
208                    "                               "
209                            "substitute two immediately following call/ret\n"
210                    "                               "
211                            "instructions by a single jump instruction.\n"
212                    "                               "
213                            "This option disables this optimization.\n"));
214   fprintf (file, _("     --no-stubs "
215                            "If the linker detects to attempt to access\n"
216                    "                               "
217                            "an instruction beyond 128k by a reloc that\n"
218                    "                               "
219                            "is limited to 128k max, it inserts a jump\n"
220                    "                               "
221                            "stub. You can de-active this with this switch.\n"));
222   fprintf (file, _("     --debug-stubs Used for debugging avr-ld.\n"));
223   fprintf (file, _("     --debug-relax Used for debugging avr-ld.\n"));
224 '
225
226 PARSE_AND_LIST_ARGS_CASES='
227
228     case OPTION_PMEM_WRAP_AROUND:
229       { 
230         /* This variable is defined in the bfd library.  */
231         if ((!strcmp (optarg,"32k"))      || (!strcmp (optarg,"32K")))
232           avr_pc_wrap_around = 32768;
233         else if ((!strcmp (optarg,"8k")) || (!strcmp (optarg,"8K")))
234           avr_pc_wrap_around = 8192;
235         else if ((!strcmp (optarg,"16k")) || (!strcmp (optarg,"16K")))
236           avr_pc_wrap_around = 16384;
237         else if ((!strcmp (optarg,"64k")) || (!strcmp (optarg,"64K")))
238           avr_pc_wrap_around = 0x10000;
239         else
240           return FALSE;
241       }
242       break;
243
244     case OPTION_DEBUG_STUBS:
245       avr_debug_stubs = TRUE;
246       break;
247
248     case OPTION_DEBUG_RELAX:
249       avr_debug_relax = TRUE;
250       break;
251
252     case OPTION_NO_STUBS:
253       avr_no_stubs = TRUE;
254       break;
255
256     case OPTION_NO_CALL_RET_REPLACEMENT:
257       {
258         /* This variable is defined in the bfd library.  */
259         avr_replace_call_ret_sequences = FALSE;
260       }
261       break;
262 '
263
264 #
265 # Put these extra avr-elf routines in ld_${EMULATION_NAME}_emulation
266 #
267 LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation
268 LDEMUL_FINISH=avr_elf_finish
269 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements