* emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Treat
[deliverable/binutils-gdb.git] / ld / emultempl / aix.em
CommitLineData
57fc1e90
ILT
1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3cat >e${EMULATION_NAME}.c <<EOF
4/* This file is is generated by a shell script. DO NOT EDIT! */
5
6/* AIX emulation code for ${EMULATION_NAME}
7 Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc.
8 Written by Steve Chamberlain <sac@cygnus.com>
9 AIX support by Ian Lance Taylor <ian@cygnus.com>
10
11This file is part of GLD, the Gnu Linker.
12
13This program is free software; you can redistribute it and/or modify
14it under the terms of the GNU General Public License as published by
15the Free Software Foundation; either version 2 of the License, or
16(at your option) any later version.
17
18This program is distributed in the hope that it will be useful,
19but WITHOUT ANY WARRANTY; without even the implied warranty of
20MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with this program; if not, write to the Free Software
25Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26
27#define TARGET_IS_${EMULATION_NAME}
28
29#include "bfd.h"
30#include "sysdep.h"
31#include "libiberty.h"
32#include "getopt.h"
33#include "bfdlink.h"
34
35#include <ctype.h>
36
37#include "ld.h"
38#include "ldmain.h"
39#include "ldemul.h"
40#include "ldfile.h"
41#include "ldmisc.h"
42#include "ldexp.h"
43#include "ldlang.h"
44
45static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
46static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **));
47static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
48static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean));
49static void gld${EMULATION_NAME}_free PARAMS ((PTR));
50static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
51
52/* The file alignment required for each section. */
53static unsigned long file_align;
54
55/* The maximum size the stack is permitted to grow. This is stored in
56 the a.out header. */
57static unsigned long maxstack;
58
59/* The maximum data size. This is stored in the a.out header. */
60static unsigned long maxdata;
61
62/* Whether to perform garbage collection. */
63static int gc = 1;
64
65/* The module type to use. */
66static unsigned short modtype = ('1' << 8) | 'L';
67
68/* Whether the .text section must be read-only (i.e., no relocs
69 permitted). */
70static int textro;
71
72/* Structure used to hold import or export file list. */
73
74struct filelist
75{
76 struct filelist *next;
77 const char *name;
78};
79
80/* List of import files. */
81struct filelist *import_files;
82
83/* List of export files. */
84struct filelist *export_files;
85
86static void
87gld${EMULATION_NAME}_before_parse()
88{
89#ifndef TARGET_ /* I.e., if not generic. */
90 ldfile_output_architecture = bfd_arch_${ARCH};
91#endif /* not TARGET_ */
92}
93
94/* Handle AIX specific options. */
95
96static int
97gld${EMULATION_NAME}_parse_args (argc, argv)
98 int argc;
99 char **argv;
100{
101 int prevoptind = optind;
102 int prevopterr = opterr;
103 int longind;
104 int optc;
105 long val;
106 char *end;
107
108#define OPTION_IGNORE (300)
109#define OPTION_AUTOIMP (OPTION_IGNORE + 1)
110#define OPTION_ERNOTOK (OPTION_AUTOIMP + 1)
111#define OPTION_EROK (OPTION_ERNOTOK + 1)
112#define OPTION_EXPORT (OPTION_EROK + 1)
113#define OPTION_IMPORT (OPTION_EXPORT + 1)
114#define OPTION_MAXDATA (OPTION_IMPORT + 1)
115#define OPTION_MAXSTACK (OPTION_MAXDATA + 1)
116#define OPTION_MODTYPE (OPTION_MAXSTACK + 1)
117#define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1)
118#define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1)
119#define OPTION_STRCMPCT (OPTION_NOSTRCMPCT + 1)
120
121 static struct option longopts[] = {
122 {"basis", no_argument, NULL, OPTION_IGNORE},
123 {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
124 {"bcomprld", no_argument, NULL, OPTION_IGNORE},
125 {"bcrld", no_argument, NULL, OPTION_IGNORE},
126 {"bcror31", no_argument, NULL, OPTION_IGNORE},
127 {"bD", required_argument, NULL, OPTION_MAXDATA},
128 {"bE", required_argument, NULL, OPTION_EXPORT},
129 {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
130 {"berok", no_argument, NULL, OPTION_EROK},
131 {"berrmsg", no_argument, NULL, OPTION_IGNORE},
132 {"bexport", required_argument, NULL, OPTION_EXPORT},
133 {"bf", no_argument, NULL, OPTION_ERNOTOK},
134 {"bgc", no_argument, &gc, 1},
135 {"bh", required_argument, NULL, OPTION_IGNORE},
136 {"bhalt", required_argument, NULL, OPTION_IGNORE},
137 {"bI", required_argument, NULL, OPTION_IMPORT},
138 {"bimport", required_argument, NULL, OPTION_IMPORT},
139 {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
140 {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
141 {"bM", required_argument, NULL, OPTION_MODTYPE},
142 {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
143 {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
144 {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
145 {"bnogc", no_argument, &gc, 0},
146 {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
147 {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
148 {"bnotextro", no_argument, &textro, 0},
149 {"bnro", no_argument, &textro, 0},
150 {"bro", no_argument, &textro, 1},
151 {"bS", required_argument, NULL, OPTION_MAXSTACK},
152 {"bso", no_argument, NULL, OPTION_AUTOIMP},
153 {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
154 {"btextro", no_argument, &textro, 1},
c7c8b500 155 {"static", no_argument, NULL, OPTION_NOAUTOIMP},
57fc1e90
ILT
156 {NULL, no_argument, NULL, 0}
157 };
158
159 /* Options supported by the AIX linker which we do not support: -f,
160 -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
161 -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
162 -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
163 -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
164 -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
165 -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
166 -bx, -bX, -bxref. */
167
168 /* If the first option starts with -b, change the first : to an =.
169 The AIX linker uses : to separate the option from the argument;
170 changing it to = lets us treat it as a getopt option. */
171 if (optind < argc && strncmp (argv[optind], "-b", 2) == 0)
172 {
173 char *s;
174
175 for (s = argv[optind]; *s != '\0'; s++)
176 {
177 if (*s == ':')
178 {
179 *s = '=';
180 break;
181 }
182 }
183 }
184
185 opterr = 0;
186 optc = getopt_long_only (argc, argv, "-D:H:KT:z", longopts, &longind);
187 opterr = prevopterr;
188
189 switch (optc)
190 {
191 default:
192 optind = prevoptind;
193 return 0;
194
1764521f
ILT
195 case 0:
196 /* Long option which just sets a flag. */
197 break;
198
57fc1e90
ILT
199 case 'D':
200 val = strtol (optarg, &end, 0);
201 if (*end != '\0')
202 einfo ("%P: warning: ignoring invalid -D number %s\n", optarg);
203 else if (val != -1)
204 lang_section_start (".data", exp_intop (val));
205 break;
206
207 case 'H':
208 val = strtoul (optarg, &end, 0);
209 if (*end != '\0'
210 || (val & (val - 1)) != 0)
211 einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
212 else
213 file_align = val;
214 break;
215
216 case 'K':
217 case 'z':
218 /* FIXME: This should use the page size for the target system. */
219 file_align = 4096;
220 break;
221
222 case 'T':
223 /* On AIX this is the same as GNU ld -Ttext. When we see -T
224 number, we assume the AIX option is intended. Otherwise, we
225 assume the usual GNU ld -T option is intended. We can't just
226 ignore the AIX option, because gcc passes it to the linker. */
227 val = strtoul (optarg, &end, 0);
228 if (*end != '\0')
229 {
230 optind = prevoptind;
231 return 0;
232 }
233 lang_section_start (".text", exp_intop (val));
234 break;
235
236 case OPTION_IGNORE:
237 break;
238
239 case OPTION_AUTOIMP:
240 link_info.static_link = false;
241 break;
242
243 case OPTION_ERNOTOK:
244 force_make_executable = false;
245 break;
246
247 case OPTION_EROK:
248 force_make_executable = true;
249 break;
250
251 case OPTION_EXPORT:
252 case OPTION_IMPORT:
253 {
254 struct filelist *n;
255 struct filelist **flpp;
256
257 n = (struct filelist *) xmalloc (sizeof (struct filelist));
258 n->next = NULL;
259 n->name = optarg;
260 if (optc == OPTION_EXPORT)
261 flpp = &export_files;
262 else
263 flpp = &import_files;
264 while (*flpp != NULL)
265 flpp = &(*flpp)->next;
266 *flpp = n;
267 }
268 break;
269
270 case OPTION_MAXDATA:
271 val = strtoul (optarg, &end, 0);
272 if (*end != '\0')
273 einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n",
274 optarg);
275 else
276 maxdata = val;
277 break;
278
279 case OPTION_MAXSTACK:
280 val = strtoul (optarg, &end, 0);
281 if (*end != '\0')
282 einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
283 optarg);
284 else
285 maxstack = val;
286 break;
287
288 case OPTION_MODTYPE:
289 if (*optarg == 'S')
290 {
291 link_info.shared = true;
292 ++optarg;
293 }
294 if (*optarg == '\0' || optarg[1] == '\0')
295 einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
296 else
297 modtype = (*optarg << 8) | optarg[1];
298 break;
299
300 case OPTION_NOAUTOIMP:
301 link_info.static_link = true;
302 break;
303
304 case OPTION_NOSTRCMPCT:
305 config.traditional_format = true;
306 break;
307
308 case OPTION_STRCMPCT:
309 config.traditional_format = false;
310 break;
311 }
312
313 return 1;
314}
315
316/* This is called after the sections have been attached to output
317 sections, but before any sizes or addresses have been set. */
318
319static void
320gld${EMULATION_NAME}_before_allocation ()
321{
322 struct filelist *fl;
323 char *libpath;
324
325 /* Handle the import and export files, if any. */
326 for (fl = import_files; fl != NULL; fl = fl->next)
327 gld${EMULATION_NAME}_read_file (fl->name, true);
328 for (fl = export_files; fl != NULL; fl = fl->next)
329 gld${EMULATION_NAME}_read_file (fl->name, false);
330
331 /* We need to build LIBPATH from the -L arguments. If any -rpath
332 arguments were used, though, we use -rpath instead, as a GNU
333 extension. */
334 if (command_line.rpath != NULL)
335 libpath = command_line.rpath;
336 else if (search_head == NULL)
337 libpath = (char *) "";
338 else
339 {
340 size_t len;
341 search_dirs_type *search;
342
343 len = strlen (search_head->name);
344 libpath = xmalloc (len + 1);
345 strcpy (libpath, search_head->name);
346 for (search = search_head->next; search != NULL; search = search->next)
347 {
348 size_t nlen;
349
350 nlen = strlen (search->name);
351 libpath = xrealloc (libpath, len + nlen + 2);
352 libpath[len] = ':';
353 strcpy (libpath + len + 1, search->name);
354 len += nlen + 1;
355 }
356 }
357
358 /* Let the XCOFF backend set up the .loader section. */
359 if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath,
360 entry_symbol, file_align,
361 maxstack, maxdata,
362 gc ? true : false,
363 modtype,
364 textro ? true : false))
365 einfo ("%P%F: failed to set dynamic section sizes: %E\n");
366}
367
368/* Read an import or export file. */
369
370static void
371gld${EMULATION_NAME}_read_file (filename, import)
372 const char *filename;
373 boolean import;
374{
375 struct obstack *o;
376 FILE *f;
377 int lineno;
378 int c;
379 boolean keep;
380 const char *imppath;
381 const char *impfile;
382 const char *impmember;
383
384 o = (struct obstack *) xmalloc (sizeof (struct obstack));
385 obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free);
386
387 f = fopen (filename, "r");
388 if (f == NULL)
389 {
390 bfd_set_error (bfd_error_system_call);
391 einfo ("%F%s: %E\n", filename);
392 }
393
394 keep = false;
395
396 imppath = NULL;
397 impfile = NULL;
398 impmember = NULL;
399
400 lineno = 0;
401 while ((c = getc (f)) != EOF)
402 {
403 char *s;
404 char *symname;
405 boolean syscall;
406 bfd_vma address;
407 struct bfd_link_hash_entry *h;
408
409 if (c != '\n')
410 {
411 obstack_1grow (o, c);
412 continue;
413 }
414
415 obstack_1grow (o, '\0');
416 ++lineno;
417
418 s = (char *) obstack_base (o);
419 while (isspace ((unsigned char) *s))
420 ++s;
421 if (*s == '\0'
422 || *s == '*'
423 || (*s == '#' && s[1] == ' ')
424 || (! import && *s == '#' && s[1] == '!'))
425 {
426 obstack_free (o, obstack_base (o));
427 continue;
428 }
429
430 if (*s == '#' && s[1] == '!')
431 {
432 s += 2;
433 while (isspace ((unsigned char) *s))
434 ++s;
435 if (*s == '\0')
436 {
437 imppath = NULL;
438 impfile = NULL;
439 impmember = NULL;
440 obstack_free (o, obstack_base (o));
441 }
442 else if (*s == '(')
443 einfo ("%F%s%d: #! ([member]) is not supported in import files",
444 filename, lineno);
445 else
446 {
447 char cs;
448 char *file;
449
450 (void) obstack_finish (o);
451 keep = true;
452 imppath = s;
453 impfile = NULL;
454 while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0')
455 {
456 if (*s == '/')
457 file = s + 1;
458 ++s;
459 }
460 if (file != NULL)
461 {
462 file[-1] = '\0';
463 impfile = file;
464 if (imppath == file - 1)
465 imppath = "/";
466 }
467 else
468 {
469 impfile = imppath;
470 imppath = "";
471 }
472 cs = *s;
473 *s = '\0';
474 while (isspace ((unsigned char) cs))
475 {
476 ++s;
477 cs = *s;
478 }
479 if (cs != '(')
480 {
481 impmember = "";
482 if (cs != '\0')
483 einfo ("%s:%d: warning: syntax error in import file\n",
484 filename, lineno);
485 }
486 else
487 {
488 ++s;
489 impmember = s;
490 while (*s != ')' && *s != '\0')
491 ++s;
492 if (*s == ')')
493 *s = '\0';
494 else
495 einfo ("%s:%d: warning: syntax error in import file\n",
496 filename, lineno);
497 }
498 }
499
500 continue;
501 }
502
503 /* This is a symbol to be imported or exported. */
504 symname = s;
505 syscall = false;
506 address = (bfd_vma) -1;
507
508 while (! isspace ((unsigned char) *s) && *s != '\0')
509 ++s;
510 if (*s != '\0')
511 {
512 char *se;
513
514 *s++ = '\0';
515
516 while (isspace ((unsigned char) *s))
517 ++s;
518
519 se = s;
520 while (! isspace ((unsigned char) *se) && *se != '\0')
521 ++se;
522 if (*se != '\0')
523 {
524 *se++ = '\0';
525 while (isspace ((unsigned char) *se))
526 ++se;
527 if (*se != '\0')
528 einfo ("%s%d: warning: syntax error in import/export file\n",
529 filename, lineno);
530 }
531
532 if (strcasecmp (s, "svc") == 0
533 || strcasecmp (s, "syscall") == 0)
534 syscall = true;
535 else
536 {
537 char *end;
538
539 address = strtoul (s, &end, 0);
540 if (*end != '\0')
541 einfo ("%s:%d: warning: syntax error in import/export file\n",
542 filename, lineno);
543 }
544 }
545
546 h = bfd_link_hash_lookup (link_info.hash, symname, false, false, true);
547 if (h == NULL || h->type == bfd_link_hash_new)
548 {
549 /* We can just ignore attempts to import an unreferenced
550 symbol. */
551 if (! import)
552 einfo ("%X%s:%d: attempt to export undefined symbol %s\n",
553 filename, lineno, symname);
554 }
555 else if (import)
556 {
557 if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h, address,
558 imppath, impfile, impmember))
559 einfo ("%X%s:%d: failed to import symbol %s: %E\n",
560 filename, lineno, symname);
561 }
562 else
563 {
564 if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, syscall))
565 einfo ("%X%s:%d: failed to export symbol %s: %E\n",
566 filename, lineno, symname);
567 }
568
569 obstack_free (o, obstack_base (o));
570 }
571
572 if (obstack_object_size (o) > 0)
573 {
574 einfo ("%s:%d: warning: ignoring unterminated last line\n",
575 filename, lineno);
576 obstack_free (o, obstack_base (o));
577 }
578
579 if (! keep)
580 {
581 obstack_free (o, NULL);
582 free (o);
583 }
584}
585
586/* This routine saves us from worrying about declaring free. */
587
588static void
589gld${EMULATION_NAME}_free (p)
590 PTR p;
591{
592 free (p);
593}
594
595static char *
596gld${EMULATION_NAME}_get_script(isfile)
597 int *isfile;
598EOF
599
600if test -n "$COMPILE_IN"
601then
602# Scripts compiled in.
603
604# sed commands to quote an ld script as a C string.
605sc="-f ${srcdir}/emultempl/stringify.sed"
606
607cat >>e${EMULATION_NAME}.c <<EOF
608{
609 *isfile = 0;
610
611 if (link_info.relocateable == true && config.build_constructors == true)
612 return
613EOF
614sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
615echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
616sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
617echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
618sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
619echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
620sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
621echo ' ; else return' >> e${EMULATION_NAME}.c
622sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
623echo '; }' >> e${EMULATION_NAME}.c
624
625else
626# Scripts read from the filesystem.
627
628cat >>e${EMULATION_NAME}.c <<EOF
629{
630 *isfile = 1;
631
632 if (link_info.relocateable == true && config.build_constructors == true)
633 return "ldscripts/${EMULATION_NAME}.xu";
634 else if (link_info.relocateable == true)
635 return "ldscripts/${EMULATION_NAME}.xr";
636 else if (!config.text_read_only)
637 return "ldscripts/${EMULATION_NAME}.xbn";
638 else if (!config.magic_demand_paged)
639 return "ldscripts/${EMULATION_NAME}.xn";
640 else
641 return "ldscripts/${EMULATION_NAME}.x";
642}
643EOF
644
645fi
646
647cat >>e${EMULATION_NAME}.c <<EOF
648
649struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
650{
651 gld${EMULATION_NAME}_before_parse,
652 syslib_default,
653 hll_default,
654 after_parse_default,
655 after_open_default,
656 after_allocation_default,
657 set_output_arch_default,
658 ldemul_default_target,
659 gld${EMULATION_NAME}_before_allocation,
660 gld${EMULATION_NAME}_get_script,
661 "${EMULATION_NAME}",
662 "${OUTPUT_FORMAT}",
663 0, /* finish */
664 0, /* create_output_section_statements */
665 0, /* open_dynamic_archive */
666 0, /* place_orphan */
667 0, /* set_symbols */
668 gld${EMULATION_NAME}_parse_args,
669};
670EOF
This page took 0.047723 seconds and 4 git commands to generate.