Change linker's default behaviour - it will now reject binary files whoes
[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 ();
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   /* XXX: Should we accept the unknown bfd format here ?  */
381   if (bfd_arch_get_compatible (inbfd, outbfd, TRUE) == NULL)
382     non_fatal (_("warning: input and output formats are not compatible"));
383
384   /* Move the values read from the command file into outbfd.  */
385   *nlm_fixed_header (outbfd) = fixed_hdr_struct;
386   *nlm_variable_header (outbfd) = var_hdr_struct;
387   *nlm_version_header (outbfd) = version_hdr_struct;
388   *nlm_copyright_header (outbfd) = copyright_hdr_struct;
389   *nlm_extended_header (outbfd) = extended_hdr_struct;
390
391   /* Start copying the input BFD to the output BFD.  */
392   if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
393     bfd_fatal (bfd_get_filename (outbfd));
394
395   symsize = bfd_get_symtab_upper_bound (inbfd);
396   if (symsize < 0)
397     bfd_fatal (input_file);
398   symbols = (asymbol **) xmalloc (symsize);
399   symcount = bfd_canonicalize_symtab (inbfd, symbols);
400   if (symcount < 0)
401     bfd_fatal (input_file);
402
403   /* Make sure we have a .bss section.  */
404   bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
405   if (bss_sec == NULL)
406     {
407       bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
408       if (bss_sec == NULL
409           || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
410           || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
411         bfd_fatal (_("make .bss section"));
412     }
413
414   /* We store the original section names in the .nlmsections section,
415      so that programs which understand it can resurrect the original
416      sections from the NLM.  We will put a pointer to .nlmsections in
417      the NLM header area.  */
418   secsec = bfd_make_section (outbfd, ".nlmsections");
419   if (secsec == NULL)
420     bfd_fatal (_("make .nlmsections section"));
421   if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
422     bfd_fatal (_("set .nlmsections flags"));
423
424 #ifdef NLMCONV_POWERPC
425   /* For PowerPC NetWare we need to build stubs for calls to undefined
426      symbols.  Because each stub requires an entry in the TOC section
427      which must be at the same location as other entries in the TOC
428      section, we must do this before determining where the TOC section
429      goes in setup_sections.  */
430   if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
431     powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
432 #endif
433
434   /* Set up the sections.  */
435   bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
436
437   text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
438
439   /* The .bss section immediately follows the .data section.  */
440   data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
441   if (data_sec != NULL)
442     {
443       bfd_size_type add;
444
445       vma = bfd_get_section_size_before_reloc (data_sec);
446       align = 1 << bss_sec->alignment_power;
447       add = ((vma + align - 1) &~ (align - 1)) - vma;
448       vma += add;
449       if (! bfd_set_section_vma (outbfd, bss_sec, vma))
450         bfd_fatal (_("set .bss vma"));
451       if (add != 0)
452         {
453           bfd_size_type data_size;
454
455           data_size = bfd_get_section_size_before_reloc (data_sec);
456           if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
457             bfd_fatal (_("set .data size"));
458         }
459     }
460
461   /* Adjust symbol information.  */
462   inlead = bfd_get_symbol_leading_char (inbfd);
463   outlead = bfd_get_symbol_leading_char (outbfd);
464   gotstart = FALSE;
465   gotexit = FALSE;
466   gotcheck = FALSE;
467   newsymalloc = 10;
468   newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
469   newsymcount = 0;
470   endsym = NULL;
471   for (i = 0; i < symcount; i++)
472     {
473       register asymbol *sym;
474
475       sym = symbols[i];
476
477       /* Add or remove a leading underscore.  */
478       if (inlead != outlead)
479         {
480           if (inlead != '\0')
481             {
482               if (bfd_asymbol_name (sym)[0] == inlead)
483                 {
484                   if (outlead == '\0')
485                     ++sym->name;
486                   else
487                     {
488                       char *new;
489
490                       new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
491                       new[0] = outlead;
492                       strcpy (new + 1, bfd_asymbol_name (sym) + 1);
493                       sym->name = new;
494                     }
495                 }
496             }
497           else
498             {
499               char *new;
500
501               new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
502               new[0] = outlead;
503               strcpy (new + 1, bfd_asymbol_name (sym));
504               sym->name = new;
505             }
506         }
507
508       /* NLM's have an uninitialized data section, but they do not
509          have a common section in the Unix sense.  Move all common
510          symbols into the .bss section, and mark them as exported.  */
511       if (bfd_is_com_section (bfd_get_section (sym)))
512         {
513           bfd_vma size;
514
515           sym->section = bss_sec;
516           size = sym->value;
517           sym->value = bss_sec->_raw_size;
518           bss_sec->_raw_size += size;
519           align = 1 << bss_sec->alignment_power;
520           bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
521           sym->flags |= BSF_EXPORT | BSF_GLOBAL;
522         }
523       else if (bfd_get_section (sym)->output_section != NULL)
524         {
525           /* Move the symbol into the output section.  */
526           sym->value += bfd_get_section (sym)->output_offset;
527           sym->section = bfd_get_section (sym)->output_section;
528           /* This is no longer a section symbol.  */
529           sym->flags &=~ BSF_SECTION_SYM;
530         }
531
532       /* Force _edata and _end to be defined.  This would normally be
533          done by the linker, but the manipulation of the common
534          symbols will confuse it.  */
535       if ((sym->flags & BSF_DEBUGGING) == 0
536           && bfd_asymbol_name (sym)[0] == '_'
537           && bfd_is_und_section (bfd_get_section (sym)))
538         {
539           if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
540             {
541               sym->section = bss_sec;
542               sym->value = 0;
543             }
544           if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
545             {
546               sym->section = bss_sec;
547               endsym = sym;
548             }
549
550 #ifdef NLMCONV_POWERPC
551           /* For PowerPC NetWare, we define __GOT0.  This is the start
552              of the .got section.  */
553           if (bfd_get_arch (inbfd) == bfd_arch_powerpc
554               && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
555             {
556               asection *got_sec;
557
558               got_sec = bfd_get_section_by_name (inbfd, ".got");
559               assert (got_sec != (asection *) NULL);
560               sym->value = got_sec->output_offset;
561               sym->section = got_sec->output_section;
562             }
563 #endif
564         }
565
566       /* If this is a global symbol, check the export list.  */
567       if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
568         {
569           register struct string_list *l;
570           int found_simple;
571
572           /* Unfortunately, a symbol can appear multiple times on the
573              export list, with and without prefixes.  */
574           found_simple = 0;
575           for (l = export_symbols; l != NULL; l = l->next)
576             {
577               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
578                 found_simple = 1;
579               else
580                 {
581                   char *zbase;
582
583                   zbase = strchr (l->string, '@');
584                   if (zbase != NULL
585                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
586                     {
587                       /* We must add a symbol with this prefix.  */
588                       if (newsymcount >= newsymalloc)
589                         {
590                           newsymalloc += 10;
591                           newsyms = ((asymbol **)
592                                      xrealloc ((PTR) newsyms,
593                                                (newsymalloc
594                                                 * sizeof (asymbol *))));
595                         }
596                       newsyms[newsymcount] =
597                         (asymbol *) xmalloc (sizeof (asymbol));
598                       *newsyms[newsymcount] = *sym;
599                       newsyms[newsymcount]->name = l->string;
600                       ++newsymcount;
601                     }
602                 }
603             }
604           if (! found_simple)
605             {
606               /* The unmodified symbol is actually not exported at
607                  all.  */
608               sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
609               sym->flags |= BSF_LOCAL;
610             }
611         }
612
613       /* If it's an undefined symbol, see if it's on the import list.
614          Change the prefix if necessary.  */
615       if (bfd_is_und_section (bfd_get_section (sym)))
616         {
617           register struct string_list *l;
618
619           for (l = import_symbols; l != NULL; l = l->next)
620             {
621               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
622                 break;
623               else
624                 {
625                   char *zbase;
626
627                   zbase = strchr (l->string, '@');
628                   if (zbase != NULL
629                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
630                     {
631                       sym->name = l->string;
632                       break;
633                     }
634                 }
635             }
636           if (l == NULL)
637             non_fatal (_("warning: symbol %s imported but not in import list"),
638                        bfd_asymbol_name (sym));
639         }
640
641       /* See if it's one of the special named symbols.  */
642       if ((sym->flags & BSF_DEBUGGING) == 0)
643         {
644           bfd_vma val;
645
646           /* FIXME: If these symbols are not in the .text section, we
647              add the .text section size to the value.  This may not be
648              correct for all targets.  I'm not sure how this should
649              really be handled.  */
650           if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
651             {
652               val = bfd_asymbol_value (sym);
653               if (bfd_get_section (sym) == data_sec
654                   && text_sec != (asection *) NULL)
655                 val += bfd_section_size (outbfd, text_sec);
656               if (! bfd_set_start_address (outbfd, val))
657                 bfd_fatal (_("set start address"));
658               gotstart = TRUE;
659             }
660           if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
661             {
662               val = bfd_asymbol_value (sym);
663               if (bfd_get_section (sym) == data_sec
664                   && text_sec != (asection *) NULL)
665                 val += bfd_section_size (outbfd, text_sec);
666               nlm_fixed_header (outbfd)->exitProcedureOffset = val;
667               gotexit = TRUE;
668             }
669           if (check_procedure != NULL
670               && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
671             {
672               val = bfd_asymbol_value (sym);
673               if (bfd_get_section (sym) == data_sec
674                   && text_sec != (asection *) NULL)
675                 val += bfd_section_size (outbfd, text_sec);
676               nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
677               gotcheck = TRUE;
678             }
679         }
680     }
681
682   if (endsym != NULL)
683     {
684       endsym->value = bfd_get_section_size_before_reloc (bss_sec);
685
686       /* FIXME: If any relocs referring to _end use inplace addends,
687          then I think they need to be updated.  This is handled by
688          i386_mangle_relocs.  Is it needed for any other object
689          formats?  */
690     }
691
692   if (newsymcount == 0)
693     outsyms = symbols;
694   else
695     {
696       outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
697                                       * sizeof (asymbol *));
698       memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
699       memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
700       outsyms[symcount + newsymcount] = NULL;
701     }
702
703   bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
704
705   if (! gotstart)
706     non_fatal (_("warning: START procedure %s not defined"), start_procedure);
707   if (! gotexit)
708     non_fatal (_("warning: EXIT procedure %s not defined"), exit_procedure);
709   if (check_procedure != NULL && ! gotcheck)
710     non_fatal (_("warning: CHECK procedure %s not defined"), check_procedure);
711
712   /* Add additional sections required for the header information.  */
713   if (custom_file != NULL)
714     {
715       custom_data = fopen (custom_file, "r");
716       if (custom_data == NULL
717           || fstat (fileno (custom_data), &st) < 0)
718         {
719           fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
720                    strerror (errno));
721           custom_file = NULL;
722         }
723       else
724         {
725           custom_size = st.st_size;
726           custom_section = bfd_make_section (outbfd, ".nlmcustom");
727           if (custom_section == NULL
728               || ! bfd_set_section_size (outbfd, custom_section, custom_size)
729               || ! bfd_set_section_flags (outbfd, custom_section,
730                                           SEC_HAS_CONTENTS))
731             bfd_fatal (_("custom section"));
732         }
733     }
734   if (help_file != NULL)
735     {
736       help_data = fopen (help_file, "r");
737       if (help_data == NULL
738           || fstat (fileno (help_data), &st) < 0)
739         {
740           fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
741                    strerror (errno));
742           help_file = NULL;
743         }
744       else
745         {
746           help_size = st.st_size;
747           help_section = bfd_make_section (outbfd, ".nlmhelp");
748           if (help_section == NULL
749               || ! bfd_set_section_size (outbfd, help_section, help_size)
750               || ! bfd_set_section_flags (outbfd, help_section,
751                                           SEC_HAS_CONTENTS))
752             bfd_fatal (_("help section"));
753           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
754         }
755     }
756   if (message_file != NULL)
757     {
758       message_data = fopen (message_file, "r");
759       if (message_data == NULL
760           || fstat (fileno (message_data), &st) < 0)
761         {
762           fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
763                    strerror (errno));
764           message_file = NULL;
765         }
766       else
767         {
768           message_size = st.st_size;
769           message_section = bfd_make_section (outbfd, ".nlmmessages");
770           if (message_section == NULL
771               || ! bfd_set_section_size (outbfd, message_section, message_size)
772               || ! bfd_set_section_flags (outbfd, message_section,
773                                           SEC_HAS_CONTENTS))
774             bfd_fatal (_("message section"));
775           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
776         }
777     }
778   if (modules != NULL)
779     {
780       struct string_list *l;
781
782       module_size = 0;
783       for (l = modules; l != NULL; l = l->next)
784         module_size += strlen (l->string) + 1;
785       module_section = bfd_make_section (outbfd, ".nlmmodules");
786       if (module_section == NULL
787           || ! bfd_set_section_size (outbfd, module_section, module_size)
788           || ! bfd_set_section_flags (outbfd, module_section,
789                                       SEC_HAS_CONTENTS))
790         bfd_fatal (_("module section"));
791     }
792   if (rpc_file != NULL)
793     {
794       rpc_data = fopen (rpc_file, "r");
795       if (rpc_data == NULL
796           || fstat (fileno (rpc_data), &st) < 0)
797         {
798           fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
799                    strerror (errno));
800           rpc_file = NULL;
801         }
802       else
803         {
804           rpc_size = st.st_size;
805           rpc_section = bfd_make_section (outbfd, ".nlmrpc");
806           if (rpc_section == NULL
807               || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
808               || ! bfd_set_section_flags (outbfd, rpc_section,
809                                           SEC_HAS_CONTENTS))
810             bfd_fatal (_("rpc section"));
811           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
812         }
813     }
814   if (sharelib_file != NULL)
815     {
816       sharedbfd = bfd_openr (sharelib_file, output_format);
817       if (sharedbfd == NULL
818           || ! bfd_check_format (sharedbfd, bfd_object))
819         {
820           fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
821                    bfd_errmsg (bfd_get_error ()));
822           sharelib_file = NULL;
823         }
824       else
825         {
826           sharedhdr = *nlm_fixed_header (sharedbfd);
827           bfd_close (sharedbfd);
828           shared_data = fopen (sharelib_file, "r");
829           if (shared_data == NULL
830               || (fstat (fileno (shared_data), &st) < 0))
831             {
832               fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
833                        strerror (errno));
834               sharelib_file = NULL;
835             }
836           else
837             {
838               /* If we were clever, we could just copy out the
839                  sections of the shared library which we actually
840                  need.  However, we would have to figure out the sizes
841                  of the external and public information, and that can
842                  not be done without reading through them.  */
843               if (sharedhdr.uninitializedDataSize > 0)
844                 {
845                   /* There is no place to record this information.  */
846                   non_fatal (_("%s: warning: shared libraries can not have uninitialized data"),
847                              sharelib_file);
848                 }
849               shared_offset = st.st_size;
850               if (shared_offset > (size_t) sharedhdr.codeImageOffset)
851                 shared_offset = sharedhdr.codeImageOffset;
852               if (shared_offset > (size_t) sharedhdr.dataImageOffset)
853                 shared_offset = sharedhdr.dataImageOffset;
854               if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
855                 shared_offset = sharedhdr.relocationFixupOffset;
856               if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
857                 shared_offset = sharedhdr.externalReferencesOffset;
858               if (shared_offset > (size_t) sharedhdr.publicsOffset)
859                 shared_offset = sharedhdr.publicsOffset;
860               shared_size = st.st_size - shared_offset;
861               shared_section = bfd_make_section (outbfd, ".nlmshared");
862               if (shared_section == NULL
863                   || ! bfd_set_section_size (outbfd, shared_section,
864                                              shared_size)
865                   || ! bfd_set_section_flags (outbfd, shared_section,
866                                               SEC_HAS_CONTENTS))
867                 bfd_fatal (_("shared section"));
868               strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
869             }
870         }
871     }
872
873   /* Check whether a version was given.  */
874   if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
875     non_fatal (_("warning: No version number given"));
876
877   /* At least for now, always create an extended header, because that
878      is what NLMLINK does.  */
879   strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
880
881   strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
882
883   /* If the date was not given, force it in.  */
884   if (nlm_version_header (outbfd)->month == 0
885       && nlm_version_header (outbfd)->day == 0
886       && nlm_version_header (outbfd)->year == 0)
887     {
888       time_t now;
889       struct tm *ptm;
890
891       time (&now);
892       ptm = localtime (&now);
893       nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
894       nlm_version_header (outbfd)->day = ptm->tm_mday;
895       nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
896       strncpy (version_hdr->stamp, "VeRsIoN#", 8);
897     }
898
899 #ifdef NLMCONV_POWERPC
900   /* Resolve the stubs we build for PowerPC NetWare.  */
901   if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
902     powerpc_resolve_stubs (inbfd, outbfd);
903 #endif
904
905   /* Copy over the sections.  */
906   bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
907
908   /* Finish up the header information.  */
909   if (custom_file != NULL)
910     {
911       PTR data;
912
913       data = xmalloc (custom_size);
914       if (fread (data, 1, custom_size, custom_data) != custom_size)
915         non_fatal (_("%s: read: %s"), custom_file, strerror (errno));
916       else
917         {
918           if (! bfd_set_section_contents (outbfd, custom_section, data,
919                                           (file_ptr) 0, custom_size))
920             bfd_fatal (_("custom section"));
921           nlm_fixed_header (outbfd)->customDataOffset =
922             custom_section->filepos;
923           nlm_fixed_header (outbfd)->customDataSize = custom_size;
924         }
925       free (data);
926     }
927   if (! debug_info)
928     {
929       /* As a special hack, the backend recognizes a debugInfoOffset
930          of -1 to mean that it should not output any debugging
931          information.  This can not be handling by fiddling with the
932          symbol table because exported symbols appear in both the
933          export information and the debugging information.  */
934       nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
935     }
936   if (map_file != NULL)
937     non_fatal (_("warning: MAP and FULLMAP are not supported; try ld -M"));
938   if (help_file != NULL)
939     {
940       PTR data;
941
942       data = xmalloc (help_size);
943       if (fread (data, 1, help_size, help_data) != help_size)
944         non_fatal (_("%s: read: %s"), help_file, strerror (errno));
945       else
946         {
947           if (! bfd_set_section_contents (outbfd, help_section, data,
948                                           (file_ptr) 0, help_size))
949             bfd_fatal (_("help section"));
950           nlm_extended_header (outbfd)->helpFileOffset =
951             help_section->filepos;
952           nlm_extended_header (outbfd)->helpFileLength = help_size;
953         }
954       free (data);
955     }
956   if (message_file != NULL)
957     {
958       PTR data;
959
960       data = xmalloc (message_size);
961       if (fread (data, 1, message_size, message_data) != message_size)
962         non_fatal (_("%s: read: %s"), message_file, strerror (errno));
963       else
964         {
965           if (! bfd_set_section_contents (outbfd, message_section, data,
966                                           (file_ptr) 0, message_size))
967             bfd_fatal (_("message section"));
968           nlm_extended_header (outbfd)->messageFileOffset =
969             message_section->filepos;
970           nlm_extended_header (outbfd)->messageFileLength = message_size;
971
972           /* FIXME: Are these offsets correct on all platforms?  Are
973              they 32 bits on all platforms?  What endianness?  */
974           nlm_extended_header (outbfd)->languageID =
975             bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
976           nlm_extended_header (outbfd)->messageCount =
977             bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
978         }
979       free (data);
980     }
981   if (modules != NULL)
982     {
983       PTR data;
984       unsigned char *set;
985       struct string_list *l;
986       bfd_size_type c;
987
988       data = xmalloc (module_size);
989       c = 0;
990       set = (unsigned char *) data;
991       for (l = modules; l != NULL; l = l->next)
992         {
993           *set = strlen (l->string);
994           strncpy (set + 1, l->string, *set);
995           set += *set + 1;
996           ++c;
997         }
998       if (! bfd_set_section_contents (outbfd, module_section, data,
999                                       (file_ptr) 0, module_size))
1000         bfd_fatal (_("module section"));
1001       nlm_fixed_header (outbfd)->moduleDependencyOffset =
1002         module_section->filepos;
1003       nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
1004     }
1005   if (rpc_file != NULL)
1006     {
1007       PTR data;
1008
1009       data = xmalloc (rpc_size);
1010       if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
1011         non_fatal (_("%s: read: %s"), rpc_file, strerror (errno));
1012       else
1013         {
1014           if (! bfd_set_section_contents (outbfd, rpc_section, data,
1015                                           (file_ptr) 0, rpc_size))
1016             bfd_fatal (_("rpc section"));
1017           nlm_extended_header (outbfd)->RPCDataOffset =
1018             rpc_section->filepos;
1019           nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1020         }
1021       free (data);
1022     }
1023   if (sharelib_file != NULL)
1024     {
1025       PTR data;
1026
1027       data = xmalloc (shared_size);
1028       if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1029           || fread (data, 1, shared_size, shared_data) != shared_size)
1030         non_fatal (_("%s: read: %s"), sharelib_file, strerror (errno));
1031       else
1032         {
1033           if (! bfd_set_section_contents (outbfd, shared_section, data,
1034                                           (file_ptr) 0, shared_size))
1035             bfd_fatal (_("shared section"));
1036         }
1037       nlm_extended_header (outbfd)->sharedCodeOffset =
1038         sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1039       nlm_extended_header (outbfd)->sharedCodeLength =
1040         sharedhdr.codeImageSize;
1041       nlm_extended_header (outbfd)->sharedDataOffset =
1042         sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1043       nlm_extended_header (outbfd)->sharedDataLength =
1044         sharedhdr.dataImageSize;
1045       nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1046         (sharedhdr.relocationFixupOffset
1047          - shared_offset
1048          + shared_section->filepos);
1049       nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1050         sharedhdr.numberOfRelocationFixups;
1051       nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1052         (sharedhdr.externalReferencesOffset
1053          - shared_offset
1054          + shared_section->filepos);
1055       nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1056         sharedhdr.numberOfExternalReferences;
1057       nlm_extended_header (outbfd)->sharedPublicsOffset =
1058         sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1059       nlm_extended_header (outbfd)->sharedPublicsCount =
1060         sharedhdr.numberOfPublics;
1061       nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1062         sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1063       nlm_extended_header (outbfd)->sharedDebugRecordCount =
1064         sharedhdr.numberOfDebugRecords;
1065       nlm_extended_header (outbfd)->SharedInitializationOffset =
1066         sharedhdr.codeStartOffset;
1067       nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1068         sharedhdr.exitProcedureOffset;
1069       free (data);
1070     }
1071   len = strlen (output_file);
1072   if (len > NLM_MODULE_NAME_SIZE - 2)
1073     len = NLM_MODULE_NAME_SIZE - 2;
1074   nlm_fixed_header (outbfd)->moduleName[0] = len;
1075
1076   strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1077            NLM_MODULE_NAME_SIZE - 2);
1078   nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1079   for (modname = nlm_fixed_header (outbfd)->moduleName;
1080        *modname != '\0';
1081        modname++)
1082     *modname = TOUPPER (*modname);
1083
1084   strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1085            NLM_OLD_THREAD_NAME_LENGTH);
1086
1087   nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1088   nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1089
1090   if (! bfd_close (outbfd))
1091     bfd_fatal (output_file);
1092   if (! bfd_close (inbfd))
1093     bfd_fatal (input_file);
1094
1095   if (unlink_on_exit != NULL)
1096     unlink (unlink_on_exit);
1097
1098   return 0;
1099 }
1100 \f
1101
1102 /* Show a usage message and exit.  */
1103
1104 static void
1105 show_usage (file, status)
1106      FILE *file;
1107      int status;
1108 {
1109   fprintf (file, _("Usage: %s [option(s)] [in-file [out-file]]\n"), program_name);
1110   fprintf (file, _(" Convert an object file into a NetWare Loadable Module\n"));
1111   fprintf (file, _(" The options are:\n\
1112   -I --input-target=<bfdname>   Set the input binary file format\n\
1113   -O --output-target=<bfdname>  Set the output binary file format\n\
1114   -T --header-file=<file>       Read <file> for NLM header information\n\
1115   -l --linker=<linker>          Use <linker> for any linking\n\
1116   -d --debug                    Display on stderr the linker command line\n\
1117   -h --help                     Display this information\n\
1118   -v --version                  Display the program's version\n\
1119 "));
1120   if (status == 0)
1121     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1122   exit (status);
1123 }
1124 \f
1125 /* Select the output format based on the input architecture, machine,
1126    and endianness.  This chooses the appropriate NLM target.  */
1127
1128 static const char *
1129 select_output_format (arch, mach, bigendian)
1130      enum bfd_architecture arch;
1131      unsigned long mach;
1132      bfd_boolean bigendian ATTRIBUTE_UNUSED;
1133 {
1134   switch (arch)
1135     {
1136 #ifdef NLMCONV_I386
1137     case bfd_arch_i386:
1138       return "nlm32-i386";
1139 #endif
1140 #ifdef NLMCONV_SPARC
1141     case bfd_arch_sparc:
1142       return "nlm32-sparc";
1143 #endif
1144 #ifdef NLMCONV_ALPHA
1145     case bfd_arch_alpha:
1146       return "nlm32-alpha";
1147 #endif
1148 #ifdef NLMCONV_POWERPC
1149     case bfd_arch_powerpc:
1150       return "nlm32-powerpc";
1151 #endif
1152     default:
1153       fatal (_("support not compiled in for %s"),
1154              bfd_printable_arch_mach (arch, mach));
1155     }
1156   /*NOTREACHED*/
1157 }
1158 \f
1159 /* The BFD sections are copied in two passes.  This function selects
1160    the output section for each input section, and sets up the section
1161    name, size, etc.  */
1162
1163 static void
1164 setup_sections (inbfd, insec, data_ptr)
1165      bfd *inbfd ATTRIBUTE_UNUSED;
1166      asection *insec;
1167      PTR data_ptr;
1168 {
1169   bfd *outbfd = (bfd *) data_ptr;
1170   flagword f;
1171   const char *outname;
1172   asection *outsec;
1173   bfd_vma offset;
1174   bfd_size_type align;
1175   bfd_size_type add;
1176   bfd_size_type secsecsize;
1177
1178   f = bfd_get_section_flags (inbfd, insec);
1179   if (f & SEC_CODE)
1180     outname = NLM_CODE_NAME;
1181   else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1182     outname = NLM_INITIALIZED_DATA_NAME;
1183   else if (f & SEC_ALLOC)
1184     outname = NLM_UNINITIALIZED_DATA_NAME;
1185   else
1186     outname = bfd_section_name (inbfd, insec);
1187
1188   outsec = bfd_get_section_by_name (outbfd, outname);
1189   if (outsec == NULL)
1190     {
1191       outsec = bfd_make_section (outbfd, outname);
1192       if (outsec == NULL)
1193         bfd_fatal (_("make section"));
1194     }
1195
1196   insec->output_section = outsec;
1197
1198   offset = bfd_section_size (outbfd, outsec);
1199   align = 1 << bfd_section_alignment (inbfd, insec);
1200   add = ((offset + align - 1) &~ (align - 1)) - offset;
1201   insec->output_offset = offset + add;
1202
1203   if (! bfd_set_section_size (outbfd, outsec,
1204                               (bfd_section_size (outbfd, outsec)
1205                                + bfd_section_size (inbfd, insec)
1206                                + add)))
1207     bfd_fatal (_("set section size"));
1208
1209   if ((bfd_section_alignment (inbfd, insec)
1210        > bfd_section_alignment (outbfd, outsec))
1211       && ! bfd_set_section_alignment (outbfd, outsec,
1212                                       bfd_section_alignment (inbfd, insec)))
1213     bfd_fatal (_("set section alignment"));
1214
1215   if (! bfd_set_section_flags (outbfd, outsec,
1216                                f | bfd_get_section_flags (outbfd, outsec)))
1217     bfd_fatal (_("set section flags"));
1218
1219   bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1220
1221   /* For each input section we allocate space for an entry in
1222      .nlmsections.  */
1223   secsecsize = bfd_section_size (outbfd, secsec);
1224   secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1225   secsecsize = (secsecsize + 3) &~ 3;
1226   secsecsize += 8;
1227   if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1228     bfd_fatal (_("set .nlmsections size"));
1229 }
1230
1231 /* Copy the section contents.  */
1232
1233 static void
1234 copy_sections (inbfd, insec, data_ptr)
1235      bfd *inbfd;
1236      asection *insec;
1237      PTR data_ptr;
1238 {
1239   static bfd_size_type secsecoff = 0;
1240   bfd *outbfd = (bfd *) data_ptr;
1241   const char *inname;
1242   asection *outsec;
1243   bfd_size_type size;
1244   PTR contents;
1245   long reloc_size;
1246   bfd_byte buf[4];
1247   bfd_size_type add;
1248
1249   inname = bfd_section_name (inbfd, insec);
1250
1251   outsec = insec->output_section;
1252   assert (outsec != NULL);
1253
1254   size = bfd_get_section_size_before_reloc (insec);
1255
1256   /* FIXME: Why are these necessary?  */
1257   insec->_cooked_size = insec->_raw_size;
1258   insec->reloc_done = TRUE;
1259
1260   if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1261     contents = NULL;
1262   else
1263     {
1264       contents = xmalloc (size);
1265       if (! bfd_get_section_contents (inbfd, insec, contents,
1266                                       (file_ptr) 0, size))
1267         bfd_fatal (bfd_get_filename (inbfd));
1268     }
1269
1270   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1271   if (reloc_size < 0)
1272     bfd_fatal (bfd_get_filename (inbfd));
1273   if (reloc_size != 0)
1274     {
1275       arelent **relocs;
1276       long reloc_count;
1277
1278       relocs = (arelent **) xmalloc (reloc_size);
1279       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1280       if (reloc_count < 0)
1281         bfd_fatal (bfd_get_filename (inbfd));
1282       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1283                      size);
1284
1285       /* FIXME: refers to internal BFD fields.  */
1286       if (outsec->orelocation != (arelent **) NULL)
1287         {
1288           bfd_size_type total_count;
1289           arelent **combined;
1290
1291           total_count = reloc_count + outsec->reloc_count;
1292           combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1293           memcpy (combined, outsec->orelocation,
1294                   outsec->reloc_count * sizeof (arelent *));
1295           memcpy (combined + outsec->reloc_count, relocs,
1296                   (size_t) (reloc_count * sizeof (arelent *)));
1297           free (outsec->orelocation);
1298           reloc_count = total_count;
1299           relocs = combined;
1300         }
1301
1302       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1303     }
1304
1305   if (contents != NULL)
1306     {
1307       if (! bfd_set_section_contents (outbfd, outsec, contents,
1308                                       insec->output_offset, size))
1309         bfd_fatal (bfd_get_filename (outbfd));
1310       free (contents);
1311     }
1312
1313   /* Add this section to .nlmsections.  */
1314   if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
1315                                   strlen (inname) + 1))
1316     bfd_fatal (_("set .nlmsection contents"));
1317   secsecoff += strlen (inname) + 1;
1318
1319   add = ((secsecoff + 3) &~ 3) - secsecoff;
1320   if (add != 0)
1321     {
1322       bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1323       if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1324         bfd_fatal (_("set .nlmsection contents"));
1325       secsecoff += add;
1326     }
1327
1328   if (contents != NULL)
1329     bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1330   else
1331     bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1332   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1333     bfd_fatal (_("set .nlmsection contents"));
1334   secsecoff += 4;
1335
1336   bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1337   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1338     bfd_fatal (_("set .nlmsection contents"));
1339   secsecoff += 4;
1340 }
1341
1342 /* Some, perhaps all, NetWare targets require changing the relocs used
1343    by the input formats.  */
1344
1345 static void
1346 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1347                contents_size)
1348      bfd *outbfd;
1349      asection *insec;
1350      arelent ***relocs_ptr;
1351      long *reloc_count_ptr;
1352      char *contents;
1353      bfd_size_type contents_size;
1354 {
1355   switch (bfd_get_arch (outbfd))
1356     {
1357 #ifdef NLMCONV_I386
1358     case bfd_arch_i386:
1359       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1360                           contents, contents_size);
1361       break;
1362 #endif
1363 #ifdef NLMCONV_ALPHA
1364     case bfd_arch_alpha:
1365       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1366                            contents, contents_size);
1367       break;
1368 #endif
1369 #ifdef NLMCONV_POWERPC
1370     case bfd_arch_powerpc:
1371       powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1372                              contents, contents_size);
1373       break;
1374 #endif
1375     default:
1376       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1377                              contents, contents_size);
1378       break;
1379     }
1380 }
1381
1382 /* By default all we need to do for relocs is change the address by
1383    the output_offset.  */
1384
1385 static void
1386 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1387                        contents_size)
1388      bfd *outbfd ATTRIBUTE_UNUSED;
1389      asection *insec;
1390      arelent ***relocs_ptr;
1391      long *reloc_count_ptr;
1392      char *contents ATTRIBUTE_UNUSED;
1393      bfd_size_type contents_size ATTRIBUTE_UNUSED;
1394 {
1395   if (insec->output_offset != 0)
1396     {
1397       long reloc_count;
1398       register arelent **relocs;
1399       register long i;
1400
1401       reloc_count = *reloc_count_ptr;
1402       relocs = *relocs_ptr;
1403       for (i = 0; i < reloc_count; i++, relocs++)
1404         (*relocs)->address += insec->output_offset;
1405     }
1406 }
1407 \f
1408 #ifdef NLMCONV_I386
1409
1410 /* NetWare on the i386 supports a restricted set of relocs, which are
1411    different from those used on other i386 targets.  This routine
1412    converts the relocs.  It is, obviously, very target dependent.  At
1413    the moment, the nlm32-i386 backend performs similar translations;
1414    however, it is more reliable and efficient to do them here.  */
1415
1416 static reloc_howto_type nlm_i386_pcrel_howto =
1417   HOWTO (1,                     /* type */
1418          0,                     /* rightshift */
1419          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1420          32,                    /* bitsize */
1421          TRUE,                  /* pc_relative */
1422          0,                     /* bitpos */
1423          complain_overflow_signed, /* complain_on_overflow */
1424          0,                     /* special_function */
1425          "DISP32",              /* name */
1426          TRUE,                  /* partial_inplace */
1427          0xffffffff,            /* src_mask */
1428          0xffffffff,            /* dst_mask */
1429          TRUE);                 /* pcrel_offset */
1430
1431 static void
1432 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1433                     contents_size)
1434      bfd *outbfd;
1435      asection *insec;
1436      arelent ***relocs_ptr;
1437      long *reloc_count_ptr;
1438      char *contents;
1439      bfd_size_type contents_size;
1440 {
1441   long reloc_count, i;
1442   arelent **relocs;
1443
1444   reloc_count = *reloc_count_ptr;
1445   relocs = *relocs_ptr;
1446   for (i = 0; i < reloc_count; i++)
1447     {
1448       arelent *rel;
1449       asymbol *sym;
1450       bfd_size_type address;
1451       bfd_vma addend;
1452
1453       rel = *relocs++;
1454       sym = *rel->sym_ptr_ptr;
1455
1456       /* We're moving the relocs from the input section to the output
1457          section, so we must adjust the address accordingly.  */
1458       address = rel->address;
1459       rel->address += insec->output_offset;
1460
1461       /* Note that no serious harm will ensue if we fail to change a
1462          reloc.  The backend will fail when writing out the reloc.  */
1463
1464       /* Make sure this reloc is within the data we have.  We use only
1465          4 byte relocs here, so we insist on having 4 bytes.  */
1466       if (address + 4 > contents_size)
1467         continue;
1468
1469       /* A PC relative reloc entirely within a single section is
1470          completely unnecessary.  This can be generated by ld -r.  */
1471       if (sym == insec->symbol
1472           && rel->howto != NULL
1473           && rel->howto->pc_relative
1474           && ! rel->howto->pcrel_offset)
1475         {
1476           --*reloc_count_ptr;
1477           --relocs;
1478           memmove (relocs, relocs + 1,
1479                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1480           continue;
1481         }
1482
1483       /* Get the amount the relocation will add in.  */
1484       addend = rel->addend + sym->value;
1485
1486       /* NetWare doesn't support PC relative relocs against defined
1487          symbols, so we have to eliminate them by doing the relocation
1488          now.  We can only do this if the reloc is within a single
1489          section.  */
1490       if (rel->howto != NULL
1491           && rel->howto->pc_relative
1492           && bfd_get_section (sym) == insec->output_section)
1493         {
1494           bfd_vma val;
1495
1496           if (rel->howto->pcrel_offset)
1497             addend -= address;
1498
1499           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1500           val += addend;
1501           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1502
1503           --*reloc_count_ptr;
1504           --relocs;
1505           memmove (relocs, relocs + 1,
1506                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1507           continue;
1508         }
1509
1510       /* NetWare doesn't support reloc addends, so we get rid of them
1511          here by simply adding them into the object data.  We handle
1512          the symbol value, if any, the same way.  */
1513       if (addend != 0
1514           && rel->howto != NULL
1515           && rel->howto->rightshift == 0
1516           && rel->howto->size == 2
1517           && rel->howto->bitsize == 32
1518           && rel->howto->bitpos == 0
1519           && rel->howto->src_mask == 0xffffffff
1520           && rel->howto->dst_mask == 0xffffffff)
1521         {
1522           bfd_vma val;
1523
1524           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1525           val += addend;
1526           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1527
1528           /* Adjust the reloc for the changes we just made.  */
1529           rel->addend = 0;
1530           if (! bfd_is_und_section (bfd_get_section (sym)))
1531             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1532         }
1533
1534       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1535          pc_relative relocs accordingly.  We are going to change the
1536          howto field, so we can only do this if the current one is
1537          compatible.  We should check that special_function is NULL
1538          here, but at the moment coff-i386 uses a special_function
1539          which does not affect what we are doing here.  */
1540       if (rel->howto != NULL
1541           && rel->howto->pc_relative
1542           && ! rel->howto->pcrel_offset
1543           && rel->howto->rightshift == 0
1544           && rel->howto->size == 2
1545           && rel->howto->bitsize == 32
1546           && rel->howto->bitpos == 0
1547           && rel->howto->src_mask == 0xffffffff
1548           && rel->howto->dst_mask == 0xffffffff)
1549         {
1550           bfd_vma val;
1551
1552           /* When pcrel_offset is not set, it means that the negative
1553              of the address of the memory location is stored in the
1554              memory location.  We must add it back in.  */
1555           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1556           val += address;
1557           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1558
1559           /* We must change to a new howto.  */
1560           rel->howto = &nlm_i386_pcrel_howto;
1561         }
1562     }
1563 }
1564
1565 #endif /* NLMCONV_I386 */
1566 \f
1567 #ifdef NLMCONV_ALPHA
1568
1569 /* On the Alpha the first reloc for every section must be a special
1570    relocs which hold the GP address.  Also, the first reloc in the
1571    file must be a special reloc which holds the address of the .lita
1572    section.  */
1573
1574 static reloc_howto_type nlm32_alpha_nw_howto =
1575   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1576          0,                     /* rightshift */
1577          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1578          0,                     /* bitsize */
1579          FALSE,                 /* pc_relative */
1580          0,                     /* bitpos */
1581          complain_overflow_dont, /* complain_on_overflow */
1582          0,                     /* special_function */
1583          "NW_RELOC",            /* name */
1584          FALSE,                 /* partial_inplace */
1585          0,                     /* src_mask */
1586          0,                     /* dst_mask */
1587          FALSE);                /* pcrel_offset */
1588
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 static void
1910 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1911                        contents_size)
1912      bfd *outbfd;
1913      asection *insec;
1914      register arelent ***relocs_ptr;
1915      long *reloc_count_ptr;
1916      char *contents;
1917      bfd_size_type contents_size ATTRIBUTE_UNUSED;
1918 {
1919   reloc_howto_type *toc_howto;
1920   long reloc_count;
1921   register arelent **relocs;
1922   register long i;
1923
1924   toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1925   if (toc_howto == (reloc_howto_type *) NULL)
1926     abort ();
1927
1928   /* If this is the .got section, clear out all the contents beyond
1929      the initial size.  We must do this here because copy_sections is
1930      going to write out whatever we return in the contents field.  */
1931   if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1932     memset (contents + powerpc_initial_got_size, 0,
1933             (size_t) (bfd_get_section_size_after_reloc (insec)
1934                       - powerpc_initial_got_size));
1935
1936   reloc_count = *reloc_count_ptr;
1937   relocs = *relocs_ptr;
1938   for (i = 0; i < reloc_count; i++)
1939     {
1940       arelent *rel;
1941       asymbol *sym;
1942       bfd_vma sym_value;
1943
1944       rel = *relocs++;
1945       sym = *rel->sym_ptr_ptr;
1946
1947       /* Convert any relocs against the .bss section into relocs
1948          against the .data section.  */
1949       if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1950                   NLM_UNINITIALIZED_DATA_NAME) == 0)
1951         {
1952           asection *datasec;
1953
1954           datasec = bfd_get_section_by_name (outbfd,
1955                                              NLM_INITIALIZED_DATA_NAME);
1956           if (datasec != NULL)
1957             {
1958               rel->addend += (bfd_get_section_vma (outbfd,
1959                                                    bfd_get_section (sym))
1960                               + sym->value);
1961               rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1962               sym = *rel->sym_ptr_ptr;
1963             }
1964         }
1965
1966       /* We must be able to resolve all PC relative relocs at this
1967          point.  If we get a branch to an undefined symbol we build a
1968          stub, since NetWare will resolve undefined symbols into a
1969          pointer to a function descriptor.  */
1970       if (rel->howto->pc_relative)
1971         {
1972           /* This check for whether a symbol is in the same section as
1973              the reloc will be wrong if there is a PC relative reloc
1974              between two sections both of which were placed in the
1975              same output section.  This should not happen.  */
1976           if (bfd_get_section (sym) != insec->output_section)
1977             non_fatal (_("unresolved PC relative reloc against %s"),
1978                        bfd_asymbol_name (sym));
1979           else
1980             {
1981               bfd_vma val;
1982
1983               assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1984               val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1985               val = ((val &~ rel->howto->dst_mask)
1986                      | (((val & rel->howto->src_mask)
1987                          + (sym->value - rel->address)
1988                          + rel->addend)
1989                         & rel->howto->dst_mask));
1990               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1991
1992               /* If this reloc is against an stubbed symbol and the
1993                  next instruction is
1994                      cror 31,31,31
1995                  then we replace the next instruction with
1996                      lwz  r2,20(r1)
1997                  This reloads the TOC pointer after a stub call.  */
1998               if (bfd_asymbol_name (sym)[0] == '.'
1999                   && (sym->flags & BSF_DYNAMIC) != 0
2000                   && (bfd_get_32 (outbfd,
2001                                   (bfd_byte *) contents + rel->address + 4)
2002                       == 0x4ffffb82)) /* cror 31,31,31 */
2003                 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
2004                             (bfd_byte *) contents + rel->address + 4);
2005
2006               --*reloc_count_ptr;
2007               --relocs;
2008               memmove (relocs, relocs + 1,
2009                        (size_t) ((reloc_count - 1) * sizeof (arelent *)));
2010               continue;
2011             }
2012         }
2013
2014       /* When considering a TOC reloc, we do not want to include the
2015          symbol value.  The symbol will be start of the TOC section
2016          (which is named .got).  We do want to include the addend.  */
2017       if (rel->howto == toc_howto)
2018         sym_value = 0;
2019       else
2020         sym_value = sym->value;
2021
2022       /* If this is a relocation against a symbol with a value, or
2023          there is a reloc addend, we need to update the addend in the
2024          object file.  */
2025       if (sym_value + rel->addend != 0)
2026         {
2027           bfd_vma val;
2028
2029           switch (rel->howto->size)
2030             {
2031             case 1:
2032               val = bfd_get_16 (outbfd,
2033                                 (bfd_byte *) contents + rel->address);
2034               val = ((val &~ rel->howto->dst_mask)
2035                      | (((val & rel->howto->src_mask)
2036                          + sym_value
2037                          + rel->addend)
2038                         & rel->howto->dst_mask));
2039               if ((bfd_signed_vma) val < - 0x8000
2040                   || (bfd_signed_vma) val >= 0x8000)
2041                 non_fatal (_("overflow when adjusting relocation against %s"),
2042                            bfd_asymbol_name (sym));
2043               bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2044               break;
2045
2046             case 2:
2047               val = bfd_get_32 (outbfd,
2048                                 (bfd_byte *) contents + rel->address);
2049               val = ((val &~ rel->howto->dst_mask)
2050                      | (((val & rel->howto->src_mask)
2051                          + sym_value
2052                          + rel->addend)
2053                         & rel->howto->dst_mask));
2054               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2055               break;
2056
2057             default:
2058               abort ();
2059             }
2060
2061           if (! bfd_is_und_section (bfd_get_section (sym)))
2062             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2063           rel->addend = 0;
2064         }
2065
2066       /* Now that we have incorporated the addend, remove any TOC
2067          relocs.  */
2068       if (rel->howto == toc_howto)
2069         {
2070           --*reloc_count_ptr;
2071           --relocs;
2072           memmove (relocs, relocs + 1,
2073                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
2074           continue;
2075         }
2076
2077       rel->address += insec->output_offset;
2078     }
2079 }
2080
2081 #endif /* NLMCONV_POWERPC */
2082 \f
2083 /* Name of linker.  */
2084 #ifndef LD_NAME
2085 #define LD_NAME "ld"
2086 #endif
2087
2088 /* The user has specified several input files.  Invoke the linker to
2089    link them all together, and convert and delete the resulting output
2090    file.  */
2091
2092 static char *
2093 link_inputs (inputs, ld)
2094      struct string_list *inputs;
2095      char *ld;
2096 {
2097   size_t c;
2098   struct string_list *q;
2099   char **argv;
2100   size_t i;
2101   int pid;
2102   int status;
2103   char *errfmt;
2104   char *errarg;
2105
2106   c = 0;
2107   for (q = inputs; q != NULL; q = q->next)
2108     ++c;
2109
2110   argv = (char **) alloca ((c + 5) * sizeof(char *));
2111
2112 #ifndef __MSDOS__
2113   if (ld == NULL)
2114     {
2115       char *p;
2116
2117       /* Find the linker to invoke based on how nlmconv was run.  */
2118       p = program_name + strlen (program_name);
2119       while (p != program_name)
2120         {
2121           if (p[-1] == '/')
2122             {
2123               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2124               memcpy (ld, program_name, p - program_name);
2125               strcpy (ld + (p - program_name), LD_NAME);
2126               break;
2127             }
2128           --p;
2129         }
2130     }
2131 #endif
2132
2133   if (ld == NULL)
2134     ld = (char *) LD_NAME;
2135
2136   unlink_on_exit = make_temp_file (".O");
2137
2138   argv[0] = ld;
2139   argv[1] = (char *) "-Ur";
2140   argv[2] = (char *) "-o";
2141   argv[3] = unlink_on_exit;
2142   i = 4;
2143   for (q = inputs; q != NULL; q = q->next, i++)
2144     argv[i] = q->string;
2145   argv[i] = NULL;
2146
2147   if (debug)
2148     {
2149       for (i = 0; argv[i] != NULL; i++)
2150         fprintf (stderr, " %s", argv[i]);
2151       fprintf (stderr, "\n");
2152     }
2153
2154   pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2155                   PEXECUTE_SEARCH | PEXECUTE_ONE);
2156   if (pid == -1)
2157     {
2158       fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2159       fprintf (stderr, errfmt, errarg);
2160       unlink (unlink_on_exit);
2161       exit (1);
2162     }
2163
2164   if (pwait (pid, &status, 0) < 0)
2165     {
2166       perror ("pwait");
2167       unlink (unlink_on_exit);
2168       exit (1);
2169     }
2170
2171   if (status != 0)
2172     {
2173       non_fatal (_("Execution of %s failed"), ld);
2174       unlink (unlink_on_exit);
2175       exit (1);
2176     }
2177
2178   return unlink_on_exit;
2179 }