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