* emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Treat
[platform/upstream/binutils.git] / ld / emultempl / aix.em
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 cat >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
11 This file is part of GLD, the Gnu Linker.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, 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
45 static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
46 static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **));
47 static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
48 static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean));
49 static void gld${EMULATION_NAME}_free PARAMS ((PTR));
50 static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
51
52 /* The file alignment required for each section.  */
53 static unsigned long file_align;
54
55 /* The maximum size the stack is permitted to grow.  This is stored in
56    the a.out header.  */
57 static unsigned long maxstack;
58
59 /* The maximum data size.  This is stored in the a.out header.  */
60 static unsigned long maxdata;
61
62 /* Whether to perform garbage collection.  */
63 static int gc = 1;
64
65 /* The module type to use.  */
66 static unsigned short modtype = ('1' << 8) | 'L';
67
68 /* Whether the .text section must be read-only (i.e., no relocs
69    permitted).  */
70 static int textro;
71
72 /* Structure used to hold import or export file list.  */
73
74 struct filelist
75 {
76   struct filelist *next;
77   const char *name;
78 };
79
80 /* List of import files.  */
81 struct filelist *import_files;
82
83 /* List of export files.  */
84 struct filelist *export_files;
85
86 static void
87 gld${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
96 static int
97 gld${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},
155     {"static", no_argument, NULL, OPTION_NOAUTOIMP},
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
195     case 0:
196       /* Long option which just sets a flag.  */
197       break;
198
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
319 static void
320 gld${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
370 static void
371 gld${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
588 static void
589 gld${EMULATION_NAME}_free (p)
590      PTR p;
591 {
592   free (p);
593 }
594
595 static char *
596 gld${EMULATION_NAME}_get_script(isfile)
597      int *isfile;
598 EOF
599
600 if test -n "$COMPILE_IN"
601 then
602 # Scripts compiled in.
603
604 # sed commands to quote an ld script as a C string.
605 sc="-f ${srcdir}/emultempl/stringify.sed"
606
607 cat >>e${EMULATION_NAME}.c <<EOF
608 {                            
609   *isfile = 0;
610
611   if (link_info.relocateable == true && config.build_constructors == true)
612     return
613 EOF
614 sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
615 echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
616 sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
617 echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
618 sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
619 echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
620 sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
621 echo '  ; else return'                                     >> e${EMULATION_NAME}.c
622 sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
623 echo '; }'                                                 >> e${EMULATION_NAME}.c
624
625 else
626 # Scripts read from the filesystem.
627
628 cat >>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 }
643 EOF
644
645 fi
646
647 cat >>e${EMULATION_NAME}.c <<EOF
648
649 struct 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 };
670 EOF