Commit | Line | Data |
---|---|---|
d4e5e3c3 DM |
1 | /* Parse options for the GNU linker. |
2 | Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GLD, the Gnu Linker. | |
5 | ||
6 | GLD 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, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GLD 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 GLD; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | ||
20 | #include "bfd.h" | |
21 | #include "sysdep.h" | |
22 | #include <stdio.h> | |
23 | #include <string.h> | |
24 | #include "getopt.h" | |
25 | #include "bfdlink.h" | |
26 | #include "config.h" | |
27 | #include "ld.h" | |
28 | #include "ldmain.h" | |
29 | #include "ldmisc.h" | |
30 | #include "ldexp.h" | |
31 | #include "ldlang.h" | |
32 | #include "ldgram.h" | |
33 | #include "ldlex.h" | |
34 | #include "ldfile.h" | |
4725fb48 | 35 | #include "ldver.h" |
d4e5e3c3 DM |
36 | |
37 | /* Omit args to avoid the possibility of clashing with a system header | |
38 | that might disagree about consts. */ | |
39 | unsigned long strtoul (); | |
40 | ||
41 | static void set_default_dirlist PARAMS ((char *dirlist_ptr)); | |
42 | static void set_section_start PARAMS ((char *sect, char *valstr)); | |
43 | ||
44 | void | |
45 | parse_args (argc, argv) | |
46 | int argc; | |
47 | char **argv; | |
48 | { | |
49 | /* Starting the short option string with '-' is for programs that | |
50 | expect options and other ARGV-elements in any order and that care about | |
51 | the ordering of the two. We describe each non-option ARGV-element | |
52 | as if it were the argument of an option with character code 1. */ | |
53 | ||
d5b79a89 | 54 | const char *shortopts = "-A:B::b:cde:F::G:giL:l:Mm:NnO:o:R:rSsT:tu:VvXxY:y:"; |
d4e5e3c3 | 55 | |
d5b79a89 DM |
56 | /* 150 isn't special; it's just an arbitrary non-ASCII char value. */ |
57 | ||
bec7a138 ILT |
58 | #define OPTION_CALL_SHARED 150 |
59 | #define OPTION_DEFSYM (OPTION_CALL_SHARED + 1) | |
7fb9ca5f ILT |
60 | #define OPTION_DYNAMIC_LINKER (OPTION_DEFSYM + 1) |
61 | #define OPTION_EB (OPTION_DYNAMIC_LINKER + 1) | |
bec7a138 ILT |
62 | #define OPTION_EL (OPTION_EB + 1) |
63 | #define OPTION_HELP (OPTION_EL + 1) | |
64 | #define OPTION_IGNORE (OPTION_HELP + 1) | |
65 | #define OPTION_MAP (OPTION_IGNORE + 1) | |
66 | #define OPTION_NO_KEEP_MEMORY (OPTION_MAP + 1) | |
67 | #define OPTION_NOINHIBIT_EXEC (OPTION_NO_KEEP_MEMORY + 1) | |
68 | #define OPTION_NON_SHARED (OPTION_NOINHIBIT_EXEC + 1) | |
69 | #define OPTION_OFORMAT (OPTION_NON_SHARED + 1) | |
70 | #define OPTION_RELAX (OPTION_OFORMAT + 1) | |
71 | #define OPTION_RETAIN_SYMBOLS_FILE (OPTION_RELAX + 1) | |
72 | #define OPTION_SORT_COMMON (OPTION_RETAIN_SYMBOLS_FILE + 1) | |
73 | #define OPTION_STATS (OPTION_SORT_COMMON + 1) | |
74 | #define OPTION_TBSS (OPTION_STATS + 1) | |
75 | #define OPTION_TDATA (OPTION_TBSS + 1) | |
76 | #define OPTION_TTEXT (OPTION_TDATA + 1) | |
77 | #define OPTION_TRADITIONAL_FORMAT (OPTION_TTEXT + 1) | |
78 | #define OPTION_UR (OPTION_TRADITIONAL_FORMAT + 1) | |
79 | #define OPTION_VERSION (OPTION_UR + 1) | |
80 | #define OPTION_WARN_COMMON (OPTION_VERSION + 1) | |
81 | ||
d5b79a89 | 82 | static struct option longopts[] = { |
d5b79a89 | 83 | {"call_shared", no_argument, NULL, OPTION_CALL_SHARED}, |
d4e5e3c3 | 84 | {"dc", no_argument, NULL, 'd'}, |
d5b79a89 | 85 | {"defsym", required_argument, NULL, OPTION_DEFSYM}, |
2a9fa50c | 86 | {"dn", no_argument, NULL, OPTION_NON_SHARED}, |
d4e5e3c3 | 87 | {"dp", no_argument, NULL, 'd'}, |
2a9fa50c | 88 | {"dy", no_argument, NULL, OPTION_CALL_SHARED}, |
7fb9ca5f | 89 | {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER}, |
d5b79a89 | 90 | {"EB", no_argument, NULL, OPTION_EB}, |
d5b79a89 | 91 | {"EL", no_argument, NULL, OPTION_EL}, |
d4e5e3c3 | 92 | {"format", required_argument, NULL, 'b'}, |
d5b79a89 | 93 | {"help", no_argument, NULL, OPTION_HELP}, |
d5b79a89 | 94 | {"Map", required_argument, NULL, OPTION_MAP}, |
d5b79a89 | 95 | {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY}, |
d5b79a89 DM |
96 | {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC}, |
97 | {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC}, | |
2a9fa50c | 98 | {"non_shared", no_argument, NULL, OPTION_NON_SHARED}, |
d5b79a89 | 99 | {"oformat", required_argument, NULL, OPTION_OFORMAT}, |
2a9fa50c | 100 | {"Qy", no_argument, NULL, OPTION_IGNORE}, |
cbbf9608 | 101 | {"qmagic", no_argument, NULL, OPTION_IGNORE}, /* Linux compatibility. */ |
d5b79a89 | 102 | {"relax", no_argument, NULL, OPTION_RELAX}, |
d5b79a89 | 103 | {"retain-symbols-file", no_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE}, |
d5b79a89 DM |
104 | {"sort-common", no_argument, NULL, OPTION_SORT_COMMON}, |
105 | {"sort_common", no_argument, NULL, OPTION_SORT_COMMON}, | |
d5b79a89 | 106 | {"stats", no_argument, NULL, OPTION_STATS}, |
42792411 | 107 | {"static", no_argument, NULL, OPTION_NON_SHARED}, |
d5b79a89 | 108 | {"Tbss", required_argument, NULL, OPTION_TBSS}, |
d5b79a89 | 109 | {"Tdata", required_argument, NULL, OPTION_TDATA}, |
d5b79a89 | 110 | {"Ttext", required_argument, NULL, OPTION_TTEXT}, |
c96386c4 | 111 | {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT}, |
d5b79a89 | 112 | {"Ur", no_argument, NULL, OPTION_UR}, |
d5b79a89 | 113 | {"version", no_argument, NULL, OPTION_VERSION}, |
d5b79a89 | 114 | {"warn-common", no_argument, NULL, OPTION_WARN_COMMON}, |
d4e5e3c3 DM |
115 | {NULL, no_argument, NULL, 0} |
116 | }; | |
117 | ||
118 | while (1) | |
119 | { | |
120 | /* getopt_long_only is like getopt_long, but '-' as well as '--' can | |
121 | indicate a long option. */ | |
d5b79a89 DM |
122 | int longind; |
123 | int optc = getopt_long_only (argc, argv, shortopts, longopts, &longind); | |
124 | ||
d4e5e3c3 DM |
125 | if (optc == -1) |
126 | break; | |
127 | ||
128 | switch (optc) | |
129 | { | |
130 | default: | |
131 | xexit (1); | |
132 | case 1: /* File name. */ | |
133 | lang_add_input_file (optarg, lang_input_file_is_file_enum, | |
134 | (char *) NULL); | |
135 | break; | |
136 | ||
2a9fa50c ILT |
137 | case OPTION_IGNORE: |
138 | break; | |
d4e5e3c3 DM |
139 | case 'A': |
140 | ldfile_add_arch (optarg); | |
141 | break; | |
142 | case 'B': | |
143 | /* Ignore. */ | |
144 | break; | |
145 | case 'b': | |
146 | lang_add_target (optarg); | |
147 | break; | |
148 | case 'c': | |
149 | ldfile_open_command_file (optarg); | |
150 | parser_input = input_mri_script; | |
151 | yyparse (); | |
152 | break; | |
d5b79a89 | 153 | case OPTION_CALL_SHARED: |
2a9fa50c ILT |
154 | config.dynamic_link = true; |
155 | break; | |
156 | case OPTION_NON_SHARED: | |
157 | config.dynamic_link = false; | |
d4e5e3c3 DM |
158 | break; |
159 | case 'd': | |
160 | command_line.force_common_definition = true; | |
161 | break; | |
d5b79a89 | 162 | case OPTION_DEFSYM: |
d4e5e3c3 DM |
163 | lex_redirect (optarg); |
164 | parser_input = input_defsym; | |
165 | yyparse (); | |
166 | break; | |
7fb9ca5f ILT |
167 | case OPTION_DYNAMIC_LINKER: |
168 | command_line.interpreter = optarg; | |
169 | break; | |
d5b79a89 | 170 | case OPTION_EB: |
d4e5e3c3 DM |
171 | /* FIXME: This is currently ignored. It means |
172 | ``produce a big-endian object file''. It could | |
173 | be used to select an output format. */ | |
174 | break; | |
d5b79a89 | 175 | case OPTION_EL: |
d4e5e3c3 DM |
176 | /* FIXME: This is currently ignored. It means |
177 | ``produce a little-endian object file''. It could | |
178 | be used to select an output format. */ | |
179 | break; | |
180 | case 'e': | |
60e8a534 | 181 | lang_add_entry (optarg, 1); |
d4e5e3c3 DM |
182 | break; |
183 | case 'F': | |
184 | /* Ignore. */ | |
185 | break; | |
186 | case 'G': | |
187 | { | |
188 | char *end; | |
189 | g_switch_value = strtoul (optarg, &end, 0); | |
190 | if (*end) | |
9d3898b2 | 191 | einfo ("%P%F: invalid number `%s'\n", optarg); |
d4e5e3c3 DM |
192 | } |
193 | break; | |
194 | case 'g': | |
195 | /* Ignore. */ | |
196 | break; | |
d5b79a89 | 197 | case OPTION_HELP: |
d4e5e3c3 DM |
198 | help (); |
199 | xexit (0); | |
200 | break; | |
201 | case 'L': | |
0cd82d00 | 202 | ldfile_add_library_path (optarg, true); |
d4e5e3c3 DM |
203 | break; |
204 | case 'l': | |
205 | lang_add_input_file (optarg, lang_input_file_is_l_enum, | |
206 | (char *) NULL); | |
207 | break; | |
208 | case 'M': | |
209 | config.map_filename = "-"; | |
210 | break; | |
211 | case 'm': | |
212 | /* Ignore. Was handled in a pre-parse. */ | |
213 | break; | |
d5b79a89 | 214 | case OPTION_MAP: |
d4e5e3c3 DM |
215 | config.map_filename = optarg; |
216 | break; | |
217 | case 'N': | |
218 | config.text_read_only = false; | |
219 | config.magic_demand_paged = false; | |
220 | break; | |
221 | case 'n': | |
222 | config.magic_demand_paged = false; | |
223 | break; | |
d5b79a89 | 224 | case OPTION_NO_KEEP_MEMORY: |
d4e5e3c3 DM |
225 | link_info.keep_memory = false; |
226 | break; | |
d5b79a89 | 227 | case OPTION_NOINHIBIT_EXEC: |
d4e5e3c3 DM |
228 | force_make_executable = true; |
229 | break; | |
230 | case 'O': | |
231 | /* FIXME "-O<non-digits> <value>" used to set the address of | |
232 | section <non-digits>. Was this for compatibility with | |
233 | something, or can we create a new option to do that | |
234 | (with a syntax similar to -defsym)? | |
235 | getopt can't handle two args to an option without kludges. */ | |
236 | set_default_dirlist (optarg); | |
237 | break; | |
238 | case 'o': | |
239 | lang_add_output (optarg, 0); | |
240 | break; | |
d5b79a89 | 241 | case OPTION_OFORMAT: |
d4e5e3c3 DM |
242 | lang_add_output_format (optarg, 0); |
243 | break; | |
3e1fd33d | 244 | case 'i': |
d4e5e3c3 DM |
245 | case 'r': |
246 | link_info.relocateable = true; | |
247 | config.build_constructors = false; | |
248 | config.magic_demand_paged = false; | |
249 | config.text_read_only = false; | |
2a9fa50c | 250 | config.dynamic_link = false; |
d4e5e3c3 DM |
251 | break; |
252 | case 'R': | |
253 | lang_add_input_file (optarg, | |
254 | lang_input_file_is_symbols_only_enum, | |
255 | (char *) NULL); | |
256 | break; | |
d5b79a89 | 257 | case OPTION_RELAX: |
d4e5e3c3 DM |
258 | command_line.relax = true; |
259 | break; | |
d5b79a89 | 260 | case OPTION_RETAIN_SYMBOLS_FILE: |
d4e5e3c3 DM |
261 | add_keepsyms_file (optarg); |
262 | break; | |
263 | case 'S': | |
264 | link_info.strip = strip_debugger; | |
265 | break; | |
266 | case 's': | |
267 | link_info.strip = strip_all; | |
268 | break; | |
d5b79a89 | 269 | case OPTION_SORT_COMMON: |
d4e5e3c3 DM |
270 | config.sort_common = true; |
271 | break; | |
d5b79a89 | 272 | case OPTION_STATS: |
d4e5e3c3 DM |
273 | config.stats = true; |
274 | break; | |
275 | case 't': | |
276 | trace_files = true; | |
277 | break; | |
278 | case 'T': | |
279 | ldfile_open_command_file (optarg); | |
280 | parser_input = input_script; | |
281 | yyparse (); | |
282 | break; | |
d5b79a89 | 283 | case OPTION_TBSS: |
d4e5e3c3 DM |
284 | set_section_start (".bss", optarg); |
285 | break; | |
d5b79a89 | 286 | case OPTION_TDATA: |
d4e5e3c3 DM |
287 | set_section_start (".data", optarg); |
288 | break; | |
d5b79a89 | 289 | case OPTION_TTEXT: |
d4e5e3c3 DM |
290 | set_section_start (".text", optarg); |
291 | break; | |
c96386c4 ILT |
292 | case OPTION_TRADITIONAL_FORMAT: |
293 | config.traditional_format = true; | |
294 | break; | |
d5b79a89 | 295 | case OPTION_UR: |
d4e5e3c3 DM |
296 | link_info.relocateable = true; |
297 | config.build_constructors = true; | |
298 | config.magic_demand_paged = false; | |
299 | config.text_read_only = false; | |
2a9fa50c | 300 | config.dynamic_link = false; |
d4e5e3c3 DM |
301 | break; |
302 | case 'u': | |
303 | ldlang_add_undef (optarg); | |
304 | break; | |
305 | case 'V': | |
306 | ldversion (1); | |
307 | version_printed = true; | |
308 | trace_file_tries = true; | |
309 | break; | |
310 | case 'v': | |
311 | ldversion (0); | |
312 | version_printed = true; | |
313 | break; | |
d5b79a89 | 314 | case OPTION_VERSION: |
d4e5e3c3 DM |
315 | ldversion (0); |
316 | version_printed = true; | |
317 | break; | |
d5b79a89 | 318 | case OPTION_WARN_COMMON: |
d4e5e3c3 DM |
319 | config.warn_common = true; |
320 | break; | |
321 | case 'X': | |
322 | link_info.discard = discard_l; | |
323 | break; | |
324 | case 'x': | |
325 | link_info.discard = discard_all; | |
326 | break; | |
d5b79a89 DM |
327 | case 'Y': |
328 | set_default_dirlist (optarg); | |
329 | break; | |
d4e5e3c3 DM |
330 | case 'y': |
331 | add_ysym (optarg); | |
332 | break; | |
333 | } | |
334 | } | |
335 | } | |
336 | ||
337 | /* Add the (colon-separated) elements of DIRLIST_PTR to the | |
338 | library search path. */ | |
339 | ||
340 | static void | |
341 | set_default_dirlist (dirlist_ptr) | |
342 | char *dirlist_ptr; | |
343 | { | |
344 | char *p; | |
345 | ||
346 | while (1) | |
347 | { | |
348 | p = strchr (dirlist_ptr, ':'); | |
349 | if (p != NULL) | |
350 | *p = 0; | |
351 | if (*dirlist_ptr) | |
0cd82d00 | 352 | ldfile_add_library_path (dirlist_ptr, true); |
d4e5e3c3 DM |
353 | if (p == NULL) |
354 | break; | |
355 | *p = ':'; | |
356 | dirlist_ptr = p + 1; | |
357 | } | |
358 | } | |
359 | ||
360 | static void | |
361 | set_section_start (sect, valstr) | |
362 | char *sect, *valstr; | |
363 | { | |
364 | char *end; | |
365 | unsigned long val = strtoul (valstr, &end, 16); | |
366 | if (*end) | |
d5b79a89 | 367 | einfo ("%P%F: invalid hex number `%s'\n", valstr); |
d4e5e3c3 DM |
368 | lang_section_start (sect, exp_intop (val)); |
369 | } |