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