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