OSDN Git Service

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