2002-02-10 Daniel Jacobowitz <drow@mvista.com>
[external/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 PARAMS ((const time_t *));
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 PARAMS ((FILE *, int));
128 static const char *select_output_format PARAMS ((enum bfd_architecture,
129                                                  unsigned long, boolean));
130 static void setup_sections PARAMS ((bfd *, asection *, PTR));
131 static void copy_sections PARAMS ((bfd *, asection *, PTR));
132 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
133                                    long *, char *,
134                                    bfd_size_type));
135 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
136                                            long *, char *,
137                                            bfd_size_type));
138 static char *link_inputs PARAMS ((struct string_list *, char *));
139
140 #ifdef NLMCONV_I386
141 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
142                                         long *, char *,
143                                         bfd_size_type));
144 #endif
145
146 #ifdef NLMCONV_ALPHA
147 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
148                                          long *, char *,
149                                          bfd_size_type));
150 #endif
151
152 #ifdef NLMCONV_POWERPC
153 static void powerpc_build_stubs PARAMS ((bfd *, bfd *, asymbol ***, long *));
154 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
155 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
156                                            long *, char *,
157                                            bfd_size_type));
158 #endif
159 \f
160 /* The main routine.  */
161
162 int
163 main (argc, argv)
164      int argc;
165      char **argv;
166 {
167   int opt;
168   char *input_file = NULL;
169   const char *input_format = NULL;
170   const char *output_format = NULL;
171   const char *header_file = NULL;
172   char *ld_arg = NULL;
173   Nlm_Internal_Fixed_Header fixed_hdr_struct;
174   Nlm_Internal_Variable_Header var_hdr_struct;
175   Nlm_Internal_Version_Header version_hdr_struct;
176   Nlm_Internal_Copyright_Header copyright_hdr_struct;
177   Nlm_Internal_Extended_Header extended_hdr_struct;
178   bfd *inbfd;
179   bfd *outbfd;
180   asymbol **newsyms, **outsyms;
181   long symcount, newsymalloc, newsymcount;
182   long symsize;
183   asection *text_sec, *bss_sec, *data_sec;
184   bfd_vma vma;
185   bfd_size_type align;
186   asymbol *endsym;
187   long i;
188   char inlead, outlead;
189   boolean gotstart, gotexit, gotcheck;
190   struct stat st;
191   FILE *custom_data = NULL;
192   FILE *help_data = NULL;
193   FILE *message_data = NULL;
194   FILE *rpc_data = NULL;
195   FILE *shared_data = NULL;
196   size_t custom_size = 0;
197   size_t help_size = 0;
198   size_t message_size = 0;
199   size_t module_size = 0;
200   size_t rpc_size = 0;
201   asection *custom_section = NULL;
202   asection *help_section = NULL;
203   asection *message_section = NULL;
204   asection *module_section = NULL;
205   asection *rpc_section = NULL;
206   asection *shared_section = NULL;
207   bfd *sharedbfd;
208   size_t shared_offset = 0;
209   size_t shared_size = 0;
210   Nlm_Internal_Fixed_Header sharedhdr;
211   int len;
212   char *modname;
213   char **matching;
214
215 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
216   setlocale (LC_MESSAGES, "");
217 #endif
218 #if defined (HAVE_SETLOCALE)
219   setlocale (LC_CTYPE, "");
220 #endif
221   bindtextdomain (PACKAGE, LOCALEDIR);
222   textdomain (PACKAGE);
223
224   program_name = argv[0];
225   xmalloc_set_program_name (program_name);
226
227   bfd_init ();
228   set_default_bfd_target ();
229
230   while ((opt = getopt_long (argc, argv, "dHhI:l:O:T:Vv", long_options,
231                              (int *) NULL))
232          != EOF)
233     {
234       switch (opt)
235         {
236         case 'd':
237           debug = 1;
238           break;
239         case 'H':
240         case 'h':
241           show_usage (stdout, 0);
242           break;
243         case 'I':
244           input_format = optarg;
245           break;
246         case 'l':
247           ld_arg = optarg;
248           break;
249         case 'O':
250           output_format = optarg;
251           break;
252         case 'T':
253           header_file = optarg;
254           break;
255         case 'v':
256         case 'V':
257           print_version ("nlmconv");
258           break;
259         case 0:
260           break;
261         default:
262           show_usage (stderr, 1);
263           break;
264         }
265     }
266
267   /* The input and output files may be named on the command line.  */
268   output_file = NULL;
269   if (optind < argc)
270     {
271       input_file = argv[optind];
272       ++optind;
273       if (optind < argc)
274         {
275           output_file = argv[optind];
276           ++optind;
277           if (optind < argc)
278             show_usage (stderr, 1);
279           if (strcmp (input_file, output_file) == 0)
280             {
281               fatal (_("input and output files must be different"));
282             }
283         }
284     }
285
286   /* Initialize the header information to default values.  */
287   fixed_hdr = &fixed_hdr_struct;
288   memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
289   var_hdr = &var_hdr_struct;
290   memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
291   version_hdr = &version_hdr_struct;
292   memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
293   copyright_hdr = &copyright_hdr_struct;
294   memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
295   extended_hdr = &extended_hdr_struct;
296   memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
297   check_procedure = NULL;
298   custom_file = NULL;
299   debug_info = false;
300   exit_procedure = "_Stop";
301   export_symbols = NULL;
302   map_file = NULL;
303   full_map = false;
304   help_file = NULL;
305   import_symbols = NULL;
306   message_file = NULL;
307   modules = NULL;
308   sharelib_file = NULL;
309   start_procedure = "_Prelude";
310   verbose = false;
311   rpc_file = NULL;
312
313   parse_errors = 0;
314
315   /* Parse the header file (if there is one).  */
316   if (header_file != NULL)
317     {
318       if (! nlmlex_file (header_file)
319           || yyparse () != 0
320           || parse_errors != 0)
321         exit (1);
322     }
323
324   if (input_files != NULL)
325     {
326       if (input_file != NULL)
327         {
328           fatal (_("input file named both on command line and with INPUT"));
329         }
330       if (input_files->next == NULL)
331         input_file = input_files->string;
332       else
333         input_file = link_inputs (input_files, ld_arg);
334     }
335   else if (input_file == NULL)
336     {
337       non_fatal (_("no input file"));
338       show_usage (stderr, 1);
339     }
340
341   inbfd = bfd_openr (input_file, input_format);
342   if (inbfd == NULL)
343     bfd_fatal (input_file);
344
345   if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
346     {
347       bfd_nonfatal (input_file);
348       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
349         {
350           list_matching_formats (matching);
351           free (matching);
352         }
353       exit (1);
354     }
355
356   if (output_format == NULL)
357     output_format = select_output_format (bfd_get_arch (inbfd),
358                                           bfd_get_mach (inbfd),
359                                           bfd_big_endian (inbfd));
360
361   assert (output_format != NULL);
362
363   /* Use the output file named on the command line if it exists.
364      Otherwise use the file named in the OUTPUT statement.  */
365   if (output_file == NULL)
366     {
367       non_fatal (_("no name for output file"));
368       show_usage (stderr, 1);
369     }
370
371   outbfd = bfd_openw (output_file, output_format);
372   if (outbfd == NULL)
373     bfd_fatal (output_file);
374   if (! bfd_set_format (outbfd, bfd_object))
375     bfd_fatal (output_file);
376
377   assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
378
379   if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
380     non_fatal (_("warning: input and output formats are not compatible"));
381
382   /* Move the values read from the command file into outbfd.  */
383   *nlm_fixed_header (outbfd) = fixed_hdr_struct;
384   *nlm_variable_header (outbfd) = var_hdr_struct;
385   *nlm_version_header (outbfd) = version_hdr_struct;
386   *nlm_copyright_header (outbfd) = copyright_hdr_struct;
387   *nlm_extended_header (outbfd) = extended_hdr_struct;
388
389   /* Start copying the input BFD to the output BFD.  */
390   if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
391     bfd_fatal (bfd_get_filename (outbfd));
392
393   symsize = bfd_get_symtab_upper_bound (inbfd);
394   if (symsize < 0)
395     bfd_fatal (input_file);
396   symbols = (asymbol **) xmalloc (symsize);
397   symcount = bfd_canonicalize_symtab (inbfd, symbols);
398   if (symcount < 0)
399     bfd_fatal (input_file);
400
401   /* Make sure we have a .bss section.  */
402   bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
403   if (bss_sec == NULL)
404     {
405       bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
406       if (bss_sec == NULL
407           || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
408           || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
409         bfd_fatal (_("make .bss section"));
410     }
411
412   /* We store the original section names in the .nlmsections section,
413      so that programs which understand it can resurrect the original
414      sections from the NLM.  We will put a pointer to .nlmsections in
415      the NLM header area.  */
416   secsec = bfd_make_section (outbfd, ".nlmsections");
417   if (secsec == NULL)
418     bfd_fatal (_("make .nlmsections section"));
419   if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
420     bfd_fatal (_("set .nlmsections flags"));
421
422 #ifdef NLMCONV_POWERPC
423   /* For PowerPC NetWare we need to build stubs for calls to undefined
424      symbols.  Because each stub requires an entry in the TOC section
425      which must be at the same location as other entries in the TOC
426      section, we must do this before determining where the TOC section
427      goes in setup_sections.  */
428   if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
429     powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
430 #endif
431
432   /* Set up the sections.  */
433   bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
434
435   text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
436
437   /* The .bss section immediately follows the .data section.  */
438   data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
439   if (data_sec != NULL)
440     {
441       bfd_size_type add;
442
443       vma = bfd_get_section_size_before_reloc (data_sec);
444       align = 1 << bss_sec->alignment_power;
445       add = ((vma + align - 1) &~ (align - 1)) - vma;
446       vma += add;
447       if (! bfd_set_section_vma (outbfd, bss_sec, vma))
448         bfd_fatal (_("set .bss vma"));
449       if (add != 0)
450         {
451           bfd_size_type data_size;
452
453           data_size = bfd_get_section_size_before_reloc (data_sec);
454           if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
455             bfd_fatal (_("set .data size"));
456         }
457     }
458
459   /* Adjust symbol information.  */
460   inlead = bfd_get_symbol_leading_char (inbfd);
461   outlead = bfd_get_symbol_leading_char (outbfd);
462   gotstart = false;
463   gotexit = false;
464   gotcheck = false;
465   newsymalloc = 10;
466   newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
467   newsymcount = 0;
468   endsym = NULL;
469   for (i = 0; i < symcount; i++)
470     {
471       register asymbol *sym;
472
473       sym = symbols[i];
474
475       /* Add or remove a leading underscore.  */
476       if (inlead != outlead)
477         {
478           if (inlead != '\0')
479             {
480               if (bfd_asymbol_name (sym)[0] == inlead)
481                 {
482                   if (outlead == '\0')
483                     ++sym->name;
484                   else
485                     {
486                       char *new;
487
488                       new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
489                       new[0] = outlead;
490                       strcpy (new + 1, bfd_asymbol_name (sym) + 1);
491                       sym->name = new;
492                     }
493                 }
494             }
495           else
496             {
497               char *new;
498
499               new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
500               new[0] = outlead;
501               strcpy (new + 1, bfd_asymbol_name (sym));
502               sym->name = new;
503             }
504         }
505
506       /* NLM's have an uninitialized data section, but they do not
507          have a common section in the Unix sense.  Move all common
508          symbols into the .bss section, and mark them as exported.  */
509       if (bfd_is_com_section (bfd_get_section (sym)))
510         {
511           bfd_vma size;
512
513           sym->section = bss_sec;
514           size = sym->value;
515           sym->value = bss_sec->_raw_size;
516           bss_sec->_raw_size += size;
517           align = 1 << bss_sec->alignment_power;
518           bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
519           sym->flags |= BSF_EXPORT | BSF_GLOBAL;
520         }
521       else if (bfd_get_section (sym)->output_section != NULL)
522         {
523           /* Move the symbol into the output section.  */
524           sym->value += bfd_get_section (sym)->output_offset;
525           sym->section = bfd_get_section (sym)->output_section;
526           /* This is no longer a section symbol.  */
527           sym->flags &=~ BSF_SECTION_SYM;
528         }
529
530       /* Force _edata and _end to be defined.  This would normally be
531          done by the linker, but the manipulation of the common
532          symbols will confuse it.  */
533       if ((sym->flags & BSF_DEBUGGING) == 0
534           && bfd_asymbol_name (sym)[0] == '_'
535           && bfd_is_und_section (bfd_get_section (sym)))
536         {
537           if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
538             {
539               sym->section = bss_sec;
540               sym->value = 0;
541             }
542           if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
543             {
544               sym->section = bss_sec;
545               endsym = sym;
546             }
547
548 #ifdef NLMCONV_POWERPC
549           /* For PowerPC NetWare, we define __GOT0.  This is the start
550              of the .got section.  */
551           if (bfd_get_arch (inbfd) == bfd_arch_powerpc
552               && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
553             {
554               asection *got_sec;
555
556               got_sec = bfd_get_section_by_name (inbfd, ".got");
557               assert (got_sec != (asection *) NULL);
558               sym->value = got_sec->output_offset;
559               sym->section = got_sec->output_section;
560             }
561 #endif
562         }
563
564       /* If this is a global symbol, check the export list.  */
565       if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
566         {
567           register struct string_list *l;
568           int found_simple;
569
570           /* Unfortunately, a symbol can appear multiple times on the
571              export list, with and without prefixes.  */
572           found_simple = 0;
573           for (l = export_symbols; l != NULL; l = l->next)
574             {
575               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
576                 found_simple = 1;
577               else
578                 {
579                   char *zbase;
580
581                   zbase = strchr (l->string, '@');
582                   if (zbase != NULL
583                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
584                     {
585                       /* We must add a symbol with this prefix.  */
586                       if (newsymcount >= newsymalloc)
587                         {
588                           newsymalloc += 10;
589                           newsyms = ((asymbol **)
590                                      xrealloc ((PTR) newsyms,
591                                                (newsymalloc
592                                                 * sizeof (asymbol *))));
593                         }
594                       newsyms[newsymcount] =
595                         (asymbol *) xmalloc (sizeof (asymbol));
596                       *newsyms[newsymcount] = *sym;
597                       newsyms[newsymcount]->name = l->string;
598                       ++newsymcount;
599                     }
600                 }
601             }
602           if (! found_simple)
603             {
604               /* The unmodified symbol is actually not exported at
605                  all.  */
606               sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
607               sym->flags |= BSF_LOCAL;
608             }
609         }
610
611       /* If it's an undefined symbol, see if it's on the import list.
612          Change the prefix if necessary.  */
613       if (bfd_is_und_section (bfd_get_section (sym)))
614         {
615           register struct string_list *l;
616
617           for (l = import_symbols; l != NULL; l = l->next)
618             {
619               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
620                 break;
621               else
622                 {
623                   char *zbase;
624
625                   zbase = strchr (l->string, '@');
626                   if (zbase != NULL
627                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
628                     {
629                       sym->name = l->string;
630                       break;
631                     }
632                 }
633             }
634           if (l == NULL)
635             non_fatal (_("warning: symbol %s imported but not in import list"),
636                        bfd_asymbol_name (sym));
637         }
638         
639       /* See if it's one of the special named symbols.  */
640       if ((sym->flags & BSF_DEBUGGING) == 0)
641         {
642           bfd_vma val;
643
644           /* FIXME: If these symbols are not in the .text section, we
645              add the .text section size to the value.  This may not be
646              correct for all targets.  I'm not sure how this should
647              really be handled.  */
648           if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
649             {
650               val = bfd_asymbol_value (sym);
651               if (bfd_get_section (sym) == data_sec
652                   && text_sec != (asection *) NULL)
653                 val += bfd_section_size (outbfd, text_sec);
654               if (! bfd_set_start_address (outbfd, val))
655                 bfd_fatal (_("set start address"));
656               gotstart = true;
657             }
658           if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
659             {
660               val = bfd_asymbol_value (sym);
661               if (bfd_get_section (sym) == data_sec
662                   && text_sec != (asection *) NULL)
663                 val += bfd_section_size (outbfd, text_sec);
664               nlm_fixed_header (outbfd)->exitProcedureOffset = val;
665               gotexit = true;
666             }
667           if (check_procedure != NULL
668               && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
669             {
670               val = bfd_asymbol_value (sym);
671               if (bfd_get_section (sym) == data_sec
672                   && text_sec != (asection *) NULL)
673                 val += bfd_section_size (outbfd, text_sec);
674               nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
675               gotcheck = true;
676             }
677         }
678     }
679
680   if (endsym != NULL)
681     {
682       endsym->value = bfd_get_section_size_before_reloc (bss_sec);
683
684       /* FIXME: If any relocs referring to _end use inplace addends,
685          then I think they need to be updated.  This is handled by
686          i386_mangle_relocs.  Is it needed for any other object
687          formats?  */
688     }
689
690   if (newsymcount == 0)
691     outsyms = symbols;
692   else
693     {
694       outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
695                                       * sizeof (asymbol *));
696       memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
697       memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
698       outsyms[symcount + newsymcount] = NULL;
699     }
700
701   bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
702     
703   if (! gotstart)
704     non_fatal (_("warning: START procedure %s not defined"), start_procedure);
705   if (! gotexit)
706     non_fatal (_("warning: EXIT procedure %s not defined"), exit_procedure);
707   if (check_procedure != NULL && ! gotcheck)
708     non_fatal (_("warning: CHECK procedure %s not defined"), check_procedure);
709
710   /* Add additional sections required for the header information.  */
711   if (custom_file != NULL)
712     {
713       custom_data = fopen (custom_file, "r");
714       if (custom_data == NULL
715           || fstat (fileno (custom_data), &st) < 0)
716         {
717           fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
718                    strerror (errno));
719           custom_file = NULL;
720         }
721       else
722         {
723           custom_size = st.st_size;
724           custom_section = bfd_make_section (outbfd, ".nlmcustom");
725           if (custom_section == NULL
726               || ! bfd_set_section_size (outbfd, custom_section, custom_size)
727               || ! bfd_set_section_flags (outbfd, custom_section,
728                                           SEC_HAS_CONTENTS))
729             bfd_fatal (_("custom section"));
730         }
731     }
732   if (help_file != NULL)
733     {
734       help_data = fopen (help_file, "r");
735       if (help_data == NULL
736           || fstat (fileno (help_data), &st) < 0)
737         {
738           fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
739                    strerror (errno));
740           help_file = NULL;
741         }
742       else
743         {
744           help_size = st.st_size;
745           help_section = bfd_make_section (outbfd, ".nlmhelp");
746           if (help_section == NULL
747               || ! bfd_set_section_size (outbfd, help_section, help_size)
748               || ! bfd_set_section_flags (outbfd, help_section,
749                                           SEC_HAS_CONTENTS))
750             bfd_fatal (_("help section"));
751           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
752         }
753     }
754   if (message_file != NULL)
755     {
756       message_data = fopen (message_file, "r");
757       if (message_data == NULL
758           || fstat (fileno (message_data), &st) < 0)
759         {
760           fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
761                    strerror (errno));
762           message_file = NULL;
763         }
764       else
765         {
766           message_size = st.st_size;
767           message_section = bfd_make_section (outbfd, ".nlmmessages");
768           if (message_section == NULL
769               || ! bfd_set_section_size (outbfd, message_section, message_size)
770               || ! bfd_set_section_flags (outbfd, message_section,
771                                           SEC_HAS_CONTENTS))
772             bfd_fatal (_("message section"));
773           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
774         }
775     }
776   if (modules != NULL)
777     {
778       struct string_list *l;
779
780       module_size = 0;
781       for (l = modules; l != NULL; l = l->next)
782         module_size += strlen (l->string) + 1;
783       module_section = bfd_make_section (outbfd, ".nlmmodules");
784       if (module_section == NULL
785           || ! bfd_set_section_size (outbfd, module_section, module_size)
786           || ! bfd_set_section_flags (outbfd, module_section,
787                                       SEC_HAS_CONTENTS))
788         bfd_fatal (_("module section"));
789     }
790   if (rpc_file != NULL)
791     {
792       rpc_data = fopen (rpc_file, "r");
793       if (rpc_data == NULL
794           || fstat (fileno (rpc_data), &st) < 0)
795         {
796           fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
797                    strerror (errno));
798           rpc_file = NULL;
799         }
800       else
801         {
802           rpc_size = st.st_size;
803           rpc_section = bfd_make_section (outbfd, ".nlmrpc");
804           if (rpc_section == NULL
805               || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
806               || ! bfd_set_section_flags (outbfd, rpc_section,
807                                           SEC_HAS_CONTENTS))
808             bfd_fatal (_("rpc section"));
809           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
810         }
811     }
812   if (sharelib_file != NULL)
813     {
814       sharedbfd = bfd_openr (sharelib_file, output_format);
815       if (sharedbfd == NULL
816           || ! bfd_check_format (sharedbfd, bfd_object))
817         {
818           fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
819                    bfd_errmsg (bfd_get_error ()));
820           sharelib_file = NULL;
821         }
822       else
823         {
824           sharedhdr = *nlm_fixed_header (sharedbfd);
825           bfd_close (sharedbfd);
826           shared_data = fopen (sharelib_file, "r");
827           if (shared_data == NULL
828               || (fstat (fileno (shared_data), &st) < 0))
829             {
830               fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
831                        strerror (errno));
832               sharelib_file = NULL;
833             }
834           else
835             {
836               /* If we were clever, we could just copy out the
837                  sections of the shared library which we actually
838                  need.  However, we would have to figure out the sizes
839                  of the external and public information, and that can
840                  not be done without reading through them.  */
841               if (sharedhdr.uninitializedDataSize > 0)
842                 {
843                   /* There is no place to record this information.  */
844                   non_fatal (_("%s: warning: shared libraries can not have uninitialized data"),
845                              sharelib_file);
846                 }
847               shared_offset = st.st_size;
848               if (shared_offset > (size_t) sharedhdr.codeImageOffset)
849                 shared_offset = sharedhdr.codeImageOffset;
850               if (shared_offset > (size_t) sharedhdr.dataImageOffset)
851                 shared_offset = sharedhdr.dataImageOffset;
852               if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
853                 shared_offset = sharedhdr.relocationFixupOffset;
854               if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
855                 shared_offset = sharedhdr.externalReferencesOffset;
856               if (shared_offset > (size_t) sharedhdr.publicsOffset)
857                 shared_offset = sharedhdr.publicsOffset;
858               shared_size = st.st_size - shared_offset;
859               shared_section = bfd_make_section (outbfd, ".nlmshared");
860               if (shared_section == NULL
861                   || ! bfd_set_section_size (outbfd, shared_section,
862                                              shared_size)
863                   || ! bfd_set_section_flags (outbfd, shared_section,
864                                               SEC_HAS_CONTENTS))
865                 bfd_fatal (_("shared section"));
866               strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
867             }
868         }
869     }
870
871   /* Check whether a version was given.  */
872   if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
873     non_fatal (_("warning: No version number given"));
874
875   /* At least for now, always create an extended header, because that
876      is what NLMLINK does.  */
877   strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
878
879   strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
880
881   /* If the date was not given, force it in.  */
882   if (nlm_version_header (outbfd)->month == 0
883       && nlm_version_header (outbfd)->day == 0
884       && nlm_version_header (outbfd)->year == 0)
885     {
886       time_t now;
887       struct tm *ptm;
888
889       time (&now);
890       ptm = localtime (&now);
891       nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
892       nlm_version_header (outbfd)->day = ptm->tm_mday;
893       nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
894       strncpy (version_hdr->stamp, "VeRsIoN#", 8);
895     }
896
897 #ifdef NLMCONV_POWERPC
898   /* Resolve the stubs we build for PowerPC NetWare.  */
899   if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
900     powerpc_resolve_stubs (inbfd, outbfd);
901 #endif
902
903   /* Copy over the sections.  */
904   bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
905
906   /* Finish up the header information.  */
907   if (custom_file != NULL)
908     {
909       PTR data;
910
911       data = xmalloc (custom_size);
912       if (fread (data, 1, custom_size, custom_data) != custom_size)
913         non_fatal (_("%s: read: %s"), custom_file, strerror (errno));
914       else
915         {
916           if (! bfd_set_section_contents (outbfd, custom_section, data,
917                                           (file_ptr) 0, custom_size))
918             bfd_fatal (_("custom section"));
919           nlm_fixed_header (outbfd)->customDataOffset =
920             custom_section->filepos;
921           nlm_fixed_header (outbfd)->customDataSize = custom_size;
922         }
923       free (data);
924     }
925   if (! debug_info)
926     {
927       /* As a special hack, the backend recognizes a debugInfoOffset
928          of -1 to mean that it should not output any debugging
929          information.  This can not be handling by fiddling with the
930          symbol table because exported symbols appear in both the
931          export information and the debugging information.  */
932       nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
933     }
934   if (map_file != NULL)
935     non_fatal (_("warning: MAP and FULLMAP are not supported; try ld -M"));
936   if (help_file != NULL)
937     {
938       PTR data;
939
940       data = xmalloc (help_size);
941       if (fread (data, 1, help_size, help_data) != help_size)
942         non_fatal (_("%s: read: %s"), help_file, strerror (errno));
943       else
944         {
945           if (! bfd_set_section_contents (outbfd, help_section, data,
946                                           (file_ptr) 0, help_size))
947             bfd_fatal (_("help section"));
948           nlm_extended_header (outbfd)->helpFileOffset =
949             help_section->filepos;
950           nlm_extended_header (outbfd)->helpFileLength = help_size;
951         }
952       free (data);
953     }
954   if (message_file != NULL)
955     {
956       PTR data;
957
958       data = xmalloc (message_size);
959       if (fread (data, 1, message_size, message_data) != message_size)
960         non_fatal (_("%s: read: %s"), message_file, strerror (errno));
961       else
962         {
963           if (! bfd_set_section_contents (outbfd, message_section, data,
964                                           (file_ptr) 0, message_size))
965             bfd_fatal (_("message section"));
966           nlm_extended_header (outbfd)->messageFileOffset =
967             message_section->filepos;
968           nlm_extended_header (outbfd)->messageFileLength = message_size;
969
970           /* FIXME: Are these offsets correct on all platforms?  Are
971              they 32 bits on all platforms?  What endianness?  */
972           nlm_extended_header (outbfd)->languageID =
973             bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
974           nlm_extended_header (outbfd)->messageCount =
975             bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
976         }
977       free (data);
978     }
979   if (modules != NULL)
980     {
981       PTR data;
982       unsigned char *set;
983       struct string_list *l;
984       bfd_size_type c;
985
986       data = xmalloc (module_size);
987       c = 0;
988       set = (unsigned char *) data;
989       for (l = modules; l != NULL; l = l->next)
990         {
991           *set = strlen (l->string);
992           strncpy (set + 1, l->string, *set);
993           set += *set + 1;
994           ++c;
995         }
996       if (! bfd_set_section_contents (outbfd, module_section, data,
997                                       (file_ptr) 0, module_size))
998         bfd_fatal (_("module section"));
999       nlm_fixed_header (outbfd)->moduleDependencyOffset =
1000         module_section->filepos;
1001       nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
1002     }
1003   if (rpc_file != NULL)
1004     {
1005       PTR data;
1006
1007       data = xmalloc (rpc_size);
1008       if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
1009         non_fatal (_("%s: read: %s"), rpc_file, strerror (errno));
1010       else
1011         {
1012           if (! bfd_set_section_contents (outbfd, rpc_section, data,
1013                                           (file_ptr) 0, rpc_size))
1014             bfd_fatal (_("rpc section"));
1015           nlm_extended_header (outbfd)->RPCDataOffset =
1016             rpc_section->filepos;
1017           nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1018         }
1019       free (data);
1020     }
1021   if (sharelib_file != NULL)
1022     {
1023       PTR data;
1024
1025       data = xmalloc (shared_size);
1026       if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1027           || fread (data, 1, shared_size, shared_data) != shared_size)
1028         non_fatal (_("%s: read: %s"), sharelib_file, strerror (errno));
1029       else
1030         {
1031           if (! bfd_set_section_contents (outbfd, shared_section, data,
1032                                           (file_ptr) 0, shared_size))
1033             bfd_fatal (_("shared section"));
1034         }
1035       nlm_extended_header (outbfd)->sharedCodeOffset =
1036         sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1037       nlm_extended_header (outbfd)->sharedCodeLength =
1038         sharedhdr.codeImageSize;
1039       nlm_extended_header (outbfd)->sharedDataOffset =
1040         sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1041       nlm_extended_header (outbfd)->sharedDataLength =
1042         sharedhdr.dataImageSize;
1043       nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1044         (sharedhdr.relocationFixupOffset
1045          - shared_offset
1046          + shared_section->filepos);
1047       nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1048         sharedhdr.numberOfRelocationFixups;
1049       nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1050         (sharedhdr.externalReferencesOffset
1051          - shared_offset
1052          + shared_section->filepos);
1053       nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1054         sharedhdr.numberOfExternalReferences;
1055       nlm_extended_header (outbfd)->sharedPublicsOffset =
1056         sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1057       nlm_extended_header (outbfd)->sharedPublicsCount =
1058         sharedhdr.numberOfPublics;
1059       nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1060         sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1061       nlm_extended_header (outbfd)->sharedDebugRecordCount =
1062         sharedhdr.numberOfDebugRecords;
1063       nlm_extended_header (outbfd)->SharedInitializationOffset =
1064         sharedhdr.codeStartOffset;
1065       nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1066         sharedhdr.exitProcedureOffset;
1067       free (data);
1068     }
1069   len = strlen (output_file);
1070   if (len > NLM_MODULE_NAME_SIZE - 2)
1071     len = NLM_MODULE_NAME_SIZE - 2;
1072   nlm_fixed_header (outbfd)->moduleName[0] = len;
1073
1074   strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1075            NLM_MODULE_NAME_SIZE - 2);
1076   nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1077   for (modname = nlm_fixed_header (outbfd)->moduleName;
1078        *modname != '\0';
1079        modname++)
1080     *modname = TOUPPER (*modname);
1081
1082   strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1083            NLM_OLD_THREAD_NAME_LENGTH);
1084
1085   nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1086   nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1087
1088   if (! bfd_close (outbfd))
1089     bfd_fatal (output_file);
1090   if (! bfd_close (inbfd))
1091     bfd_fatal (input_file);
1092
1093   if (unlink_on_exit != NULL)
1094     unlink (unlink_on_exit);
1095
1096   return 0;
1097 }
1098 \f
1099
1100 /* Show a usage message and exit.  */
1101
1102 static void
1103 show_usage (file, status)
1104      FILE *file;
1105      int status;
1106 {
1107   fprintf (file, _("Usage: %s [option(s)] [in-file [out-file]]\n"), program_name);
1108   fprintf (file, _(" Convert an object file into a NetWare Loadable Module\n"));
1109   fprintf (file, _(" The options are:\n\
1110   -I --input-target=<bfdname>   Set the input binary file format\n\
1111   -O --output-target=<bfdname>  Set the output binary file format\n\
1112   -T --header-file=<file>       Read <file> for NLM header information\n\
1113   -l --linker=<linker>          Use <linker> for any linking\n\
1114   -d --debug                    Display on stderr the linker command line\n\
1115   -h --help                     Display this information\n\
1116   -v --version                  Display the program's version\n\
1117 "));
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 ATTRIBUTE_UNUSED;
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 ATTRIBUTE_UNUSED;
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 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 /*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 ATTRIBUTE_UNUSED;
1597      bfd_size_type contents_size ATTRIBUTE_UNUSED;
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 ATTRIBUTE_UNUSED;
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 ATTRIBUTE_UNUSED;
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 }