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