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