start-sanitize-powerpc-netware
[platform/upstream/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 *, 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, outbfd, &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, outbfd, symbols_ptr, symcount_ptr)
1665      bfd *inbfd;
1666      bfd *outbfd;
1667      asymbol ***symbols_ptr;
1668      long *symcount_ptr;
1669 {
1670   asection *stub_sec;
1671   asection *got_sec;
1672   unsigned int got_base;
1673   long i;
1674   long symcount;
1675   long stubcount;
1676
1677   /* Make a section to hold stubs.  We don't set SEC_HAS_CONTENTS for
1678      the section to prevent copy_sections from reading from it.  */
1679   stub_sec = bfd_make_section (inbfd, ".stubs");
1680   if (stub_sec == (asection *) NULL
1681       || ! bfd_set_section_flags (inbfd, stub_sec,
1682                                   (SEC_CODE
1683                                    | SEC_RELOC
1684                                    | SEC_ALLOC
1685                                    | SEC_LOAD))
1686       || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1687     bfd_fatal (".stubs");
1688
1689   /* Get the TOC section, which is named .got.  */
1690   got_sec = bfd_get_section_by_name (inbfd, ".got");
1691   if (got_sec == (asection *) NULL)
1692     {
1693       got_sec = bfd_make_section (inbfd, ".got");
1694       if (got_sec == (asection *) NULL
1695           || ! bfd_set_section_flags (inbfd, got_sec,
1696                                       (SEC_DATA
1697                                        | SEC_RELOC
1698                                        | SEC_ALLOC
1699                                        | SEC_LOAD
1700                                        | SEC_HAS_CONTENTS))
1701           || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1702         bfd_fatal (".got");
1703     }
1704
1705   powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1706   got_base = powerpc_initial_got_size;
1707   got_base = (got_base + 3) &~ 3;
1708
1709   stubcount = 0;
1710
1711   symcount = *symcount_ptr;
1712   for (i = 0; i < symcount; i++)
1713     {
1714       asymbol *sym;
1715       asymbol *newsym;
1716       char *newname;
1717       struct powerpc_stub *item;
1718
1719       sym = (*symbols_ptr)[i];
1720
1721       /* We must make a stub for every undefined symbol whose name
1722          starts with '.'.  */
1723       if (bfd_asymbol_name (sym)[0] != '.'
1724           || bfd_get_section (sym) != &bfd_und_section)
1725         continue;
1726
1727       /* Make a new undefined symbol with the same name but without
1728          the leading `.'.  */
1729       newsym = (asymbol *) xmalloc (sizeof (asymbol));
1730       *newsym = *sym;
1731       newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1732       strcpy (newname, bfd_asymbol_name (sym) + 1);
1733       newsym->name = newname;
1734
1735       /* Define the `.' symbol to be in the stub section.  */
1736       sym->section = stub_sec;
1737       sym->value = stubcount * POWERPC_STUB_SIZE;
1738       /* We set the BSF_DYNAMIC flag here so that we can check it when
1739          we are mangling relocs.  FIXME: This is a hack.  */
1740       sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1741
1742       /* Add this stub to the linked list.  */
1743       item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1744       item->start = sym;
1745       item->reloc = newsym;
1746       item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1747
1748       item->next = powerpc_stubs;
1749       powerpc_stubs = item;
1750       
1751       ++stubcount;
1752     }
1753
1754   if (stubcount > 0)
1755     {
1756       asymbol **s;
1757       struct powerpc_stub *l;
1758
1759       /* Add the new symbols we just created to the symbol table.  */
1760       *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1761                                             ((symcount + stubcount)
1762                                              * sizeof (asymbol)));
1763       *symcount_ptr += stubcount;
1764       s = &(*symbols_ptr)[symcount];
1765       for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1766         *s++ = l->reloc;
1767
1768       /* Set the size of the .stubs section and increase the size of
1769          the .got section.  */
1770       if (! bfd_set_section_size (inbfd, stub_sec,
1771                                   stubcount * POWERPC_STUB_SIZE)
1772           || ! bfd_set_section_size (inbfd, got_sec,
1773                                      (got_base
1774                                       + (stubcount
1775                                          * POWERPC_STUB_TOC_ENTRY_SIZE))))
1776         bfd_fatal ("stub section sizes");
1777     }
1778
1779   /* PowerPC NetWare requires a custom header.  We create it here.
1780      The first word is the header version number, currently 1.  The
1781      second word is the timestamp of the input file.  */
1782   memcpy (nlm_custom_header (outbfd)->stamp, "CuStHeAd", 8);
1783   nlm_custom_header (outbfd)->dataLength = 8;
1784   nlm_custom_header (outbfd)->data = xmalloc (8);
1785   bfd_h_put_32 (outbfd, (bfd_vma) 1,
1786                 (bfd_byte *) nlm_custom_header (outbfd)->data);
1787   {
1788     struct stat s;
1789
1790     if (stat (bfd_get_filename (inbfd), &s) < 0)
1791       s.st_mtime = 0;
1792     bfd_h_put_32 (outbfd, (bfd_vma) s.st_mtime,
1793                   (bfd_byte *) nlm_custom_header (outbfd)->data + 4);
1794   }
1795 }
1796
1797 /* Resolve all the stubs for PowerPC NetWare.  We fill in the contents
1798    of the output section, and create new relocs in the TOC.  */
1799
1800 static void
1801 powerpc_resolve_stubs (inbfd, outbfd)
1802      bfd *inbfd;
1803      bfd *outbfd;
1804 {
1805   bfd_byte buf[POWERPC_STUB_SIZE];
1806   unsigned int i;
1807   unsigned int stubcount;
1808   arelent **relocs;
1809   asection *got_sec;
1810   arelent **r;
1811   struct powerpc_stub *l;
1812
1813   if (powerpc_stubs == (struct powerpc_stub *) NULL)
1814     return;
1815
1816   for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1817     bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1818
1819   got_sec = bfd_get_section_by_name (inbfd, ".got");
1820   assert (got_sec != (asection *) NULL);
1821   assert (got_sec->output_section->orelocation == (arelent **) NULL);
1822
1823   stubcount = 0;
1824   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1825     ++stubcount;
1826   relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1827
1828   r = relocs;
1829   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1830     {
1831       arelent *reloc;
1832
1833       /* Adjust the first instruction to use the right TOC index.  */
1834       bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1835
1836       /* Write this stub out.  */
1837       if (! bfd_set_section_contents (outbfd,
1838                                       bfd_get_section (l->start),
1839                                       buf,
1840                                       l->start->value,
1841                                       POWERPC_STUB_SIZE))
1842         bfd_fatal ("writing stub");
1843
1844       /* Create a new reloc for the TOC entry.  */
1845       reloc = (arelent *) xmalloc (sizeof (arelent));
1846       reloc->sym_ptr_ptr = &l->reloc;
1847       reloc->address = l->toc_index + got_sec->output_offset;
1848       reloc->addend = 0;
1849       reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1850                                       
1851       *r++ = reloc;
1852     }
1853
1854   bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1855 }
1856
1857 /* Adjust relocation entries for PowerPC NetWare.  We do not output
1858    TOC relocations.  The object code already contains the offset from
1859    the TOC pointer.  When the function is called, the TOC register,
1860    r2, will be set to the correct TOC value, so there is no need for
1861    any further reloc.  */
1862
1863 /*ARGSUSED*/
1864 static void
1865 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1866                        contents_size)
1867      bfd *outbfd;
1868      asection *insec;
1869      register arelent ***relocs_ptr;
1870      long *reloc_count_ptr;
1871      char *contents;
1872      bfd_size_type contents_size;
1873 {
1874   const reloc_howto_type *toc_howto;
1875   long reloc_count;
1876   register arelent **relocs;
1877   register long i;
1878
1879   toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1880   if (toc_howto == (reloc_howto_type *) NULL)
1881     abort ();
1882
1883   /* If this is the .got section, clear out all the contents beyond
1884      the initial size.  We must do this here because copy_sections is
1885      going to write out whatever we return in the contents field.  */
1886   if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1887     memset (contents + powerpc_initial_got_size, 0,
1888             (bfd_get_section_size_after_reloc (insec)
1889              - powerpc_initial_got_size));
1890
1891   reloc_count = *reloc_count_ptr;
1892   relocs = *relocs_ptr;
1893   for (i = 0; i < reloc_count; i++)
1894     {
1895       arelent *rel;
1896       asymbol *sym;
1897       bfd_vma symvalue;
1898
1899       rel = *relocs++;
1900       sym = *rel->sym_ptr_ptr;
1901
1902       /* We must be able to resolve all PC relative relocs at this
1903          point.  If we get a branch to an undefined symbol we build a
1904          stub, since NetWare will resolve undefined symbols into a
1905          pointer to a function descriptor.  */
1906       if (rel->howto->pc_relative)
1907         {
1908           /* This check for whether a symbol is in the same section as
1909              the reloc will be wrong if there is a PC relative reloc
1910              between two sections both of which were placed in the
1911              same output section.  This should not happen.  */
1912           if (bfd_get_section (sym) != insec->output_section)
1913             fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1914                      program_name, bfd_asymbol_name (sym));
1915           else
1916             {
1917               bfd_vma val;
1918
1919               assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1920               val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1921               val = ((val &~ rel->howto->dst_mask)
1922                      | (((val & rel->howto->src_mask)
1923                          + (sym->value - rel->address)
1924                          + rel->addend)
1925                         & rel->howto->dst_mask));
1926               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1927
1928               /* If this reloc is against an stubbed symbol and the
1929                  next instruction is
1930                      cror 31,31,31
1931                  then we replace the next instruction with
1932                      lwz  r2,20(r1)
1933                  This reloads the TOC pointer after a stub call.  */
1934               if (bfd_asymbol_name (sym)[0] == '.'
1935                   && (sym->flags & BSF_DYNAMIC) != 0
1936                   && (bfd_get_32 (outbfd,
1937                                   (bfd_byte *) contents + rel->address + 4)
1938                       == 0x4ffffb82)) /* cror 31,31,31 */
1939                 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1940                             (bfd_byte *) contents + rel->address + 4);
1941
1942               --*reloc_count_ptr;
1943               --relocs;
1944               memmove (relocs, relocs + 1,
1945                        (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1946               continue;
1947             }
1948         }
1949
1950       /* When considering a TOC reloc, we do not want to include the
1951          symbol value.  The symbol will be start of the TOC section
1952          (which is named .got).  We do want to include the addend.  */
1953       if (rel->howto == toc_howto)
1954         symvalue = 0;
1955       else
1956         symvalue = sym->value;
1957
1958       /* If this is a relocation against a symbol with a value, or
1959          there is a reloc addend, we need to update the addend in the
1960          object file.  */
1961       if (symvalue + rel->addend != 0)
1962         {
1963           bfd_vma val;
1964
1965           switch (rel->howto->size)
1966             {
1967             case 1:
1968               val = bfd_get_16 (outbfd,
1969                                 (bfd_byte *) contents + rel->address);
1970               val = ((val &~ rel->howto->dst_mask)
1971                      | (((val & rel->howto->src_mask)
1972                          + symvalue
1973                          + rel->addend)
1974                         & rel->howto->dst_mask));
1975               if ((bfd_signed_vma) val < - 0x8000
1976                   || (bfd_signed_vma) val >= 0x8000)
1977                 fprintf (stderr,
1978                          "%s: overflow when adjusting relocation against %s\n",
1979                          program_name, bfd_asymbol_name (sym));
1980               bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1981               break;
1982
1983             case 2:
1984               val = bfd_get_32 (outbfd,
1985                                 (bfd_byte *) contents + rel->address);
1986               val = ((val &~ rel->howto->dst_mask)
1987                      | (((val & rel->howto->src_mask)
1988                          + symvalue
1989                          + rel->addend)
1990                         & rel->howto->dst_mask));
1991               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1992               break;
1993
1994             default:
1995               abort ();
1996             }
1997
1998           rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1999           rel->addend = 0;
2000         }
2001
2002       /* Now that we have incorporated the addend, remove any TOC
2003          relocs.  */
2004       if (rel->howto == toc_howto)
2005         {
2006           --*reloc_count_ptr;
2007           --relocs;
2008           memmove (relocs, relocs + 1,
2009                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
2010           continue;
2011         }
2012
2013       rel->address += insec->output_offset;
2014     }
2015 }
2016 /* end-sanitize-powerpc-netware */
2017 \f
2018 /* Name of linker.  */
2019 #ifndef LD_NAME
2020 #define LD_NAME "ld"
2021 #endif
2022
2023 /* Temporary file name base.  */
2024 static char *temp_filename;
2025
2026 /* The user has specified several input files.  Invoke the linker to
2027    link them all together, and convert and delete the resulting output
2028    file.  */
2029
2030 static char *
2031 link_inputs (inputs, ld)
2032      struct string_list *inputs;
2033      char *ld;
2034 {
2035   size_t c;
2036   struct string_list *q;
2037   char **argv;
2038   size_t i;
2039   int pid;
2040   int status;
2041
2042   c = 0;
2043   for (q = inputs; q != NULL; q = q->next)
2044     ++c;
2045
2046   argv = (char **) alloca (c + 5);
2047
2048 #ifndef __MSDOS__
2049   if (ld == NULL)
2050     {
2051       char *p;
2052
2053       /* Find the linker to invoke based on how nlmconv was run.  */
2054       p = program_name + strlen (program_name);
2055       while (p != program_name)
2056         {
2057           if (p[-1] == '/')
2058             {
2059               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2060               memcpy (ld, program_name, p - program_name);
2061               strcpy (ld + (p - program_name), LD_NAME);
2062               break;
2063             }
2064           --p;
2065         }
2066     }
2067 #endif
2068
2069   if (ld == NULL)
2070     ld = (char *) LD_NAME;
2071
2072   choose_temp_base ();
2073
2074   unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2075   sprintf (unlink_on_exit, "%s.O", temp_filename);
2076
2077   argv[0] = ld;
2078   argv[1] = (char *) "-r";
2079   argv[2] = (char *) "-o";
2080   argv[3] = unlink_on_exit;
2081   i = 4;
2082   for (q = inputs; q != NULL; q = q->next, i++)
2083     argv[i] = q->string;
2084   argv[i] = NULL;
2085
2086   if (debug)
2087     {
2088       for (i = 0; argv[i] != NULL; i++)
2089         fprintf (stderr, " %s", argv[i]);
2090       fprintf (stderr, "\n");
2091     }
2092
2093   pid = pexecute (ld, argv);
2094
2095   if (waitpid (pid, &status, 0) < 0)
2096     {
2097       perror ("waitpid");
2098       unlink (unlink_on_exit);
2099       exit (1);
2100     }
2101
2102   if (status != 0)
2103     {
2104       fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2105       unlink (unlink_on_exit);
2106       exit (1);
2107     }
2108
2109   return unlink_on_exit;
2110 }
2111
2112 /* Choose a temporary file name.  Stolen from gcc.c.  */
2113
2114 static const char *
2115 choose_temp_base_try (try, base)
2116      const char *try;
2117      const char *base;
2118 {
2119   const char *rv;
2120
2121   if (base)
2122     rv = base;
2123   else if (try == NULL)
2124     rv = NULL;
2125   else if (access (try, R_OK | W_OK) != 0)
2126     rv = NULL;
2127   else
2128     rv = try;
2129   return rv;
2130 }
2131
2132 static void
2133 choose_temp_base ()
2134 {
2135   const char *base = NULL;
2136   int len;
2137
2138   base = choose_temp_base_try (getenv ("TMPDIR"), base);
2139   base = choose_temp_base_try (getenv ("TMP"), base);
2140   base = choose_temp_base_try (getenv ("TEMP"), base);
2141
2142 #ifdef P_tmpdir
2143   base = choose_temp_base_try (P_tmpdir, base);
2144 #endif
2145
2146   base = choose_temp_base_try ("/usr/tmp", base);
2147   base = choose_temp_base_try ("/tmp", base);
2148
2149   /* If all else fails, use the current directory! */  
2150   if (base == NULL)
2151     base = "./";
2152
2153   len = strlen (base);
2154   temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2155   strcpy (temp_filename, base);
2156   if (len > 0 && temp_filename[len-1] != '/')
2157     temp_filename[len++] = '/';
2158   strcpy (temp_filename + len, "ccXXXXXX");
2159
2160   mktemp (temp_filename);
2161   if (*temp_filename == '\0')
2162     abort ();
2163 }
2164
2165 /* Execute a job.  Stolen from gcc.c.  */
2166
2167 #ifndef OS2
2168 #ifdef __MSDOS__
2169
2170 static int
2171 pexecute (program, argv)
2172      char *program;
2173      char *argv[];
2174 {
2175   char *scmd, *rf;
2176   FILE *argfile;
2177   int i;
2178
2179   scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2180   rf = scmd + strlen(program) + 2 + el;
2181   sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2182   argfile = fopen (rf, "w");
2183   if (argfile == 0)
2184     pfatal_with_name (rf);
2185
2186   for (i=1; argv[i]; i++)
2187     {
2188       char *cp;
2189       for (cp = argv[i]; *cp; cp++)
2190         {
2191           if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2192             fputc ('\\', argfile);
2193           fputc (*cp, argfile);
2194         }
2195       fputc ('\n', argfile);
2196     }
2197   fclose (argfile);
2198
2199   i = system (scmd);
2200
2201   remove (rf);
2202   
2203   if (i == -1)
2204     {
2205       perror (program);
2206       return MIN_FATAL_STATUS << 8;
2207     }
2208
2209   return i << 8;
2210 }
2211
2212 #else /* not __MSDOS__ */
2213
2214 static int
2215 pexecute (program, argv)
2216      char *program;
2217      char *argv[];
2218 {
2219   int pid;
2220   int retries, sleep_interval;
2221
2222   /* Fork a subprocess; wait and retry if it fails.  */
2223   sleep_interval = 1;
2224   for (retries = 0; retries < 4; retries++)
2225     {
2226       pid = vfork ();
2227       if (pid >= 0)
2228         break;
2229       sleep (sleep_interval);
2230       sleep_interval *= 2;
2231     }
2232
2233   switch (pid)
2234     {
2235     case -1:
2236 #ifdef vfork
2237       perror ("fork");
2238 #else
2239       perror ("vfork");
2240 #endif
2241       exit (1);
2242       /* NOTREACHED */
2243       return 0;
2244
2245     case 0: /* child */
2246       /* Exec the program.  */
2247       execvp (program, argv);
2248       perror (program);
2249       exit (1);
2250       /* NOTREACHED */
2251       return 0;
2252
2253     default:
2254       /* Return child's process number.  */
2255       return pid;
2256     }
2257 }
2258
2259 #endif /* not __MSDOS__ */
2260 #else /* not OS2 */
2261
2262 static int
2263 pexecute (program, argv)
2264      char *program;
2265      char *argv[];
2266 {
2267   return spawnvp (1, program, argv);
2268 }
2269 #endif /* not OS2 */