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