* nlmconv.c (main): For PowerPC, call powerpc_build_stubs and
[external/binutils.git] / binutils / nlmconv.c
1 /* nlmconv.c -- NLM conversion program
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /* Written by Ian Lance Taylor <ian@cygnus.com>.
21
22    This program can be used to convert any appropriate object file
23    into a NetWare Loadable Module (an NLM).  It will accept a linker
24    specification file which is identical to that accepted by the
25    NetWare linker, NLMLINK, except that the INPUT command, normally
26    used to give a list of object files to link together, is not used.
27    This program will convert only a single object file.  */
28
29 #include <ansidecl.h>
30 #include <stdio.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/file.h>
36 #include <assert.h>
37 #include <getopt.h>
38 #include <bfd.h>
39 #include <libiberty.h>
40 #include "sysdep.h"
41 #include "bucomm.h"
42 /* Internal BFD NLM header.  */
43 #include "libnlm.h"
44 #include "nlmconv.h"
45
46 /* Needed for Alpha support.  */
47 #include "coff/sym.h"
48 #include "coff/ecoff.h"
49
50 /* If strerror is just a macro, we want to use the one from libiberty
51    since it will handle undefined values.  */
52 #undef strerror
53 extern char *strerror ();
54
55 #ifndef localtime
56 extern struct tm *localtime ();
57 #endif
58
59 #ifndef getenv
60 extern char *getenv ();
61 #endif
62
63 #ifndef SEEK_SET
64 #define SEEK_SET 0
65 #endif
66
67 #ifndef R_OK
68 #define R_OK 4
69 #define W_OK 2
70 #define X_OK 1
71 #endif
72 \f
73 /* Global variables.  */
74
75 /* The name used to invoke the program.  */
76 char *program_name;
77
78 /* The version number.  */
79 extern char *program_version;
80
81 /* Local variables.  */
82
83 /* Whether to print out debugging information (currently just controls
84    whether it prints the linker command if there is one).  */
85 static int debug;
86
87 /* The symbol table.  */
88 static asymbol **symbols;
89
90 /* A temporary file name to be unlinked on exit.  Actually, for most
91    errors, we leave it around.  It's not clear whether that is helpful
92    or not.  */
93 static char *unlink_on_exit;
94
95 /* The list of long options.  */
96 static struct option long_options[] =
97 {
98   { "debug", no_argument, 0, 'd' },
99   { "header-file", required_argument, 0, 'T' },
100   { "help", no_argument, 0, 'h' },
101   { "input-target", required_argument, 0, 'I' },
102   { "input-format", required_argument, 0, 'I' }, /* Obsolete */
103   { "linker", required_argument, 0, 'l' },
104   { "output-target", required_argument, 0, 'O' },
105   { "output-format", required_argument, 0, 'O' }, /* Obsolete */
106   { "version", no_argument, 0, 'V' },
107   { NULL, no_argument, 0, 0 }
108 };
109
110 /* Local routines.  */
111
112 static void show_help PARAMS ((void));
113 static void show_usage PARAMS ((FILE *, int));
114 static const char *select_output_format PARAMS ((enum bfd_architecture,
115                                                  unsigned long, boolean));
116 static void setup_sections PARAMS ((bfd *, asection *, PTR));
117 static void copy_sections PARAMS ((bfd *, asection *, PTR));
118 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
119                                    bfd_size_type *, char *,
120                                    bfd_size_type));
121 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
122                                         bfd_size_type *, char *,
123                                         bfd_size_type));
124 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
125                                          bfd_size_type *, char *,
126                                          bfd_size_type));
127 /* start-sanitize-powerpc-netware */
128 static void powerpc_build_stubs PARAMS ((bfd *, asymbol ***, unsigned int *));
129 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
130 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
131                                            bfd_size_type *, char *,
132                                            bfd_size_type));
133 /* end-sanitize-powerpc-netware */
134 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
135                                            bfd_size_type *, char *,
136                                            bfd_size_type));
137 static char *link_inputs PARAMS ((struct string_list *, char *));
138 static const char *choose_temp_base_try PARAMS ((const char *,
139                                                  const char *));
140 static void choose_temp_base PARAMS ((void));
141 static int pexecute PARAMS ((char *, char *[]));
142 \f
143 /* The main routine.  */
144
145 int
146 main (argc, argv)
147      int argc;
148      char **argv;
149 {
150   int opt;
151   char *input_file = NULL;
152   const char *input_format = NULL;
153   const char *output_format = NULL;
154   const char *header_file = NULL;
155   char *ld_arg = NULL;
156   Nlm_Internal_Fixed_Header fixed_hdr_struct;
157   Nlm_Internal_Variable_Header var_hdr_struct;
158   Nlm_Internal_Version_Header version_hdr_struct;
159   Nlm_Internal_Copyright_Header copyright_hdr_struct;
160   Nlm_Internal_Extended_Header extended_hdr_struct;
161   bfd *inbfd;
162   bfd *outbfd;
163   asymbol **newsyms, **outsyms;
164   unsigned int symcount, newsymalloc, newsymcount;
165   asection *text_sec, *bss_sec, *data_sec;
166   bfd_vma vma;
167   bfd_size_type align;
168   asymbol *endsym;
169   unsigned int i;
170   char inlead, outlead;
171   boolean gotstart, gotexit, gotcheck;
172   struct stat st;
173   FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
174   size_t custom_size, help_size, message_size, module_size, rpc_size;
175   asection *custom_section, *help_section, *message_section, *module_section;
176   asection *rpc_section, *shared_section;
177   bfd *sharedbfd;
178   size_t shared_offset, shared_size;
179   Nlm_Internal_Fixed_Header sharedhdr;
180   int len;
181   char *modname;
182   char **matching;
183
184   program_name = argv[0];
185   xmalloc_set_program_name (program_name);
186
187   bfd_init ();
188
189   while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
190                              (int *) NULL))
191          != EOF)
192     {
193       switch (opt)
194         {
195         case 'd':
196           debug = 1;
197           break;
198         case 'h':
199           show_help ();
200           /*NOTREACHED*/
201         case 'I':
202           input_format = optarg;
203           break;
204         case 'l':
205           ld_arg = optarg;
206           break;
207         case 'O':
208           output_format = optarg;
209           break;
210         case 'T':
211           header_file = optarg;
212           break;
213         case 'V':
214           printf ("GNU %s version %s\n", program_name, program_version);
215           exit (0);
216           /*NOTREACHED*/
217         case 0:
218           break;
219         default:
220           show_usage (stderr, 1);
221           /*NOTREACHED*/
222         }
223     }
224
225   /* The input and output files may be named on the command line.  */
226   output_file = NULL;
227   if (optind < argc)
228     {
229       input_file = argv[optind];
230       ++optind;
231       if (optind < argc)
232         {
233           output_file = argv[optind];
234           ++optind;
235           if (optind < argc)
236             show_usage (stderr, 1);
237           if (strcmp (input_file, output_file) == 0)
238             {
239               fprintf (stderr,
240                        "%s: input and output files must be different\n",
241                        program_name);
242               exit (1);
243             }
244         }
245     }
246
247   /* Initialize the header information to default values.  */
248   fixed_hdr = &fixed_hdr_struct;
249   memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
250   var_hdr = &var_hdr_struct;
251   memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
252   version_hdr = &version_hdr_struct;
253   memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
254   copyright_hdr = &copyright_hdr_struct;
255   memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
256   extended_hdr = &extended_hdr_struct;
257   memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
258   check_procedure = NULL;
259   custom_file = NULL;
260   debug_info = false;
261   exit_procedure = "_Stop";
262   export_symbols = NULL;
263   map_file = NULL;
264   full_map = false;
265   help_file = NULL;
266   import_symbols = NULL;
267   message_file = NULL;
268   modules = NULL;
269   sharelib_file = NULL;
270   start_procedure = "_Prelude";
271   verbose = false;
272   rpc_file = NULL;
273
274   parse_errors = 0;
275
276   /* Parse the header file (if there is one).  */
277   if (header_file != NULL)
278     {
279       if (! nlmlex_file (header_file)
280           || yyparse () != 0
281           || parse_errors != 0)
282         exit (1);
283     }
284
285   if (input_files != NULL)
286     {
287       if (input_file != NULL)
288         {
289           fprintf (stderr,
290                    "%s: input file named both on command line and with INPUT\n",
291                    program_name);
292           exit (1);
293         }
294       if (input_files->next == NULL)
295         input_file = input_files->string;
296       else
297         input_file = link_inputs (input_files, ld_arg);
298     }
299   else if (input_file == NULL)
300     {
301       fprintf (stderr, "%s: no input file\n", program_name);
302       show_usage (stderr, 1);
303     }
304
305   inbfd = bfd_openr (input_file, input_format);
306   if (inbfd == NULL)
307     bfd_fatal (input_file);
308
309   if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
310     {
311       bfd_nonfatal (input_file);
312       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
313         {
314           list_matching_formats (matching);
315           free (matching);
316         }
317       exit (1);
318     }
319
320   if (output_format == NULL)
321     output_format = select_output_format (bfd_get_arch (inbfd),
322                                           bfd_get_mach (inbfd),
323                                           inbfd->xvec->byteorder_big_p);
324
325   assert (output_format != NULL);
326
327   /* Use the output file named on the command line if it exists.
328      Otherwise use the file named in the OUTPUT statement.  */
329   if (output_file == NULL)
330     {
331       fprintf (stderr, "%s: no name for output file\n",
332                program_name);
333       show_usage (stderr, 1);
334     }
335
336   outbfd = bfd_openw (output_file, output_format);
337   if (outbfd == NULL)
338     bfd_fatal (output_file);
339   if (! bfd_set_format (outbfd, bfd_object))
340     bfd_fatal (output_file);
341
342   assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
343
344   if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
345     fprintf (stderr,
346              "%s: warning:input and output formats are not compatible\n",
347              program_name);
348
349   /* Move the values read from the command file into outbfd.  */
350   *nlm_fixed_header (outbfd) = fixed_hdr_struct;
351   *nlm_variable_header (outbfd) = var_hdr_struct;
352   *nlm_version_header (outbfd) = version_hdr_struct;
353   *nlm_copyright_header (outbfd) = copyright_hdr_struct;
354   *nlm_extended_header (outbfd) = extended_hdr_struct;
355
356   /* Start copying the input BFD to the output BFD.  */
357   if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
358     bfd_fatal (bfd_get_filename (outbfd));
359
360   symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
361   symcount = bfd_canonicalize_symtab (inbfd, symbols);
362
363   /* Make sure we have a .bss section.  */
364   bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
365   if (bss_sec == NULL)
366     {
367       bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
368       if (bss_sec == NULL
369           || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
370           || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
371         bfd_fatal ("make .bss section");
372     }
373 /* start-sanitize-powerpc-netware */
374
375   /* For PowerPC NetWare we need to build stubs for calls to undefined
376      symbols.  Because each stub requires an entry in the TOC section
377      which must be at the same location as other entries in the TOC
378      section, we must do this before determining where the TOC section
379      goes in setup_sections.  */
380   powerpc_build_stubs (inbfd, &symbols, &symcount);
381 /* end-sanitize-powerpc-netware */
382
383   /* Set up the sections.  */
384   bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
385
386   text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
387
388   /* The .bss section immediately follows the .data section.  */
389   data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
390   if (data_sec != NULL)
391     {
392       bfd_size_type add;
393
394       vma = bfd_get_section_size_before_reloc (data_sec);
395       align = 1 << bss_sec->alignment_power;
396       add = ((vma + align - 1) &~ (align - 1)) - vma;
397       vma += add;
398       if (! bfd_set_section_vma (outbfd, bss_sec, vma))
399         bfd_fatal ("set .bss vma");
400       if (add != 0)
401         {
402           bfd_size_type data_size;
403
404           data_size = bfd_get_section_size_before_reloc (data_sec);
405           if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
406             bfd_fatal ("set .data size");
407         }
408     }
409
410   /* Adjust symbol information.  */
411   inlead = bfd_get_symbol_leading_char (inbfd);
412   outlead = bfd_get_symbol_leading_char (outbfd);
413   gotstart = false;
414   gotexit = false;
415   gotcheck = false;
416   newsymalloc = 10;
417   newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
418   newsymcount = 0;
419   endsym = NULL;
420   for (i = 0; i < symcount; i++)
421     {
422       register asymbol *sym;
423
424       sym = symbols[i];
425
426       /* Add or remove a leading underscore.  */
427       if (inlead != outlead)
428         {
429           if (inlead != '\0')
430             {
431               if (bfd_asymbol_name (sym)[0] == inlead)
432                 {
433                   if (outlead == '\0')
434                     ++sym->name;
435                   else
436                     {
437                       char *new;
438
439                       new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
440                       new[0] = outlead;
441                       strcpy (new + 1, bfd_asymbol_name (sym) + 1);
442                       sym->name = new;
443                     }
444                 }
445             }
446           else
447             {
448               char *new;
449
450               new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
451               new[0] = outlead;
452               strcpy (new + 1, bfd_asymbol_name (sym));
453               sym->name = new;
454             }
455         }
456
457       /* NLM's have an uninitialized data section, but they do not
458          have a common section in the Unix sense.  Move all common
459          symbols into the .bss section, and mark them as exported.  */
460       if (bfd_is_com_section (bfd_get_section (sym)))
461         {
462           bfd_vma size;
463
464           sym->section = bss_sec;
465           size = sym->value;
466           sym->value = bss_sec->_raw_size;
467           bss_sec->_raw_size += size;
468           align = 1 << bss_sec->alignment_power;
469           bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
470           sym->flags |= BSF_EXPORT | BSF_GLOBAL;
471         }
472       else if (bfd_get_section (sym)->output_section != NULL)
473         {
474           /* Move the symbol into the output section.  */
475           sym->value += bfd_get_section (sym)->output_offset;
476           sym->section = bfd_get_section (sym)->output_section;
477           /* This is no longer a section symbol.  */
478           sym->flags &=~ BSF_SECTION_SYM;
479         }
480
481       /* Force _edata and _end to be defined.  This would normally be
482          done by the linker, but the manipulation of the common
483          symbols will confuse it.  */
484       if ((sym->flags & BSF_DEBUGGING) == 0
485           && bfd_asymbol_name (sym)[0] == '_'
486           && bfd_get_section (sym) == &bfd_und_section)
487         {
488           if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
489             {
490               sym->section = bss_sec;
491               sym->value = 0;
492             }
493           if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
494             {
495               sym->section = bss_sec;
496               endsym = sym;
497             }
498 /* start-sanitize-powerpc-netware */
499           /* For PowerPC NetWare, we define __GOT0.  This is the start
500              of the .got section.  */
501           if (bfd_get_arch (inbfd) == bfd_arch_powerpc
502               && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
503             {
504               asection *got_sec;
505
506               got_sec = bfd_get_section_by_name (inbfd, ".got");
507               assert (got_sec != (asection *) NULL);
508               sym->value = got_sec->output_offset;
509               sym->section = got_sec->output_section;
510             }
511 /* end-sanitize-powerpc-netware */
512         }
513
514       /* If this is a global symbol, check the export list.  */
515       if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
516         {
517           register struct string_list *l;
518           int found_simple;
519
520           /* Unfortunately, a symbol can appear multiple times on the
521              export list, with and without prefixes.  */
522           found_simple = 0;
523           for (l = export_symbols; l != NULL; l = l->next)
524             {
525               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
526                 found_simple = 1;
527               else
528                 {
529                   char *zbase;
530
531                   zbase = strchr (l->string, '@');
532                   if (zbase != NULL
533                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
534                     {
535                       /* We must add a symbol with this prefix.  */
536                       if (newsymcount >= newsymalloc)
537                         {
538                           newsymalloc += 10;
539                           newsyms = ((asymbol **)
540                                      xrealloc ((PTR) newsyms,
541                                                (newsymalloc
542                                                 * sizeof (asymbol *))));
543                         }
544                       newsyms[newsymcount] =
545                         (asymbol *) xmalloc (sizeof (asymbol));
546                       *newsyms[newsymcount] = *sym;
547                       newsyms[newsymcount]->name = l->string;
548                       ++newsymcount;
549                     }
550                 }
551             }
552           if (! found_simple)
553             {
554               /* The unmodified symbol is actually not exported at
555                  all.  */
556               sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
557               sym->flags |= BSF_LOCAL;
558             }
559         }
560
561       /* If it's an undefined symbol, see if it's on the import list.
562          Change the prefix if necessary.  */
563       if (bfd_get_section (sym) == &bfd_und_section)
564         {
565           register struct string_list *l;
566
567           for (l = import_symbols; l != NULL; l = l->next)
568             {
569               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
570                 break;
571               else
572                 {
573                   char *zbase;
574
575                   zbase = strchr (l->string, '@');
576                   if (zbase != NULL
577                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
578                     {
579                       sym->name = l->string;
580                       break;
581                     }
582                 }
583             }
584           if (l == NULL)
585             fprintf (stderr,
586                      "%s: warning: symbol %s imported but not in import list\n",
587                      program_name, bfd_asymbol_name (sym));
588         }
589         
590       /* See if it's one of the special named symbols.  */
591       if ((sym->flags & BSF_DEBUGGING) == 0)
592         {
593           bfd_vma val;
594
595           /* FIXME: If these symbols are not in the .text section, we
596              add the .text section size to the value.  This may not be
597              correct for all targets.  I'm not sure how this should
598              really be handled.  */
599           if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
600             {
601               val = bfd_asymbol_value (sym);
602               if (bfd_get_section (sym) == data_sec
603                   && text_sec != (asection *) NULL)
604                 val += bfd_section_size (outbfd, text_sec);
605               if (! bfd_set_start_address (outbfd, val))
606                 bfd_fatal ("set start address");
607               gotstart = true;
608             }
609           if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
610             {
611               val = bfd_asymbol_value (sym);
612               if (bfd_get_section (sym) == data_sec
613                   && text_sec != (asection *) NULL)
614                 val += bfd_section_size (outbfd, text_sec);
615               nlm_fixed_header (outbfd)->exitProcedureOffset = val;
616               gotexit = true;
617             }
618           if (check_procedure != NULL
619               && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
620             {
621               val = bfd_asymbol_value (sym);
622               if (bfd_get_section (sym) == data_sec
623                   && text_sec != (asection *) NULL)
624                 val += bfd_section_size (outbfd, text_sec);
625               nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
626               gotcheck = true;
627             }
628         }
629     }
630
631   if (endsym != NULL)
632     {
633       endsym->value = bfd_get_section_size_before_reloc (bss_sec);
634
635       /* FIXME: If any relocs referring to _end use inplace addends,
636          then I think they need to be updated.  This is handled by
637          i386_mangle_relocs.  Is it needed for any other object
638          formats?  */
639     }
640
641   if (newsymcount == 0)
642     outsyms = symbols;
643   else
644     {
645       outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
646                                       * sizeof (asymbol *));
647       memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
648       memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
649       outsyms[symcount + newsymcount] = NULL;
650     }
651
652   bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
653     
654   if (! gotstart)
655     fprintf (stderr, "%s: warning: START procedure %s not defined\n",
656              program_name, start_procedure);
657   if (! gotexit)
658     fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
659              program_name, exit_procedure);
660   if (check_procedure != NULL
661       && ! gotcheck)
662     fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
663              program_name, check_procedure);
664
665   /* Add additional sections required for the header information.  */
666   if (custom_file != NULL)
667     {
668       custom_data = fopen (custom_file, "r");
669       if (custom_data == NULL
670           || fstat (fileno (custom_data), &st) < 0)
671         {
672           fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
673                    strerror (errno));
674           custom_file = NULL;
675         }
676       else
677         {
678           custom_size = st.st_size;
679           custom_section = bfd_make_section (outbfd, ".nlmcustom");
680           if (custom_section == NULL
681               || ! bfd_set_section_size (outbfd, custom_section, custom_size)
682               || ! bfd_set_section_flags (outbfd, custom_section,
683                                           SEC_HAS_CONTENTS))
684             bfd_fatal ("custom section");
685         }
686     }
687   if (help_file != NULL)
688     {
689       help_data = fopen (help_file, "r");
690       if (help_data == NULL
691           || fstat (fileno (help_data), &st) < 0)
692         {
693           fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
694                    strerror (errno));
695           help_file = NULL;
696         }
697       else
698         {
699           help_size = st.st_size;
700           help_section = bfd_make_section (outbfd, ".nlmhelp");
701           if (help_section == NULL
702               || ! bfd_set_section_size (outbfd, help_section, help_size)
703               || ! bfd_set_section_flags (outbfd, help_section,
704                                           SEC_HAS_CONTENTS))
705             bfd_fatal ("help section");
706           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
707         }
708     }
709   if (message_file != NULL)
710     {
711       message_data = fopen (message_file, "r");
712       if (message_data == NULL
713           || fstat (fileno (message_data), &st) < 0)
714         {
715           fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
716                    strerror (errno));
717           message_file = NULL;
718         }
719       else
720         {
721           message_size = st.st_size;
722           message_section = bfd_make_section (outbfd, ".nlmmessages");
723           if (message_section == NULL
724               || ! bfd_set_section_size (outbfd, message_section, message_size)
725               || ! bfd_set_section_flags (outbfd, message_section,
726                                           SEC_HAS_CONTENTS))
727             bfd_fatal ("message section");
728           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
729         }
730     }
731   if (modules != NULL)
732     {
733       struct string_list *l;
734
735       module_size = 0;
736       for (l = modules; l != NULL; l = l->next)
737         module_size += strlen (l->string) + 1;
738       module_section = bfd_make_section (outbfd, ".nlmmodules");
739       if (module_section == NULL
740           || ! bfd_set_section_size (outbfd, module_section, module_size)
741           || ! bfd_set_section_flags (outbfd, module_section,
742                                       SEC_HAS_CONTENTS))
743         bfd_fatal ("module section");
744     }
745   if (rpc_file != NULL)
746     {
747       rpc_data = fopen (rpc_file, "r");
748       if (rpc_data == NULL
749           || fstat (fileno (rpc_data), &st) < 0)
750         {
751           fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
752                    strerror (errno));
753           rpc_file = NULL;
754         }
755       else
756         {
757           rpc_size = st.st_size;
758           rpc_section = bfd_make_section (outbfd, ".nlmrpc");
759           if (rpc_section == NULL
760               || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
761               || ! bfd_set_section_flags (outbfd, rpc_section,
762                                           SEC_HAS_CONTENTS))
763             bfd_fatal ("rpc section");
764           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
765         }
766     }
767   if (sharelib_file != NULL)
768     {
769       sharedbfd = bfd_openr (sharelib_file, output_format);
770       if (sharedbfd == NULL
771           || ! bfd_check_format (sharedbfd, bfd_object))
772         {
773           fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
774                    bfd_errmsg (bfd_get_error ()));
775           sharelib_file = NULL;
776         }
777       else
778         {
779           sharedhdr = *nlm_fixed_header (sharedbfd);
780           bfd_close (sharedbfd);
781           shared_data = fopen (sharelib_file, "r");
782           if (shared_data == NULL
783               || (fstat (fileno (shared_data), &st) < 0))
784             {
785               fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
786                        strerror (errno));
787               sharelib_file = NULL;
788             }
789           else
790             {
791               /* If we were clever, we could just copy out the
792                  sections of the shared library which we actually
793                  need.  However, we would have to figure out the sizes
794                  of the external and public information, and that can
795                  not be done without reading through them.  */
796               if (sharedhdr.uninitializedDataSize > 0)
797                 {
798                   /* There is no place to record this information.  */
799                   fprintf (stderr,
800                            "%s:%s: warning: shared libraries can not have uninitialized data\n",
801                            program_name, sharelib_file);
802                 }
803               shared_offset = st.st_size;
804               if (shared_offset > sharedhdr.codeImageOffset)
805                 shared_offset = sharedhdr.codeImageOffset;
806               if (shared_offset > sharedhdr.dataImageOffset)
807                 shared_offset = sharedhdr.dataImageOffset;
808               if (shared_offset > sharedhdr.relocationFixupOffset)
809                 shared_offset = sharedhdr.relocationFixupOffset;
810               if (shared_offset > sharedhdr.externalReferencesOffset)
811                 shared_offset = sharedhdr.externalReferencesOffset;
812               if (shared_offset > sharedhdr.publicsOffset)
813                 shared_offset = sharedhdr.publicsOffset;
814               shared_size = st.st_size - shared_offset;
815               shared_section = bfd_make_section (outbfd, ".nlmshared");
816               if (shared_section == NULL
817                   || ! bfd_set_section_size (outbfd, shared_section,
818                                              shared_size)
819                   || ! bfd_set_section_flags (outbfd, shared_section,
820                                               SEC_HAS_CONTENTS))
821                 bfd_fatal ("shared section");
822               strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
823             }
824         }
825     }
826
827   /* Check whether a version was given.  */
828   if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
829     fprintf (stderr, "%s: warning: No version number given\n",
830              program_name);
831
832   /* At least for now, always create an extended header, because that
833      is what NLMLINK does.  */
834   strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
835
836   /* If the date was not given, force it in.  */
837   if (nlm_version_header (outbfd)->month == 0
838       && nlm_version_header (outbfd)->day == 0
839       && nlm_version_header (outbfd)->year == 0)
840     {
841       time_t now;
842       struct tm *ptm;
843
844       time (&now);
845       ptm = localtime (&now);
846       nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
847       nlm_version_header (outbfd)->day = ptm->tm_mday;
848       nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
849       strncpy (version_hdr->stamp, "VeRsIoN#", 8);
850     }
851 /* start-sanitize-powerpc-netware */
852
853   /* Resolve the stubs we build for PowerPC NetWare.  */
854   powerpc_resolve_stubs (inbfd, outbfd);
855 /* end-sanitize-powerpc-netware */
856
857   /* Copy over the sections.  */
858   bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
859
860   /* Finish up the header information.  */
861   if (custom_file != NULL)
862     {
863       PTR data;
864
865       data = xmalloc (custom_size);
866       if (fread (data, 1, custom_size, custom_data) != custom_size)
867         fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
868                  strerror (errno));
869       else
870         {
871           if (! bfd_set_section_contents (outbfd, custom_section, data,
872                                           (file_ptr) 0, custom_size))
873             bfd_fatal ("custom section");
874           nlm_fixed_header (outbfd)->customDataOffset =
875             custom_section->filepos;
876           nlm_fixed_header (outbfd)->customDataSize = custom_size;
877         }
878       free (data);
879     }
880   if (! debug_info)
881     {
882       /* As a special hack, the backend recognizes a debugInfoOffset
883          of -1 to mean that it should not output any debugging
884          information.  This can not be handling by fiddling with the
885          symbol table because exported symbols appear in both the
886          export information and the debugging information.  */
887       nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
888     }
889   if (map_file != NULL)
890     fprintf (stderr,
891              "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
892              program_name);
893   if (help_file != NULL)
894     {
895       PTR data;
896
897       data = xmalloc (help_size);
898       if (fread (data, 1, help_size, help_data) != help_size)
899         fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
900                  strerror (errno));
901       else
902         {
903           if (! bfd_set_section_contents (outbfd, help_section, data,
904                                           (file_ptr) 0, help_size))
905             bfd_fatal ("help section");
906           nlm_extended_header (outbfd)->helpFileOffset =
907             help_section->filepos;
908           nlm_extended_header (outbfd)->helpFileLength = help_size;
909         }
910       free (data);
911     }
912   if (message_file != NULL)
913     {
914       PTR data;
915
916       data = xmalloc (message_size);
917       if (fread (data, 1, message_size, message_data) != message_size)
918         fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
919                  strerror (errno));
920       else
921         {
922           if (! bfd_set_section_contents (outbfd, message_section, data,
923                                           (file_ptr) 0, message_size))
924             bfd_fatal ("message section");
925           nlm_extended_header (outbfd)->messageFileOffset =
926             message_section->filepos;
927           nlm_extended_header (outbfd)->messageFileLength = message_size;
928
929           /* FIXME: Are these offsets correct on all platforms?  Are
930              they 32 bits on all platforms?  What endianness?  */
931           nlm_extended_header (outbfd)->languageID =
932             bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
933           nlm_extended_header (outbfd)->messageCount =
934             bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
935         }
936       free (data);
937     }
938   if (modules != NULL)
939     {
940       PTR data;
941       unsigned char *set;
942       struct string_list *l;
943       bfd_size_type c;
944
945       data = xmalloc (module_size);
946       c = 0;
947       set = (unsigned char *) data;
948       for (l = modules; l != NULL; l = l->next)
949         {
950           *set = strlen (l->string);
951           strncpy (set + 1, l->string, *set);
952           set += *set + 1;
953           ++c;
954         }
955       if (! bfd_set_section_contents (outbfd, module_section, data,
956                                       (file_ptr) 0, module_size))
957         bfd_fatal ("module section");
958       nlm_fixed_header (outbfd)->moduleDependencyOffset =
959         module_section->filepos;
960       nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
961     }
962   if (rpc_file != NULL)
963     {
964       PTR data;
965
966       data = xmalloc (rpc_size);
967       if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
968         fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
969                  strerror (errno));
970       else
971         {
972           if (! bfd_set_section_contents (outbfd, rpc_section, data,
973                                           (file_ptr) 0, rpc_size))
974             bfd_fatal ("rpc section");
975           nlm_extended_header (outbfd)->RPCDataOffset =
976             rpc_section->filepos;
977           nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
978         }
979       free (data);
980     }
981   if (sharelib_file != NULL)
982     {
983       PTR data;
984
985       data = xmalloc (shared_size);
986       if (fseek (shared_data, shared_offset, SEEK_SET) != 0
987           || fread (data, 1, shared_size, shared_data) != shared_size)
988         fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
989                  strerror (errno));
990       else
991         {
992           if (! bfd_set_section_contents (outbfd, shared_section, data,
993                                           (file_ptr) 0, shared_size))
994             bfd_fatal ("shared section");
995         }
996       nlm_extended_header (outbfd)->sharedCodeOffset =
997         sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
998       nlm_extended_header (outbfd)->sharedCodeLength =
999         sharedhdr.codeImageSize;
1000       nlm_extended_header (outbfd)->sharedDataOffset =
1001         sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1002       nlm_extended_header (outbfd)->sharedDataLength =
1003         sharedhdr.dataImageSize;
1004       nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1005         (sharedhdr.relocationFixupOffset
1006          - shared_offset
1007          + shared_section->filepos);
1008       nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1009         sharedhdr.numberOfRelocationFixups;
1010       nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1011         (sharedhdr.externalReferencesOffset
1012          - shared_offset
1013          + shared_section->filepos);
1014       nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1015         sharedhdr.numberOfExternalReferences;
1016       nlm_extended_header (outbfd)->sharedPublicsOffset =
1017         sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1018       nlm_extended_header (outbfd)->sharedPublicsCount =
1019         sharedhdr.numberOfPublics;
1020       nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1021         sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1022       nlm_extended_header (outbfd)->sharedDebugRecordCount =
1023         sharedhdr.numberOfDebugRecords;
1024       nlm_extended_header (outbfd)->SharedInitializationOffset =
1025         sharedhdr.codeStartOffset;
1026       nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1027         sharedhdr.exitProcedureOffset;
1028       free (data);
1029     }
1030   len = strlen (output_file);
1031   if (len > NLM_MODULE_NAME_SIZE - 2)
1032     len = NLM_MODULE_NAME_SIZE - 2;
1033   nlm_fixed_header (outbfd)->moduleName[0] = len;
1034
1035   strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1036            NLM_MODULE_NAME_SIZE - 2);
1037   nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1038   for (modname = nlm_fixed_header (outbfd)->moduleName;
1039        *modname != '\0';
1040        modname++)
1041     if (islower (*modname))
1042       *modname = toupper (*modname);
1043
1044   strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1045            NLM_OLD_THREAD_NAME_LENGTH);
1046
1047   if (! bfd_close (outbfd))
1048     bfd_fatal (output_file);
1049   if (! bfd_close (inbfd))
1050     bfd_fatal (input_file);
1051
1052   if (unlink_on_exit != NULL)
1053     unlink (unlink_on_exit);
1054
1055   return 0;
1056 }
1057 \f
1058 /* Display a help message and exit.  */
1059
1060 static void
1061 show_help ()
1062 {
1063   printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1064           program_name);
1065   show_usage (stdout, 0);
1066 }
1067
1068 /* Show a usage message and exit.  */
1069
1070 static void
1071 show_usage (file, status)
1072      FILE *file;
1073      int status;
1074 {
1075   fprintf (file, "\
1076 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1077        [--input-target=bfdname] [--output-target=bfdname]\n\
1078        [--header-file=file] [--linker=linker] [--debug]\n\
1079        [--help] [--version]\n\
1080        [in-file [out-file]]\n",
1081            program_name);
1082   exit (status);
1083 }
1084 \f
1085 /* Select the output format based on the input architecture, machine,
1086    and endianness.  This chooses the appropriate NLM target.  */
1087
1088 static const char *
1089 select_output_format (arch, mach, bigendian)
1090      enum bfd_architecture arch;
1091      unsigned long mach;
1092      boolean bigendian;
1093 {
1094   switch (arch)
1095     {
1096     case bfd_arch_i386:
1097       return "nlm32-i386";
1098     case bfd_arch_sparc:
1099       return "nlm32-sparc";
1100     case bfd_arch_alpha:
1101       return "nlm32-alpha";
1102 /* start-sanitize-powerpc-netware */
1103     case bfd_arch_powerpc:
1104       return "nlm32-powerpc";
1105 /* end-sanitize-powerpc-netware */
1106     default:
1107       fprintf (stderr, "%s: no default NLM format for %s\n",
1108                program_name, bfd_printable_arch_mach (arch, mach));
1109       exit (1);
1110       /* Avoid warning.  */
1111       return NULL;
1112     }
1113   /*NOTREACHED*/
1114 }
1115 \f
1116 /* The BFD sections are copied in two passes.  This function selects
1117    the output section for each input section, and sets up the section
1118    name, size, etc.  */
1119
1120 static void
1121 setup_sections (inbfd, insec, data_ptr)
1122      bfd *inbfd;
1123      asection *insec;
1124      PTR data_ptr;
1125 {
1126   bfd *outbfd = (bfd *) data_ptr;
1127   flagword f;
1128   const char *outname;
1129   asection *outsec;
1130   bfd_vma offset;
1131   bfd_size_type align;
1132   bfd_size_type add;
1133
1134   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1135      file.  However, I don't have a good way to describe this section.
1136      We do want to copy the section when using objcopy.  */
1137   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1138       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1139     return;
1140
1141   f = bfd_get_section_flags (inbfd, insec);
1142   if (f & SEC_CODE)
1143     outname = NLM_CODE_NAME;
1144   else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1145     outname = NLM_INITIALIZED_DATA_NAME;
1146   else if (f & SEC_ALLOC)
1147     outname = NLM_UNINITIALIZED_DATA_NAME;
1148   else
1149     outname = bfd_section_name (inbfd, insec);
1150
1151   outsec = bfd_get_section_by_name (outbfd, outname);
1152   if (outsec == NULL)
1153     {
1154       outsec = bfd_make_section (outbfd, outname);
1155       if (outsec == NULL)
1156         bfd_fatal ("make section");
1157     }
1158
1159   insec->output_section = outsec;
1160
1161   offset = bfd_section_size (outbfd, outsec);
1162   align = 1 << bfd_section_alignment (inbfd, insec);
1163   add = ((offset + align - 1) &~ (align - 1)) - offset;
1164   insec->output_offset = offset + add;
1165
1166   if (! bfd_set_section_size (outbfd, outsec,
1167                               (bfd_section_size (outbfd, outsec)
1168                                + bfd_section_size (inbfd, insec)
1169                                + add)))
1170     bfd_fatal ("set section size");
1171
1172   if ((bfd_section_alignment (inbfd, insec)
1173        > bfd_section_alignment (outbfd, outsec))
1174       && ! bfd_set_section_alignment (outbfd, outsec,
1175                                       bfd_section_alignment (inbfd, insec)))
1176     bfd_fatal ("set section alignment");
1177
1178   if (! bfd_set_section_flags (outbfd, outsec, f))
1179     bfd_fatal ("set section flags");
1180
1181   bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1182 }
1183
1184 /* Copy the section contents.  */
1185
1186 static void
1187 copy_sections (inbfd, insec, data_ptr)
1188      bfd *inbfd;
1189      asection *insec;
1190      PTR data_ptr;
1191 {
1192   bfd *outbfd = (bfd *) data_ptr;
1193   asection *outsec;
1194   bfd_size_type size;
1195   PTR contents;
1196   bfd_size_type reloc_size;
1197
1198   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1199      file.  However, I don't have a good way to describe this section.
1200      We do want to copy the section when using objcopy.  */
1201   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1202       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1203     return;
1204
1205   outsec = insec->output_section;
1206   assert (outsec != NULL);
1207
1208   size = bfd_get_section_size_before_reloc (insec);
1209   if (size == 0)
1210     return;
1211
1212   /* FIXME: Why are these necessary?  */
1213   insec->_cooked_size = insec->_raw_size;
1214   insec->reloc_done = true;
1215
1216   if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1217     contents = NULL;
1218   else
1219     {
1220       contents = xmalloc (size);
1221       if (! bfd_get_section_contents (inbfd, insec, contents,
1222                                       (file_ptr) 0, size))
1223         bfd_fatal (bfd_get_filename (inbfd));
1224     }
1225
1226   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1227   if (reloc_size != 0)
1228     {
1229       arelent **relocs;
1230       bfd_size_type reloc_count;
1231
1232       relocs = (arelent **) xmalloc (reloc_size);
1233       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1234       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1235                      size);
1236
1237       /* FIXME: refers to internal BFD fields.  */
1238       if (outsec->orelocation != (arelent **) NULL)
1239         {
1240           bfd_size_type total_count;
1241           arelent **combined;
1242
1243           total_count = reloc_count + outsec->reloc_count;
1244           combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1245           memcpy (combined, outsec->orelocation,
1246                   outsec->reloc_count * sizeof (arelent));
1247           memcpy (combined + outsec->reloc_count, relocs,
1248                   (size_t) (reloc_count * sizeof (arelent)));
1249           free (outsec->orelocation);
1250           reloc_count = total_count;
1251           relocs = combined;
1252         }
1253
1254       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1255     }
1256
1257   if (contents != NULL)
1258     {
1259       if (! bfd_set_section_contents (outbfd, outsec, contents,
1260                                       insec->output_offset, size))
1261         bfd_fatal (bfd_get_filename (outbfd));
1262       free (contents);
1263     }
1264 }
1265
1266 /* Some, perhaps all, NetWare targets require changing the relocs used
1267    by the input formats.  */
1268
1269 static void
1270 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1271                contents_size)
1272      bfd *outbfd;
1273      asection *insec;
1274      arelent ***relocs_ptr;
1275      bfd_size_type *reloc_count_ptr;
1276      char *contents;
1277      bfd_size_type contents_size;
1278 {
1279   switch (bfd_get_arch (outbfd))
1280     {
1281     case bfd_arch_i386:
1282       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1283                           contents, contents_size);
1284       break;
1285     case bfd_arch_alpha:
1286       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1287                            contents, contents_size);
1288       break;
1289 /* start-sanitize-powerpc-netware */
1290     case bfd_arch_powerpc:
1291       powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1292                              contents, contents_size);
1293       break;
1294 /* end-sanitize-powerpc-netware */
1295     default:
1296       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1297                              contents, contents_size);
1298       break;
1299     }
1300 }
1301
1302 /* By default all we need to do for relocs is change the address by
1303    the output_offset.  */
1304
1305 /*ARGSUSED*/
1306 static void
1307 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1308                        contents_size)
1309      bfd *outbfd;
1310      asection *insec;
1311      arelent ***relocs_ptr;
1312      bfd_size_type *reloc_count_ptr;
1313      char *contents;
1314      bfd_size_type contents_size;
1315 {
1316   if (insec->output_offset != 0)
1317     {
1318       bfd_size_type reloc_count;
1319       register arelent **relocs;
1320       register bfd_size_type i;
1321
1322       reloc_count = *reloc_count_ptr;
1323       relocs = *relocs_ptr;
1324       for (i = 0; i < reloc_count; i++, relocs++)
1325         (*relocs)->address += insec->output_offset;
1326     }
1327 }
1328
1329 /* NetWare on the i386 supports a restricted set of relocs, which are
1330    different from those used on other i386 targets.  This routine
1331    converts the relocs.  It is, obviously, very target dependent.  At
1332    the moment, the nlm32-i386 backend performs similar translations;
1333    however, it is more reliable and efficient to do them here.  */
1334
1335 static reloc_howto_type nlm_i386_pcrel_howto =
1336   HOWTO (1,                     /* type */
1337          0,                     /* rightshift */
1338          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1339          32,                    /* bitsize */
1340          true,                  /* pc_relative */
1341          0,                     /* bitpos */
1342          complain_overflow_signed, /* complain_on_overflow */
1343          0,                     /* special_function */
1344          "DISP32",              /* name */
1345          true,                  /* partial_inplace */
1346          0xffffffff,            /* src_mask */
1347          0xffffffff,            /* dst_mask */
1348          true);                 /* pcrel_offset */
1349
1350 static void
1351 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1352                     contents_size)
1353      bfd *outbfd;
1354      asection *insec;
1355      arelent ***relocs_ptr;
1356      bfd_size_type *reloc_count_ptr;
1357      char *contents;
1358      bfd_size_type contents_size;
1359 {
1360   bfd_size_type reloc_count, i;
1361   arelent **relocs;
1362
1363   reloc_count = *reloc_count_ptr;
1364   relocs = *relocs_ptr;
1365   for (i = 0; i < reloc_count; i++)
1366     {
1367       arelent *rel;
1368       asymbol *sym;
1369       bfd_size_type address;
1370       bfd_vma addend;
1371
1372       rel = *relocs++;
1373       sym = *rel->sym_ptr_ptr;
1374
1375       /* We're moving the relocs from the input section to the output
1376          section, so we must adjust the address accordingly.  */
1377       address = rel->address;
1378       rel->address += insec->output_offset;
1379
1380       /* Note that no serious harm will ensue if we fail to change a
1381          reloc.  The backend will fail when writing out the reloc.  */
1382
1383       /* Make sure this reloc is within the data we have.  We use only
1384          4 byte relocs here, so we insist on having 4 bytes.  */
1385       if (address + 4 > contents_size)
1386         continue;
1387
1388       /* A PC relative reloc entirely within a single section is
1389          completely unnecessary.  This can be generated by ld -r.  */
1390       if (sym == insec->symbol
1391           && rel->howto != NULL
1392           && rel->howto->pc_relative
1393           && ! rel->howto->pcrel_offset)
1394         {
1395           --*reloc_count_ptr;
1396           --relocs;
1397           memmove (relocs, relocs + 1,
1398                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1399           continue;
1400         }
1401
1402       /* Get the amount the relocation will add in.  */
1403       addend = rel->addend + sym->value;
1404
1405       /* NetWare doesn't support PC relative relocs against defined
1406          symbols, so we have to eliminate them by doing the relocation
1407          now.  We can only do this if the reloc is within a single
1408          section.  */
1409       if (rel->howto != NULL
1410           && rel->howto->pc_relative
1411           && bfd_get_section (sym) == insec->output_section)
1412         {
1413           bfd_vma val;
1414
1415           if (rel->howto->pcrel_offset)
1416             addend -= address;
1417
1418           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1419           val += addend;
1420           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1421
1422           --*reloc_count_ptr;
1423           --relocs;
1424           memmove (relocs, relocs + 1,
1425                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1426           continue;
1427         }
1428
1429       /* NetWare doesn't support reloc addends, so we get rid of them
1430          here by simply adding them into the object data.  We handle
1431          the symbol value, if any, the same way.  */
1432       if (addend != 0
1433           && rel->howto != NULL
1434           && rel->howto->rightshift == 0
1435           && rel->howto->size == 2
1436           && rel->howto->bitsize == 32
1437           && rel->howto->bitpos == 0
1438           && rel->howto->src_mask == 0xffffffff
1439           && rel->howto->dst_mask == 0xffffffff)
1440         {
1441           bfd_vma val;
1442
1443           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1444           val += addend;
1445           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1446
1447           /* Adjust the reloc for the changes we just made.  */
1448           rel->addend = 0;
1449           if (bfd_get_section (sym) != &bfd_und_section)
1450             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1451         }
1452
1453       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1454          pc_relative relocs accordingly.  We are going to change the
1455          howto field, so we can only do this if the current one is
1456          compatible.  We should check that special_function is NULL
1457          here, but at the moment coff-i386 uses a special_function
1458          which does not affect what we are doing here.  */
1459       if (rel->howto != NULL
1460           && rel->howto->pc_relative
1461           && ! rel->howto->pcrel_offset
1462           && rel->howto->rightshift == 0
1463           && rel->howto->size == 2
1464           && rel->howto->bitsize == 32
1465           && rel->howto->bitpos == 0
1466           && rel->howto->src_mask == 0xffffffff
1467           && rel->howto->dst_mask == 0xffffffff)
1468         {
1469           bfd_vma val;
1470
1471           /* When pcrel_offset is not set, it means that the negative
1472              of the address of the memory location is stored in the
1473              memory location.  We must add it back in.  */
1474           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1475           val += address;
1476           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1477
1478           /* We must change to a new howto.  */
1479           rel->howto = &nlm_i386_pcrel_howto;
1480         }
1481     }
1482 }
1483
1484 /* On the Alpha the first reloc for every section must be a special
1485    relocs which hold the GP address.  Also, the first reloc in the
1486    file must be a special reloc which holds the address of the .lita
1487    section.  */
1488
1489 static reloc_howto_type nlm32_alpha_nw_howto =
1490   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1491          0,                     /* rightshift */
1492          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1493          0,                     /* bitsize */
1494          false,                 /* pc_relative */
1495          0,                     /* bitpos */
1496          complain_overflow_dont, /* complain_on_overflow */
1497          0,                     /* special_function */
1498          "NW_RELOC",            /* name */
1499          false,                 /* partial_inplace */
1500          0,                     /* src_mask */
1501          0,                     /* dst_mask */
1502          false);                /* pcrel_offset */
1503
1504 /*ARGSUSED*/
1505 static void
1506 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1507                      contents_size)
1508      bfd *outbfd;
1509      asection *insec;
1510      register arelent ***relocs_ptr;
1511      bfd_size_type *reloc_count_ptr;
1512      char *contents;
1513      bfd_size_type contents_size;
1514 {
1515   bfd_size_type old_reloc_count;
1516   arelent **old_relocs;
1517   register arelent **relocs;
1518
1519   old_reloc_count = *reloc_count_ptr;
1520   old_relocs = *relocs_ptr;
1521   relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1522   *relocs_ptr = relocs;
1523
1524   if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1525     {
1526       bfd *inbfd;
1527       asection *lita_section;
1528
1529       inbfd = insec->owner;
1530       lita_section = bfd_get_section_by_name (inbfd, _LITA);
1531       if (lita_section != (asection *) NULL)
1532         {
1533           nlm_alpha_backend_data (outbfd)->lita_address =
1534             bfd_get_section_vma (inbfd, lita_section);
1535           nlm_alpha_backend_data (outbfd)->lita_size =
1536             bfd_section_size (inbfd, lita_section);
1537         }
1538       else
1539         {
1540           /* Avoid outputting this reloc again.  */
1541           nlm_alpha_backend_data (outbfd)->lita_address = 4;
1542         }
1543
1544       *relocs = (arelent *) xmalloc (sizeof (arelent));
1545       (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1546       (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1547       (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1548       (*relocs)->howto = &nlm32_alpha_nw_howto;
1549       ++relocs;
1550       ++(*reloc_count_ptr);
1551     }
1552
1553   /* Get the GP value from bfd.  It is in the .reginfo section.  */
1554   if (nlm_alpha_backend_data (outbfd)->gp == 0)
1555     {
1556       bfd *inbfd;
1557       asection *reginfo_sec;
1558       struct ecoff_reginfo sreginfo;
1559
1560       inbfd = insec->owner;
1561       assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1562       reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1563       if (reginfo_sec != (asection *) NULL
1564           && bfd_get_section_contents (inbfd, reginfo_sec,
1565                                        (PTR) &sreginfo, (file_ptr) 0,
1566                                        sizeof sreginfo) != false)
1567         nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1568     }
1569
1570   *relocs = (arelent *) xmalloc (sizeof (arelent));
1571   (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1572   (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1573   (*relocs)->addend = 0;
1574   (*relocs)->howto = &nlm32_alpha_nw_howto;
1575   ++relocs;
1576   ++(*reloc_count_ptr);
1577
1578   memcpy ((PTR) relocs, (PTR) old_relocs,
1579           (size_t) old_reloc_count * sizeof (arelent *));
1580   relocs[old_reloc_count] = (arelent *) NULL;
1581
1582   free (old_relocs);
1583
1584   if (insec->output_offset != 0)
1585     {
1586       register bfd_size_type i;
1587
1588       for (i = 0; i < old_reloc_count; i++, relocs++)
1589         (*relocs)->address += insec->output_offset;
1590     }
1591 }
1592 /* start-sanitize-powerpc-netware */
1593
1594 /* We keep a linked list of stubs which we must build.  Because BFD
1595    requires us to know the sizes of all sections before we can set the
1596    contents of any, we must figure out which stubs we want to build
1597    before we can actually build any of them.  */
1598
1599 struct powerpc_stub
1600 {
1601   /* Next stub in linked list.  */
1602   struct powerpc_stub *next;
1603
1604   /* Symbol whose value is the start of the stub.  This is a symbol
1605      whose name begins with `.'.  */
1606   asymbol *start;
1607
1608   /* Symbol we are going to create a reloc against.  This is a symbol
1609      with the same name as START but without the leading `.'.  */
1610   asymbol *reloc;
1611
1612   /* The TOC index for this stub.  This is the index into the TOC
1613      section at which the reloc is created.  */
1614   unsigned int toc_index;
1615 };
1616
1617 /* The linked list of stubs.  */
1618
1619 static struct powerpc_stub *powerpc_stubs;
1620
1621 /* This is what a stub looks like.  The first instruction will get
1622    adjusted with the correct TOC index.  */
1623
1624 static unsigned long powerpc_stub_insns[] =
1625 {
1626   0x81820000,           /* lwz   r12,0(r2) */
1627   0x90410014,           /* stw   r2,20(r1) */
1628   0x800c0000,           /* lwz   r0,0(r12) */
1629   0x804c0004,           /* lwz   r2,r(r12) */
1630   0x7c0903a6,           /* mtctr r0 */
1631   0x4e800420,           /* bctr */
1632   0,                    /* Traceback table.  */
1633   0xc8000,
1634   0
1635 };
1636
1637 #define POWERPC_STUB_INSN_COUNT \
1638   (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1639
1640 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1641
1642 /* Each stub uses a four byte TOC entry.  */
1643 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1644
1645 /* The original size of the .got section.  */
1646 static bfd_size_type powerpc_initial_got_size;
1647
1648 /* Look for all undefined symbols beginning with `.', and prepare to
1649    build a stub for each one.  */
1650
1651 static void
1652 powerpc_build_stubs (inbfd, symbols_ptr, symcount_ptr)
1653      bfd *inbfd;
1654      asymbol ***symbols_ptr;
1655      unsigned int *symcount_ptr;
1656 {
1657   asection *stub_sec;
1658   asection *got_sec;
1659   unsigned int got_base;
1660   unsigned int i;
1661   unsigned int symcount;
1662   unsigned int stubcount;
1663
1664   /* Make a section to hold stubs.  We don't set SEC_HAS_CONTENTS for
1665      the section to prevent copy_sections from reading from it.  */
1666   stub_sec = bfd_make_section (inbfd, ".stubs");
1667   if (stub_sec == (asection *) NULL
1668       || ! bfd_set_section_flags (inbfd, stub_sec,
1669                                   (SEC_CODE
1670                                    | SEC_RELOC
1671                                    | SEC_ALLOC
1672                                    | SEC_LOAD))
1673       || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1674     bfd_fatal (".stubs");
1675
1676   /* Get the TOC section, which is named .got.  */
1677   got_sec = bfd_get_section_by_name (inbfd, ".got");
1678   if (got_sec == (asection *) NULL)
1679     {
1680       got_sec = bfd_make_section (inbfd, ".got");
1681       if (got_sec == (asection *) NULL
1682           || ! bfd_set_section_flags (inbfd, got_sec,
1683                                       (SEC_DATA
1684                                        | SEC_RELOC
1685                                        | SEC_ALLOC
1686                                        | SEC_LOAD
1687                                        | SEC_HAS_CONTENTS))
1688           || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1689         bfd_fatal (".got");
1690     }
1691
1692   powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1693   got_base = powerpc_initial_got_size;
1694   got_base = (got_base + 3) &~ 3;
1695
1696   stubcount = 0;
1697
1698   symcount = *symcount_ptr;
1699   for (i = 0; i < symcount; i++)
1700     {
1701       asymbol *sym;
1702       asymbol *newsym;
1703       char *newname;
1704       struct powerpc_stub *item;
1705
1706       sym = (*symbols_ptr)[i];
1707
1708       /* We must make a stub for every undefined symbol whose name
1709          starts with '.'.  */
1710       if (bfd_asymbol_name (sym)[0] != '.'
1711           || bfd_get_section (sym) != &bfd_und_section)
1712         continue;
1713
1714       /* Make a new undefined symbol with the same name but without
1715          the leading `.'.  */
1716       newsym = (asymbol *) xmalloc (sizeof (asymbol));
1717       *newsym = *sym;
1718       newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1719       strcpy (newname, bfd_asymbol_name (sym) + 1);
1720       newsym->name = newname;
1721
1722       /* Define the `.' symbol to be in the stub section.  */
1723       sym->section = stub_sec;
1724       sym->value = stubcount * POWERPC_STUB_SIZE;
1725       sym->flags = BSF_LOCAL;
1726
1727       /* Add this stub to the linked list.  */
1728       item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1729       item->start = sym;
1730       item->reloc = newsym;
1731       item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1732
1733       item->next = powerpc_stubs;
1734       powerpc_stubs = item;
1735       
1736       ++stubcount;
1737     }
1738
1739   if (stubcount > 0)
1740     {
1741       asymbol **s;
1742       struct powerpc_stub *l;
1743
1744       /* Add the new symbols we just created to the symbol table.  */
1745       *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1746                                             ((symcount + stubcount)
1747                                              * sizeof (asymbol)));
1748       *symcount_ptr += stubcount;
1749       s = &(*symbols_ptr)[symcount];
1750       for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1751         *s++ = l->reloc;
1752
1753       /* Set the size of the .stubs section and increase the size of
1754          the .got section.  */
1755       if (! bfd_set_section_size (inbfd, stub_sec,
1756                                   stubcount * POWERPC_STUB_SIZE)
1757           || ! bfd_set_section_size (inbfd, got_sec,
1758                                      (got_base
1759                                       + (stubcount
1760                                          * POWERPC_STUB_TOC_ENTRY_SIZE))))
1761         bfd_fatal ("stub section sizes");
1762     }
1763 }
1764
1765 /* Resolve all the stubs for PowerPC NetWare.  We fill in the contents
1766    of the output section, and create new relocs in the TOC.  */
1767
1768 static void
1769 powerpc_resolve_stubs (inbfd, outbfd)
1770      bfd *inbfd;
1771      bfd *outbfd;
1772 {
1773   bfd_byte buf[POWERPC_STUB_SIZE];
1774   unsigned int i;
1775   unsigned int stubcount;
1776   arelent **relocs;
1777   asection *got_sec;
1778   arelent **r;
1779   struct powerpc_stub *l;
1780
1781   if (powerpc_stubs == (struct powerpc_stub *) NULL)
1782     return;
1783
1784   for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1785     bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1786
1787   got_sec = bfd_get_section_by_name (inbfd, ".got");
1788   assert (got_sec != (asection *) NULL);
1789   assert (got_sec->output_section->orelocation == (arelent **) NULL);
1790
1791   stubcount = 0;
1792   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1793     ++stubcount;
1794   relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1795
1796   r = relocs;
1797   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1798     {
1799       arelent *reloc;
1800
1801       /* Adjust the first instruction to use the right TOC index.  */
1802       bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1803
1804       /* Write this stub out.  */
1805       if (! bfd_set_section_contents (outbfd,
1806                                       bfd_get_section (l->start),
1807                                       buf,
1808                                       l->start->value,
1809                                       POWERPC_STUB_SIZE))
1810         bfd_fatal ("writing stub");
1811
1812       /* Create a new reloc for the TOC entry.  */
1813       reloc = (arelent *) xmalloc (sizeof (arelent));
1814       reloc->sym_ptr_ptr = &l->reloc;
1815       reloc->address = l->toc_index + got_sec->output_offset;
1816       reloc->addend = 0;
1817       reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1818                                       
1819       *r++ = reloc;
1820     }
1821
1822   bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1823 }
1824
1825 /* Adjust relocation entries for PowerPC NetWare.  We do not output
1826    TOC relocations.  The object code already contains the offset from
1827    the TOC pointer.  When the function is called, the TOC register,
1828    r2, will be set to the correct TOC value, so there is no need for
1829    any further reloc.  */
1830
1831 /*ARGSUSED*/
1832 static void
1833 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1834                        contents_size)
1835      bfd *outbfd;
1836      asection *insec;
1837      register arelent ***relocs_ptr;
1838      bfd_size_type *reloc_count_ptr;
1839      char *contents;
1840      bfd_size_type contents_size;
1841 {
1842   const reloc_howto_type *toc_howto;
1843   bfd_size_type reloc_count;
1844   register arelent **relocs;
1845   register bfd_size_type i;
1846
1847   toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1848   if (toc_howto == (reloc_howto_type *) NULL)
1849     abort ();
1850
1851   /* If this is the .got section, clear out all the contents beyond
1852      the initial size.  We must do this here because copy_sections is
1853      going to write out whatever we return in the contents field.  */
1854   if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1855     memset (contents + powerpc_initial_got_size, 0,
1856             (bfd_get_section_size_after_reloc (insec)
1857              - powerpc_initial_got_size));
1858
1859   reloc_count = *reloc_count_ptr;
1860   relocs = *relocs_ptr;
1861   for (i = 0; i < reloc_count; i++)
1862     {
1863       arelent *rel;
1864       asymbol *sym;
1865       bfd_vma symvalue;
1866
1867       rel = *relocs++;
1868       sym = *rel->sym_ptr_ptr;
1869
1870       /* We must be able to resolve all PC relative relocs at this
1871          point.  If we get a branch to an undefined symbol we build a
1872          stub, since NetWare will resolve undefined symbols into a
1873          pointer to a function descriptor.  */
1874       if (rel->howto->pc_relative)
1875         {
1876           /* This check for whether a symbol is in the same section as
1877              the reloc will be wrong if there is a PC relative reloc
1878              between two sections both of which were placed in the
1879              same output section.  This should not happen.  */
1880           if (bfd_get_section (sym) != insec->output_section)
1881             fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1882                      program_name, bfd_asymbol_name (sym));
1883           else
1884             {
1885               bfd_vma val;
1886
1887               assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1888               val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1889               val = ((val &~ rel->howto->dst_mask)
1890                      | (((val & rel->howto->src_mask)
1891                          + (sym->value - rel->address)
1892                          + rel->addend)
1893                         & rel->howto->dst_mask));
1894               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1895
1896               /* If this reloc is against a symbol whose name begins
1897                  with a `.', and the next instruction is
1898                      cror 31,31,31
1899                  then we replace the next instruction with
1900                      lwz  r2,20(r1)
1901                  This reloads the TOC pointer after a call.  */
1902               if (bfd_asymbol_name (sym)[0] == '.'
1903                   && (bfd_get_32 (outbfd,
1904                                   (bfd_byte *) contents + rel->address + 4)
1905                       == 0x4ffffb82)) /* cror 31,31,31 */
1906                 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1907                             (bfd_byte *) contents + rel->address + 4);
1908
1909               --*reloc_count_ptr;
1910               --relocs;
1911               memmove (relocs, relocs + 1,
1912                        (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1913               continue;
1914             }
1915         }
1916
1917       /* When considering a TOC reloc, we do not want to include the
1918          symbol value.  The symbol will be start of the TOC section
1919          (which is named .got).  We do want to include the addend.  */
1920       if (rel->howto == toc_howto)
1921         symvalue = 0;
1922       else
1923         symvalue = sym->value;
1924
1925       /* If this is a relocation against a symbol with a value, or
1926          there is a reloc addend, we need to update the addend in the
1927          object file.  */
1928       if (symvalue + rel->addend != 0)
1929         {
1930           bfd_vma val;
1931
1932           switch (rel->howto->size)
1933             {
1934             case 1:
1935               val = bfd_get_16 (outbfd,
1936                                 (bfd_byte *) contents + rel->address);
1937               val = ((val &~ rel->howto->dst_mask)
1938                      | (((val & rel->howto->src_mask)
1939                          + symvalue
1940                          + rel->addend)
1941                         & rel->howto->dst_mask));
1942               if ((bfd_signed_vma) val < - 0x8000
1943                   || (bfd_signed_vma) val >= 0x8000)
1944                 fprintf (stderr,
1945                          "%s: overflow when adjusting relocation against %s\n",
1946                          program_name, bfd_asymbol_name (sym));
1947               bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1948               break;
1949
1950             case 2:
1951               val = bfd_get_32 (outbfd,
1952                                 (bfd_byte *) contents + rel->address);
1953               val = ((val &~ rel->howto->dst_mask)
1954                      | (((val & rel->howto->src_mask)
1955                          + symvalue
1956                          + rel->addend)
1957                         & rel->howto->dst_mask));
1958               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1959               break;
1960
1961             default:
1962               abort ();
1963             }
1964
1965           rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1966           rel->addend = 0;
1967         }
1968
1969       /* Now that we have incorporated the addend, remove any TOC
1970          relocs.  */
1971       if (rel->howto == toc_howto)
1972         {
1973           --*reloc_count_ptr;
1974           --relocs;
1975           memmove (relocs, relocs + 1,
1976                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1977           continue;
1978         }
1979
1980       rel->address += insec->output_offset;
1981     }
1982 }
1983 /* end-sanitize-powerpc-netware */
1984 \f
1985 /* Name of linker.  */
1986 #ifndef LD_NAME
1987 #define LD_NAME "ld"
1988 #endif
1989
1990 /* Temporary file name base.  */
1991 static char *temp_filename;
1992
1993 /* The user has specified several input files.  Invoke the linker to
1994    link them all together, and convert and delete the resulting output
1995    file.  */
1996
1997 static char *
1998 link_inputs (inputs, ld)
1999      struct string_list *inputs;
2000      char *ld;
2001 {
2002   size_t c;
2003   struct string_list *q;
2004   char **argv;
2005   size_t i;
2006   int pid;
2007   int status;
2008
2009   c = 0;
2010   for (q = inputs; q != NULL; q = q->next)
2011     ++c;
2012
2013   argv = (char **) alloca (c + 5);
2014
2015 #ifndef __MSDOS__
2016   if (ld == NULL)
2017     {
2018       char *p;
2019
2020       /* Find the linker to invoke based on how nlmconv was run.  */
2021       p = program_name + strlen (program_name);
2022       while (p != program_name)
2023         {
2024           if (p[-1] == '/')
2025             {
2026               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2027               memcpy (ld, program_name, p - program_name);
2028               strcpy (ld + (p - program_name), LD_NAME);
2029               break;
2030             }
2031           --p;
2032         }
2033     }
2034 #endif
2035
2036   if (ld == NULL)
2037     ld = (char *) LD_NAME;
2038
2039   choose_temp_base ();
2040
2041   unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2042   sprintf (unlink_on_exit, "%s.O", temp_filename);
2043
2044   argv[0] = ld;
2045   argv[1] = (char *) "-r";
2046   argv[2] = (char *) "-o";
2047   argv[3] = unlink_on_exit;
2048   i = 4;
2049   for (q = inputs; q != NULL; q = q->next, i++)
2050     argv[i] = q->string;
2051   argv[i] = NULL;
2052
2053   if (debug)
2054     {
2055       for (i = 0; argv[i] != NULL; i++)
2056         fprintf (stderr, " %s", argv[i]);
2057       fprintf (stderr, "\n");
2058     }
2059
2060   pid = pexecute (ld, argv);
2061
2062   if (waitpid (pid, &status, 0) < 0)
2063     {
2064       perror ("waitpid");
2065       unlink (unlink_on_exit);
2066       exit (1);
2067     }
2068
2069   if (status != 0)
2070     {
2071       fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2072       unlink (unlink_on_exit);
2073       exit (1);
2074     }
2075
2076   return unlink_on_exit;
2077 }
2078
2079 /* Choose a temporary file name.  Stolen from gcc.c.  */
2080
2081 static const char *
2082 choose_temp_base_try (try, base)
2083      const char *try;
2084      const char *base;
2085 {
2086   const char *rv;
2087
2088   if (base)
2089     rv = base;
2090   else if (try == NULL)
2091     rv = NULL;
2092   else if (access (try, R_OK | W_OK) != 0)
2093     rv = NULL;
2094   else
2095     rv = try;
2096   return rv;
2097 }
2098
2099 static void
2100 choose_temp_base ()
2101 {
2102   const char *base = NULL;
2103   int len;
2104
2105   base = choose_temp_base_try (getenv ("TMPDIR"), base);
2106   base = choose_temp_base_try (getenv ("TMP"), base);
2107   base = choose_temp_base_try (getenv ("TEMP"), base);
2108
2109 #ifdef P_tmpdir
2110   base = choose_temp_base_try (P_tmpdir, base);
2111 #endif
2112
2113   base = choose_temp_base_try ("/usr/tmp", base);
2114   base = choose_temp_base_try ("/tmp", base);
2115
2116   /* If all else fails, use the current directory! */  
2117   if (base == NULL)
2118     base = "./";
2119
2120   len = strlen (base);
2121   temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2122   strcpy (temp_filename, base);
2123   if (len > 0 && temp_filename[len-1] != '/')
2124     temp_filename[len++] = '/';
2125   strcpy (temp_filename + len, "ccXXXXXX");
2126
2127   mktemp (temp_filename);
2128   if (*temp_filename == '\0')
2129     abort ();
2130 }
2131
2132 /* Execute a job.  Stolen from gcc.c.  */
2133
2134 #ifndef OS2
2135 #ifdef __MSDOS__
2136
2137 static int
2138 pexecute (program, argv)
2139      char *program;
2140      char *argv[];
2141 {
2142   char *scmd, *rf;
2143   FILE *argfile;
2144   int i;
2145
2146   scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2147   rf = scmd + strlen(program) + 2 + el;
2148   sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2149   argfile = fopen (rf, "w");
2150   if (argfile == 0)
2151     pfatal_with_name (rf);
2152
2153   for (i=1; argv[i]; i++)
2154     {
2155       char *cp;
2156       for (cp = argv[i]; *cp; cp++)
2157         {
2158           if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2159             fputc ('\\', argfile);
2160           fputc (*cp, argfile);
2161         }
2162       fputc ('\n', argfile);
2163     }
2164   fclose (argfile);
2165
2166   i = system (scmd);
2167
2168   remove (rf);
2169   
2170   if (i == -1)
2171     {
2172       perror (program);
2173       return MIN_FATAL_STATUS << 8;
2174     }
2175
2176   return i << 8;
2177 }
2178
2179 #else /* not __MSDOS__ */
2180
2181 static int
2182 pexecute (program, argv)
2183      char *program;
2184      char *argv[];
2185 {
2186   int pid;
2187   int retries, sleep_interval;
2188
2189   /* Fork a subprocess; wait and retry if it fails.  */
2190   sleep_interval = 1;
2191   for (retries = 0; retries < 4; retries++)
2192     {
2193       pid = vfork ();
2194       if (pid >= 0)
2195         break;
2196       sleep (sleep_interval);
2197       sleep_interval *= 2;
2198     }
2199
2200   switch (pid)
2201     {
2202     case -1:
2203 #ifdef vfork
2204       perror ("fork");
2205 #else
2206       perror ("vfork");
2207 #endif
2208       exit (1);
2209       /* NOTREACHED */
2210       return 0;
2211
2212     case 0: /* child */
2213       /* Exec the program.  */
2214       execvp (program, argv);
2215       perror (program);
2216       exit (1);
2217       /* NOTREACHED */
2218       return 0;
2219
2220     default:
2221       /* Return child's process number.  */
2222       return pid;
2223     }
2224 }
2225
2226 #endif /* not __MSDOS__ */
2227 #else /* not OS2 */
2228
2229 static int
2230 pexecute (program, argv)
2231      char *program;
2232      char *argv[];
2233 {
2234   return spawnvp (1, program, argv);
2235 }
2236 #endif /* not OS2 */