gdb: Remove hard-coded line number from test
[external/binutils.git] / binutils / nlmconv.c
1 /* nlmconv.c -- NLM conversion program
2    Copyright (C) 1993-2017 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   bfd_byte *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       if (!bfd_malloc_and_get_section (inbfd, insec, &contents))
1244         bfd_fatal (bfd_get_filename (inbfd));
1245     }
1246
1247   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1248   if (reloc_size < 0)
1249     bfd_fatal (bfd_get_filename (inbfd));
1250   if (reloc_size != 0)
1251     {
1252       arelent **relocs;
1253       long reloc_count;
1254
1255       relocs = (arelent **) xmalloc (reloc_size);
1256       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1257       if (reloc_count < 0)
1258         bfd_fatal (bfd_get_filename (inbfd));
1259       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1260                      size);
1261
1262       /* FIXME: refers to internal BFD fields.  */
1263       if (outsec->orelocation != (arelent **) NULL)
1264         {
1265           bfd_size_type total_count;
1266           arelent **combined;
1267
1268           total_count = reloc_count + outsec->reloc_count;
1269           combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1270           memcpy (combined, outsec->orelocation,
1271                   outsec->reloc_count * sizeof (arelent *));
1272           memcpy (combined + outsec->reloc_count, relocs,
1273                   (size_t) (reloc_count * sizeof (arelent *)));
1274           free (outsec->orelocation);
1275           reloc_count = total_count;
1276           relocs = combined;
1277         }
1278
1279       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1280     }
1281
1282   if (contents != NULL)
1283     {
1284       if (! bfd_set_section_contents (outbfd, outsec, contents,
1285                                       insec->output_offset, size))
1286         bfd_fatal (bfd_get_filename (outbfd));
1287       free (contents);
1288     }
1289
1290   /* Add this section to .nlmsections.  */
1291   if (! bfd_set_section_contents (outbfd, secsec, (void *) inname, secsecoff,
1292                                   strlen (inname) + 1))
1293     bfd_fatal (_("set .nlmsection contents"));
1294   secsecoff += strlen (inname) + 1;
1295
1296   add = ((secsecoff + 3) &~ 3) - secsecoff;
1297   if (add != 0)
1298     {
1299       bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1300       if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1301         bfd_fatal (_("set .nlmsection contents"));
1302       secsecoff += add;
1303     }
1304
1305   if (contents != NULL)
1306     bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1307   else
1308     bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1309   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1310     bfd_fatal (_("set .nlmsection contents"));
1311   secsecoff += 4;
1312
1313   bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1314   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1315     bfd_fatal (_("set .nlmsection contents"));
1316   secsecoff += 4;
1317 }
1318
1319 /* Some, perhaps all, NetWare targets require changing the relocs used
1320    by the input formats.  */
1321
1322 static void
1323 mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
1324                long *reloc_count_ptr, char *contents,
1325                bfd_size_type contents_size)
1326 {
1327   switch (bfd_get_arch (outbfd))
1328     {
1329 #ifdef NLMCONV_I386
1330     case bfd_arch_i386:
1331       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1332                           contents, contents_size);
1333       break;
1334 #endif
1335 #ifdef NLMCONV_ALPHA
1336     case bfd_arch_alpha:
1337       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1338                            contents, contents_size);
1339       break;
1340 #endif
1341 #ifdef NLMCONV_POWERPC
1342     case bfd_arch_powerpc:
1343       powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1344                              contents, contents_size);
1345       break;
1346 #endif
1347     default:
1348       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1349                              contents, contents_size);
1350       break;
1351     }
1352 }
1353
1354 /* By default all we need to do for relocs is change the address by
1355    the output_offset.  */
1356
1357 static void
1358 default_mangle_relocs (bfd *outbfd ATTRIBUTE_UNUSED, asection *insec,
1359                        arelent ***relocs_ptr, long *reloc_count_ptr,
1360                        char *contents ATTRIBUTE_UNUSED,
1361                        bfd_size_type contents_size ATTRIBUTE_UNUSED)
1362 {
1363   if (insec->output_offset != 0)
1364     {
1365       long reloc_count;
1366       arelent **relocs;
1367       long i;
1368
1369       reloc_count = *reloc_count_ptr;
1370       relocs = *relocs_ptr;
1371       for (i = 0; i < reloc_count; i++, relocs++)
1372         (*relocs)->address += insec->output_offset;
1373     }
1374 }
1375 \f
1376 #ifdef NLMCONV_I386
1377
1378 /* NetWare on the i386 supports a restricted set of relocs, which are
1379    different from those used on other i386 targets.  This routine
1380    converts the relocs.  It is, obviously, very target dependent.  At
1381    the moment, the nlm32-i386 backend performs similar translations;
1382    however, it is more reliable and efficient to do them here.  */
1383
1384 static reloc_howto_type nlm_i386_pcrel_howto =
1385   HOWTO (1,                     /* type */
1386          0,                     /* rightshift */
1387          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1388          32,                    /* bitsize */
1389          TRUE,                  /* pc_relative */
1390          0,                     /* bitpos */
1391          complain_overflow_signed, /* complain_on_overflow */
1392          0,                     /* special_function */
1393          "DISP32",              /* name */
1394          TRUE,                  /* partial_inplace */
1395          0xffffffff,            /* src_mask */
1396          0xffffffff,            /* dst_mask */
1397          TRUE);                 /* pcrel_offset */
1398
1399 static void
1400 i386_mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
1401                     long *reloc_count_ptr, char *contents,
1402                     bfd_size_type contents_size)
1403 {
1404   long reloc_count, i;
1405   arelent **relocs;
1406
1407   reloc_count = *reloc_count_ptr;
1408   relocs = *relocs_ptr;
1409   for (i = 0; i < reloc_count; i++)
1410     {
1411       arelent *rel;
1412       asymbol *sym;
1413       bfd_size_type address;
1414       bfd_vma addend;
1415
1416       rel = *relocs++;
1417       /* PR 17512: file: 057f89c1.  */
1418       if (rel->sym_ptr_ptr == NULL)
1419         continue;
1420       sym = *rel->sym_ptr_ptr;
1421
1422       /* We're moving the relocs from the input section to the output
1423          section, so we must adjust the address accordingly.  */
1424       address = rel->address;
1425       rel->address += insec->output_offset;
1426
1427       /* Note that no serious harm will ensue if we fail to change a
1428          reloc.  The backend will fail when writing out the reloc.  */
1429
1430       /* Make sure this reloc is within the data we have.  We use only
1431          4 byte relocs here, so we insist on having 4 bytes.  */
1432       if (address + 4 > contents_size)
1433         continue;
1434
1435       /* A PC relative reloc entirely within a single section is
1436          completely unnecessary.  This can be generated by ld -r.  */
1437       if (sym == insec->symbol
1438           && rel->howto != NULL
1439           && rel->howto->pc_relative
1440           && ! rel->howto->pcrel_offset)
1441         {
1442           --*reloc_count_ptr;
1443           --relocs;
1444           memmove (relocs, relocs + 1,
1445                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1446           continue;
1447         }
1448
1449       /* Get the amount the relocation will add in.  */
1450       addend = rel->addend + sym->value;
1451
1452       /* NetWare doesn't support PC relative relocs against defined
1453          symbols, so we have to eliminate them by doing the relocation
1454          now.  We can only do this if the reloc is within a single
1455          section.  */
1456       if (rel->howto != NULL
1457           && rel->howto->pc_relative
1458           && bfd_get_section (sym) == insec->output_section)
1459         {
1460           bfd_vma val;
1461
1462           if (rel->howto->pcrel_offset)
1463             addend -= address;
1464
1465           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1466           val += addend;
1467           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1468
1469           --*reloc_count_ptr;
1470           --relocs;
1471           memmove (relocs, relocs + 1,
1472                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1473           continue;
1474         }
1475
1476       /* NetWare doesn't support reloc addends, so we get rid of them
1477          here by simply adding them into the object data.  We handle
1478          the symbol value, if any, the same way.  */
1479       if (addend != 0
1480           && rel->howto != NULL
1481           && rel->howto->rightshift == 0
1482           && rel->howto->size == 2
1483           && rel->howto->bitsize == 32
1484           && rel->howto->bitpos == 0
1485           && rel->howto->src_mask == 0xffffffff
1486           && rel->howto->dst_mask == 0xffffffff)
1487         {
1488           bfd_vma val;
1489
1490           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1491           val += addend;
1492           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1493
1494           /* Adjust the reloc for the changes we just made.  */
1495           rel->addend = 0;
1496           if (! bfd_is_und_section (bfd_get_section (sym)))
1497             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1498         }
1499
1500       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1501          pc_relative relocs accordingly.  We are going to change the
1502          howto field, so we can only do this if the current one is
1503          compatible.  We should check that special_function is NULL
1504          here, but at the moment coff-i386 uses a special_function
1505          which does not affect what we are doing here.  */
1506       if (rel->howto != NULL
1507           && rel->howto->pc_relative
1508           && ! rel->howto->pcrel_offset
1509           && rel->howto->rightshift == 0
1510           && rel->howto->size == 2
1511           && rel->howto->bitsize == 32
1512           && rel->howto->bitpos == 0
1513           && rel->howto->src_mask == 0xffffffff
1514           && rel->howto->dst_mask == 0xffffffff)
1515         {
1516           bfd_vma val;
1517
1518           /* When pcrel_offset is not set, it means that the negative
1519              of the address of the memory location is stored in the
1520              memory location.  We must add it back in.  */
1521           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1522           val += address;
1523           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1524
1525           /* We must change to a new howto.  */
1526           rel->howto = &nlm_i386_pcrel_howto;
1527         }
1528     }
1529 }
1530
1531 #endif /* NLMCONV_I386 */
1532 \f
1533 #ifdef NLMCONV_ALPHA
1534
1535 /* On the Alpha the first reloc for every section must be a special
1536    relocs which hold the GP address.  Also, the first reloc in the
1537    file must be a special reloc which holds the address of the .lita
1538    section.  */
1539
1540 static reloc_howto_type nlm32_alpha_nw_howto =
1541   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1542          0,                     /* rightshift */
1543          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1544          0,                     /* bitsize */
1545          FALSE,                 /* pc_relative */
1546          0,                     /* bitpos */
1547          complain_overflow_dont, /* complain_on_overflow */
1548          0,                     /* special_function */
1549          "NW_RELOC",            /* name */
1550          FALSE,                 /* partial_inplace */
1551          0,                     /* src_mask */
1552          0,                     /* dst_mask */
1553          FALSE);                /* pcrel_offset */
1554
1555 static void
1556 alpha_mangle_relocs (bfd *outbfd, asection *insec,
1557                      arelent ***relocs_ptr, long *reloc_count_ptr,
1558                      char *contents ATTRIBUTE_UNUSED,
1559                      bfd_size_type contents_size ATTRIBUTE_UNUSED)
1560 {
1561   long old_reloc_count;
1562   arelent **old_relocs;
1563   arelent **relocs;
1564
1565   old_reloc_count = *reloc_count_ptr;
1566   old_relocs = *relocs_ptr;
1567   relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1568   *relocs_ptr = relocs;
1569
1570   if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1571     {
1572       bfd *inbfd;
1573       asection *lita_section;
1574
1575       inbfd = insec->owner;
1576       lita_section = bfd_get_section_by_name (inbfd, _LITA);
1577       if (lita_section != (asection *) NULL)
1578         {
1579           nlm_alpha_backend_data (outbfd)->lita_address =
1580             bfd_get_section_vma (inbfd, lita_section);
1581           nlm_alpha_backend_data (outbfd)->lita_size =
1582             bfd_section_size (inbfd, lita_section);
1583         }
1584       else
1585         {
1586           /* Avoid outputting this reloc again.  */
1587           nlm_alpha_backend_data (outbfd)->lita_address = 4;
1588         }
1589
1590       *relocs = (arelent *) xmalloc (sizeof (arelent));
1591       (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1592       (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1593       (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1594       (*relocs)->howto = &nlm32_alpha_nw_howto;
1595       ++relocs;
1596       ++(*reloc_count_ptr);
1597     }
1598
1599   /* Get the GP value from bfd.  */
1600   if (nlm_alpha_backend_data (outbfd)->gp == 0)
1601     nlm_alpha_backend_data (outbfd)->gp =
1602       bfd_ecoff_get_gp_value (insec->owner);
1603
1604   *relocs = (arelent *) xmalloc (sizeof (arelent));
1605   (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1606   (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1607   (*relocs)->addend = 0;
1608   (*relocs)->howto = &nlm32_alpha_nw_howto;
1609   ++relocs;
1610   ++(*reloc_count_ptr);
1611
1612   memcpy (relocs, old_relocs, (size_t) old_reloc_count * sizeof (arelent *));
1613   relocs[old_reloc_count] = (arelent *) NULL;
1614
1615   free (old_relocs);
1616
1617   if (insec->output_offset != 0)
1618     {
1619       bfd_size_type i;
1620
1621       for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
1622         (*relocs)->address += insec->output_offset;
1623     }
1624 }
1625
1626 #endif /* NLMCONV_ALPHA */
1627 \f
1628 #ifdef NLMCONV_POWERPC
1629
1630 /* We keep a linked list of stubs which we must build.  Because BFD
1631    requires us to know the sizes of all sections before we can set the
1632    contents of any, we must figure out which stubs we want to build
1633    before we can actually build any of them.  */
1634
1635 struct powerpc_stub
1636 {
1637   /* Next stub in linked list.  */
1638   struct powerpc_stub *next;
1639
1640   /* Symbol whose value is the start of the stub.  This is a symbol
1641      whose name begins with `.'.  */
1642   asymbol *start;
1643
1644   /* Symbol we are going to create a reloc against.  This is a symbol
1645      with the same name as START but without the leading `.'.  */
1646   asymbol *reloc;
1647
1648   /* The TOC index for this stub.  This is the index into the TOC
1649      section at which the reloc is created.  */
1650   unsigned int toc_index;
1651 };
1652
1653 /* The linked list of stubs.  */
1654
1655 static struct powerpc_stub *powerpc_stubs;
1656
1657 /* This is what a stub looks like.  The first instruction will get
1658    adjusted with the correct TOC index.  */
1659
1660 static unsigned long powerpc_stub_insns[] =
1661 {
1662   0x81820000,           /* lwz   r12,0(r2) */
1663   0x90410014,           /* stw   r2,20(r1) */
1664   0x800c0000,           /* lwz   r0,0(r12) */
1665   0x804c0004,           /* lwz   r2,r(r12) */
1666   0x7c0903a6,           /* mtctr r0 */
1667   0x4e800420,           /* bctr */
1668   0,                    /* Traceback table.  */
1669   0xc8000,
1670   0
1671 };
1672
1673 #define POWERPC_STUB_INSN_COUNT \
1674   (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1675
1676 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1677
1678 /* Each stub uses a four byte TOC entry.  */
1679 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1680
1681 /* The original size of the .got section.  */
1682 static bfd_size_type powerpc_initial_got_size;
1683
1684 /* Look for all undefined symbols beginning with `.', and prepare to
1685    build a stub for each one.  */
1686
1687 static void
1688 powerpc_build_stubs (bfd *inbfd, bfd *outbfd ATTRIBUTE_UNUSED,
1689                      asymbol ***symbols_ptr, long *symcount_ptr)
1690 {
1691   asection *stub_sec;
1692   asection *got_sec;
1693   unsigned int got_base;
1694   long i;
1695   long symcount;
1696   long stubcount;
1697
1698   /* Make a section to hold stubs.  We don't set SEC_HAS_CONTENTS for
1699      the section to prevent copy_sections from reading from it.  */
1700   stub_sec = bfd_make_section_with_flags (inbfd, ".stubs",
1701                                           (SEC_CODE
1702                                            | SEC_RELOC
1703                                            | SEC_ALLOC
1704                                            | SEC_LOAD));
1705   if (stub_sec == (asection *) NULL
1706       || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1707     bfd_fatal (".stubs");
1708
1709   /* Get the TOC section, which is named .got.  */
1710   got_sec = bfd_get_section_by_name (inbfd, ".got");
1711   if (got_sec == (asection *) NULL)
1712     {
1713       got_sec = bfd_make_section_with_flags (inbfd, ".got",
1714                                              (SEC_DATA
1715                                               | SEC_RELOC
1716                                               | SEC_ALLOC
1717                                               | SEC_LOAD
1718                                               | SEC_HAS_CONTENTS));
1719       if (got_sec == (asection *) NULL
1720           || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1721         bfd_fatal (".got");
1722     }
1723
1724   powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1725   got_base = powerpc_initial_got_size;
1726   got_base = (got_base + 3) &~ 3;
1727
1728   stubcount = 0;
1729
1730   symcount = *symcount_ptr;
1731   for (i = 0; i < symcount; i++)
1732     {
1733       asymbol *sym;
1734       asymbol *newsym;
1735       char *newname;
1736       struct powerpc_stub *item;
1737
1738       sym = (*symbols_ptr)[i];
1739
1740       /* We must make a stub for every undefined symbol whose name
1741          starts with '.'.  */
1742       if (bfd_asymbol_name (sym)[0] != '.'
1743           || ! bfd_is_und_section (bfd_get_section (sym)))
1744         continue;
1745
1746       /* Make a new undefined symbol with the same name but without
1747          the leading `.'.  */
1748       newsym = xmalloc (sizeof (asymbol));
1749       *newsym = *sym;
1750       newname = xmalloc (strlen (bfd_asymbol_name (sym)));
1751       strcpy (newname, bfd_asymbol_name (sym) + 1);
1752       newsym->name = newname;
1753
1754       /* Define the `.' symbol to be in the stub section.  */
1755       sym->section = stub_sec;
1756       sym->value = stubcount * POWERPC_STUB_SIZE;
1757       /* We set the BSF_DYNAMIC flag here so that we can check it when
1758          we are mangling relocs.  FIXME: This is a hack.  */
1759       sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1760
1761       /* Add this stub to the linked list.  */
1762       item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1763       item->start = sym;
1764       item->reloc = newsym;
1765       item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1766
1767       item->next = powerpc_stubs;
1768       powerpc_stubs = item;
1769
1770       ++stubcount;
1771     }
1772
1773   if (stubcount > 0)
1774     {
1775       asymbol **s;
1776       struct powerpc_stub *l;
1777
1778       /* Add the new symbols we just created to the symbol table.  */
1779       *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1780                                             ((symcount + stubcount)
1781                                              * sizeof (asymbol)));
1782       *symcount_ptr += stubcount;
1783       s = &(*symbols_ptr)[symcount];
1784       for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1785         *s++ = l->reloc;
1786
1787       /* Set the size of the .stubs section and increase the size of
1788          the .got section.  */
1789       if (! bfd_set_section_size (inbfd, stub_sec,
1790                                   stubcount * POWERPC_STUB_SIZE)
1791           || ! bfd_set_section_size (inbfd, got_sec,
1792                                      (got_base
1793                                       + (stubcount
1794                                          * POWERPC_STUB_TOC_ENTRY_SIZE))))
1795         bfd_fatal (_("stub section sizes"));
1796     }
1797 }
1798
1799 /* Resolve all the stubs for PowerPC NetWare.  We fill in the contents
1800    of the output section, and create new relocs in the TOC.  */
1801
1802 static void
1803 powerpc_resolve_stubs (bfd *inbfd, bfd *outbfd)
1804 {
1805   bfd_byte buf[POWERPC_STUB_SIZE];
1806   unsigned int i;
1807   unsigned int stubcount;
1808   arelent **relocs;
1809   asection *got_sec;
1810   arelent **r;
1811   struct powerpc_stub *l;
1812
1813   if (powerpc_stubs == (struct powerpc_stub *) NULL)
1814     return;
1815
1816   for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1817     bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1818
1819   got_sec = bfd_get_section_by_name (inbfd, ".got");
1820   assert (got_sec != (asection *) NULL);
1821   assert (got_sec->output_section->orelocation == (arelent **) NULL);
1822
1823   stubcount = 0;
1824   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1825     ++stubcount;
1826   relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1827
1828   r = relocs;
1829   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1830     {
1831       arelent *reloc;
1832
1833       /* Adjust the first instruction to use the right TOC index.  */
1834       bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1835
1836       /* Write this stub out.  */
1837       if (! bfd_set_section_contents (outbfd,
1838                                       bfd_get_section (l->start),
1839                                       buf,
1840                                       l->start->value,
1841                                       POWERPC_STUB_SIZE))
1842         bfd_fatal (_("writing stub"));
1843
1844       /* Create a new reloc for the TOC entry.  */
1845       reloc = (arelent *) xmalloc (sizeof (arelent));
1846       reloc->sym_ptr_ptr = &l->reloc;
1847       reloc->address = l->toc_index + got_sec->output_offset;
1848       reloc->addend = 0;
1849       reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1850
1851       *r++ = reloc;
1852     }
1853
1854   bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1855 }
1856
1857 /* Adjust relocation entries for PowerPC NetWare.  We do not output
1858    TOC relocations.  The object code already contains the offset from
1859    the TOC pointer.  When the function is called, the TOC register,
1860    r2, will be set to the correct TOC value, so there is no need for
1861    any further reloc.  */
1862
1863 static void
1864 powerpc_mangle_relocs (bfd *outbfd, asection *insec,
1865                        arelent ***relocs_ptr,
1866                        long *reloc_count_ptr, char *contents,
1867                        bfd_size_type contents_size ATTRIBUTE_UNUSED)
1868 {
1869   reloc_howto_type *toc_howto;
1870   long reloc_count;
1871   arelent **relocs;
1872   long i;
1873
1874   toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1875   if (toc_howto == (reloc_howto_type *) NULL)
1876     fatal (_("Unable to locate PPC_TOC16 reloc information"));
1877
1878   /* If this is the .got section, clear out all the contents beyond
1879      the initial size.  We must do this here because copy_sections is
1880      going to write out whatever we return in the contents field.  */
1881   if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1882     memset (contents + powerpc_initial_got_size, 0,
1883             (size_t) (bfd_get_section_size (insec) - powerpc_initial_got_size));
1884
1885   reloc_count = *reloc_count_ptr;
1886   relocs = *relocs_ptr;
1887   for (i = 0; i < reloc_count; i++)
1888     {
1889       arelent *rel;
1890       asymbol *sym;
1891       bfd_vma sym_value;
1892
1893       rel = *relocs++;
1894       sym = *rel->sym_ptr_ptr;
1895
1896       /* Convert any relocs against the .bss section into relocs
1897          against the .data section.  */
1898       if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1899                   NLM_UNINITIALIZED_DATA_NAME) == 0)
1900         {
1901           asection *datasec;
1902
1903           datasec = bfd_get_section_by_name (outbfd,
1904                                              NLM_INITIALIZED_DATA_NAME);
1905           if (datasec != NULL)
1906             {
1907               rel->addend += (bfd_get_section_vma (outbfd,
1908                                                    bfd_get_section (sym))
1909                               + sym->value);
1910               rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1911               sym = *rel->sym_ptr_ptr;
1912             }
1913         }
1914
1915       /* PR 17512: file: 70cfde95.  */
1916       if (rel->howto == NULL)
1917         continue;
1918
1919       /* We must be able to resolve all PC relative relocs at this
1920          point.  If we get a branch to an undefined symbol we build a
1921          stub, since NetWare will resolve undefined symbols into a
1922          pointer to a function descriptor.  */
1923       if (rel->howto->pc_relative)
1924         {
1925           /* This check for whether a symbol is in the same section as
1926              the reloc will be wrong if there is a PC relative reloc
1927              between two sections both of which were placed in the
1928              same output section.  This should not happen.  */
1929           if (bfd_get_section (sym) != insec->output_section)
1930             non_fatal (_("unresolved PC relative reloc against %s"),
1931                        bfd_asymbol_name (sym));
1932           else
1933             {
1934               bfd_vma val;
1935
1936               if (rel->address > contents_size - 4)
1937                 {
1938                   non_fatal (_("Out of range relocation: %lx"),
1939                              (long) rel->address);
1940                   break;
1941                 }
1942
1943               assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1944               val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1945               val = ((val &~ rel->howto->dst_mask)
1946                      | (((val & rel->howto->src_mask)
1947                          + (sym->value - rel->address)
1948                          + rel->addend)
1949                         & rel->howto->dst_mask));
1950               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1951
1952               /* If this reloc is against an stubbed symbol and the
1953                  next instruction is
1954                      cror 31,31,31
1955                  then we replace the next instruction with
1956                      lwz  r2,20(r1)
1957                  This reloads the TOC pointer after a stub call.  */
1958               if (bfd_asymbol_name (sym)[0] == '.'
1959                   && (sym->flags & BSF_DYNAMIC) != 0
1960                   && (bfd_get_32 (outbfd,
1961                                   (bfd_byte *) contents + rel->address + 4)
1962                       == 0x4ffffb82)) /* cror 31,31,31 */
1963                 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1964                             (bfd_byte *) contents + rel->address + 4);
1965
1966               --*reloc_count_ptr;
1967               --relocs;
1968               memmove (relocs, relocs + 1,
1969                        (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1970               continue;
1971             }
1972         }
1973
1974       /* When considering a TOC reloc, we do not want to include the
1975          symbol value.  The symbol will be start of the TOC section
1976          (which is named .got).  We do want to include the addend.  */
1977       if (rel->howto == toc_howto)
1978         sym_value = 0;
1979       else
1980         sym_value = sym->value;
1981
1982       /* If this is a relocation against a symbol with a value, or
1983          there is a reloc addend, we need to update the addend in the
1984          object file.  */
1985       if (sym_value + rel->addend != 0)
1986         {
1987           bfd_vma val;
1988
1989           switch (rel->howto->size)
1990             {
1991             case 1:
1992               if (rel->address > contents_size - 2)
1993                 {
1994                   non_fatal (_("Out of range relocation: %lx"),
1995                              (long) rel->address);
1996                   break;
1997                 }
1998
1999               val = bfd_get_16 (outbfd,
2000                                 (bfd_byte *) contents + rel->address);
2001               val = ((val &~ rel->howto->dst_mask)
2002                      | (((val & rel->howto->src_mask)
2003                          + sym_value
2004                          + rel->addend)
2005                         & rel->howto->dst_mask));
2006               if ((bfd_signed_vma) val < - 0x8000
2007                   || (bfd_signed_vma) val >= 0x8000)
2008                 non_fatal (_("overflow when adjusting relocation against %s"),
2009                            bfd_asymbol_name (sym));
2010               bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2011               break;
2012
2013             case 2:
2014               /* PR 17512: file: 0455a112.  */
2015               if (rel->address > contents_size - 4)
2016                 {
2017                   non_fatal (_("Out of range relocation: %lx"),
2018                              (long) rel->address);
2019                   break;
2020                 }
2021
2022               val = bfd_get_32 (outbfd,
2023                                 (bfd_byte *) contents + rel->address);
2024               val = ((val &~ rel->howto->dst_mask)
2025                      | (((val & rel->howto->src_mask)
2026                          + sym_value
2027                          + rel->addend)
2028                         & rel->howto->dst_mask));
2029               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2030               break;
2031
2032             default:
2033               fatal (_("Unsupported relocation size: %d"), rel->howto->size);
2034             }
2035
2036           if (! bfd_is_und_section (bfd_get_section (sym)))
2037             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2038           rel->addend = 0;
2039         }
2040
2041       /* Now that we have incorporated the addend, remove any TOC
2042          relocs.  */
2043       if (rel->howto == toc_howto)
2044         {
2045           --*reloc_count_ptr;
2046           --relocs;
2047           memmove (relocs, relocs + 1,
2048                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
2049           continue;
2050         }
2051
2052       rel->address += insec->output_offset;
2053     }
2054 }
2055
2056 #endif /* NLMCONV_POWERPC */
2057 \f
2058 /* Name of linker.  */
2059 #ifndef LD_NAME
2060 #define LD_NAME "ld"
2061 #endif
2062
2063 /* The user has specified several input files.  Invoke the linker to
2064    link them all together, and convert and delete the resulting output
2065    file.  */
2066
2067 static char *
2068 link_inputs (struct string_list *inputs, char *ld, char * mfile)
2069 {
2070   size_t c;
2071   struct string_list *q;
2072   char **argv;
2073   size_t i;
2074   int pid;
2075   int status;
2076   char *errfmt;
2077   char *errarg;
2078
2079   c = 0;
2080   for (q = inputs; q != NULL; q = q->next)
2081     ++c;
2082
2083   argv = (char **) xmalloc ((c + 7) * sizeof (char *));
2084
2085 #ifndef __MSDOS__
2086   if (ld == NULL)
2087     {
2088       char *p;
2089
2090       /* Find the linker to invoke based on how nlmconv was run.  */
2091       p = program_name + strlen (program_name);
2092       while (p != program_name)
2093         {
2094           if (p[-1] == '/')
2095             {
2096               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2097               memcpy (ld, program_name, p - program_name);
2098               strcpy (ld + (p - program_name), LD_NAME);
2099               break;
2100             }
2101           --p;
2102         }
2103     }
2104 #endif
2105
2106   if (ld == NULL)
2107     ld = (char *) LD_NAME;
2108
2109   unlink_on_exit = make_temp_file (".O");
2110
2111   argv[0] = ld;
2112   argv[1] = (char *) "-Ur";
2113   argv[2] = (char *) "-o";
2114   argv[3] = unlink_on_exit;
2115   /* If we have been given the name of a mapfile and that
2116      name is not 'stderr' then pass it on to the linker.  */
2117   if (mfile
2118       && * mfile
2119       && strcmp (mfile, "stderr") == 0)
2120     {
2121       argv[4] = (char *) "-Map";
2122       argv[5] = mfile;
2123       i = 6;
2124     }
2125   else
2126     i = 4;
2127
2128   for (q = inputs; q != NULL; q = q->next, i++)
2129     argv[i] = q->string;
2130   argv[i] = NULL;
2131
2132   if (debug)
2133     {
2134       for (i = 0; argv[i] != NULL; i++)
2135         fprintf (stderr, " %s", argv[i]);
2136       fprintf (stderr, "\n");
2137     }
2138
2139   pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2140                   PEXECUTE_SEARCH | PEXECUTE_ONE);
2141   free (argv);
2142
2143   if (pid == -1)
2144     {
2145       fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2146       fprintf (stderr, errfmt, errarg);
2147       unlink (unlink_on_exit);
2148       exit (1);
2149     }
2150
2151   if (pwait (pid, &status, 0) < 0)
2152     {
2153       perror ("pwait");
2154       unlink (unlink_on_exit);
2155       exit (1);
2156     }
2157
2158   if (status != 0)
2159     {
2160       non_fatal (_("Execution of %s failed"), ld);
2161       unlink (unlink_on_exit);
2162       exit (1);
2163     }
2164
2165   return unlink_on_exit;
2166 }