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