1129202Scognet/* nlmconv.c -- NLM conversion program
2129202Scognet   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3129202Scognet   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4129202Scognet
5129202Scognet   This file is part of GNU Binutils.
6129202Scognet
7129202Scognet   This program is free software; you can redistribute it and/or modify
8129202Scognet   it under the terms of the GNU General Public License as published by
9129202Scognet   the Free Software Foundation; either version 3 of the License, or
10129202Scognet   (at your option) any later version.
11129202Scognet
12129202Scognet   This program is distributed in the hope that it will be useful,
13129202Scognet   but WITHOUT ANY WARRANTY; without even the implied warranty of
14129202Scognet   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15129202Scognet   GNU General Public License for more details.
16129202Scognet
17129202Scognet   You should have received a copy of the GNU General Public License
18129202Scognet   along with this program; if not, write to the Free Software
19129202Scognet   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20129202Scognet   MA 02110-1301, USA.  */
21129202Scognet
22129202Scognet
23129202Scognet/* Written by Ian Lance Taylor <ian@cygnus.com>.
24129202Scognet
25129202Scognet   This program can be used to convert any appropriate object file
26129202Scognet   into a NetWare Loadable Module (an NLM).  It will accept a linker
27129202Scognet   specification file which is identical to that accepted by the
28129202Scognet   NetWare linker, NLMLINK.  */
29129202Scognet
30129202Scognet/* AIX requires this to be the first thing in the file.  */
31129202Scognet#ifndef __GNUC__
32129202Scognet# ifdef _AIX
33129202Scognet #pragma alloca
34129202Scognet#endif
35129202Scognet#endif
36129202Scognet
37129202Scognet#include "sysdep.h"
38129202Scognet#include "bfd.h"
39129202Scognet#include "libiberty.h"
40129202Scognet#include "safe-ctype.h"
41129202Scognet
42245650Sandrew#include "ansidecl.h"
43245650Sandrew#include <time.h>
44245650Sandrew#include <sys/stat.h>
45245650Sandrew#include <sys/file.h>
46245650Sandrew#include <assert.h>
47245650Sandrew#include "getopt.h"
48245650Sandrew
49129202Scognet/* Internal BFD NLM header.  */
50245650Sandrew#include "libnlm.h"
51129202Scognet#include "nlmconv.h"
52129202Scognet
53129202Scognet#ifdef NLMCONV_ALPHA
54129202Scognet#include "coff/sym.h"
55129202Scognet#include "coff/ecoff.h"
56129202Scognet#endif
57129202Scognet
58129202Scognet#include "bucomm.h"
59129202Scognet
60129202Scognet/* If strerror is just a macro, we want to use the one from libiberty
61129202Scognet   since it will handle undefined values.  */
62129202Scognet#undef strerror
63129202Scognetextern char *strerror (int);
64129202Scognet
65129202Scognet#ifndef SEEK_SET
66129202Scognet#define SEEK_SET 0
67129202Scognet#endif
68129202Scognet
69129202Scognet#ifndef R_OK
70171217Speter#define R_OK 4
71171217Speter#define W_OK 2
72171217Speter#define X_OK 1
73171217Speter#endif
74171261Speter
75171261Speter/* Global variables.  */
76137464Scognet
77129202Scognet/* The name used to invoke the program.  */
78171217Speterchar *program_name;
79129202Scognet
80137464Scognet/* Local variables.  */
81129202Scognet
82129202Scognet/* Whether to print out debugging information (currently just controls
83   whether it prints the linker command if there is one).  */
84static int debug;
85
86/* The symbol table.  */
87static 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.  */
101static 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.  */
106static char *unlink_on_exit;
107
108/* The list of long options.  */
109static 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
125int main (int, char **);
126
127static void show_usage (FILE *, int);
128static const char *select_output_format
129  (enum bfd_architecture, unsigned long, bfd_boolean);
130static void setup_sections (bfd *, asection *, void *);
131static void copy_sections (bfd *, asection *, void *);
132static void mangle_relocs
133  (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
134static void default_mangle_relocs
135  (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
136static char *link_inputs (struct string_list *, char *, char *);
137
138#ifdef NLMCONV_I386
139static void i386_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
140#endif
141
142#ifdef NLMCONV_ALPHA
143static void alpha_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
144#endif
145
146#ifdef NLMCONV_POWERPC
147static void powerpc_build_stubs (bfd *, bfd *, asymbol ***, long *);
148static void powerpc_resolve_stubs (bfd *, bfd *);
149static void powerpc_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
150#endif
151
152/* The main routine.  */
153
154int
155main (int argc, char **argv)
156{
157  int opt;
158  char *input_file = NULL;
159  const char *input_format = NULL;
160  const char *output_format = NULL;
161  const char *header_file = NULL;
162  char *ld_arg = NULL;
163  Nlm_Internal_Fixed_Header fixed_hdr_struct;
164  Nlm_Internal_Variable_Header var_hdr_struct;
165  Nlm_Internal_Version_Header version_hdr_struct;
166  Nlm_Internal_Copyright_Header copyright_hdr_struct;
167  Nlm_Internal_Extended_Header extended_hdr_struct;
168  bfd *inbfd;
169  bfd *outbfd;
170  asymbol **newsyms, **outsyms;
171  long symcount, newsymalloc, newsymcount;
172  long symsize;
173  asection *text_sec, *bss_sec, *data_sec;
174  bfd_vma vma;
175  bfd_size_type align;
176  asymbol *endsym;
177  long i;
178  char inlead, outlead;
179  bfd_boolean gotstart, gotexit, gotcheck;
180  struct stat st;
181  FILE *custom_data = NULL;
182  FILE *help_data = NULL;
183  FILE *message_data = NULL;
184  FILE *rpc_data = NULL;
185  FILE *shared_data = NULL;
186  size_t custom_size = 0;
187  size_t help_size = 0;
188  size_t message_size = 0;
189  size_t module_size = 0;
190  size_t rpc_size = 0;
191  asection *custom_section = NULL;
192  asection *help_section = NULL;
193  asection *message_section = NULL;
194  asection *module_section = NULL;
195  asection *rpc_section = NULL;
196  asection *shared_section = NULL;
197  bfd *sharedbfd;
198  size_t shared_offset = 0;
199  size_t shared_size = 0;
200  static Nlm_Internal_Fixed_Header sharedhdr;
201  int len;
202  char *modname;
203  char **matching;
204
205#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
206  setlocale (LC_MESSAGES, "");
207#endif
208#if defined (HAVE_SETLOCALE)
209  setlocale (LC_CTYPE, "");
210#endif
211  bindtextdomain (PACKAGE, LOCALEDIR);
212  textdomain (PACKAGE);
213
214  program_name = argv[0];
215  xmalloc_set_program_name (program_name);
216
217  expandargv (&argc, &argv);
218
219  bfd_init ();
220  set_default_bfd_target ();
221
222  while ((opt = getopt_long (argc, argv, "dHhI:l:O:T:Vv", long_options,
223			     (int *) NULL))
224	 != EOF)
225    {
226      switch (opt)
227	{
228	case 'd':
229	  debug = 1;
230	  break;
231	case 'H':
232	case 'h':
233	  show_usage (stdout, 0);
234	  break;
235	case 'I':
236	  input_format = optarg;
237	  break;
238	case 'l':
239	  ld_arg = optarg;
240	  break;
241	case 'O':
242	  output_format = optarg;
243	  break;
244	case 'T':
245	  header_file = optarg;
246	  break;
247	case 'v':
248	case 'V':
249	  print_version ("nlmconv");
250	  break;
251	case 0:
252	  break;
253	default:
254	  show_usage (stderr, 1);
255	  break;
256	}
257    }
258
259  /* The input and output files may be named on the command line.  */
260  output_file = NULL;
261  if (optind < argc)
262    {
263      input_file = argv[optind];
264      ++optind;
265      if (optind < argc)
266	{
267	  output_file = argv[optind];
268	  ++optind;
269	  if (optind < argc)
270	    show_usage (stderr, 1);
271	  if (strcmp (input_file, output_file) == 0)
272	    {
273	      fatal (_("input and output files must be different"));
274	    }
275	}
276    }
277
278  /* Initialize the header information to default values.  */
279  fixed_hdr = &fixed_hdr_struct;
280  memset ((void *) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
281  var_hdr = &var_hdr_struct;
282  memset ((void *) &var_hdr_struct, 0, sizeof var_hdr_struct);
283  version_hdr = &version_hdr_struct;
284  memset ((void *) &version_hdr_struct, 0, sizeof version_hdr_struct);
285  copyright_hdr = &copyright_hdr_struct;
286  memset ((void *) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
287  extended_hdr = &extended_hdr_struct;
288  memset ((void *) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
289  check_procedure = NULL;
290  custom_file = NULL;
291  debug_info = FALSE;
292  exit_procedure = "_Stop";
293  export_symbols = NULL;
294  map_file = NULL;
295  full_map = FALSE;
296  help_file = NULL;
297  import_symbols = NULL;
298  message_file = NULL;
299  modules = NULL;
300  sharelib_file = NULL;
301  start_procedure = "_Prelude";
302  verbose = FALSE;
303  rpc_file = NULL;
304
305  parse_errors = 0;
306
307  /* Parse the header file (if there is one).  */
308  if (header_file != NULL)
309    {
310      if (! nlmlex_file (header_file)
311	  || yyparse () != 0
312	  || parse_errors != 0)
313	exit (1);
314    }
315
316  if (input_files != NULL)
317    {
318      if (input_file != NULL)
319	{
320	  fatal (_("input file named both on command line and with INPUT"));
321	}
322      if (input_files->next == NULL)
323	input_file = input_files->string;
324      else
325	input_file = link_inputs (input_files, ld_arg, map_file);
326    }
327  else if (input_file == NULL)
328    {
329      non_fatal (_("no input file"));
330      show_usage (stderr, 1);
331    }
332
333  inbfd = bfd_openr (input_file, input_format);
334  if (inbfd == NULL)
335    bfd_fatal (input_file);
336
337  if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
338    {
339      bfd_nonfatal (input_file);
340      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
341	{
342	  list_matching_formats (matching);
343	  free (matching);
344	}
345      exit (1);
346    }
347
348  if (output_format == NULL)
349    output_format = select_output_format (bfd_get_arch (inbfd),
350					  bfd_get_mach (inbfd),
351					  bfd_big_endian (inbfd));
352
353  assert (output_format != NULL);
354
355  /* Use the output file named on the command line if it exists.
356     Otherwise use the file named in the OUTPUT statement.  */
357  if (output_file == NULL)
358    {
359      non_fatal (_("no name for output file"));
360      show_usage (stderr, 1);
361    }
362
363  outbfd = bfd_openw (output_file, output_format);
364  if (outbfd == NULL)
365    bfd_fatal (output_file);
366  if (! bfd_set_format (outbfd, bfd_object))
367    bfd_fatal (output_file);
368
369  assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
370
371  /* XXX: Should we accept the unknown bfd format here ?  */
372  if (bfd_arch_get_compatible (inbfd, outbfd, TRUE) == NULL)
373    non_fatal (_("warning: input and output formats are not compatible"));
374
375  /* Move the values read from the command file into outbfd.  */
376  *nlm_fixed_header (outbfd) = fixed_hdr_struct;
377  *nlm_variable_header (outbfd) = var_hdr_struct;
378  *nlm_version_header (outbfd) = version_hdr_struct;
379  *nlm_copyright_header (outbfd) = copyright_hdr_struct;
380  *nlm_extended_header (outbfd) = extended_hdr_struct;
381
382  /* Start copying the input BFD to the output BFD.  */
383  if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
384    bfd_fatal (bfd_get_filename (outbfd));
385
386  symsize = bfd_get_symtab_upper_bound (inbfd);
387  if (symsize < 0)
388    bfd_fatal (input_file);
389  symbols = (asymbol **) xmalloc (symsize);
390  symcount = bfd_canonicalize_symtab (inbfd, symbols);
391  if (symcount < 0)
392    bfd_fatal (input_file);
393
394  /* Make sure we have a .bss section.  */
395  bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
396  if (bss_sec == NULL)
397    {
398      bss_sec = bfd_make_section_with_flags (outbfd,
399					     NLM_UNINITIALIZED_DATA_NAME,
400					     SEC_ALLOC);
401      if (bss_sec == NULL
402	  || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
403	bfd_fatal (_("make .bss section"));
404    }
405
406  /* We store the original section names in the .nlmsections section,
407     so that programs which understand it can resurrect the original
408     sections from the NLM.  We will put a pointer to .nlmsections in
409     the NLM header area.  */
410  secsec = bfd_make_section_with_flags (outbfd, ".nlmsections",
411					SEC_HAS_CONTENTS);
412  if (secsec == NULL)
413    bfd_fatal (_("make .nlmsections section"));
414
415#ifdef NLMCONV_POWERPC
416  /* For PowerPC NetWare we need to build stubs for calls to undefined
417     symbols.  Because each stub requires an entry in the TOC section
418     which must be at the same location as other entries in the TOC
419     section, we must do this before determining where the TOC section
420     goes in setup_sections.  */
421  if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
422    powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
423#endif
424
425  /* Set up the sections.  */
426  bfd_map_over_sections (inbfd, setup_sections, (void *) outbfd);
427
428  text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
429
430  /* The .bss section immediately follows the .data section.  */
431  data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
432  if (data_sec != NULL)
433    {
434      bfd_size_type add;
435
436      vma = bfd_get_section_size (data_sec);
437      align = 1 << bss_sec->alignment_power;
438      add = ((vma + align - 1) &~ (align - 1)) - vma;
439      vma += add;
440      if (! bfd_set_section_vma (outbfd, bss_sec, vma))
441	bfd_fatal (_("set .bss vma"));
442      if (add != 0)
443	{
444	  bfd_size_type data_size;
445
446	  data_size = bfd_get_section_size (data_sec);
447	  if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
448	    bfd_fatal (_("set .data size"));
449	}
450    }
451
452  /* Adjust symbol information.  */
453  inlead = bfd_get_symbol_leading_char (inbfd);
454  outlead = bfd_get_symbol_leading_char (outbfd);
455  gotstart = FALSE;
456  gotexit = FALSE;
457  gotcheck = FALSE;
458  newsymalloc = 10;
459  newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
460  newsymcount = 0;
461  endsym = NULL;
462  for (i = 0; i < symcount; i++)
463    {
464      asymbol *sym;
465
466      sym = symbols[i];
467
468      /* Add or remove a leading underscore.  */
469      if (inlead != outlead)
470	{
471	  if (inlead != '\0')
472	    {
473	      if (bfd_asymbol_name (sym)[0] == inlead)
474		{
475		  if (outlead == '\0')
476		    ++sym->name;
477		  else
478		    {
479		      char *new_name;
480
481		      new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
482		      new_name[0] = outlead;
483		      strcpy (new_name + 1, bfd_asymbol_name (sym) + 1);
484		      sym->name = new_name;
485		    }
486		}
487	    }
488	  else
489	    {
490	      char *new_name;
491
492	      new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
493	      new_name[0] = outlead;
494	      strcpy (new_name + 1, bfd_asymbol_name (sym));
495	      sym->name = new_name;
496	    }
497	}
498
499      /* NLM's have an uninitialized data section, but they do not
500	 have a common section in the Unix sense.  Move all common
501	 symbols into the .bss section, and mark them as exported.  */
502      if (bfd_is_com_section (bfd_get_section (sym)))
503	{
504	  bfd_vma size = sym->value;
505
506	  sym->section = bss_sec;
507	  sym->value = bfd_get_section_size (bss_sec);
508	  size += sym->value;
509	  align = 1 << bss_sec->alignment_power;
510	  size = (size + align - 1) & ~(align - 1);
511	  bfd_set_section_size (outbfd, bss_sec, size);
512	  sym->flags |= BSF_EXPORT | BSF_GLOBAL;
513	}
514      else if (bfd_get_section (sym)->output_section != NULL)
515	{
516	  /* Move the symbol into the output section.  */
517	  sym->value += bfd_get_section (sym)->output_offset;
518	  sym->section = bfd_get_section (sym)->output_section;
519	  /* This is no longer a section symbol.  */
520	  sym->flags &=~ BSF_SECTION_SYM;
521	}
522
523      /* Force _edata and _end to be defined.  This would normally be
524	 done by the linker, but the manipulation of the common
525	 symbols will confuse it.  */
526      if ((sym->flags & BSF_DEBUGGING) == 0
527	  && bfd_asymbol_name (sym)[0] == '_'
528	  && bfd_is_und_section (bfd_get_section (sym)))
529	{
530	  if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
531	    {
532	      sym->section = bss_sec;
533	      sym->value = 0;
534	    }
535	  if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
536	    {
537	      sym->section = bss_sec;
538	      endsym = sym;
539	    }
540
541#ifdef NLMCONV_POWERPC
542	  /* For PowerPC NetWare, we define __GOT0.  This is the start
543	     of the .got section.  */
544	  if (bfd_get_arch (inbfd) == bfd_arch_powerpc
545	      && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
546	    {
547	      asection *got_sec;
548
549	      got_sec = bfd_get_section_by_name (inbfd, ".got");
550	      assert (got_sec != (asection *) NULL);
551	      sym->value = got_sec->output_offset;
552	      sym->section = got_sec->output_section;
553	    }
554#endif
555	}
556
557      /* If this is a global symbol, check the export list.  */
558      if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
559	{
560	  struct string_list *l;
561	  int found_simple;
562
563	  /* Unfortunately, a symbol can appear multiple times on the
564	     export list, with and without prefixes.  */
565	  found_simple = 0;
566	  for (l = export_symbols; l != NULL; l = l->next)
567	    {
568	      if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
569		found_simple = 1;
570	      else
571		{
572		  char *zbase;
573
574		  zbase = strchr (l->string, '@');
575		  if (zbase != NULL
576		      && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
577		    {
578		      /* We must add a symbol with this prefix.  */
579		      if (newsymcount >= newsymalloc)
580			{
581			  newsymalloc += 10;
582			  newsyms = ((asymbol **)
583				     xrealloc ((void *) newsyms,
584					       (newsymalloc
585						* sizeof (asymbol *))));
586			}
587		      newsyms[newsymcount] =
588			(asymbol *) xmalloc (sizeof (asymbol));
589		      *newsyms[newsymcount] = *sym;
590		      newsyms[newsymcount]->name = l->string;
591		      ++newsymcount;
592		    }
593		}
594	    }
595	  if (! found_simple)
596	    {
597	      /* The unmodified symbol is actually not exported at
598		 all.  */
599	      sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
600	      sym->flags |= BSF_LOCAL;
601	    }
602	}
603
604      /* If it's an undefined symbol, see if it's on the import list.
605	 Change the prefix if necessary.  */
606      if (bfd_is_und_section (bfd_get_section (sym)))
607	{
608	  struct string_list *l;
609
610	  for (l = import_symbols; l != NULL; l = l->next)
611	    {
612	      if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
613		break;
614	      else
615		{
616		  char *zbase;
617
618		  zbase = strchr (l->string, '@');
619		  if (zbase != NULL
620		      && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
621		    {
622		      sym->name = l->string;
623		      break;
624		    }
625		}
626	    }
627	  if (l == NULL)
628	    non_fatal (_("warning: symbol %s imported but not in import list"),
629		       bfd_asymbol_name (sym));
630	}
631
632      /* See if it's one of the special named symbols.  */
633      if ((sym->flags & BSF_DEBUGGING) == 0)
634	{
635	  bfd_vma val;
636
637	  /* FIXME: If these symbols are not in the .text section, we
638	     add the .text section size to the value.  This may not be
639	     correct for all targets.  I'm not sure how this should
640	     really be handled.  */
641	  if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
642	    {
643	      val = bfd_asymbol_value (sym);
644	      if (bfd_get_section (sym) == data_sec
645		  && text_sec != (asection *) NULL)
646		val += bfd_section_size (outbfd, text_sec);
647	      if (! bfd_set_start_address (outbfd, val))
648		bfd_fatal (_("set start address"));
649	      gotstart = TRUE;
650	    }
651	  if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
652	    {
653	      val = bfd_asymbol_value (sym);
654	      if (bfd_get_section (sym) == data_sec
655		  && text_sec != (asection *) NULL)
656		val += bfd_section_size (outbfd, text_sec);
657	      nlm_fixed_header (outbfd)->exitProcedureOffset = val;
658	      gotexit = TRUE;
659	    }
660	  if (check_procedure != NULL
661	      && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
662	    {
663	      val = bfd_asymbol_value (sym);
664	      if (bfd_get_section (sym) == data_sec
665		  && text_sec != (asection *) NULL)
666		val += bfd_section_size (outbfd, text_sec);
667	      nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
668	      gotcheck = TRUE;
669	    }
670	}
671    }
672
673  if (endsym != NULL)
674    {
675      endsym->value = bfd_get_section_size (bss_sec);
676
677      /* FIXME: If any relocs referring to _end use inplace addends,
678	 then I think they need to be updated.  This is handled by
679	 i386_mangle_relocs.  Is it needed for any other object
680	 formats?  */
681    }
682
683  if (newsymcount == 0)
684    outsyms = symbols;
685  else
686    {
687      outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
688				      * sizeof (asymbol *));
689      memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
690      memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
691      outsyms[symcount + newsymcount] = NULL;
692    }
693
694  bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
695
696  if (! gotstart)
697    non_fatal (_("warning: START procedure %s not defined"), start_procedure);
698  if (! gotexit)
699    non_fatal (_("warning: EXIT procedure %s not defined"), exit_procedure);
700  if (check_procedure != NULL && ! gotcheck)
701    non_fatal (_("warning: CHECK procedure %s not defined"), check_procedure);
702
703  /* Add additional sections required for the header information.  */
704  if (custom_file != NULL)
705    {
706      custom_data = fopen (custom_file, "r");
707      if (custom_data == NULL
708	  || fstat (fileno (custom_data), &st) < 0)
709	{
710	  fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
711		   strerror (errno));
712	  custom_file = NULL;
713	}
714      else
715	{
716	  custom_size = st.st_size;
717	  custom_section = bfd_make_section_with_flags (outbfd, ".nlmcustom",
718							SEC_HAS_CONTENTS);
719	  if (custom_section == NULL
720	      || ! bfd_set_section_size (outbfd, custom_section, custom_size))
721	    bfd_fatal (_("custom section"));
722	}
723    }
724  if (help_file != NULL)
725    {
726      help_data = fopen (help_file, "r");
727      if (help_data == NULL
728	  || fstat (fileno (help_data), &st) < 0)
729	{
730	  fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
731		   strerror (errno));
732	  help_file = NULL;
733	}
734      else
735	{
736	  help_size = st.st_size;
737	  help_section = bfd_make_section_with_flags (outbfd, ".nlmhelp",
738						      SEC_HAS_CONTENTS);
739	  if (help_section == NULL
740	      || ! bfd_set_section_size (outbfd, help_section, help_size))
741	    bfd_fatal (_("help section"));
742	  LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
743	}
744    }
745  if (message_file != NULL)
746    {
747      message_data = fopen (message_file, "r");
748      if (message_data == NULL
749	  || fstat (fileno (message_data), &st) < 0)
750	{
751	  fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
752		   strerror (errno));
753	  message_file = NULL;
754	}
755      else
756	{
757	  message_size = st.st_size;
758	  message_section = bfd_make_section_with_flags (outbfd,
759							 ".nlmmessages",
760							 SEC_HAS_CONTENTS);
761	  if (message_section == NULL
762	      || ! bfd_set_section_size (outbfd, message_section, message_size))
763	    bfd_fatal (_("message section"));
764	  LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
765	}
766    }
767  if (modules != NULL)
768    {
769      struct string_list *l;
770
771      module_size = 0;
772      for (l = modules; l != NULL; l = l->next)
773	module_size += strlen (l->string) + 1;
774      module_section = bfd_make_section_with_flags (outbfd, ".nlmmodules",
775						    SEC_HAS_CONTENTS);
776      if (module_section == NULL
777	  || ! bfd_set_section_size (outbfd, module_section, module_size))
778	bfd_fatal (_("module section"));
779    }
780  if (rpc_file != NULL)
781    {
782      rpc_data = fopen (rpc_file, "r");
783      if (rpc_data == NULL
784	  || fstat (fileno (rpc_data), &st) < 0)
785	{
786	  fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
787		   strerror (errno));
788	  rpc_file = NULL;
789	}
790      else
791	{
792	  rpc_size = st.st_size;
793	  rpc_section = bfd_make_section_with_flags (outbfd, ".nlmrpc",
794						     SEC_HAS_CONTENTS);
795	  if (rpc_section == NULL
796	      || ! bfd_set_section_size (outbfd, rpc_section, rpc_size))
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_with_flags (outbfd,
849							    ".nlmshared",
850							    SEC_HAS_CONTENTS);
851	      if (shared_section == NULL
852		  || ! bfd_set_section_size (outbfd, shared_section,
853					     shared_size))
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 (REPORT_BUGS_TO[0] && 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_with_flags (inbfd, ".stubs",
1701					  (SEC_CODE
1702					   | SEC_RELOC
1703					   | SEC_ALLOC
1704					   | SEC_LOAD));
1705  if (stub_sec == (asection *) NULL
1706      || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1707    bfd_fatal (".stubs");
1708
1709  /* Get the TOC section, which is named .got.  */
1710  got_sec = bfd_get_section_by_name (inbfd, ".got");
1711  if (got_sec == (asection *) NULL)
1712    {
1713      got_sec = bfd_make_section_with_flags (inbfd, ".got",
1714					     (SEC_DATA
1715					      | SEC_RELOC
1716					      | SEC_ALLOC
1717					      | SEC_LOAD
1718					      | SEC_HAS_CONTENTS));
1719      if (got_sec == (asection *) NULL
1720	  || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1721	bfd_fatal (".got");
1722    }
1723
1724  powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1725  got_base = powerpc_initial_got_size;
1726  got_base = (got_base + 3) &~ 3;
1727
1728  stubcount = 0;
1729
1730  symcount = *symcount_ptr;
1731  for (i = 0; i < symcount; i++)
1732    {
1733      asymbol *sym;
1734      asymbol *newsym;
1735      char *newname;
1736      struct powerpc_stub *item;
1737
1738      sym = (*symbols_ptr)[i];
1739
1740      /* We must make a stub for every undefined symbol whose name
1741	 starts with '.'.  */
1742      if (bfd_asymbol_name (sym)[0] != '.'
1743	  || ! bfd_is_und_section (bfd_get_section (sym)))
1744	continue;
1745
1746      /* Make a new undefined symbol with the same name but without
1747	 the leading `.'.  */
1748      newsym = xmalloc (sizeof (asymbol));
1749      *newsym = *sym;
1750      newname = xmalloc (strlen (bfd_asymbol_name (sym)));
1751      strcpy (newname, bfd_asymbol_name (sym) + 1);
1752      newsym->name = newname;
1753
1754      /* Define the `.' symbol to be in the stub section.  */
1755      sym->section = stub_sec;
1756      sym->value = stubcount * POWERPC_STUB_SIZE;
1757      /* We set the BSF_DYNAMIC flag here so that we can check it when
1758	 we are mangling relocs.  FIXME: This is a hack.  */
1759      sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1760
1761      /* Add this stub to the linked list.  */
1762      item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1763      item->start = sym;
1764      item->reloc = newsym;
1765      item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1766
1767      item->next = powerpc_stubs;
1768      powerpc_stubs = item;
1769
1770      ++stubcount;
1771    }
1772
1773  if (stubcount > 0)
1774    {
1775      asymbol **s;
1776      struct powerpc_stub *l;
1777
1778      /* Add the new symbols we just created to the symbol table.  */
1779      *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1780					    ((symcount + stubcount)
1781					     * sizeof (asymbol)));
1782      *symcount_ptr += stubcount;
1783      s = &(*symbols_ptr)[symcount];
1784      for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1785	*s++ = l->reloc;
1786
1787      /* Set the size of the .stubs section and increase the size of
1788	 the .got section.  */
1789      if (! bfd_set_section_size (inbfd, stub_sec,
1790				  stubcount * POWERPC_STUB_SIZE)
1791	  || ! bfd_set_section_size (inbfd, got_sec,
1792				     (got_base
1793				      + (stubcount
1794					 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1795	bfd_fatal (_("stub section sizes"));
1796    }
1797}
1798
1799/* Resolve all the stubs for PowerPC NetWare.  We fill in the contents
1800   of the output section, and create new relocs in the TOC.  */
1801
1802static void
1803powerpc_resolve_stubs (bfd *inbfd, bfd *outbfd)
1804{
1805  bfd_byte buf[POWERPC_STUB_SIZE];
1806  unsigned int i;
1807  unsigned int stubcount;
1808  arelent **relocs;
1809  asection *got_sec;
1810  arelent **r;
1811  struct powerpc_stub *l;
1812
1813  if (powerpc_stubs == (struct powerpc_stub *) NULL)
1814    return;
1815
1816  for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1817    bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1818
1819  got_sec = bfd_get_section_by_name (inbfd, ".got");
1820  assert (got_sec != (asection *) NULL);
1821  assert (got_sec->output_section->orelocation == (arelent **) NULL);
1822
1823  stubcount = 0;
1824  for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1825    ++stubcount;
1826  relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1827
1828  r = relocs;
1829  for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1830    {
1831      arelent *reloc;
1832
1833      /* Adjust the first instruction to use the right TOC index.  */
1834      bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1835
1836      /* Write this stub out.  */
1837      if (! bfd_set_section_contents (outbfd,
1838				      bfd_get_section (l->start),
1839				      buf,
1840				      l->start->value,
1841				      POWERPC_STUB_SIZE))
1842	bfd_fatal (_("writing stub"));
1843
1844      /* Create a new reloc for the TOC entry.  */
1845      reloc = (arelent *) xmalloc (sizeof (arelent));
1846      reloc->sym_ptr_ptr = &l->reloc;
1847      reloc->address = l->toc_index + got_sec->output_offset;
1848      reloc->addend = 0;
1849      reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1850
1851      *r++ = reloc;
1852    }
1853
1854  bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1855}
1856
1857/* Adjust relocation entries for PowerPC NetWare.  We do not output
1858   TOC relocations.  The object code already contains the offset from
1859   the TOC pointer.  When the function is called, the TOC register,
1860   r2, will be set to the correct TOC value, so there is no need for
1861   any further reloc.  */
1862
1863static void
1864powerpc_mangle_relocs (bfd *outbfd, asection *insec,
1865		       arelent ***relocs_ptr,
1866		       long *reloc_count_ptr, char *contents,
1867		       bfd_size_type contents_size ATTRIBUTE_UNUSED)
1868{
1869  reloc_howto_type *toc_howto;
1870  long reloc_count;
1871  arelent **relocs;
1872  long i;
1873
1874  toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1875  if (toc_howto == (reloc_howto_type *) NULL)
1876    abort ();
1877
1878  /* If this is the .got section, clear out all the contents beyond
1879     the initial size.  We must do this here because copy_sections is
1880     going to write out whatever we return in the contents field.  */
1881  if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1882    memset (contents + powerpc_initial_got_size, 0,
1883	    (size_t) (bfd_get_section_size (insec) - powerpc_initial_got_size));
1884
1885  reloc_count = *reloc_count_ptr;
1886  relocs = *relocs_ptr;
1887  for (i = 0; i < reloc_count; i++)
1888    {
1889      arelent *rel;
1890      asymbol *sym;
1891      bfd_vma sym_value;
1892
1893      rel = *relocs++;
1894      sym = *rel->sym_ptr_ptr;
1895
1896      /* Convert any relocs against the .bss section into relocs
1897         against the .data section.  */
1898      if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1899		  NLM_UNINITIALIZED_DATA_NAME) == 0)
1900	{
1901	  asection *datasec;
1902
1903	  datasec = bfd_get_section_by_name (outbfd,
1904					     NLM_INITIALIZED_DATA_NAME);
1905	  if (datasec != NULL)
1906	    {
1907	      rel->addend += (bfd_get_section_vma (outbfd,
1908						   bfd_get_section (sym))
1909			      + sym->value);
1910	      rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1911	      sym = *rel->sym_ptr_ptr;
1912	    }
1913	}
1914
1915      /* We must be able to resolve all PC relative relocs at this
1916	 point.  If we get a branch to an undefined symbol we build a
1917	 stub, since NetWare will resolve undefined symbols into a
1918	 pointer to a function descriptor.  */
1919      if (rel->howto->pc_relative)
1920	{
1921	  /* This check for whether a symbol is in the same section as
1922	     the reloc will be wrong if there is a PC relative reloc
1923	     between two sections both of which were placed in the
1924	     same output section.  This should not happen.  */
1925	  if (bfd_get_section (sym) != insec->output_section)
1926	    non_fatal (_("unresolved PC relative reloc against %s"),
1927		       bfd_asymbol_name (sym));
1928	  else
1929	    {
1930	      bfd_vma val;
1931
1932	      assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1933	      val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1934	      val = ((val &~ rel->howto->dst_mask)
1935		     | (((val & rel->howto->src_mask)
1936			 + (sym->value - rel->address)
1937			 + rel->addend)
1938			& rel->howto->dst_mask));
1939	      bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1940
1941	      /* If this reloc is against an stubbed symbol and the
1942		 next instruction is
1943		     cror 31,31,31
1944		 then we replace the next instruction with
1945		     lwz  r2,20(r1)
1946		 This reloads the TOC pointer after a stub call.  */
1947	      if (bfd_asymbol_name (sym)[0] == '.'
1948		  && (sym->flags & BSF_DYNAMIC) != 0
1949		  && (bfd_get_32 (outbfd,
1950				  (bfd_byte *) contents + rel->address + 4)
1951		      == 0x4ffffb82)) /* cror 31,31,31 */
1952		bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1953			    (bfd_byte *) contents + rel->address + 4);
1954
1955	      --*reloc_count_ptr;
1956	      --relocs;
1957	      memmove (relocs, relocs + 1,
1958		       (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1959	      continue;
1960	    }
1961	}
1962
1963      /* When considering a TOC reloc, we do not want to include the
1964	 symbol value.  The symbol will be start of the TOC section
1965	 (which is named .got).  We do want to include the addend.  */
1966      if (rel->howto == toc_howto)
1967	sym_value = 0;
1968      else
1969	sym_value = sym->value;
1970
1971      /* If this is a relocation against a symbol with a value, or
1972	 there is a reloc addend, we need to update the addend in the
1973	 object file.  */
1974      if (sym_value + rel->addend != 0)
1975	{
1976	  bfd_vma val;
1977
1978	  switch (rel->howto->size)
1979	    {
1980	    case 1:
1981	      val = bfd_get_16 (outbfd,
1982				(bfd_byte *) contents + rel->address);
1983	      val = ((val &~ rel->howto->dst_mask)
1984		     | (((val & rel->howto->src_mask)
1985			 + sym_value
1986			 + rel->addend)
1987			& rel->howto->dst_mask));
1988	      if ((bfd_signed_vma) val < - 0x8000
1989		  || (bfd_signed_vma) val >= 0x8000)
1990		non_fatal (_("overflow when adjusting relocation against %s"),
1991			   bfd_asymbol_name (sym));
1992	      bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1993	      break;
1994
1995	    case 2:
1996	      val = bfd_get_32 (outbfd,
1997				(bfd_byte *) contents + rel->address);
1998	      val = ((val &~ rel->howto->dst_mask)
1999		     | (((val & rel->howto->src_mask)
2000			 + sym_value
2001			 + rel->addend)
2002			& rel->howto->dst_mask));
2003	      bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2004	      break;
2005
2006	    default:
2007	      abort ();
2008	    }
2009
2010	  if (! bfd_is_und_section (bfd_get_section (sym)))
2011	    rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2012	  rel->addend = 0;
2013	}
2014
2015      /* Now that we have incorporated the addend, remove any TOC
2016	 relocs.  */
2017      if (rel->howto == toc_howto)
2018	{
2019	  --*reloc_count_ptr;
2020	  --relocs;
2021	  memmove (relocs, relocs + 1,
2022		   (size_t) ((reloc_count - i) * sizeof (arelent *)));
2023	  continue;
2024	}
2025
2026      rel->address += insec->output_offset;
2027    }
2028}
2029
2030#endif /* NLMCONV_POWERPC */
2031
2032/* Name of linker.  */
2033#ifndef LD_NAME
2034#define LD_NAME "ld"
2035#endif
2036
2037/* The user has specified several input files.  Invoke the linker to
2038   link them all together, and convert and delete the resulting output
2039   file.  */
2040
2041static char *
2042link_inputs (struct string_list *inputs, char *ld, char * mfile)
2043{
2044  size_t c;
2045  struct string_list *q;
2046  char **argv;
2047  size_t i;
2048  int pid;
2049  int status;
2050  char *errfmt;
2051  char *errarg;
2052
2053  c = 0;
2054  for (q = inputs; q != NULL; q = q->next)
2055    ++c;
2056
2057  argv = (char **) alloca ((c + 7) * sizeof (char *));
2058
2059#ifndef __MSDOS__
2060  if (ld == NULL)
2061    {
2062      char *p;
2063
2064      /* Find the linker to invoke based on how nlmconv was run.  */
2065      p = program_name + strlen (program_name);
2066      while (p != program_name)
2067	{
2068	  if (p[-1] == '/')
2069	    {
2070	      ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2071	      memcpy (ld, program_name, p - program_name);
2072	      strcpy (ld + (p - program_name), LD_NAME);
2073	      break;
2074	    }
2075	  --p;
2076	}
2077    }
2078#endif
2079
2080  if (ld == NULL)
2081    ld = (char *) LD_NAME;
2082
2083  unlink_on_exit = make_temp_file (".O");
2084
2085  argv[0] = ld;
2086  argv[1] = (char *) "-Ur";
2087  argv[2] = (char *) "-o";
2088  argv[3] = unlink_on_exit;
2089  /* If we have been given the name of a mapfile and that
2090     name is not 'stderr' then pass it on to the linker.  */
2091  if (mfile
2092      && * mfile
2093      && strcmp (mfile, "stderr") == 0)
2094    {
2095      argv[4] = (char *) "-Map";
2096      argv[5] = mfile;
2097      i = 6;
2098    }
2099  else
2100    i = 4;
2101
2102  for (q = inputs; q != NULL; q = q->next, i++)
2103    argv[i] = q->string;
2104  argv[i] = NULL;
2105
2106  if (debug)
2107    {
2108      for (i = 0; argv[i] != NULL; i++)
2109	fprintf (stderr, " %s", argv[i]);
2110      fprintf (stderr, "\n");
2111    }
2112
2113  pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2114		  PEXECUTE_SEARCH | PEXECUTE_ONE);
2115  if (pid == -1)
2116    {
2117      fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2118      fprintf (stderr, errfmt, errarg);
2119      unlink (unlink_on_exit);
2120      exit (1);
2121    }
2122
2123  if (pwait (pid, &status, 0) < 0)
2124    {
2125      perror ("pwait");
2126      unlink (unlink_on_exit);
2127      exit (1);
2128    }
2129
2130  if (status != 0)
2131    {
2132      non_fatal (_("Execution of %s failed"), ld);
2133      unlink (unlink_on_exit);
2134      exit (1);
2135    }
2136
2137  return unlink_on_exit;
2138}
2139