OSDN Git Service

Locale changes from Bruno Haible <haible@clisp.cons.org>.
[pf3gnuchains/pf3gnuchains3x.git] / ld / mpw-eppcmac.c
1 /* This file is is generated by a shell script.  DO NOT EDIT! */
2
3 /* AIX emulation code for ppcmacos
4    Copyright 1991, 1993, 1995, 1996, 1997, 2000, 2001
5    Free Software Foundation, Inc.
6    Written by Steve Chamberlain <sac@cygnus.com>
7    AIX support by Ian Lance Taylor <ian@cygnus.com>
8
9 This file is part of GLD, the Gnu Linker.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24
25 #define TARGET_IS_ppcmacos
26
27 #include "bfd.h"
28 #include "sysdep.h"
29 #include "libiberty.h"
30 #include "safe-ctype.h"
31 #include "getopt.h"
32 #include "bfdlink.h"
33
34 #include "ld.h"
35 #include "ldmain.h"
36 #include "ldmisc.h"
37 #include "ldexp.h"
38 #include "ldlang.h"
39 #include "ldctor.h"
40 #include "ldgram.h"
41 #include "ldfile.h"
42 #include "ldemul.h"
43
44 static void gldppcmacos_before_parse PARAMS ((void));
45 static int gldppcmacos_parse_args PARAMS ((int, char **));
46 static void gldppcmacos_after_open PARAMS ((void));
47 static void gldppcmacos_before_allocation PARAMS ((void));
48 static void gldppcmacos_read_file PARAMS ((const char *, boolean));
49 static void gldppcmacos_free PARAMS ((PTR));
50 static void gldppcmacos_find_relocs
51   PARAMS ((lang_statement_union_type *));
52 static void gldppcmacos_find_exp_assignment PARAMS ((etree_type *));
53 static char *gldppcmacos_get_script PARAMS ((int *isfile));
54
55 /* The file alignment required for each section.  */
56 static unsigned long file_align;
57
58 /* The maximum size the stack is permitted to grow.  This is stored in
59    the a.out header.  */
60 static unsigned long maxstack;
61
62 /* The maximum data size.  This is stored in the a.out header.  */
63 static unsigned long maxdata;
64
65 /* Whether to perform garbage collection.  */
66 static int gc = 1;
67
68 /* The module type to use.  */
69 static unsigned short modtype = ('1' << 8) | 'L';
70
71 /* Whether the .text section must be read-only (i.e., no relocs
72    permitted).  */
73 static int textro;
74
75 /* Whether to implement Unix like linker semantics.  */
76 static int unix_ld;
77
78 /* Structure used to hold import file list.  */
79
80 struct filelist
81 {
82   struct filelist *next;
83   const char *name;
84 };
85
86 /* List of import files.  */
87 static struct filelist *import_files;
88
89 /* List of export symbols read from the export files.  */
90
91 struct export_symbol_list
92 {
93   struct export_symbol_list *next;
94   const char *name;
95   boolean syscall;
96 };
97
98 static struct export_symbol_list *export_symbols;
99
100 /* This routine is called before anything else is done.  */
101
102 static void
103 gldppcmacos_before_parse()
104 {
105 #ifndef TARGET_                 /* I.e., if not generic.  */
106   ldfile_output_architecture = bfd_arch_powerpc;
107 #endif /* not TARGET_ */
108 }
109
110 /* Handle AIX specific options.  */
111
112 static int
113 gldppcmacos_parse_args (argc, argv)
114      int argc;
115      char **argv;
116 {
117   int prevoptind = optind;
118   int prevopterr = opterr;
119   int indx;
120   int longind;
121   int optc;
122   long val;
123   char *end;
124
125 #define OPTION_IGNORE (300)
126 #define OPTION_AUTOIMP (OPTION_IGNORE + 1)
127 #define OPTION_ERNOTOK (OPTION_AUTOIMP + 1)
128 #define OPTION_EROK (OPTION_ERNOTOK + 1)
129 #define OPTION_EXPORT (OPTION_EROK + 1)
130 #define OPTION_IMPORT (OPTION_EXPORT + 1)
131 #define OPTION_LOADMAP (OPTION_IMPORT + 1)
132 #define OPTION_MAXDATA (OPTION_LOADMAP + 1)
133 #define OPTION_MAXSTACK (OPTION_MAXDATA + 1)
134 #define OPTION_MODTYPE (OPTION_MAXSTACK + 1)
135 #define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1)
136 #define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1)
137 #define OPTION_PD (OPTION_NOSTRCMPCT + 1)
138 #define OPTION_PT (OPTION_PD + 1)
139 #define OPTION_STRCMPCT (OPTION_PT + 1)
140 #define OPTION_UNIX (OPTION_STRCMPCT + 1)
141
142   static struct option longopts[] = {
143     {"basis", no_argument, NULL, OPTION_IGNORE},
144     {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
145     {"bcomprld", no_argument, NULL, OPTION_IGNORE},
146     {"bcrld", no_argument, NULL, OPTION_IGNORE},
147     {"bcror31", no_argument, NULL, OPTION_IGNORE},
148     {"bD", required_argument, NULL, OPTION_MAXDATA},
149     {"bE", required_argument, NULL, OPTION_EXPORT},
150     {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
151     {"berok", no_argument, NULL, OPTION_EROK},
152     {"berrmsg", no_argument, NULL, OPTION_IGNORE},
153     {"bexport", required_argument, NULL, OPTION_EXPORT},
154     {"bf", no_argument, NULL, OPTION_ERNOTOK},
155     {"bgc", no_argument, &gc, 1},
156     {"bh", required_argument, NULL, OPTION_IGNORE},
157     {"bhalt", required_argument, NULL, OPTION_IGNORE},
158     {"bI", required_argument, NULL, OPTION_IMPORT},
159     {"bimport", required_argument, NULL, OPTION_IMPORT},
160     {"bl", required_argument, NULL, OPTION_LOADMAP},
161     {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
162     {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
163     {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
164     {"bM", required_argument, NULL, OPTION_MODTYPE},
165     {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
166     {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
167     {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
168     {"bnoentry", no_argument, NULL, OPTION_IGNORE},
169     {"bnogc", no_argument, &gc, 0},
170     {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
171     {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
172     {"bnotextro", no_argument, &textro, 0},
173     {"bnro", no_argument, &textro, 0},
174     {"bpD", required_argument, NULL, OPTION_PD},
175     {"bpT", required_argument, NULL, OPTION_PT},
176     {"bro", no_argument, &textro, 1},
177     {"bS", required_argument, NULL, OPTION_MAXSTACK},
178     {"bso", no_argument, NULL, OPTION_AUTOIMP},
179     {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
180     {"btextro", no_argument, &textro, 1},
181     {"static", no_argument, NULL, OPTION_NOAUTOIMP},
182     {"unix", no_argument, NULL, OPTION_UNIX},
183     {NULL, no_argument, NULL, 0}
184   };
185
186   /* Options supported by the AIX linker which we do not support: -f,
187      -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
188      -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
189      -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
190      -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
191      -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
192      -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
193      -bx, -bX, -bxref.  */
194
195   /* If the current option starts with -b, change the first : to an =.
196      The AIX linker uses : to separate the option from the argument;
197      changing it to = lets us treat it as a getopt option.  */
198   indx = optind;
199   if (indx == 0)
200     indx = 1;
201   if (indx < argc && strncmp (argv[indx], "-b", 2) == 0)
202     {
203       char *s;
204
205       for (s = argv[indx]; *s != '\0'; s++)
206         {
207           if (*s == ':')
208             {
209               *s = '=';
210               break;
211             }
212         }
213     }
214
215   opterr = 0;
216   optc = getopt_long_only (argc, argv, "-D:H:KT:z", longopts, &longind);
217   opterr = prevopterr;
218
219   switch (optc)
220     {
221     default:
222       optind = prevoptind;
223       return 0;
224
225     case 0:
226       /* Long option which just sets a flag.  */
227       break;
228
229     case 'D':
230       val = strtol (optarg, &end, 0);
231       if (*end != '\0')
232         einfo (_("%P: warning: ignoring invalid -D number %s\n"), optarg);
233       else if (val != -1)
234         lang_section_start (".data", exp_intop (val));
235       break;
236
237     case 'H':
238       val = strtoul (optarg, &end, 0);
239       if (*end != '\0'
240           || (val & (val - 1)) != 0)
241         einfo (_("%P: warning: ignoring invalid -H number %s\n"), optarg);
242       else
243         file_align = val;
244       break;
245
246     case 'K':
247     case 'z':
248       /* FIXME: This should use the page size for the target system.  */
249       file_align = 4096;
250       break;
251
252     case 'T':
253       /* On AIX this is the same as GNU ld -Ttext.  When we see -T
254          number, we assume the AIX option is intended.  Otherwise, we
255          assume the usual GNU ld -T option is intended.  We can't just
256          ignore the AIX option, because gcc passes it to the linker.  */
257       val = strtoul (optarg, &end, 0);
258       if (*end != '\0')
259         {
260           optind = prevoptind;
261           return 0;
262         }
263       lang_section_start (".text", exp_intop (val));
264       break;
265
266     case OPTION_IGNORE:
267       break;
268
269     case OPTION_AUTOIMP:
270       link_info.static_link = false;
271       break;
272
273     case OPTION_ERNOTOK:
274       force_make_executable = false;
275       break;
276
277     case OPTION_EROK:
278       force_make_executable = true;
279       break;
280
281     case OPTION_EXPORT:
282       gldppcmacos_read_file (optarg, false);
283       break;
284
285     case OPTION_IMPORT:
286       {
287         struct filelist *n;
288         struct filelist **flpp;
289
290         n = (struct filelist *) xmalloc (sizeof (struct filelist));
291         n->next = NULL;
292         n->name = optarg;
293         flpp = &import_files;
294         while (*flpp != NULL)
295           flpp = &(*flpp)->next;
296         *flpp = n;
297       }
298       break;
299
300     case OPTION_LOADMAP:
301       config.map_filename = optarg;
302       break;
303
304     case OPTION_MAXDATA:
305       val = strtoul (optarg, &end, 0);
306       if (*end != '\0')
307         einfo (_("%P: warning: ignoring invalid -bmaxdata number %s\n"),
308                optarg);
309       else
310         maxdata = val;
311       break;
312
313     case OPTION_MAXSTACK:
314       val = strtoul (optarg, &end, 0);
315       if (*end != '\0')
316         einfo (_("%P: warning: ignoring invalid -bmaxstack number %s\n"),
317                optarg);
318       else
319         maxstack = val;
320       break;
321
322     case OPTION_MODTYPE:
323       if (*optarg == 'S')
324         {
325           link_info.shared = true;
326           ++optarg;
327         }
328       if (*optarg == '\0' || optarg[1] == '\0')
329         einfo (_("%P: warning: ignoring invalid module type %s\n"), optarg);
330       else
331         modtype = (*optarg << 8) | optarg[1];
332       break;
333
334     case OPTION_NOAUTOIMP:
335       link_info.static_link = true;
336       break;
337
338     case OPTION_NOSTRCMPCT:
339       link_info.traditional_format = true;
340       break;
341
342     case OPTION_PD:
343       /* This sets the page that the .data section is supposed to
344          start on.  The offset within the page should still be the
345          offset within the file, so we need to build an appropriate
346          expression.  */
347       val = strtoul (optarg, &end, 0);
348       if (*end != '\0')
349         einfo (_("%P: warning: ignoring invalid -pD number %s\n"), optarg);
350       else
351         {
352           etree_type *t;
353
354           t = exp_binop ('+',
355                          exp_intop (val),
356                          exp_binop ('&',
357                                     exp_nameop (NAME, "."),
358                                     exp_intop (0xfff)));
359           t = exp_binop ('&',
360                          exp_binop ('+', t, exp_intop (7)),
361                          exp_intop (~ (bfd_vma) 7));
362           lang_section_start (".data", t);
363         }
364       break;
365
366     case OPTION_PT:
367       /* This set the page that the .text section is supposed to start
368          on.  The offset within the page should still be the offset
369          within the file.  */
370       val = strtoul (optarg, &end, 0);
371       if (*end != '\0')
372         einfo (_("%P: warning: ignoring invalid -pT number %s\n"), optarg);
373       else
374         {
375           etree_type *t;
376
377           t = exp_binop ('+',
378                          exp_intop (val),
379                          exp_nameop (SIZEOF_HEADERS, NULL));
380           t = exp_binop ('&',
381                          exp_binop ('+', t, exp_intop (7)),
382                          exp_intop (~ (bfd_vma) 7));
383           lang_section_start (".text", t);
384         }
385       break;
386
387     case OPTION_STRCMPCT:
388       link_info.traditional_format = false;
389       break;
390
391     case OPTION_UNIX:
392       unix_ld = true;
393       break;
394     }
395
396   return 1;
397 }
398
399 /* This is called when an input file can not be recognized as a BFD
400    object or an archive.  If the file starts with #!, we must treat it
401    as an import file.  This is for AIX compatibility.  */
402
403 static boolean
404 gldppcmacos_unrecognized_file (entry)
405      lang_input_statement_type *entry;
406 {
407   FILE *e;
408   boolean ret;
409
410   e = fopen (entry->filename, FOPEN_RT);
411   if (e == NULL)
412     return false;
413
414   ret = false;
415
416   if (getc (e) == '#' && getc (e) == '!')
417     {
418       struct filelist *n;
419       struct filelist **flpp;
420
421       n = (struct filelist *) xmalloc (sizeof (struct filelist));
422       n->next = NULL;
423       n->name = entry->filename;
424       flpp = &import_files;
425       while (*flpp != NULL)
426         flpp = &(*flpp)->next;
427       *flpp = n;
428
429       ret = true;
430       entry->loaded = true;
431     }
432
433   fclose (e);
434
435   return ret;
436 }
437
438 /* This is called after the input files have been opened.  */
439
440 static void
441 gldppcmacos_after_open ()
442 {
443   boolean r;
444   struct set_info *p;
445
446   /* Call ldctor_build_sets, after pretending that this is a
447      relocateable link.  We do this because AIX requires relocation
448      entries for all references to symbols, even in a final
449      executable.  Of course, we only want to do this if we are
450      producing an XCOFF output file.  */
451   r = link_info.relocateable;
452   if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL)
453     link_info.relocateable = true;
454   ldctor_build_sets ();
455   link_info.relocateable = r;
456
457   /* For each set, record the size, so that the XCOFF backend can
458      output the correct csect length.  */
459   for (p = sets; p != (struct set_info *) NULL; p = p->next)
460     {
461       bfd_size_type size;
462
463       /* If the symbol is defined, we may have been invoked from
464          collect, and the sets may already have been built, so we do
465          not do anything.  */
466       if (p->h->type == bfd_link_hash_defined
467           || p->h->type == bfd_link_hash_defweak)
468         continue;
469
470       if (p->reloc != BFD_RELOC_CTOR)
471         {
472           /* Handle this if we need to.  */
473           abort ();
474         }
475
476       size = (p->count + 2) * 4;
477       if (! bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size))
478         einfo (_("%F%P: bfd_xcoff_link_record_set failed: %E\n"));
479     }
480 }
481
482 /* This is called after the sections have been attached to output
483    sections, but before any sizes or addresses have been set.  */
484
485 static void
486 gldppcmacos_before_allocation ()
487 {
488   struct filelist *fl;
489   struct export_symbol_list *el;
490   char *libpath;
491   asection *special_sections[6];
492   int i;
493
494   /* Handle the import and export files, if any.  */
495   for (fl = import_files; fl != NULL; fl = fl->next)
496     gldppcmacos_read_file (fl->name, true);
497   for (el = export_symbols; el != NULL; el = el->next)
498     {
499       struct bfd_link_hash_entry *h;
500
501       h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false);
502       if (h == NULL)
503         einfo (_("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n"));
504       if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall))
505         einfo (_("%P%F: bfd_xcoff_export_symbol failed: %E\n"));
506     }
507
508   /* Track down all relocations called for by the linker script (these
509      are typically constructor/destructor entries created by
510      CONSTRUCTORS) and let the backend know it will need to create
511      .loader relocs for them.  */
512   lang_for_each_statement (gldppcmacos_find_relocs);
513
514   /* We need to build LIBPATH from the -L arguments.  If any -rpath
515      arguments were used, though, we use -rpath instead, as a GNU
516      extension.  */
517   if (command_line.rpath != NULL)
518     libpath = command_line.rpath;
519   else if (search_head == NULL)
520     libpath = (char *) "";
521   else
522     {
523       size_t len;
524       search_dirs_type *search;
525
526       len = strlen (search_head->name);
527       libpath = xmalloc (len + 1);
528       strcpy (libpath, search_head->name);
529       for (search = search_head->next; search != NULL; search = search->next)
530         {
531           size_t nlen;
532
533           nlen = strlen (search->name);
534           libpath = xrealloc (libpath, len + nlen + 2);
535           libpath[len] = ':';
536           strcpy (libpath + len + 1, search->name);
537           len += nlen + 1;
538         }
539     }
540
541   /* Let the XCOFF backend set up the .loader section.  */
542   if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath,
543                                          entry_symbol, file_align,
544                                          maxstack, maxdata,
545                                          gc && ! unix_ld ? true : false,
546                                          modtype,
547                                          textro ? true : false,
548                                          unix_ld,
549                                          special_sections))
550     einfo (_("%P%F: failed to set dynamic section sizes: %E\n"));
551
552   /* Look through the special sections, and put them in the right
553      place in the link ordering.  This is especially magic.  */
554   for (i = 0; i < 6; i++)
555     {
556       asection *sec;
557       lang_output_section_statement_type *os;
558       lang_statement_union_type **pls;
559       lang_input_section_type *is;
560       const char *oname;
561       boolean start;
562
563       sec = special_sections[i];
564       if (sec == NULL)
565         continue;
566
567       /* Remove this section from the list of the output section.
568          This assumes we know what the script looks like.  */
569       is = NULL;
570       os = lang_output_section_find (sec->output_section->name);
571       if (os == NULL)
572         einfo (_("%P%F: can't find output section %s\n"),
573                sec->output_section->name);
574       for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next)
575         {
576           if ((*pls)->header.type == lang_input_section_enum
577               && (*pls)->input_section.section == sec)
578             {
579               is = (lang_input_section_type *) *pls;
580               *pls = (*pls)->header.next;
581               break;
582             }
583           if ((*pls)->header.type == lang_wild_statement_enum)
584             {
585               lang_statement_union_type **pwls;
586
587               for (pwls = &(*pls)->wild_statement.children.head;
588                    *pwls != NULL;
589                    pwls = &(*pwls)->header.next)
590                 {
591                   if ((*pwls)->header.type == lang_input_section_enum
592                       && (*pwls)->input_section.section == sec)
593                     {
594                       is = (lang_input_section_type *) *pwls;
595                       *pwls = (*pwls)->header.next;
596                       break;
597                     }
598                 }
599               if (is != NULL)
600                 break;
601             }
602         }       
603
604       if (is == NULL)
605         einfo (_("%P%F: can't find %s in output section\n"),
606                bfd_get_section_name (sec->owner, sec));
607
608       /* Now figure out where the section should go.  */
609       switch (i)
610         {
611         default: /* to avoid warnings */
612         case 0:
613           /* _text */
614           oname = ".text";
615           start = true;
616           break;
617         case 1:
618           /* _etext */
619           oname = ".text";
620           start = false;
621           break;
622         case 2:
623           /* _data */
624           oname = ".data";
625           start = true;
626           break;
627         case 3:
628           /* _edata */
629           oname = ".data";
630           start = false;
631           break;
632         case 4:
633         case 5:
634           /* _end and end */
635           oname = ".bss";
636           start = false;
637           break;
638         }
639
640       os = lang_output_section_find (oname);
641
642       if (start)
643         {
644           is->header.next = os->children.head;
645           os->children.head = (lang_statement_union_type *) is;
646         }
647       else
648         {
649           is->header.next = NULL;
650           lang_statement_append (&os->children,
651                                  (lang_statement_union_type *) is,
652                                  &is->header.next);
653         }
654     }
655 }
656
657 /* Read an import or export file.  For an import file, this is called
658    by the before_allocation emulation routine.  For an export file,
659    this is called by the parse_args emulation routine.  */
660
661 static void
662 gldppcmacos_read_file (filename, import)
663      const char *filename;
664      boolean import;
665 {
666   struct obstack *o;
667   FILE *f;
668   int lineno;
669   int c;
670   boolean keep;
671   const char *imppath;
672   const char *impfile;
673   const char *impmember;
674
675   o = (struct obstack *) xmalloc (sizeof (struct obstack));
676   obstack_specify_allocation (o, 0, 0, xmalloc, gldppcmacos_free);
677
678   f = fopen (filename, FOPEN_RT);
679   if (f == NULL)
680     {
681       bfd_set_error (bfd_error_system_call);
682       einfo ("%F%s: %E\n", filename);
683     }
684
685   keep = false;
686
687   imppath = NULL;
688   impfile = NULL;
689   impmember = NULL;
690
691   lineno = 0;
692   while ((c = getc (f)) != EOF)
693     {
694       char *s;
695       char *symname;
696       boolean syscall;
697       bfd_vma address;
698       struct bfd_link_hash_entry *h;
699
700       if (c != '\n')
701         {
702           obstack_1grow (o, c);
703           continue;
704         }
705
706       obstack_1grow (o, '\0');
707       ++lineno;
708
709       s = (char *) obstack_base (o);
710       while (ISSPACE (*s))
711         ++s;
712       if (*s == '\0'
713           || *s == '*'
714           || (*s == '#' && s[1] == ' ')
715           || (! import && *s == '#' && s[1] == '!'))
716         {
717           obstack_free (o, obstack_base (o));
718           continue;
719         }
720
721       if (*s == '#' && s[1] == '!')
722         {
723           s += 2;
724           while (ISSPACE (*s))
725             ++s;
726           if (*s == '\0')
727             {
728               imppath = NULL;
729               impfile = NULL;
730               impmember = NULL;
731               obstack_free (o, obstack_base (o));
732             }
733           else if (*s == '(')
734             einfo (_("%F%s%d: #! ([member]) is not supported in import files\n"),
735                    filename, lineno);
736           else
737             {
738               char cs;
739               char *file;
740
741               (void) obstack_finish (o);
742               keep = true;
743               imppath = s;
744               file = NULL;
745               while (! ISSPACE (*s) && *s != '(' && *s != '\0')
746                 {
747                   if (*s == '/')
748                     file = s + 1;
749                   ++s;
750                 }
751               if (file != NULL)
752                 {
753                   file[-1] = '\0';
754                   impfile = file;
755                   if (imppath == file - 1)
756                     imppath = "/";
757                 }
758               else
759                 {
760                   impfile = imppath;
761                   imppath = "";
762                 }
763               cs = *s;
764               *s = '\0';
765               while (ISSPACE (cs))
766                 {
767                   ++s;
768                   cs = *s;
769                 }
770               if (cs != '(')
771                 {
772                   impmember = "";
773                   if (cs != '\0')
774                     einfo (_("%s:%d: warning: syntax error in import file\n"),
775                            filename, lineno);
776                 }
777               else
778                 {
779                   ++s;
780                   impmember = s;
781                   while (*s != ')' && *s != '\0')
782                     ++s;
783                   if (*s == ')')
784                     *s = '\0';
785                   else
786                     einfo (_("%s:%d: warning: syntax error in import file\n"),
787                            filename, lineno);
788                 }
789             }
790
791           continue;
792         }
793
794       /* This is a symbol to be imported or exported.  */
795       symname = s;
796       syscall = false;
797       address = (bfd_vma) -1;
798
799       while (! ISSPACE (*s) && *s != '\0')
800         ++s;
801       if (*s != '\0')
802         {
803           char *se;
804
805           *s++ = '\0';
806
807           while (ISSPACE (*s))
808             ++s;
809
810           se = s;
811           while (! ISSPACE (*se) && *se != '\0')
812             ++se;
813           if (*se != '\0')
814             {
815               *se++ = '\0';
816               while (ISSPACE (*se))
817                 ++se;
818               if (*se != '\0')
819                 einfo (_("%s%d: warning: syntax error in import/export file\n"),
820                        filename, lineno);
821             }
822
823           if (strcasecmp (s, "svc") == 0
824               || strcasecmp (s, "syscall") == 0)
825             syscall = true;
826           else
827             {
828               char *end;
829
830               address = strtoul (s, &end, 0);
831               if (*end != '\0')
832                 einfo (_("%s:%d: warning: syntax error in import/export file\n"),
833                        filename, lineno);
834             }
835         }
836
837       if (! import)
838         {
839           struct export_symbol_list *n;
840
841           ldlang_add_undef (symname);
842           n = ((struct export_symbol_list *)
843                xmalloc (sizeof (struct export_symbol_list)));
844           n->next = export_symbols;
845           n->name = xstrdup (symname);
846           n->syscall = syscall;
847           export_symbols = n;
848         }
849       else
850         {
851           h = bfd_link_hash_lookup (link_info.hash, symname, false, false,
852                                     true);
853           if (h == NULL || h->type == bfd_link_hash_new)
854             {
855               /* We can just ignore attempts to import an unreferenced
856                  symbol.  */
857             }
858           else
859             {
860               if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h,
861                                              address, imppath, impfile,
862                                              impmember))
863                 einfo (_("%X%s:%d: failed to import symbol %s: %E\n"),
864                        filename, lineno, symname);
865             }
866         }
867
868       obstack_free (o, obstack_base (o));
869     }
870
871   if (obstack_object_size (o) > 0)
872     {
873       einfo (_("%s:%d: warning: ignoring unterminated last line\n"),
874              filename, lineno);
875       obstack_free (o, obstack_base (o));
876     }
877
878   if (! keep)
879     {
880       obstack_free (o, NULL);
881       free (o);
882     }
883 }
884
885 /* This routine saves us from worrying about declaring free.  */
886
887 static void
888 gldppcmacos_free (p)
889      PTR p;
890 {
891   free (p);
892 }
893
894 /* This is called by the before_allocation routine via
895    lang_for_each_statement.  It looks for relocations and assignments
896    to symbols.  */
897
898 static void
899 gldppcmacos_find_relocs (s)
900      lang_statement_union_type *s;
901 {
902   if (s->header.type == lang_reloc_statement_enum)
903     {
904       lang_reloc_statement_type *rs;
905
906       rs = &s->reloc_statement;
907       if (rs->name == NULL)
908         einfo (_("%F%P: only relocations against symbols are permitted\n"));
909       if (! bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name))
910         einfo (_("%F%P: bfd_xcoff_link_count_reloc failed: %E\n"));
911     }
912
913   if (s->header.type == lang_assignment_statement_enum)
914     gldppcmacos_find_exp_assignment (s->assignment_statement.exp);
915 }
916
917 /* Look through an expression for an assignment statement.  */
918
919 static void
920 gldppcmacos_find_exp_assignment (exp)
921      etree_type *exp;
922 {
923   struct bfd_link_hash_entry *h;
924
925   switch (exp->type.node_class)
926     {
927     case etree_provide:
928       h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
929                                 false, false, false);
930       if (h == NULL)
931         break;
932       /* Fall through.  */
933     case etree_assign:
934       if (strcmp (exp->assign.dst, ".") != 0)
935         {
936           if (! bfd_xcoff_record_link_assignment (output_bfd, &link_info,
937                                                   exp->assign.dst))
938             einfo (_("%P%F: failed to record assignment to %s: %E\n"),
939                    exp->assign.dst);
940         }
941       gldppcmacos_find_exp_assignment (exp->assign.src);
942       break;
943
944     case etree_binary:
945       gldppcmacos_find_exp_assignment (exp->binary.lhs);
946       gldppcmacos_find_exp_assignment (exp->binary.rhs);
947       break;
948
949     case etree_trinary:
950       gldppcmacos_find_exp_assignment (exp->trinary.cond);
951       gldppcmacos_find_exp_assignment (exp->trinary.lhs);
952       gldppcmacos_find_exp_assignment (exp->trinary.rhs);
953       break;
954
955     case etree_unary:
956       gldppcmacos_find_exp_assignment (exp->unary.child);
957       break;
958
959     default:
960       break;
961     }
962 }
963
964 static char *
965 gldppcmacos_get_script(isfile)
966      int *isfile;
967 {                            
968   *isfile = 0;
969
970   if (link_info.relocateable == true && config.build_constructors == true)
971     return
972 "OUTPUT_FORMAT(\"xcoff-powermac\")\n\
973 OUTPUT_ARCH(powerpc)\n\
974 ENTRY(__start)\n\
975 SECTIONS\n\
976 {\n\
977   .pad 0 : { *(.pad) }\n\
978   .text 0 : {\n\
979     *(.text)\n\
980     *(.pr)\n\
981     *(.ro)\n\
982     *(.db)\n\
983     *(.gl)\n\
984     *(.xo)\n\
985     *(.ti)\n\
986     *(.tb)\n\
987   }\n\
988   .data 0 : {\n\
989     *(.data)\n\
990     *(.rw)\n\
991     *(.sv)\n\
992     *(.ua)\n\
993     . = ALIGN(4);\n\
994     CONSTRUCTORS\n\
995     *(.ds)\n\
996     *(.tc0)\n\
997     *(.tc)\n\
998     *(.td)\n\
999   }\n\
1000   .bss : {\n\
1001     *(.bss)\n\
1002     *(.bs)\n\
1003     *(.uc)\n\
1004     *(COMMON)\n\
1005   }\n\
1006   .loader 0 : {\n\
1007     *(.loader)\n\
1008   }\n\
1009   .debug 0 : {\n\
1010     *(.debug)\n\
1011   }\n\
1012 }\n\n"
1013   ; else if (link_info.relocateable == true) return
1014 "OUTPUT_FORMAT(\"xcoff-powermac\")\n\
1015 OUTPUT_ARCH(powerpc)\n\
1016 ENTRY(__start)\n\
1017 SECTIONS\n\
1018 {\n\
1019   .pad 0 : { *(.pad) }\n\
1020   .text 0 : {\n\
1021     *(.text)\n\
1022     *(.pr)\n\
1023     *(.ro)\n\
1024     *(.db)\n\
1025     *(.gl)\n\
1026     *(.xo)\n\
1027     *(.ti)\n\
1028     *(.tb)\n\
1029   }\n\
1030   .data 0 : {\n\
1031     *(.data)\n\
1032     *(.rw)\n\
1033     *(.sv)\n\
1034     *(.ua)\n\
1035     . = ALIGN(4);\n\
1036     *(.ds)\n\
1037     *(.tc0)\n\
1038     *(.tc)\n\
1039     *(.td)\n\
1040   }\n\
1041   .bss : {\n\
1042     *(.bss)\n\
1043     *(.bs)\n\
1044     *(.uc)\n\
1045     *(COMMON)\n\
1046   }\n\
1047   .loader 0 : {\n\
1048     *(.loader)\n\
1049   }\n\
1050   .debug 0 : {\n\
1051     *(.debug)\n\
1052   }\n\
1053 }\n\n"
1054   ; else if (!config.text_read_only) return
1055 "OUTPUT_FORMAT(\"xcoff-powermac\")\n\
1056 OUTPUT_ARCH(powerpc)\n\
1057  SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\
1058 ENTRY(__start)\n\
1059 SECTIONS\n\
1060 {\n\
1061   .pad 0 : { *(.pad) }\n\
1062   .text   : {\n\
1063     PROVIDE (_text = .);\n\
1064     *(.text)\n\
1065     *(.pr)\n\
1066     *(.ro)\n\
1067     *(.db)\n\
1068     *(.gl)\n\
1069     *(.xo)\n\
1070     *(.ti)\n\
1071     *(.tb)\n\
1072     PROVIDE (_etext = .);\n\
1073   }\n\
1074   .data 0 : {\n\
1075     PROVIDE (_data = .);\n\
1076     *(.data)\n\
1077     *(.rw)\n\
1078     *(.sv)\n\
1079     *(.ua)\n\
1080     . = ALIGN(4);\n\
1081     CONSTRUCTORS\n\
1082     *(.ds)\n\
1083     *(.tc0)\n\
1084     *(.tc)\n\
1085     *(.td)\n\
1086     PROVIDE (_edata = .);\n\
1087   }\n\
1088   .bss : {\n\
1089     *(.bss)\n\
1090     *(.bs)\n\
1091     *(.uc)\n\
1092     *(COMMON)\n\
1093     PROVIDE (_end = .);\n\
1094     PROVIDE (end = .);\n\
1095   }\n\
1096   .loader 0 : {\n\
1097     *(.loader)\n\
1098   }\n\
1099   .debug 0 : {\n\
1100     *(.debug)\n\
1101   }\n\
1102 }\n\n"
1103   ; else if (!config.magic_demand_paged) return
1104 "OUTPUT_FORMAT(\"xcoff-powermac\")\n\
1105 OUTPUT_ARCH(powerpc)\n\
1106  SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\
1107 ENTRY(__start)\n\
1108 SECTIONS\n\
1109 {\n\
1110   .pad 0 : { *(.pad) }\n\
1111   .text   : {\n\
1112     PROVIDE (_text = .);\n\
1113     *(.text)\n\
1114     *(.pr)\n\
1115     *(.ro)\n\
1116     *(.db)\n\
1117     *(.gl)\n\
1118     *(.xo)\n\
1119     *(.ti)\n\
1120     *(.tb)\n\
1121     PROVIDE (_etext = .);\n\
1122   }\n\
1123   .data 0 : {\n\
1124     PROVIDE (_data = .);\n\
1125     *(.data)\n\
1126     *(.rw)\n\
1127     *(.sv)\n\
1128     *(.ua)\n\
1129     . = ALIGN(4);\n\
1130     CONSTRUCTORS\n\
1131     *(.ds)\n\
1132     *(.tc0)\n\
1133     *(.tc)\n\
1134     *(.td)\n\
1135     PROVIDE (_edata = .);\n\
1136   }\n\
1137   .bss : {\n\
1138     *(.bss)\n\
1139     *(.bs)\n\
1140     *(.uc)\n\
1141     *(COMMON)\n\
1142     PROVIDE (_end = .);\n\
1143     PROVIDE (end = .);\n\
1144   }\n\
1145   .loader 0 : {\n\
1146     *(.loader)\n\
1147   }\n\
1148   .debug 0 : {\n\
1149     *(.debug)\n\
1150   }\n\
1151 }\n\n"
1152   ; else return
1153 "OUTPUT_FORMAT(\"xcoff-powermac\")\n\
1154 OUTPUT_ARCH(powerpc)\n\
1155  SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\
1156 ENTRY(__start)\n\
1157 SECTIONS\n\
1158 {\n\
1159   .pad 0 : { *(.pad) }\n\
1160   .text   : {\n\
1161     PROVIDE (_text = .);\n\
1162     *(.text)\n\
1163     *(.pr)\n\
1164     *(.ro)\n\
1165     *(.db)\n\
1166     *(.gl)\n\
1167     *(.xo)\n\
1168     *(.ti)\n\
1169     *(.tb)\n\
1170     PROVIDE (_etext = .);\n\
1171   }\n\
1172   .data 0 : {\n\
1173     PROVIDE (_data = .);\n\
1174     *(.data)\n\
1175     *(.rw)\n\
1176     *(.sv)\n\
1177     *(.ua)\n\
1178     . = ALIGN(4);\n\
1179     CONSTRUCTORS\n\
1180     *(.ds)\n\
1181     *(.tc0)\n\
1182     *(.tc)\n\
1183     *(.td)\n\
1184     PROVIDE (_edata = .);\n\
1185   }\n\
1186   .bss : {\n\
1187     *(.bss)\n\
1188     *(.bs)\n\
1189     *(.uc)\n\
1190     *(COMMON)\n\
1191     PROVIDE (_end = .);\n\
1192     PROVIDE (end = .);\n\
1193   }\n\
1194   .loader 0 : {\n\
1195     *(.loader)\n\
1196   }\n\
1197   .debug 0 : {\n\
1198     *(.debug)\n\
1199   }\n\
1200 }\n\n"
1201 ; }
1202
1203 struct ld_emulation_xfer_struct ld_ppcmacos_emulation = 
1204 {
1205   gldppcmacos_before_parse,
1206   syslib_default,
1207   hll_default,
1208   after_parse_default,
1209   gldppcmacos_after_open,
1210   after_allocation_default,
1211   set_output_arch_default,
1212   ldemul_default_target,
1213   gldppcmacos_before_allocation,
1214   gldppcmacos_get_script,
1215   "ppcmacos",
1216   "xcoff-powermac",
1217   0,    /* finish */
1218   0,    /* create_output_section_statements */
1219   0,    /* open_dynamic_archive */
1220   0,    /* place_orphan */
1221   0,    /* set_symbols */
1222   gldppcmacos_parse_args,
1223   gldppcmacos_unrecognized_file
1224 };