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