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