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