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