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