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