* nlmconv.c (secsec): New static variable.
[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 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_section_header (outbfd)->stamp, "CyGnUsSeCs", 10);
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_section_header (outbfd)->offset = secsec->filepos;
1082   nlm_cygnus_section_header (outbfd)->length =
1083     bfd_section_size (outbfd, secsec);
1084
1085   if (! bfd_close (outbfd))
1086     bfd_fatal (output_file);
1087   if (! bfd_close (inbfd))
1088     bfd_fatal (input_file);
1089
1090   if (unlink_on_exit != NULL)
1091     unlink (unlink_on_exit);
1092
1093   return 0;
1094 }
1095 \f
1096 /* Display a help message and exit.  */
1097
1098 static void
1099 show_help ()
1100 {
1101   printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1102           program_name);
1103   show_usage (stdout, 0);
1104 }
1105
1106 /* Show a usage message and exit.  */
1107
1108 static void
1109 show_usage (file, status)
1110      FILE *file;
1111      int status;
1112 {
1113   fprintf (file, "\
1114 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1115        [--input-target=bfdname] [--output-target=bfdname]\n\
1116        [--header-file=file] [--linker=linker] [--debug]\n\
1117        [--help] [--version]\n\
1118        [in-file [out-file]]\n",
1119            program_name);
1120   exit (status);
1121 }
1122 \f
1123 /* Select the output format based on the input architecture, machine,
1124    and endianness.  This chooses the appropriate NLM target.  */
1125
1126 static const char *
1127 select_output_format (arch, mach, bigendian)
1128      enum bfd_architecture arch;
1129      unsigned long mach;
1130      boolean bigendian;
1131 {
1132   switch (arch)
1133     {
1134     case bfd_arch_i386:
1135       return "nlm32-i386";
1136     case bfd_arch_sparc:
1137       return "nlm32-sparc";
1138     case bfd_arch_alpha:
1139       return "nlm32-alpha";
1140 /* start-sanitize-powerpc-netware */
1141     case bfd_arch_powerpc:
1142       return "nlm32-powerpc";
1143 /* end-sanitize-powerpc-netware */
1144     default:
1145       fprintf (stderr, "%s: no default NLM format for %s\n",
1146                program_name, bfd_printable_arch_mach (arch, mach));
1147       exit (1);
1148       /* Avoid warning.  */
1149       return NULL;
1150     }
1151   /*NOTREACHED*/
1152 }
1153 \f
1154 /* The BFD sections are copied in two passes.  This function selects
1155    the output section for each input section, and sets up the section
1156    name, size, etc.  */
1157
1158 static void
1159 setup_sections (inbfd, insec, data_ptr)
1160      bfd *inbfd;
1161      asection *insec;
1162      PTR data_ptr;
1163 {
1164   bfd *outbfd = (bfd *) data_ptr;
1165   flagword f;
1166   const char *outname;
1167   asection *outsec;
1168   bfd_vma offset;
1169   bfd_size_type align;
1170   bfd_size_type add;
1171   bfd_size_type secsecsize;
1172
1173   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1174      file.  However, I don't have a good way to describe this section.
1175      We do want to copy the section when using objcopy.  */
1176   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1177       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1178     return;
1179
1180   f = bfd_get_section_flags (inbfd, insec);
1181   if (f & SEC_CODE)
1182     outname = NLM_CODE_NAME;
1183   else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1184     outname = NLM_INITIALIZED_DATA_NAME;
1185   else if (f & SEC_ALLOC)
1186     outname = NLM_UNINITIALIZED_DATA_NAME;
1187   else
1188     outname = bfd_section_name (inbfd, insec);
1189
1190   outsec = bfd_get_section_by_name (outbfd, outname);
1191   if (outsec == NULL)
1192     {
1193       outsec = bfd_make_section (outbfd, outname);
1194       if (outsec == NULL)
1195         bfd_fatal ("make section");
1196     }
1197
1198   insec->output_section = outsec;
1199
1200   offset = bfd_section_size (outbfd, outsec);
1201   align = 1 << bfd_section_alignment (inbfd, insec);
1202   add = ((offset + align - 1) &~ (align - 1)) - offset;
1203   insec->output_offset = offset + add;
1204
1205   if (! bfd_set_section_size (outbfd, outsec,
1206                               (bfd_section_size (outbfd, outsec)
1207                                + bfd_section_size (inbfd, insec)
1208                                + add)))
1209     bfd_fatal ("set section size");
1210
1211   if ((bfd_section_alignment (inbfd, insec)
1212        > bfd_section_alignment (outbfd, outsec))
1213       && ! bfd_set_section_alignment (outbfd, outsec,
1214                                       bfd_section_alignment (inbfd, insec)))
1215     bfd_fatal ("set section alignment");
1216
1217   if (! bfd_set_section_flags (outbfd, outsec, f))
1218     bfd_fatal ("set section flags");
1219
1220   bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1221
1222   /* For each input section we allocate space for an entry in
1223      .nlmsections.  */
1224   secsecsize = bfd_section_size (outbfd, secsec);
1225   secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1226   secsecsize = (secsecsize + 3) &~ 3;
1227   secsecsize += 8;
1228   if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1229     bfd_fatal ("set .nlmsections size");
1230 }
1231
1232 /* Copy the section contents.  */
1233
1234 static void
1235 copy_sections (inbfd, insec, data_ptr)
1236      bfd *inbfd;
1237      asection *insec;
1238      PTR data_ptr;
1239 {
1240   static bfd_size_type secsecoff = 0;
1241   bfd *outbfd = (bfd *) data_ptr;
1242   const char *inname;
1243   asection *outsec;
1244   bfd_size_type size;
1245   PTR contents;
1246   long reloc_size;
1247   bfd_byte buf[4];
1248   bfd_size_type add;
1249
1250   inname = bfd_section_name (inbfd, insec);
1251
1252   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1253      file.  However, I don't have a good way to describe this section.
1254      We do want to copy the section when using objcopy.  */
1255   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1256       && strcmp (inname, ".reginfo") == 0)
1257     return;
1258
1259   outsec = insec->output_section;
1260   assert (outsec != NULL);
1261
1262   size = bfd_get_section_size_before_reloc (insec);
1263
1264   /* FIXME: Why are these necessary?  */
1265   insec->_cooked_size = insec->_raw_size;
1266   insec->reloc_done = true;
1267
1268   if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1269     contents = NULL;
1270   else
1271     {
1272       contents = xmalloc (size);
1273       if (! bfd_get_section_contents (inbfd, insec, contents,
1274                                       (file_ptr) 0, size))
1275         bfd_fatal (bfd_get_filename (inbfd));
1276     }
1277
1278   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1279   if (reloc_size < 0)
1280     bfd_fatal (bfd_get_filename (inbfd));
1281   if (reloc_size != 0)
1282     {
1283       arelent **relocs;
1284       long reloc_count;
1285
1286       relocs = (arelent **) xmalloc (reloc_size);
1287       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1288       if (reloc_count < 0)
1289         bfd_fatal (bfd_get_filename (inbfd));
1290       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1291                      size);
1292
1293       /* FIXME: refers to internal BFD fields.  */
1294       if (outsec->orelocation != (arelent **) NULL)
1295         {
1296           bfd_size_type total_count;
1297           arelent **combined;
1298
1299           total_count = reloc_count + outsec->reloc_count;
1300           combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1301           memcpy (combined, outsec->orelocation,
1302                   outsec->reloc_count * sizeof (arelent));
1303           memcpy (combined + outsec->reloc_count, relocs,
1304                   (size_t) (reloc_count * sizeof (arelent)));
1305           free (outsec->orelocation);
1306           reloc_count = total_count;
1307           relocs = combined;
1308         }
1309
1310       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1311     }
1312
1313   if (contents != NULL)
1314     {
1315       if (! bfd_set_section_contents (outbfd, outsec, contents,
1316                                       insec->output_offset, size))
1317         bfd_fatal (bfd_get_filename (outbfd));
1318       free (contents);
1319     }
1320
1321   /* Add this section to .nlmsections.  */
1322   if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
1323                                   strlen (inname) + 1))
1324     bfd_fatal ("set .nlmsection contents");
1325   secsecoff += strlen (inname) + 1;
1326
1327   add = ((secsecoff + 3) &~ 3) - secsecoff;
1328   if (add != 0)
1329     {
1330       bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1331       if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1332         bfd_fatal ("set .nlmsection contents");
1333       secsecoff += add;
1334     }
1335
1336   if (contents != NULL)
1337     bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1338   else
1339     bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1340   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1341     bfd_fatal ("set .nlmsection contents");
1342   secsecoff += 4;
1343
1344   bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1345   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1346     bfd_fatal ("set .nlmsection contents");
1347   secsecoff += 4;
1348 }
1349
1350 /* Some, perhaps all, NetWare targets require changing the relocs used
1351    by the input formats.  */
1352
1353 static void
1354 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1355                contents_size)
1356      bfd *outbfd;
1357      asection *insec;
1358      arelent ***relocs_ptr;
1359      long *reloc_count_ptr;
1360      char *contents;
1361      bfd_size_type contents_size;
1362 {
1363   switch (bfd_get_arch (outbfd))
1364     {
1365     case bfd_arch_i386:
1366       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1367                           contents, contents_size);
1368       break;
1369     case bfd_arch_alpha:
1370       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1371                            contents, contents_size);
1372       break;
1373 /* start-sanitize-powerpc-netware */
1374     case bfd_arch_powerpc:
1375       powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1376                              contents, contents_size);
1377       break;
1378 /* end-sanitize-powerpc-netware */
1379     default:
1380       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1381                              contents, contents_size);
1382       break;
1383     }
1384 }
1385
1386 /* By default all we need to do for relocs is change the address by
1387    the output_offset.  */
1388
1389 /*ARGSUSED*/
1390 static void
1391 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1392                        contents_size)
1393      bfd *outbfd;
1394      asection *insec;
1395      arelent ***relocs_ptr;
1396      long *reloc_count_ptr;
1397      char *contents;
1398      bfd_size_type contents_size;
1399 {
1400   if (insec->output_offset != 0)
1401     {
1402       long reloc_count;
1403       register arelent **relocs;
1404       register long i;
1405
1406       reloc_count = *reloc_count_ptr;
1407       relocs = *relocs_ptr;
1408       for (i = 0; i < reloc_count; i++, relocs++)
1409         (*relocs)->address += insec->output_offset;
1410     }
1411 }
1412
1413 /* NetWare on the i386 supports a restricted set of relocs, which are
1414    different from those used on other i386 targets.  This routine
1415    converts the relocs.  It is, obviously, very target dependent.  At
1416    the moment, the nlm32-i386 backend performs similar translations;
1417    however, it is more reliable and efficient to do them here.  */
1418
1419 static reloc_howto_type nlm_i386_pcrel_howto =
1420   HOWTO (1,                     /* type */
1421          0,                     /* rightshift */
1422          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1423          32,                    /* bitsize */
1424          true,                  /* pc_relative */
1425          0,                     /* bitpos */
1426          complain_overflow_signed, /* complain_on_overflow */
1427          0,                     /* special_function */
1428          "DISP32",              /* name */
1429          true,                  /* partial_inplace */
1430          0xffffffff,            /* src_mask */
1431          0xffffffff,            /* dst_mask */
1432          true);                 /* pcrel_offset */
1433
1434 static void
1435 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1436                     contents_size)
1437      bfd *outbfd;
1438      asection *insec;
1439      arelent ***relocs_ptr;
1440      long *reloc_count_ptr;
1441      char *contents;
1442      bfd_size_type contents_size;
1443 {
1444   long reloc_count, i;
1445   arelent **relocs;
1446
1447   reloc_count = *reloc_count_ptr;
1448   relocs = *relocs_ptr;
1449   for (i = 0; i < reloc_count; i++)
1450     {
1451       arelent *rel;
1452       asymbol *sym;
1453       bfd_size_type address;
1454       bfd_vma addend;
1455
1456       rel = *relocs++;
1457       sym = *rel->sym_ptr_ptr;
1458
1459       /* We're moving the relocs from the input section to the output
1460          section, so we must adjust the address accordingly.  */
1461       address = rel->address;
1462       rel->address += insec->output_offset;
1463
1464       /* Note that no serious harm will ensue if we fail to change a
1465          reloc.  The backend will fail when writing out the reloc.  */
1466
1467       /* Make sure this reloc is within the data we have.  We use only
1468          4 byte relocs here, so we insist on having 4 bytes.  */
1469       if (address + 4 > contents_size)
1470         continue;
1471
1472       /* A PC relative reloc entirely within a single section is
1473          completely unnecessary.  This can be generated by ld -r.  */
1474       if (sym == insec->symbol
1475           && rel->howto != NULL
1476           && rel->howto->pc_relative
1477           && ! rel->howto->pcrel_offset)
1478         {
1479           --*reloc_count_ptr;
1480           --relocs;
1481           memmove (relocs, relocs + 1,
1482                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1483           continue;
1484         }
1485
1486       /* Get the amount the relocation will add in.  */
1487       addend = rel->addend + sym->value;
1488
1489       /* NetWare doesn't support PC relative relocs against defined
1490          symbols, so we have to eliminate them by doing the relocation
1491          now.  We can only do this if the reloc is within a single
1492          section.  */
1493       if (rel->howto != NULL
1494           && rel->howto->pc_relative
1495           && bfd_get_section (sym) == insec->output_section)
1496         {
1497           bfd_vma val;
1498
1499           if (rel->howto->pcrel_offset)
1500             addend -= address;
1501
1502           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1503           val += addend;
1504           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1505
1506           --*reloc_count_ptr;
1507           --relocs;
1508           memmove (relocs, relocs + 1,
1509                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1510           continue;
1511         }
1512
1513       /* NetWare doesn't support reloc addends, so we get rid of them
1514          here by simply adding them into the object data.  We handle
1515          the symbol value, if any, the same way.  */
1516       if (addend != 0
1517           && rel->howto != NULL
1518           && rel->howto->rightshift == 0
1519           && rel->howto->size == 2
1520           && rel->howto->bitsize == 32
1521           && rel->howto->bitpos == 0
1522           && rel->howto->src_mask == 0xffffffff
1523           && rel->howto->dst_mask == 0xffffffff)
1524         {
1525           bfd_vma val;
1526
1527           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1528           val += addend;
1529           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1530
1531           /* Adjust the reloc for the changes we just made.  */
1532           rel->addend = 0;
1533           if (bfd_get_section (sym) != &bfd_und_section)
1534             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1535         }
1536
1537       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1538          pc_relative relocs accordingly.  We are going to change the
1539          howto field, so we can only do this if the current one is
1540          compatible.  We should check that special_function is NULL
1541          here, but at the moment coff-i386 uses a special_function
1542          which does not affect what we are doing here.  */
1543       if (rel->howto != NULL
1544           && rel->howto->pc_relative
1545           && ! rel->howto->pcrel_offset
1546           && rel->howto->rightshift == 0
1547           && rel->howto->size == 2
1548           && rel->howto->bitsize == 32
1549           && rel->howto->bitpos == 0
1550           && rel->howto->src_mask == 0xffffffff
1551           && rel->howto->dst_mask == 0xffffffff)
1552         {
1553           bfd_vma val;
1554
1555           /* When pcrel_offset is not set, it means that the negative
1556              of the address of the memory location is stored in the
1557              memory location.  We must add it back in.  */
1558           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1559           val += address;
1560           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1561
1562           /* We must change to a new howto.  */
1563           rel->howto = &nlm_i386_pcrel_howto;
1564         }
1565     }
1566 }
1567
1568 /* On the Alpha the first reloc for every section must be a special
1569    relocs which hold the GP address.  Also, the first reloc in the
1570    file must be a special reloc which holds the address of the .lita
1571    section.  */
1572
1573 static reloc_howto_type nlm32_alpha_nw_howto =
1574   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1575          0,                     /* rightshift */
1576          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1577          0,                     /* bitsize */
1578          false,                 /* pc_relative */
1579          0,                     /* bitpos */
1580          complain_overflow_dont, /* complain_on_overflow */
1581          0,                     /* special_function */
1582          "NW_RELOC",            /* name */
1583          false,                 /* partial_inplace */
1584          0,                     /* src_mask */
1585          0,                     /* dst_mask */
1586          false);                /* pcrel_offset */
1587
1588 /*ARGSUSED*/
1589 static void
1590 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1591                      contents_size)
1592      bfd *outbfd;
1593      asection *insec;
1594      register arelent ***relocs_ptr;
1595      long *reloc_count_ptr;
1596      char *contents;
1597      bfd_size_type contents_size;
1598 {
1599   long old_reloc_count;
1600   arelent **old_relocs;
1601   register arelent **relocs;
1602
1603   old_reloc_count = *reloc_count_ptr;
1604   old_relocs = *relocs_ptr;
1605   relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1606   *relocs_ptr = relocs;
1607
1608   if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1609     {
1610       bfd *inbfd;
1611       asection *lita_section;
1612
1613       inbfd = insec->owner;
1614       lita_section = bfd_get_section_by_name (inbfd, _LITA);
1615       if (lita_section != (asection *) NULL)
1616         {
1617           nlm_alpha_backend_data (outbfd)->lita_address =
1618             bfd_get_section_vma (inbfd, lita_section);
1619           nlm_alpha_backend_data (outbfd)->lita_size =
1620             bfd_section_size (inbfd, lita_section);
1621         }
1622       else
1623         {
1624           /* Avoid outputting this reloc again.  */
1625           nlm_alpha_backend_data (outbfd)->lita_address = 4;
1626         }
1627
1628       *relocs = (arelent *) xmalloc (sizeof (arelent));
1629       (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1630       (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1631       (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1632       (*relocs)->howto = &nlm32_alpha_nw_howto;
1633       ++relocs;
1634       ++(*reloc_count_ptr);
1635     }
1636
1637   /* Get the GP value from bfd.  It is in the .reginfo section.  */
1638   if (nlm_alpha_backend_data (outbfd)->gp == 0)
1639     {
1640       bfd *inbfd;
1641       asection *reginfo_sec;
1642       struct ecoff_reginfo sreginfo;
1643
1644       inbfd = insec->owner;
1645       assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1646       reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1647       if (reginfo_sec != (asection *) NULL
1648           && bfd_get_section_contents (inbfd, reginfo_sec,
1649                                        (PTR) &sreginfo, (file_ptr) 0,
1650                                        sizeof sreginfo) != false)
1651         nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1652     }
1653
1654   *relocs = (arelent *) xmalloc (sizeof (arelent));
1655   (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1656   (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1657   (*relocs)->addend = 0;
1658   (*relocs)->howto = &nlm32_alpha_nw_howto;
1659   ++relocs;
1660   ++(*reloc_count_ptr);
1661
1662   memcpy ((PTR) relocs, (PTR) old_relocs,
1663           (size_t) old_reloc_count * sizeof (arelent *));
1664   relocs[old_reloc_count] = (arelent *) NULL;
1665
1666   free (old_relocs);
1667
1668   if (insec->output_offset != 0)
1669     {
1670       register bfd_size_type i;
1671
1672       for (i = 0; i < old_reloc_count; i++, relocs++)
1673         (*relocs)->address += insec->output_offset;
1674     }
1675 }
1676 /* start-sanitize-powerpc-netware */
1677
1678 /* We keep a linked list of stubs which we must build.  Because BFD
1679    requires us to know the sizes of all sections before we can set the
1680    contents of any, we must figure out which stubs we want to build
1681    before we can actually build any of them.  */
1682
1683 struct powerpc_stub
1684 {
1685   /* Next stub in linked list.  */
1686   struct powerpc_stub *next;
1687
1688   /* Symbol whose value is the start of the stub.  This is a symbol
1689      whose name begins with `.'.  */
1690   asymbol *start;
1691
1692   /* Symbol we are going to create a reloc against.  This is a symbol
1693      with the same name as START but without the leading `.'.  */
1694   asymbol *reloc;
1695
1696   /* The TOC index for this stub.  This is the index into the TOC
1697      section at which the reloc is created.  */
1698   unsigned int toc_index;
1699 };
1700
1701 /* The linked list of stubs.  */
1702
1703 static struct powerpc_stub *powerpc_stubs;
1704
1705 /* This is what a stub looks like.  The first instruction will get
1706    adjusted with the correct TOC index.  */
1707
1708 static unsigned long powerpc_stub_insns[] =
1709 {
1710   0x81820000,           /* lwz   r12,0(r2) */
1711   0x90410014,           /* stw   r2,20(r1) */
1712   0x800c0000,           /* lwz   r0,0(r12) */
1713   0x804c0004,           /* lwz   r2,r(r12) */
1714   0x7c0903a6,           /* mtctr r0 */
1715   0x4e800420,           /* bctr */
1716   0,                    /* Traceback table.  */
1717   0xc8000,
1718   0
1719 };
1720
1721 #define POWERPC_STUB_INSN_COUNT \
1722   (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1723
1724 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1725
1726 /* Each stub uses a four byte TOC entry.  */
1727 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1728
1729 /* The original size of the .got section.  */
1730 static bfd_size_type powerpc_initial_got_size;
1731
1732 /* Look for all undefined symbols beginning with `.', and prepare to
1733    build a stub for each one.  */
1734
1735 static void
1736 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1737      bfd *inbfd;
1738      bfd *outbfd;
1739      asymbol ***symbols_ptr;
1740      long *symcount_ptr;
1741 {
1742   asection *stub_sec;
1743   asection *got_sec;
1744   unsigned int got_base;
1745   long i;
1746   long symcount;
1747   long stubcount;
1748
1749   /* Make a section to hold stubs.  We don't set SEC_HAS_CONTENTS for
1750      the section to prevent copy_sections from reading from it.  */
1751   stub_sec = bfd_make_section (inbfd, ".stubs");
1752   if (stub_sec == (asection *) NULL
1753       || ! bfd_set_section_flags (inbfd, stub_sec,
1754                                   (SEC_CODE
1755                                    | SEC_RELOC
1756                                    | SEC_ALLOC
1757                                    | SEC_LOAD))
1758       || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1759     bfd_fatal (".stubs");
1760
1761   /* Get the TOC section, which is named .got.  */
1762   got_sec = bfd_get_section_by_name (inbfd, ".got");
1763   if (got_sec == (asection *) NULL)
1764     {
1765       got_sec = bfd_make_section (inbfd, ".got");
1766       if (got_sec == (asection *) NULL
1767           || ! bfd_set_section_flags (inbfd, got_sec,
1768                                       (SEC_DATA
1769                                        | SEC_RELOC
1770                                        | SEC_ALLOC
1771                                        | SEC_LOAD
1772                                        | SEC_HAS_CONTENTS))
1773           || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1774         bfd_fatal (".got");
1775     }
1776
1777   powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1778   got_base = powerpc_initial_got_size;
1779   got_base = (got_base + 3) &~ 3;
1780
1781   stubcount = 0;
1782
1783   symcount = *symcount_ptr;
1784   for (i = 0; i < symcount; i++)
1785     {
1786       asymbol *sym;
1787       asymbol *newsym;
1788       char *newname;
1789       struct powerpc_stub *item;
1790
1791       sym = (*symbols_ptr)[i];
1792
1793       /* We must make a stub for every undefined symbol whose name
1794          starts with '.'.  */
1795       if (bfd_asymbol_name (sym)[0] != '.'
1796           || bfd_get_section (sym) != &bfd_und_section)
1797         continue;
1798
1799       /* Make a new undefined symbol with the same name but without
1800          the leading `.'.  */
1801       newsym = (asymbol *) xmalloc (sizeof (asymbol));
1802       *newsym = *sym;
1803       newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1804       strcpy (newname, bfd_asymbol_name (sym) + 1);
1805       newsym->name = newname;
1806
1807       /* Define the `.' symbol to be in the stub section.  */
1808       sym->section = stub_sec;
1809       sym->value = stubcount * POWERPC_STUB_SIZE;
1810       /* We set the BSF_DYNAMIC flag here so that we can check it when
1811          we are mangling relocs.  FIXME: This is a hack.  */
1812       sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1813
1814       /* Add this stub to the linked list.  */
1815       item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1816       item->start = sym;
1817       item->reloc = newsym;
1818       item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1819
1820       item->next = powerpc_stubs;
1821       powerpc_stubs = item;
1822       
1823       ++stubcount;
1824     }
1825
1826   if (stubcount > 0)
1827     {
1828       asymbol **s;
1829       struct powerpc_stub *l;
1830
1831       /* Add the new symbols we just created to the symbol table.  */
1832       *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1833                                             ((symcount + stubcount)
1834                                              * sizeof (asymbol)));
1835       *symcount_ptr += stubcount;
1836       s = &(*symbols_ptr)[symcount];
1837       for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1838         *s++ = l->reloc;
1839
1840       /* Set the size of the .stubs section and increase the size of
1841          the .got section.  */
1842       if (! bfd_set_section_size (inbfd, stub_sec,
1843                                   stubcount * POWERPC_STUB_SIZE)
1844           || ! bfd_set_section_size (inbfd, got_sec,
1845                                      (got_base
1846                                       + (stubcount
1847                                          * POWERPC_STUB_TOC_ENTRY_SIZE))))
1848         bfd_fatal ("stub section sizes");
1849     }
1850
1851   /* PowerPC NetWare requires a custom header.  We create it here.
1852      The first word is the header version number, currently 1.  The
1853      second word is the timestamp of the input file.  */
1854   memcpy (nlm_custom_header (outbfd)->stamp, "CuStHeAd", 8);
1855   nlm_custom_header (outbfd)->dataLength = 8;
1856   nlm_custom_header (outbfd)->data = xmalloc (8);
1857   bfd_h_put_32 (outbfd, (bfd_vma) 1,
1858                 (bfd_byte *) nlm_custom_header (outbfd)->data);
1859   {
1860     struct stat s;
1861
1862     if (stat (bfd_get_filename (inbfd), &s) < 0)
1863       s.st_mtime = 0;
1864     bfd_h_put_32 (outbfd, (bfd_vma) s.st_mtime,
1865                   (bfd_byte *) nlm_custom_header (outbfd)->data + 4);
1866   }
1867 }
1868
1869 /* Resolve all the stubs for PowerPC NetWare.  We fill in the contents
1870    of the output section, and create new relocs in the TOC.  */
1871
1872 static void
1873 powerpc_resolve_stubs (inbfd, outbfd)
1874      bfd *inbfd;
1875      bfd *outbfd;
1876 {
1877   bfd_byte buf[POWERPC_STUB_SIZE];
1878   unsigned int i;
1879   unsigned int stubcount;
1880   arelent **relocs;
1881   asection *got_sec;
1882   arelent **r;
1883   struct powerpc_stub *l;
1884
1885   if (powerpc_stubs == (struct powerpc_stub *) NULL)
1886     return;
1887
1888   for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1889     bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1890
1891   got_sec = bfd_get_section_by_name (inbfd, ".got");
1892   assert (got_sec != (asection *) NULL);
1893   assert (got_sec->output_section->orelocation == (arelent **) NULL);
1894
1895   stubcount = 0;
1896   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1897     ++stubcount;
1898   relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1899
1900   r = relocs;
1901   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1902     {
1903       arelent *reloc;
1904
1905       /* Adjust the first instruction to use the right TOC index.  */
1906       bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1907
1908       /* Write this stub out.  */
1909       if (! bfd_set_section_contents (outbfd,
1910                                       bfd_get_section (l->start),
1911                                       buf,
1912                                       l->start->value,
1913                                       POWERPC_STUB_SIZE))
1914         bfd_fatal ("writing stub");
1915
1916       /* Create a new reloc for the TOC entry.  */
1917       reloc = (arelent *) xmalloc (sizeof (arelent));
1918       reloc->sym_ptr_ptr = &l->reloc;
1919       reloc->address = l->toc_index + got_sec->output_offset;
1920       reloc->addend = 0;
1921       reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1922                                       
1923       *r++ = reloc;
1924     }
1925
1926   bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1927 }
1928
1929 /* Adjust relocation entries for PowerPC NetWare.  We do not output
1930    TOC relocations.  The object code already contains the offset from
1931    the TOC pointer.  When the function is called, the TOC register,
1932    r2, will be set to the correct TOC value, so there is no need for
1933    any further reloc.  */
1934
1935 /*ARGSUSED*/
1936 static void
1937 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1938                        contents_size)
1939      bfd *outbfd;
1940      asection *insec;
1941      register arelent ***relocs_ptr;
1942      long *reloc_count_ptr;
1943      char *contents;
1944      bfd_size_type contents_size;
1945 {
1946   const reloc_howto_type *toc_howto;
1947   long reloc_count;
1948   register arelent **relocs;
1949   register long i;
1950
1951   toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1952   if (toc_howto == (reloc_howto_type *) NULL)
1953     abort ();
1954
1955   /* If this is the .got section, clear out all the contents beyond
1956      the initial size.  We must do this here because copy_sections is
1957      going to write out whatever we return in the contents field.  */
1958   if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1959     memset (contents + powerpc_initial_got_size, 0,
1960             (bfd_get_section_size_after_reloc (insec)
1961              - powerpc_initial_got_size));
1962
1963   reloc_count = *reloc_count_ptr;
1964   relocs = *relocs_ptr;
1965   for (i = 0; i < reloc_count; i++)
1966     {
1967       arelent *rel;
1968       asymbol *sym;
1969       bfd_vma symvalue;
1970
1971       rel = *relocs++;
1972       sym = *rel->sym_ptr_ptr;
1973
1974       /* We must be able to resolve all PC relative relocs at this
1975          point.  If we get a branch to an undefined symbol we build a
1976          stub, since NetWare will resolve undefined symbols into a
1977          pointer to a function descriptor.  */
1978       if (rel->howto->pc_relative)
1979         {
1980           /* This check for whether a symbol is in the same section as
1981              the reloc will be wrong if there is a PC relative reloc
1982              between two sections both of which were placed in the
1983              same output section.  This should not happen.  */
1984           if (bfd_get_section (sym) != insec->output_section)
1985             fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1986                      program_name, bfd_asymbol_name (sym));
1987           else
1988             {
1989               bfd_vma val;
1990
1991               assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1992               val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1993               val = ((val &~ rel->howto->dst_mask)
1994                      | (((val & rel->howto->src_mask)
1995                          + (sym->value - rel->address)
1996                          + rel->addend)
1997                         & rel->howto->dst_mask));
1998               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1999
2000               /* If this reloc is against an stubbed symbol and the
2001                  next instruction is
2002                      cror 31,31,31
2003                  then we replace the next instruction with
2004                      lwz  r2,20(r1)
2005                  This reloads the TOC pointer after a stub call.  */
2006               if (bfd_asymbol_name (sym)[0] == '.'
2007                   && (sym->flags & BSF_DYNAMIC) != 0
2008                   && (bfd_get_32 (outbfd,
2009                                   (bfd_byte *) contents + rel->address + 4)
2010                       == 0x4ffffb82)) /* cror 31,31,31 */
2011                 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
2012                             (bfd_byte *) contents + rel->address + 4);
2013
2014               --*reloc_count_ptr;
2015               --relocs;
2016               memmove (relocs, relocs + 1,
2017                        (size_t) ((reloc_count - 1) * sizeof (arelent *)));
2018               continue;
2019             }
2020         }
2021
2022       /* When considering a TOC reloc, we do not want to include the
2023          symbol value.  The symbol will be start of the TOC section
2024          (which is named .got).  We do want to include the addend.  */
2025       if (rel->howto == toc_howto)
2026         symvalue = 0;
2027       else
2028         symvalue = sym->value;
2029
2030       /* If this is a relocation against a symbol with a value, or
2031          there is a reloc addend, we need to update the addend in the
2032          object file.  */
2033       if (symvalue + rel->addend != 0)
2034         {
2035           bfd_vma val;
2036
2037           switch (rel->howto->size)
2038             {
2039             case 1:
2040               val = bfd_get_16 (outbfd,
2041                                 (bfd_byte *) contents + rel->address);
2042               val = ((val &~ rel->howto->dst_mask)
2043                      | (((val & rel->howto->src_mask)
2044                          + symvalue
2045                          + rel->addend)
2046                         & rel->howto->dst_mask));
2047               if ((bfd_signed_vma) val < - 0x8000
2048                   || (bfd_signed_vma) val >= 0x8000)
2049                 fprintf (stderr,
2050                          "%s: overflow when adjusting relocation against %s\n",
2051                          program_name, bfd_asymbol_name (sym));
2052               bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2053               break;
2054
2055             case 2:
2056               val = bfd_get_32 (outbfd,
2057                                 (bfd_byte *) contents + rel->address);
2058               val = ((val &~ rel->howto->dst_mask)
2059                      | (((val & rel->howto->src_mask)
2060                          + symvalue
2061                          + rel->addend)
2062                         & rel->howto->dst_mask));
2063               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2064               break;
2065
2066             default:
2067               abort ();
2068             }
2069
2070           rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2071           rel->addend = 0;
2072         }
2073
2074       /* Now that we have incorporated the addend, remove any TOC
2075          relocs.  */
2076       if (rel->howto == toc_howto)
2077         {
2078           --*reloc_count_ptr;
2079           --relocs;
2080           memmove (relocs, relocs + 1,
2081                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
2082           continue;
2083         }
2084
2085       rel->address += insec->output_offset;
2086     }
2087 }
2088 /* end-sanitize-powerpc-netware */
2089 \f
2090 /* Name of linker.  */
2091 #ifndef LD_NAME
2092 #define LD_NAME "ld"
2093 #endif
2094
2095 /* Temporary file name base.  */
2096 static char *temp_filename;
2097
2098 /* The user has specified several input files.  Invoke the linker to
2099    link them all together, and convert and delete the resulting output
2100    file.  */
2101
2102 static char *
2103 link_inputs (inputs, ld)
2104      struct string_list *inputs;
2105      char *ld;
2106 {
2107   size_t c;
2108   struct string_list *q;
2109   char **argv;
2110   size_t i;
2111   int pid;
2112   int status;
2113
2114   c = 0;
2115   for (q = inputs; q != NULL; q = q->next)
2116     ++c;
2117
2118   argv = (char **) alloca (c + 5);
2119
2120 #ifndef __MSDOS__
2121   if (ld == NULL)
2122     {
2123       char *p;
2124
2125       /* Find the linker to invoke based on how nlmconv was run.  */
2126       p = program_name + strlen (program_name);
2127       while (p != program_name)
2128         {
2129           if (p[-1] == '/')
2130             {
2131               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2132               memcpy (ld, program_name, p - program_name);
2133               strcpy (ld + (p - program_name), LD_NAME);
2134               break;
2135             }
2136           --p;
2137         }
2138     }
2139 #endif
2140
2141   if (ld == NULL)
2142     ld = (char *) LD_NAME;
2143
2144   choose_temp_base ();
2145
2146   unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2147   sprintf (unlink_on_exit, "%s.O", temp_filename);
2148
2149   argv[0] = ld;
2150   argv[1] = (char *) "-r";
2151   argv[2] = (char *) "-o";
2152   argv[3] = unlink_on_exit;
2153   i = 4;
2154   for (q = inputs; q != NULL; q = q->next, i++)
2155     argv[i] = q->string;
2156   argv[i] = NULL;
2157
2158   if (debug)
2159     {
2160       for (i = 0; argv[i] != NULL; i++)
2161         fprintf (stderr, " %s", argv[i]);
2162       fprintf (stderr, "\n");
2163     }
2164
2165   pid = pexecute (ld, argv);
2166
2167   if (waitpid (pid, &status, 0) < 0)
2168     {
2169       perror ("waitpid");
2170       unlink (unlink_on_exit);
2171       exit (1);
2172     }
2173
2174   if (status != 0)
2175     {
2176       fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2177       unlink (unlink_on_exit);
2178       exit (1);
2179     }
2180
2181   return unlink_on_exit;
2182 }
2183
2184 /* Choose a temporary file name.  Stolen from gcc.c.  */
2185
2186 static const char *
2187 choose_temp_base_try (try, base)
2188      const char *try;
2189      const char *base;
2190 {
2191   const char *rv;
2192
2193   if (base)
2194     rv = base;
2195   else if (try == NULL)
2196     rv = NULL;
2197   else if (access (try, R_OK | W_OK) != 0)
2198     rv = NULL;
2199   else
2200     rv = try;
2201   return rv;
2202 }
2203
2204 static void
2205 choose_temp_base ()
2206 {
2207   const char *base = NULL;
2208   int len;
2209
2210   base = choose_temp_base_try (getenv ("TMPDIR"), base);
2211   base = choose_temp_base_try (getenv ("TMP"), base);
2212   base = choose_temp_base_try (getenv ("TEMP"), base);
2213
2214 #ifdef P_tmpdir
2215   base = choose_temp_base_try (P_tmpdir, base);
2216 #endif
2217
2218   base = choose_temp_base_try ("/usr/tmp", base);
2219   base = choose_temp_base_try ("/tmp", base);
2220
2221   /* If all else fails, use the current directory! */  
2222   if (base == NULL)
2223     base = "./";
2224
2225   len = strlen (base);
2226   temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2227   strcpy (temp_filename, base);
2228   if (len > 0 && temp_filename[len-1] != '/')
2229     temp_filename[len++] = '/';
2230   strcpy (temp_filename + len, "ccXXXXXX");
2231
2232   mktemp (temp_filename);
2233   if (*temp_filename == '\0')
2234     abort ();
2235 }
2236
2237 /* Execute a job.  Stolen from gcc.c.  */
2238
2239 #ifndef OS2
2240 #ifdef __MSDOS__
2241
2242 static int
2243 pexecute (program, argv)
2244      char *program;
2245      char *argv[];
2246 {
2247   char *scmd, *rf;
2248   FILE *argfile;
2249   int i;
2250
2251   scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2252   rf = scmd + strlen(program) + 2 + el;
2253   sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2254   argfile = fopen (rf, "w");
2255   if (argfile == 0)
2256     pfatal_with_name (rf);
2257
2258   for (i=1; argv[i]; i++)
2259     {
2260       char *cp;
2261       for (cp = argv[i]; *cp; cp++)
2262         {
2263           if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2264             fputc ('\\', argfile);
2265           fputc (*cp, argfile);
2266         }
2267       fputc ('\n', argfile);
2268     }
2269   fclose (argfile);
2270
2271   i = system (scmd);
2272
2273   remove (rf);
2274   
2275   if (i == -1)
2276     {
2277       perror (program);
2278       return MIN_FATAL_STATUS << 8;
2279     }
2280
2281   return i << 8;
2282 }
2283
2284 #else /* not __MSDOS__ */
2285
2286 static int
2287 pexecute (program, argv)
2288      char *program;
2289      char *argv[];
2290 {
2291   int pid;
2292   int retries, sleep_interval;
2293
2294   /* Fork a subprocess; wait and retry if it fails.  */
2295   sleep_interval = 1;
2296   for (retries = 0; retries < 4; retries++)
2297     {
2298       pid = vfork ();
2299       if (pid >= 0)
2300         break;
2301       sleep (sleep_interval);
2302       sleep_interval *= 2;
2303     }
2304
2305   switch (pid)
2306     {
2307     case -1:
2308 #ifdef vfork
2309       perror ("fork");
2310 #else
2311       perror ("vfork");
2312 #endif
2313       exit (1);
2314       /* NOTREACHED */
2315       return 0;
2316
2317     case 0: /* child */
2318       /* Exec the program.  */
2319       execvp (program, argv);
2320       perror (program);
2321       exit (1);
2322       /* NOTREACHED */
2323       return 0;
2324
2325     default:
2326       /* Return child's process number.  */
2327       return pid;
2328     }
2329 }
2330
2331 #endif /* not __MSDOS__ */
2332 #else /* not OS2 */
2333
2334 static int
2335 pexecute (program, argv)
2336      char *program;
2337      char *argv[];
2338 {
2339   return spawnvp (1, program, argv);
2340 }
2341 #endif /* not OS2 */