Add support for SHF_MERGE sections.
[binutils.git] / ld / emultempl / aix.em
blobc2617f2ce412590730fb5db0f470d452d92c1746
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 if [ -z "$MACHINE" ]; then
4   OUTPUT_ARCH=${ARCH}
5 else
6   OUTPUT_ARCH=${ARCH}:${MACHINE}
7 fi
8 cat >e${EMULATION_NAME}.c <<EOF
9 /* This file is is generated by a shell script.  DO NOT EDIT! */
11 /* AIX emulation code for ${EMULATION_NAME}
12    Copyright 1991, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
13    2003, 2004, 2005, 2006, 2007
14    Free Software Foundation, Inc.
15    Written by Steve Chamberlain <sac@cygnus.com>
16    AIX support by Ian Lance Taylor <ian@cygnus.com>
17    AIX 64 bit support by Tom Rix <trix@redhat.com>
19 This file is part of GLD, the Gnu Linker.
21 This program is free software; you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation; either version 2 of the License, or
24 (at your option) any later version.
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 GNU General Public License for more details.
31 You should have received a copy of the GNU General Public License
32 along with this program; if not, write to the Free Software
33 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
35 #define TARGET_IS_${EMULATION_NAME}
37 #include "sysdep.h"
38 #include "bfd.h"
39 #include "libiberty.h"
40 #include "safe-ctype.h"
41 #include "getopt.h"
42 #include "obstack.h"
43 #include "bfdlink.h"
45 #include "ld.h"
46 #include "ldmain.h"
47 #include "ldmisc.h"
48 #include "ldexp.h"
49 #include "ldlang.h"
50 #include "ldfile.h"
51 #include "ldemul.h"
52 #include "ldctor.h"
53 #include <ldgram.h>
55 #include "coff/internal.h"
56 #include "coff/xcoff.h"
57 #include "libcoff.h"
58 #include "libxcoff.h"
60 static void gld${EMULATION_NAME}_read_file (const char *, bfd_boolean);
61 static void gld${EMULATION_NAME}_free (void *);
62 static void gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *);
63 static void gld${EMULATION_NAME}_find_exp_assignment (etree_type *);
66 /* The file alignment required for each section.  */
67 static unsigned long file_align;
69 /* The maximum size the stack is permitted to grow.  This is stored in
70    the a.out header.  */
71 static unsigned long maxstack;
73 /* The maximum data size.  This is stored in the a.out header.  */
74 static unsigned long maxdata;
76 /* Whether to perform garbage collection.  */
77 static int gc = 1;
79 /* The module type to use.  */
80 static unsigned short modtype = ('1' << 8) | 'L';
82 /* Whether the .text section must be read-only (i.e., no relocs
83    permitted).  */
84 static int textro;
86 /* Whether to implement Unix like linker semantics.  */
87 static int unix_ld;
89 /* Structure used to hold import file list.  */
91 struct filelist
93   struct filelist *next;
94   const char *name;
97 /* List of import files.  */
98 static struct filelist *import_files;
100 /* List of export symbols read from the export files.  */
102 struct export_symbol_list
104   struct export_symbol_list *next;
105   const char *name;
108 static struct export_symbol_list *export_symbols;
110 /* Maintains the 32 or 64 bit mode state of import file */
111 static unsigned int symbol_mode = 0x04;
113 /* Which symbol modes are valid */
114 static unsigned int symbol_mode_mask = 0x0d;
116 /* Whether this is a 64 bit link */
117 static int is_64bit = 0;
119 /* Which syscalls from import file are valid */
120 static unsigned int syscall_mask = 0x77;
122 /* fake file for -binitfini support */
123 static lang_input_statement_type *initfini_file;
125 /* Whether to do run time linking
126    -brtl enables, -bnortl and -bnortllib disable. */
127 static int rtld;
129 /* Explicit command line library path, -blibpath */
130 static char *command_line_blibpath = NULL;
132 /* This routine is called before anything else is done.  */
134 static void
135 gld${EMULATION_NAME}_before_parse (void)
137   ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
139   config.has_shared = TRUE;
141   /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
142      Override them here so we can use the link_info.init_function as a
143      state flag that lets the backend know that -binitfini has been done.  */
145   link_info.init_function = NULL;
146   link_info.fini_function = NULL;
149 /* Handle AIX specific options.  */
151 enum
152   {
153     OPTION_IGNORE = 300,
154     OPTION_AUTOIMP,
155     OPTION_ERNOTOK,
156     OPTION_EROK,
157     OPTION_EXPORT,
158     OPTION_IMPORT,
159     OPTION_INITFINI,
160     OPTION_LOADMAP,
161     OPTION_MAXDATA,
162     OPTION_MAXSTACK,
163     OPTION_MODTYPE,
164     OPTION_NOAUTOIMP,
165     OPTION_NOSTRCMPCT,
166     OPTION_PD,
167     OPTION_PT,
168     OPTION_STRCMPCT,
169     OPTION_UNIX,
170     OPTION_32,
171     OPTION_64,
172     OPTION_LIBPATH,
173     OPTION_NOLIBPATH,
174   };
176 static void
177 gld${EMULATION_NAME}_add_options
178   (int ns, char **shortopts, int nl, struct option **longopts,
179    int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
181   static const char xtra_short[] = "D:H:KT:z";
182   static const struct option xtra_long[] = {
183   /* -binitfini has special handling in the linker backend.  The native linker
184      uses the arguemnts to generate a table of init and fini functions for
185      the executable.  The important use for this option is to support aix 4.2+
186      c++ constructors and destructors.  This is tied into gcc via collect2.c.
188      The function table is accessed by the runtime linker/loader by checking if
189      the first symbol in the loader symbol table is __rtinit.  The gnu linker
190      generates this symbol and makes it the first loader symbol.  */
192     {"basis", no_argument, NULL, OPTION_IGNORE},
193     {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
194     {"bcomprld", no_argument, NULL, OPTION_IGNORE},
195     {"bcrld", no_argument, NULL, OPTION_IGNORE},
196     {"bcror31", no_argument, NULL, OPTION_IGNORE},
197     {"bD", required_argument, NULL, OPTION_MAXDATA},
198     {"bE", required_argument, NULL, OPTION_EXPORT},
199     {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
200     {"berok", no_argument, NULL, OPTION_EROK},
201     {"berrmsg", no_argument, NULL, OPTION_IGNORE},
202     {"bexport", required_argument, NULL, OPTION_EXPORT},
203     {"bf", no_argument, NULL, OPTION_ERNOTOK},
204     {"bgc", no_argument, &gc, 1},
205     {"bh", required_argument, NULL, OPTION_IGNORE},
206     {"bhalt", required_argument, NULL, OPTION_IGNORE},
207     {"bI", required_argument, NULL, OPTION_IMPORT},
208     {"bimport", required_argument, NULL, OPTION_IMPORT},
209     {"binitfini", required_argument, NULL, OPTION_INITFINI},
210     {"bl", required_argument, NULL, OPTION_LOADMAP},
211     {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
212     {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
213     {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
214     {"bM", required_argument, NULL, OPTION_MODTYPE},
215     {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
216     {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
217     {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
218     {"bnoentry", no_argument, NULL, OPTION_IGNORE},
219     {"bnogc", no_argument, &gc, 0},
220     {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
221     {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
222     {"bnotextro", no_argument, &textro, 0},
223     {"bnro", no_argument, &textro, 0},
224     {"bpD", required_argument, NULL, OPTION_PD},
225     {"bpT", required_argument, NULL, OPTION_PT},
226     {"bro", no_argument, &textro, 1},
227     {"brtl", no_argument, &rtld, 1},
228     {"bnortl", no_argument, &rtld, 0},
229     {"bnortllib", no_argument, &rtld, 0},
230     {"bS", required_argument, NULL, OPTION_MAXSTACK},
231     {"bso", no_argument, NULL, OPTION_AUTOIMP},
232     {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
233     {"btextro", no_argument, &textro, 1},
234     {"b32", no_argument, NULL, OPTION_32},
235     {"b64", no_argument, NULL, OPTION_64},
236     {"static", no_argument, NULL, OPTION_NOAUTOIMP},
237     {"unix", no_argument, NULL, OPTION_UNIX},
238     {"blibpath", required_argument, NULL, OPTION_LIBPATH},
239     {"bnolibpath", required_argument, NULL, OPTION_NOLIBPATH},
240     {NULL, no_argument, NULL, 0}
241   };
243   /* Options supported by the AIX linker which we do not support: -f,
244      -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
245      -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
246      -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
247      -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
248      -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
249      -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
250      -bx, -bX, -bxref.  */
252   *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
253   memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
254   *longopts = xrealloc (*longopts,
255                         nl * sizeof (struct option) + sizeof (xtra_long));
256   memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
259 static bfd_boolean
260 gld${EMULATION_NAME}_parse_args (int argc, char **argv)
262   int indx;
264   /* If the current option starts with -b, change the first : to an =.
265      The AIX linker uses : to separate the option from the argument;
266      changing it to = lets us treat it as a getopt option.  */
267   indx = optind;
268   if (indx == 0)
269     indx = 1;
271   if (indx < argc && CONST_STRNEQ (argv[indx], "-b"))
272     {
273       char *s;
275       for (s = argv[indx]; *s != '\0'; s++)
276         {
277           if (*s == ':')
278             {
279               *s = '=';
280               break;
281             }
282         }
283     }
284   return FALSE;
287 static bfd_boolean
288 gld${EMULATION_NAME}_handle_option (int optc)
290   bfd_signed_vma val;
291   const char *end;
293   switch (optc)
294     {
295     default:
296       return FALSE;
298     case 0:
299       /* Long option which just sets a flag.  */
300       break;
302     case 'D':
303       val = bfd_scan_vma (optarg, &end, 0);
304       if (*end != '\0')
305         einfo ("%P: warning: ignoring invalid -D number %s\n", optarg);
306       else if (val != -1)
307         lang_section_start (".data", exp_intop (val), NULL);
308       break;
310     case 'H':
311       val = bfd_scan_vma (optarg, &end, 0);
312       if (*end != '\0' || (val & (val - 1)) != 0)
313         einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
314       else
315         file_align = val;
316       break;
318     case 'K':
319     case 'z':
320       /* FIXME: This should use the page size for the target system.  */
321       file_align = 4096;
322       break;
324     case 'T':
325       /* On AIX this is the same as GNU ld -Ttext.  When we see -T
326          number, we assume the AIX option is intended.  Otherwise, we
327          assume the usual GNU ld -T option is intended.  We can't just
328          ignore the AIX option, because gcc passes it to the linker.  */
329       val = bfd_scan_vma (optarg, &end, 0);
330       if (*end != '\0')
331         return FALSE;
332       lang_section_start (".text", exp_intop (val), NULL);
333       break;
335     case OPTION_IGNORE:
336       break;
338     case OPTION_INITFINI:
339       {
340         /*
341          * The aix linker init fini has the format :
342          *
343          * -binitfini:[ Initial][:Termination][:Priority]
344          *
345          * it allows the Termination and Priority to be optional.
346          *
347          * Since we support only one init/fini pair, we ignore the Priority.
348          *
349          * Define the special symbol __rtinit.
350          *
351          * strtok does not correctly handle the case of -binitfini::fini: so
352          * do it by hand
353          */
354         char *t, *i, *f;
356         i = t = optarg;
357         while (*t && ':' != *t)
358           t++;
359         if (*t)
360           *t++ = 0;
362         if (0 != strlen (i))
363           link_info.init_function = i;
365         f = t;
366         while (*t && ':' != *t)
367           t++;
368         *t = 0;
370         if (0 != strlen (f))
371           link_info.fini_function = f;
372       }
373       break;
375     case OPTION_AUTOIMP:
376       link_info.static_link = FALSE;
377       break;
379     case OPTION_ERNOTOK:
380       force_make_executable = FALSE;
381       break;
383     case OPTION_EROK:
384       force_make_executable = TRUE;
385       break;
387     case OPTION_EXPORT:
388       gld${EMULATION_NAME}_read_file (optarg, FALSE);
389       break;
391     case OPTION_IMPORT:
392       {
393         struct filelist *n;
394         struct filelist **flpp;
396         n = (struct filelist *) xmalloc (sizeof (struct filelist));
397         n->next = NULL;
398         n->name = optarg;
399         flpp = &import_files;
400         while (*flpp != NULL)
401           flpp = &(*flpp)->next;
402         *flpp = n;
403       }
404       break;
406     case OPTION_LOADMAP:
407       config.map_filename = optarg;
408       break;
410     case OPTION_MAXDATA:
411       val = bfd_scan_vma (optarg, &end, 0);
412       if (*end != '\0')
413         einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", optarg);
414       else
415         maxdata = val;
416       break;
418     case OPTION_MAXSTACK:
419       val = bfd_scan_vma (optarg, &end, 0);
420       if (*end != '\0')
421         einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
422                optarg);
423       else
424         maxstack = val;
425       break;
427     case OPTION_MODTYPE:
428       if (*optarg == 'S')
429         {
430           link_info.shared = TRUE;
431           ++optarg;
432         }
433       if (*optarg == '\0' || optarg[1] == '\0')
434         einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
435       else
436         modtype = (*optarg << 8) | optarg[1];
437       break;
439     case OPTION_NOAUTOIMP:
440       link_info.static_link = TRUE;
441       break;
443     case OPTION_NOSTRCMPCT:
444       link_info.traditional_format = TRUE;
445       break;
447     case OPTION_PD:
448       /* This sets the page that the .data section is supposed to
449          start on.  The offset within the page should still be the
450          offset within the file, so we need to build an appropriate
451          expression.  */
452       val = bfd_scan_vma (optarg, &end, 0);
453       if (*end != '\0')
454         einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg);
455       else
456         {
457           etree_type *t;
459           t = exp_binop ('+',
460                          exp_intop (val),
461                          exp_binop ('&',
462                                     exp_nameop (NAME, "."),
463                                     exp_intop (0xfff)));
464           t = exp_binop ('&',
465                          exp_binop ('+', t, exp_intop (31)),
466                          exp_intop (~(bfd_vma) 31));
467           lang_section_start (".data", t, NULL);
468         }
469       break;
471     case OPTION_PT:
472       /* This set the page that the .text section is supposed to start
473          on.  The offset within the page should still be the offset
474          within the file.  */
475       val = bfd_scan_vma (optarg, &end, 0);
476       if (*end != '\0')
477         einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg);
478       else
479         {
480           etree_type *t;
482           t = exp_binop ('+',
483                          exp_intop (val),
484                          exp_nameop (SIZEOF_HEADERS, NULL));
485           t = exp_binop ('&',
486                          exp_binop ('+', t, exp_intop (31)),
487                          exp_intop (~(bfd_vma) 31));
488           lang_section_start (".text", t, NULL);
489         }
490       break;
492     case OPTION_STRCMPCT:
493       link_info.traditional_format = FALSE;
494       break;
496     case OPTION_UNIX:
497       unix_ld = TRUE;
498       break;
500     case OPTION_32:
501       is_64bit = 0;
502       syscall_mask = 0x77;
503       symbol_mode_mask = 0x0d;
504       break;
506     case OPTION_64:
507       is_64bit = 1;
508       syscall_mask = 0xcc;
509       symbol_mode_mask = 0x0e;
510       break;
512     case OPTION_LIBPATH:
513       command_line_blibpath = optarg;
514       break;
516     case OPTION_NOLIBPATH:
517       command_line_blibpath = NULL;
518       break;
520     }
522   return TRUE;
525 /* This is called when an input file can not be recognized as a BFD
526    object or an archive.  If the file starts with #!, we must treat it
527    as an import file.  This is for AIX compatibility.  */
529 static bfd_boolean
530 gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry)
532   FILE *e;
533   bfd_boolean ret;
535   e = fopen (entry->filename, FOPEN_RT);
536   if (e == NULL)
537     return FALSE;
539   ret = FALSE;
541   if (getc (e) == '#' && getc (e) == '!')
542     {
543       struct filelist *n;
544       struct filelist **flpp;
546       n = (struct filelist *) xmalloc (sizeof (struct filelist));
547       n->next = NULL;
548       n->name = entry->filename;
549       flpp = &import_files;
550       while (*flpp != NULL)
551         flpp = &(*flpp)->next;
552       *flpp = n;
554       ret = TRUE;
555       entry->loaded = TRUE;
556     }
558   fclose (e);
560   return ret;
563 /* This is called after the input files have been opened.  */
565 static void
566 gld${EMULATION_NAME}_after_open (void)
568   bfd_boolean r;
569   struct set_info *p;
571   /* Call ldctor_build_sets, after pretending that this is a
572      relocatable link.  We do this because AIX requires relocation
573      entries for all references to symbols, even in a final
574      executable.  Of course, we only want to do this if we are
575      producing an XCOFF output file.  */
576   r = link_info.relocatable;
577   if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL)
578     link_info.relocatable = TRUE;
579   ldctor_build_sets ();
580   link_info.relocatable = r;
582   /* For each set, record the size, so that the XCOFF backend can
583      output the correct csect length.  */
584   for (p = sets; p != (struct set_info *) NULL; p = p->next)
585     {
586       bfd_size_type size;
588       /* If the symbol is defined, we may have been invoked from
589          collect, and the sets may already have been built, so we do
590          not do anything.  */
591       if (p->h->type == bfd_link_hash_defined
592           || p->h->type == bfd_link_hash_defweak)
593         continue;
595       if (p->reloc != BFD_RELOC_CTOR)
596         {
597           /* Handle this if we need to.  */
598           abort ();
599         }
601       size = (p->count + 2) * 4;
602       if (!bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size))
603         einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n");
604     }
607 /* This is called after the sections have been attached to output
608    sections, but before any sizes or addresses have been set.  */
610 static void
611 gld${EMULATION_NAME}_before_allocation (void)
613   struct filelist *fl;
614   struct export_symbol_list *el;
615   char *libpath;
616   asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS];
617   int i;
619   /* Handle the import and export files, if any.  */
620   for (fl = import_files; fl != NULL; fl = fl->next)
621     gld${EMULATION_NAME}_read_file (fl->name, TRUE);
622   for (el = export_symbols; el != NULL; el = el->next)
623     {
624       struct bfd_link_hash_entry *h;
626       h = bfd_link_hash_lookup (link_info.hash, el->name, FALSE, FALSE, FALSE);
627       if (h == NULL)
628         einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n");
629       if (!bfd_xcoff_export_symbol (output_bfd, &link_info, h))
630         einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
631     }
633   /* Track down all relocations called for by the linker script (these
634      are typically constructor/destructor entries created by
635      CONSTRUCTORS) and let the backend know it will need to create
636      .loader relocs for them.  */
637   lang_for_each_statement (gld${EMULATION_NAME}_find_relocs);
639   /* Precedence of LIBPATH
640      -blibpath:  native support always first
641      -rpath:     gnu extension
642      -L          build from command line -L's */
643   if (command_line_blibpath != NULL)
644     libpath = command_line_blibpath;
645   else if (command_line.rpath != NULL)
646     libpath = command_line.rpath;
647   else if (search_head == NULL)
648     libpath = (char *) "";
649   else
650     {
651       size_t len;
652       search_dirs_type *search;
654       /* PR ld/4023: Strip sysroot prefix from any paths
655          being inserted into the output binary's DT_RPATH.  */
656       if (ld_sysroot != NULL
657           && * ld_sysroot != 0)
658         {
659           const char * name = search_head->name;
660           size_t ld_sysroot_len = strlen (ld_sysroot);
662           if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0)
663             name += ld_sysroot_len;
665           len = strlen (name);
666           libpath = xmalloc (len + 1);
667           strcpy (libpath, name);
669           for (search = search_head->next; search != NULL; search = search->next)
670             {
671               size_t nlen;
673               name = search->name;
674               if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0)
675                 name += ld_sysroot_len;
677               nlen = strlen (name);
678               libpath = xrealloc (libpath, len + nlen + 2);
679               libpath[len] = ':';
680               strcpy (libpath + len + 1, name);
681               len += nlen + 1;
682             }
683         }
684       else
685         {
686           len = strlen (search_head->name);
687           libpath = xmalloc (len + 1);
688           strcpy (libpath, search_head->name);
690           for (search = search_head->next; search != NULL; search = search->next)
691             {
692               size_t nlen;
694               nlen = strlen (search->name);
695               libpath = xrealloc (libpath, len + nlen + 2);
696               libpath[len] = ':';
697               strcpy (libpath + len + 1, search->name);
698               len += nlen + 1;
699             }
700         }
701     }
703   /* Let the XCOFF backend set up the .loader section.  */
704   if (!bfd_xcoff_size_dynamic_sections
705       (output_bfd, &link_info, libpath, entry_symbol.name, file_align,
706        maxstack, maxdata, gc && !unix_ld ? TRUE : FALSE,
707        modtype, textro ? TRUE : FALSE, unix_ld, special_sections,
708        rtld ? TRUE : FALSE))
709     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
711   /* Look through the special sections, and put them in the right
712      place in the link ordering.  This is especially magic.  */
713   for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
714     {
715       asection *sec;
716       lang_output_section_statement_type *os;
717       lang_statement_union_type **pls;
718       lang_input_section_type *is;
719       const char *oname;
720       bfd_boolean start;
722       sec = special_sections[i];
723       if (sec == NULL)
724         continue;
726       /* Remove this section from the list of the output section.
727          This assumes we know what the script looks like.  */
728       is = NULL;
729       os = lang_output_section_find (sec->output_section->name);
730       if (os == NULL)
731         einfo ("%P%F: can't find output section %s\n",
732                sec->output_section->name);
734       for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next)
735         {
736           if ((*pls)->header.type == lang_input_section_enum
737               && (*pls)->input_section.section == sec)
738             {
739               is = (lang_input_section_type *) * pls;
740               *pls = (*pls)->header.next;
741               break;
742             }
744           if ((*pls)->header.type == lang_wild_statement_enum)
745             {
746               lang_statement_union_type **pwls;
748               for (pwls = &(*pls)->wild_statement.children.head;
749                    *pwls != NULL; pwls = &(*pwls)->header.next)
750                 {
752                   if ((*pwls)->header.type == lang_input_section_enum
753                       && (*pwls)->input_section.section == sec)
754                     {
755                       is = (lang_input_section_type *) * pwls;
756                       *pwls = (*pwls)->header.next;
757                       break;
758                     }
759                 }
761               if (is != NULL)
762                 break;
763             }
764         }
766       if (is == NULL)
767         {
768           einfo ("%P%F: can't find %s in output section\n",
769                  bfd_get_section_name (sec->owner, sec));
770         }
772       /* Now figure out where the section should go.  */
773       switch (i)
774         {
776         default:                /* to avoid warnings */
777         case XCOFF_SPECIAL_SECTION_TEXT:
778           /* _text */
779           oname = ".text";
780           start = TRUE;
781           break;
783         case XCOFF_SPECIAL_SECTION_ETEXT:
784           /* _etext */
785           oname = ".text";
786           start = FALSE;
787           break;
789         case XCOFF_SPECIAL_SECTION_DATA:
790           /* _data */
791           oname = ".data";
792           start = TRUE;
793           break;
795         case XCOFF_SPECIAL_SECTION_EDATA:
796           /* _edata */
797           oname = ".data";
798           start = FALSE;
799           break;
801         case XCOFF_SPECIAL_SECTION_END:
802         case XCOFF_SPECIAL_SECTION_END2:
803           /* _end and end */
804           oname = ".bss";
805           start = FALSE;
806           break;
807         }
809       os = lang_output_section_find (oname);
811       if (start)
812         {
813           is->header.next = os->children.head;
814           os->children.head = (lang_statement_union_type *) is;
815         }
816       else
817         {
818           is->header.next = NULL;
819           lang_statement_append (&os->children,
820                                  (lang_statement_union_type *) is,
821                                  &is->header.next);
822         }
823     }
825   before_allocation_default ();
828 static char *
829 gld${EMULATION_NAME}_choose_target (int argc, char **argv)
831   int i, j, jmax;
832   static char *from_outside;
833   static char *from_inside;
834   static char *argv_to_target[][2] = {
835     {NULL,   "${OUTPUT_FORMAT}"},
836     {"-b32", "${OUTPUT_FORMAT_32BIT}"},
837     {"-b64", "${OUTPUT_FORMAT_64BIT}"},
838   };
840   jmax = 3;
842   from_outside = getenv (TARGET_ENVIRON);
843   if (from_outside != (char *) NULL)
844     return from_outside;
846   /* Set to default. */
847   from_inside = argv_to_target[0][1];
848   for (i = 1; i < argc; i++)
849     {
850       for (j = 1; j < jmax; j++)
851         {
852           if (0 == strcmp (argv[i], argv_to_target[j][0]))
853             from_inside = argv_to_target[j][1];
854         }
855     }
857   return from_inside;
860 /* Returns
861    1 : state changed
862    0 : no change */
863 static int
864 change_symbol_mode (char *input)
866   char *symbol_mode_string[] = {
867     "# 32",                     /* 0x01 */
868     "# 64",                     /* 0x02 */
869     "# no32",                   /* 0x04 */
870     "# no64",                   /* 0x08 */
871     NULL,
872   };
874   unsigned int bit;
875   char *string;
877   for (bit = 0;; bit++)
878     {
879       string = symbol_mode_string[bit];
880       if (string == NULL)
881         return 0;
883       if (0 == strcmp (input, string))
884         {
885           symbol_mode = (1 << bit);
886           return 1;
887         }
888     }
889   /* should not be here */
890   return 0;
893 /* Returns
894    1 : yes
895    0 : ignore
896    -1 : error, try something else */
897 static int
898 is_syscall (char *input, unsigned int *flag)
900   unsigned int bit;
901   char *string;
903   struct sc {
904     char *syscall_string;
905     unsigned int flag;
906   } s [] = {
907     { "svc"         /* 0x01 */, XCOFF_SYSCALL32 },
908     { "svc32"       /* 0x02 */, XCOFF_SYSCALL32 },
909     { "svc3264"     /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
910     { "svc64"       /* 0x08 */, XCOFF_SYSCALL64 },
911     { "syscall"     /* 0x10 */, XCOFF_SYSCALL32 },
912     { "syscall32"   /* 0x20 */, XCOFF_SYSCALL32 },
913     { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
914     { "syscall64"   /* 0x80 */, XCOFF_SYSCALL64 },
915     { NULL, 0 },
916   };
918   *flag = 0;
920   for (bit = 0;; bit++)
921     {
922       string = s[bit].syscall_string;
923       if (string == NULL)
924         return -1;
926       if (0 == strcmp (input, string))
927         {
928           if (1 << bit & syscall_mask)
929             {
930               *flag = s[bit].flag;
931               return 1;
932             }
933           else
934             {
935               return 0;
936             }
937         }
938     }
939   /* should not be here */
940   return -1;
943 /* Read an import or export file.  For an import file, this is called
944    by the before_allocation emulation routine.  For an export file,
945    this is called by the handle_option emulation routine.  */
947 static void
948 gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
950   struct obstack *o;
951   FILE *f;
952   int lineno;
953   int c;
954   bfd_boolean keep;
955   const char *imppath;
956   const char *impfile;
957   const char *impmember;
959   o = (struct obstack *) xmalloc (sizeof (struct obstack));
960   obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free);
962   f = fopen (filename, FOPEN_RT);
963   if (f == NULL)
964     {
965       bfd_set_error (bfd_error_system_call);
966       einfo ("%F%s: %E\n", filename);
967     }
969   keep = FALSE;
971   imppath = NULL;
972   impfile = NULL;
973   impmember = NULL;
975   lineno = 0;
977   /* Default to 32 and 64 bit mode
978      symbols at top of /lib/syscalls.exp do not have a mode modifier and they
979      are not repeated, assume 64 bit routines also want to use them.
980      See the routine change_symbol_mode for more information.  */
982   symbol_mode = 0x04;
984   while ((c = getc (f)) != EOF)
985     {
986       char *s;
987       char *symname;
988       unsigned int syscall_flag = 0;
989       bfd_vma address;
990       struct bfd_link_hash_entry *h;
992       if (c != '\n')
993         {
994           obstack_1grow (o, c);
995           continue;
996         }
998       obstack_1grow (o, '\0');
999       ++lineno;
1001       s = (char *) obstack_base (o);
1002       while (ISSPACE (*s))
1003         ++s;
1004       if (*s == '\0'
1005           || *s == '*'
1006           || change_symbol_mode (s)
1007           || (*s == '#' && s[1] == ' ')
1008           || (!import && *s == '#' && s[1] == '!'))
1009         {
1010           obstack_free (o, obstack_base (o));
1011           continue;
1012         }
1014       if (*s == '#' && s[1] == '!')
1015         {
1016           s += 2;
1017           while (ISSPACE (*s))
1018             ++s;
1019           if (*s == '\0')
1020             {
1021               imppath = NULL;
1022               impfile = NULL;
1023               impmember = NULL;
1024               obstack_free (o, obstack_base (o));
1025             }
1026           else if (*s == '(')
1027             einfo ("%F%s%d: #! ([member]) is not supported in import files\n",
1028                    filename, lineno);
1029           else
1030             {
1031               char cs;
1032               char *file;
1034               (void) obstack_finish (o);
1035               keep = TRUE;
1036               imppath = s;
1037               file = NULL;
1038               while (!ISSPACE (*s) && *s != '(' && *s != '\0')
1039                 {
1040                   if (*s == '/')
1041                     file = s + 1;
1042                   ++s;
1043                 }
1044               if (file != NULL)
1045                 {
1046                   file[-1] = '\0';
1047                   impfile = file;
1048                   if (imppath == file - 1)
1049                     imppath = "/";
1050                 }
1051               else
1052                 {
1053                   impfile = imppath;
1054                   imppath = "";
1055                 }
1056               cs = *s;
1057               *s = '\0';
1058               while (ISSPACE (cs))
1059                 {
1060                   ++s;
1061                   cs = *s;
1062                 }
1063               if (cs != '(')
1064                 {
1065                   impmember = "";
1066                   if (cs != '\0')
1067                     einfo ("%s:%d: warning: syntax error in import file\n",
1068                            filename, lineno);
1069                 }
1070               else
1071                 {
1072                   ++s;
1073                   impmember = s;
1074                   while (*s != ')' && *s != '\0')
1075                     ++s;
1076                   if (*s == ')')
1077                     *s = '\0';
1078                   else
1079                     einfo ("%s:%d: warning: syntax error in import file\n",
1080                            filename, lineno);
1081                 }
1082             }
1084           continue;
1085         }
1087       if (symbol_mode & symbol_mode_mask)
1088         {
1089           /* This is a symbol to be imported or exported.  */
1090           symname = s;
1091           syscall_flag = 0;
1092           address = (bfd_vma) -1;
1094           while (!ISSPACE (*s) && *s != '\0')
1095             ++s;
1096           if (*s != '\0')
1097             {
1098               char *se;
1100               *s++ = '\0';
1102               while (ISSPACE (*s))
1103                 ++s;
1105               se = s;
1106               while (!ISSPACE (*se) && *se != '\0')
1107                 ++se;
1108               if (*se != '\0')
1109                 {
1110                   *se++ = '\0';
1111                   while (ISSPACE (*se))
1112                     ++se;
1113                   if (*se != '\0')
1114                     einfo ("%s%d: warning: syntax error in import/export file\n",
1115                            filename, lineno);
1116                 }
1118               if (s != se)
1119                 {
1120                   int status;
1121                   const char *end;
1123                   status = is_syscall (s, &syscall_flag);
1125                   if (0 > status)
1126                     {
1127                       /* not a system call, check for address */
1128                       address = bfd_scan_vma (s, &end, 0);
1129                       if (*end != '\0')
1130                         {
1131                           einfo ("%s:%d: warning: syntax error in import/export file\n",
1132                                  filename, lineno);
1134                         }
1135                     }
1136                 }
1137             }
1139           if (!import)
1140             {
1141               struct export_symbol_list *n;
1143               ldlang_add_undef (symname);
1144               n = ((struct export_symbol_list *)
1145                    xmalloc (sizeof (struct export_symbol_list)));
1146               n->next = export_symbols;
1147               n->name = xstrdup (symname);
1148               export_symbols = n;
1149             }
1150           else
1151             {
1152               h = bfd_link_hash_lookup (link_info.hash, symname, FALSE, FALSE,
1153                                         TRUE);
1154               if (h == NULL || h->type == bfd_link_hash_new)
1155                 {
1156                   /* We can just ignore attempts to import an unreferenced
1157                      symbol.  */
1158                 }
1159               else
1160                 {
1161                   if (!bfd_xcoff_import_symbol (output_bfd, &link_info, h,
1162                                                 address, imppath, impfile,
1163                                                 impmember, syscall_flag))
1164                     einfo ("%X%s:%d: failed to import symbol %s: %E\n",
1165                            filename, lineno, symname);
1166                 }
1167             }
1168         }
1169       obstack_free (o, obstack_base (o));
1170     }
1172   if (obstack_object_size (o) > 0)
1173     {
1174       einfo ("%s:%d: warning: ignoring unterminated last line\n",
1175              filename, lineno);
1176       obstack_free (o, obstack_base (o));
1177     }
1179   if (!keep)
1180     {
1181       obstack_free (o, NULL);
1182       free (o);
1183     }
1186 /* This routine saves us from worrying about declaring free.  */
1188 static void
1189 gld${EMULATION_NAME}_free (void *p)
1191   free (p);
1194 /* This is called by the before_allocation routine via
1195    lang_for_each_statement.  It looks for relocations and assignments
1196    to symbols.  */
1198 static void
1199 gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *s)
1201   if (s->header.type == lang_reloc_statement_enum)
1202     {
1203       lang_reloc_statement_type *rs;
1205       rs = &s->reloc_statement;
1206       if (rs->name == NULL)
1207         einfo ("%F%P: only relocations against symbols are permitted\n");
1208       if (!bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name))
1209         einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n");
1210     }
1212   if (s->header.type == lang_assignment_statement_enum)
1213     gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
1216 /* Look through an expression for an assignment statement.  */
1218 static void
1219 gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
1221   struct bfd_link_hash_entry *h;
1223   switch (exp->type.node_class)
1224     {
1225     case etree_provide:
1226       h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
1227                                 FALSE, FALSE, FALSE);
1228       if (h == NULL)
1229         break;
1230       /* Fall through.  */
1231     case etree_assign:
1232       if (strcmp (exp->assign.dst, ".") != 0)
1233         {
1234           if (!bfd_xcoff_record_link_assignment (output_bfd, &link_info,
1235                                                  exp->assign.dst))
1236             einfo ("%P%F: failed to record assignment to %s: %E\n",
1237                    exp->assign.dst);
1238         }
1239       gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
1240       break;
1242     case etree_binary:
1243       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
1244       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
1245       break;
1247     case etree_trinary:
1248       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
1249       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
1250       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
1251       break;
1253     case etree_unary:
1254       gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
1255       break;
1257     default:
1258       break;
1259     }
1262 static char *
1263 gld${EMULATION_NAME}_get_script (int *isfile)
1266 if test -n "$COMPILE_IN"
1267 then
1268 # Scripts compiled in.
1270 # sed commands to quote an ld script as a C string.
1271 sc="-f ${srcdir}/emultempl/ostring.sed"
1273 cat >>e${EMULATION_NAME}.c <<EOF
1275   *isfile = 0;
1277   if (link_info.relocatable && config.build_constructors)
1278     return
1280 sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
1281 echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
1282 sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
1283 echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
1284 sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
1285 echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
1286 sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
1287 echo '  ; else return'                                 >> e${EMULATION_NAME}.c
1288 sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
1289 echo '; }'                                             >> e${EMULATION_NAME}.c
1291 else
1292 # Scripts read from the filesystem.
1294 cat >>e${EMULATION_NAME}.c <<EOF
1296   *isfile = 1;
1298   if (link_info.relocatable && config.build_constructors)
1299     return "ldscripts/${EMULATION_NAME}.xu";
1300   else if (link_info.relocatable)
1301     return "ldscripts/${EMULATION_NAME}.xr";
1302   else if (!config.text_read_only)
1303     return "ldscripts/${EMULATION_NAME}.xbn";
1304   else if (!config.magic_demand_paged)
1305     return "ldscripts/${EMULATION_NAME}.xn";
1306   else
1307     return "ldscripts/${EMULATION_NAME}.x";
1313 cat >>e${EMULATION_NAME}.c <<EOF
1315 static void
1316 gld${EMULATION_NAME}_create_output_section_statements (void)
1318   /* __rtinit */
1319   if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
1320       && (link_info.init_function != NULL
1321           || link_info.fini_function != NULL
1322           || rtld))
1323     {
1324       initfini_file = lang_add_input_file ("initfini",
1325                                            lang_input_file_is_file_enum,
1326                                            NULL);
1328       initfini_file->the_bfd = bfd_create ("initfini", output_bfd);
1329       if (initfini_file->the_bfd == NULL
1330           || ! bfd_set_arch_mach (initfini_file->the_bfd,
1331                                   bfd_get_arch (output_bfd),
1332                                   bfd_get_mach (output_bfd)))
1333         {
1334           einfo ("%X%P: can not create BFD %E\n");
1335           return;
1336         }
1338       /* Call backend to fill in the rest */
1339       if (! bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd,
1340                                             link_info.init_function,
1341                                             link_info.fini_function,
1342                                             rtld))
1343         {
1344           einfo ("%X%P: can not create BFD %E\n");
1345           return;
1346         }
1348       /* __rtld defined in /lib/librtl.a */
1349       if (rtld)
1350         lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL);
1351     }
1354 static void
1355 gld${EMULATION_NAME}_set_output_arch (void)
1357   bfd_set_arch_mach (output_bfd,
1358                      bfd_xcoff_architecture (output_bfd),
1359                      bfd_xcoff_machine (output_bfd));
1361   ldfile_output_architecture = bfd_get_arch (output_bfd);
1362   ldfile_output_machine = bfd_get_mach (output_bfd);
1363   ldfile_output_machine_name = bfd_printable_name (output_bfd);
1366 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
1367   gld${EMULATION_NAME}_before_parse,
1368   syslib_default,
1369   hll_default,
1370   after_parse_default,
1371   gld${EMULATION_NAME}_after_open,
1372   after_allocation_default,
1373   gld${EMULATION_NAME}_set_output_arch,
1374   gld${EMULATION_NAME}_choose_target,
1375   gld${EMULATION_NAME}_before_allocation,
1376   gld${EMULATION_NAME}_get_script,
1377   "${EMULATION_NAME}",
1378   "${OUTPUT_FORMAT}",
1379   finish_default,
1380   gld${EMULATION_NAME}_create_output_section_statements,
1381   0,                            /* open_dynamic_archive */
1382   0,                            /* place_orphan */
1383   0,                            /* set_symbols */
1384   gld${EMULATION_NAME}_parse_args,
1385   gld${EMULATION_NAME}_add_options,
1386   gld${EMULATION_NAME}_handle_option,
1387   gld${EMULATION_NAME}_unrecognized_file,
1388   NULL,                         /* list_options */
1389   NULL,                         /* recognized_file */
1390   NULL,                         /* find potential_libraries */
1391   NULL                          /* new_vers_pattern */