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