OSDN Git Service

Updated Russian translation.
[pf3gnuchains/pf3gnuchains3x.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, 2008, 2009 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_with_flags (outbfd,
399                                              NLM_UNINITIALIZED_DATA_NAME,
400                                              SEC_ALLOC);
401       if (bss_sec == NULL
402           || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
403         bfd_fatal (_("make .bss section"));
404     }
405
406   /* We store the original section names in the .nlmsections section,
407      so that programs which understand it can resurrect the original
408      sections from the NLM.  We will put a pointer to .nlmsections in
409      the NLM header area.  */
410   secsec = bfd_make_section_with_flags (outbfd, ".nlmsections",
411                                         SEC_HAS_CONTENTS);
412   if (secsec == NULL)
413     bfd_fatal (_("make .nlmsections section"));
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_name;
480
481                       new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
482                       new_name[0] = outlead;
483                       strcpy (new_name + 1, bfd_asymbol_name (sym) + 1);
484                       sym->name = new_name;
485                     }
486                 }
487             }
488           else
489             {
490               char *new_name;
491
492               new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
493               new_name[0] = outlead;
494               strcpy (new_name + 1, bfd_asymbol_name (sym));
495               sym->name = new_name;
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_with_flags (outbfd, ".nlmcustom",
718                                                         SEC_HAS_CONTENTS);
719           if (custom_section == NULL
720               || ! bfd_set_section_size (outbfd, custom_section, custom_size))
721             bfd_fatal (_("custom section"));
722         }
723     }
724   if (help_file != NULL)
725     {
726       help_data = fopen (help_file, "r");
727       if (help_data == NULL
728           || fstat (fileno (help_data), &st) < 0)
729         {
730           fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
731                    strerror (errno));
732           help_file = NULL;
733         }
734       else
735         {
736           help_size = st.st_size;
737           help_section = bfd_make_section_with_flags (outbfd, ".nlmhelp",
738                                                       SEC_HAS_CONTENTS);
739           if (help_section == NULL
740               || ! bfd_set_section_size (outbfd, help_section, help_size))
741             bfd_fatal (_("help section"));
742           LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
743         }
744     }
745   if (message_file != NULL)
746     {
747       message_data = fopen (message_file, "r");
748       if (message_data == NULL
749           || fstat (fileno (message_data), &st) < 0)
750         {
751           fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
752                    strerror (errno));
753           message_file = NULL;
754         }
755       else
756         {
757           message_size = st.st_size;
758           message_section = bfd_make_section_with_flags (outbfd,
759                                                          ".nlmmessages",
760                                                          SEC_HAS_CONTENTS);
761           if (message_section == NULL
762               || ! bfd_set_section_size (outbfd, message_section, message_size))
763             bfd_fatal (_("message section"));
764           LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
765         }
766     }
767   if (modules != NULL)
768     {
769       struct string_list *l;
770
771       module_size = 0;
772       for (l = modules; l != NULL; l = l->next)
773         module_size += strlen (l->string) + 1;
774       module_section = bfd_make_section_with_flags (outbfd, ".nlmmodules",
775                                                     SEC_HAS_CONTENTS);
776       if (module_section == NULL
777           || ! bfd_set_section_size (outbfd, module_section, module_size))
778         bfd_fatal (_("module section"));
779     }
780   if (rpc_file != NULL)
781     {
782       rpc_data = fopen (rpc_file, "r");
783       if (rpc_data == NULL
784           || fstat (fileno (rpc_data), &st) < 0)
785         {
786           fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
787                    strerror (errno));
788           rpc_file = NULL;
789         }
790       else
791         {
792           rpc_size = st.st_size;
793           rpc_section = bfd_make_section_with_flags (outbfd, ".nlmrpc",
794                                                      SEC_HAS_CONTENTS);
795           if (rpc_section == NULL
796               || ! bfd_set_section_size (outbfd, rpc_section, rpc_size))
797             bfd_fatal (_("rpc section"));
798           LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
799         }
800     }
801   if (sharelib_file != NULL)
802     {
803       sharedbfd = bfd_openr (sharelib_file, output_format);
804       if (sharedbfd == NULL
805           || ! bfd_check_format (sharedbfd, bfd_object))
806         {
807           fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
808                    bfd_errmsg (bfd_get_error ()));
809           sharelib_file = NULL;
810         }
811       else
812         {
813           sharedhdr = *nlm_fixed_header (sharedbfd);
814           bfd_close (sharedbfd);
815           shared_data = fopen (sharelib_file, "r");
816           if (shared_data == NULL
817               || (fstat (fileno (shared_data), &st) < 0))
818             {
819               fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
820                        strerror (errno));
821               sharelib_file = NULL;
822             }
823           else
824             {
825               /* If we were clever, we could just copy out the
826                  sections of the shared library which we actually
827                  need.  However, we would have to figure out the sizes
828                  of the external and public information, and that can
829                  not be done without reading through them.  */
830               if (sharedhdr.uninitializedDataSize > 0)
831                 {
832                   /* There is no place to record this information.  */
833                   non_fatal (_("%s: warning: shared libraries can not have uninitialized data"),
834                              sharelib_file);
835                 }
836               shared_offset = st.st_size;
837               if (shared_offset > (size_t) sharedhdr.codeImageOffset)
838                 shared_offset = sharedhdr.codeImageOffset;
839               if (shared_offset > (size_t) sharedhdr.dataImageOffset)
840                 shared_offset = sharedhdr.dataImageOffset;
841               if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
842                 shared_offset = sharedhdr.relocationFixupOffset;
843               if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
844                 shared_offset = sharedhdr.externalReferencesOffset;
845               if (shared_offset > (size_t) sharedhdr.publicsOffset)
846                 shared_offset = sharedhdr.publicsOffset;
847               shared_size = st.st_size - shared_offset;
848               shared_section = bfd_make_section_with_flags (outbfd,
849                                                             ".nlmshared",
850                                                             SEC_HAS_CONTENTS);
851               if (shared_section == NULL
852                   || ! bfd_set_section_size (outbfd, shared_section,
853                                              shared_size))
854                 bfd_fatal (_("shared section"));
855               LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
856             }
857         }
858     }
859
860   /* Check whether a version was given.  */
861   if (!CONST_STRNEQ (version_hdr->stamp, "VeRsIoN#"))
862     non_fatal (_("warning: No version number given"));
863
864   /* At least for now, always create an extended header, because that
865      is what NLMLINK does.  */
866   LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
867
868   LITMEMCPY (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx");
869
870   /* If the date was not given, force it in.  */
871   if (nlm_version_header (outbfd)->month == 0
872       && nlm_version_header (outbfd)->day == 0
873       && nlm_version_header (outbfd)->year == 0)
874     {
875       time_t now;
876       struct tm *ptm;
877
878       time (&now);
879       ptm = localtime (&now);
880       nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
881       nlm_version_header (outbfd)->day = ptm->tm_mday;
882       nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
883       LITMEMCPY (version_hdr->stamp, "VeRsIoN#");
884     }
885
886 #ifdef NLMCONV_POWERPC
887   /* Resolve the stubs we build for PowerPC NetWare.  */
888   if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
889     powerpc_resolve_stubs (inbfd, outbfd);
890 #endif
891
892   /* Copy over the sections.  */
893   bfd_map_over_sections (inbfd, copy_sections, (void *) outbfd);
894
895   /* Finish up the header information.  */
896   if (custom_file != NULL)
897     {
898       void *data;
899
900       data = xmalloc (custom_size);
901       if (fread (data, 1, custom_size, custom_data) != custom_size)
902         non_fatal (_("%s: read: %s"), custom_file, strerror (errno));
903       else
904         {
905           if (! bfd_set_section_contents (outbfd, custom_section, data,
906                                           (file_ptr) 0, custom_size))
907             bfd_fatal (_("custom section"));
908           nlm_fixed_header (outbfd)->customDataOffset =
909             custom_section->filepos;
910           nlm_fixed_header (outbfd)->customDataSize = custom_size;
911         }
912       free (data);
913     }
914   if (! debug_info)
915     {
916       /* As a special hack, the backend recognizes a debugInfoOffset
917          of -1 to mean that it should not output any debugging
918          information.  This can not be handling by fiddling with the
919          symbol table because exported symbols appear in both the
920          export information and the debugging information.  */
921       nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
922     }
923   if (full_map)
924     non_fatal (_("warning: FULLMAP is not supported; try ld -M"));
925   if (help_file != NULL)
926     {
927       void *data;
928
929       data = xmalloc (help_size);
930       if (fread (data, 1, help_size, help_data) != help_size)
931         non_fatal (_("%s: read: %s"), help_file, strerror (errno));
932       else
933         {
934           if (! bfd_set_section_contents (outbfd, help_section, data,
935                                           (file_ptr) 0, help_size))
936             bfd_fatal (_("help section"));
937           nlm_extended_header (outbfd)->helpFileOffset =
938             help_section->filepos;
939           nlm_extended_header (outbfd)->helpFileLength = help_size;
940         }
941       free (data);
942     }
943   if (message_file != NULL)
944     {
945       void *data;
946
947       data = xmalloc (message_size);
948       if (fread (data, 1, message_size, message_data) != message_size)
949         non_fatal (_("%s: read: %s"), message_file, strerror (errno));
950       else
951         {
952           if (! bfd_set_section_contents (outbfd, message_section, data,
953                                           (file_ptr) 0, message_size))
954             bfd_fatal (_("message section"));
955           nlm_extended_header (outbfd)->messageFileOffset =
956             message_section->filepos;
957           nlm_extended_header (outbfd)->messageFileLength = message_size;
958
959           /* FIXME: Are these offsets correct on all platforms?  Are
960              they 32 bits on all platforms?  What endianness?  */
961           nlm_extended_header (outbfd)->languageID =
962             bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
963           nlm_extended_header (outbfd)->messageCount =
964             bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
965         }
966       free (data);
967     }
968   if (modules != NULL)
969     {
970       void *data;
971       unsigned char *set;
972       struct string_list *l;
973       bfd_size_type c;
974
975       data = xmalloc (module_size);
976       c = 0;
977       set = (unsigned char *) data;
978       for (l = modules; l != NULL; l = l->next)
979         {
980           *set = strlen (l->string);
981           strncpy ((char *) set + 1, l->string, *set);
982           set += *set + 1;
983           ++c;
984         }
985       if (! bfd_set_section_contents (outbfd, module_section, data,
986                                       (file_ptr) 0, module_size))
987         bfd_fatal (_("module section"));
988       nlm_fixed_header (outbfd)->moduleDependencyOffset =
989         module_section->filepos;
990       nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
991     }
992   if (rpc_file != NULL)
993     {
994       void *data;
995
996       data = xmalloc (rpc_size);
997       if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
998         non_fatal (_("%s: read: %s"), rpc_file, strerror (errno));
999       else
1000         {
1001           if (! bfd_set_section_contents (outbfd, rpc_section, data,
1002                                           (file_ptr) 0, rpc_size))
1003             bfd_fatal (_("rpc section"));
1004           nlm_extended_header (outbfd)->RPCDataOffset =
1005             rpc_section->filepos;
1006           nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1007         }
1008       free (data);
1009     }
1010   if (sharelib_file != NULL)
1011     {
1012       void *data;
1013
1014       data = xmalloc (shared_size);
1015       if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1016           || fread (data, 1, shared_size, shared_data) != shared_size)
1017         non_fatal (_("%s: read: %s"), sharelib_file, strerror (errno));
1018       else
1019         {
1020           if (! bfd_set_section_contents (outbfd, shared_section, data,
1021                                           (file_ptr) 0, shared_size))
1022             bfd_fatal (_("shared section"));
1023         }
1024       nlm_extended_header (outbfd)->sharedCodeOffset =
1025         sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1026       nlm_extended_header (outbfd)->sharedCodeLength =
1027         sharedhdr.codeImageSize;
1028       nlm_extended_header (outbfd)->sharedDataOffset =
1029         sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1030       nlm_extended_header (outbfd)->sharedDataLength =
1031         sharedhdr.dataImageSize;
1032       nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1033         (sharedhdr.relocationFixupOffset
1034          - shared_offset
1035          + shared_section->filepos);
1036       nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1037         sharedhdr.numberOfRelocationFixups;
1038       nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1039         (sharedhdr.externalReferencesOffset
1040          - shared_offset
1041          + shared_section->filepos);
1042       nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1043         sharedhdr.numberOfExternalReferences;
1044       nlm_extended_header (outbfd)->sharedPublicsOffset =
1045         sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1046       nlm_extended_header (outbfd)->sharedPublicsCount =
1047         sharedhdr.numberOfPublics;
1048       nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1049         sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1050       nlm_extended_header (outbfd)->sharedDebugRecordCount =
1051         sharedhdr.numberOfDebugRecords;
1052       nlm_extended_header (outbfd)->SharedInitializationOffset =
1053         sharedhdr.codeStartOffset;
1054       nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1055         sharedhdr.exitProcedureOffset;
1056       free (data);
1057     }
1058
1059   {
1060     const int    max_len  = NLM_MODULE_NAME_SIZE - 2;
1061     const char * filename = lbasename (output_file);
1062     
1063     len = strlen (filename);
1064     if (len > max_len)
1065       len = max_len;
1066     nlm_fixed_header (outbfd)->moduleName[0] = len;
1067
1068     strncpy (nlm_fixed_header (outbfd)->moduleName + 1, filename, max_len);
1069     nlm_fixed_header (outbfd)->moduleName[max_len + 1] = '\0';
1070
1071     for (modname = nlm_fixed_header (outbfd)->moduleName;
1072          *modname != '\0';
1073          modname++)
1074       *modname = TOUPPER (*modname);
1075   }
1076
1077   strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1078            NLM_OLD_THREAD_NAME_LENGTH);
1079
1080   nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1081   nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1082
1083   if (! bfd_close (outbfd))
1084     bfd_fatal (output_file);
1085   if (! bfd_close (inbfd))
1086     bfd_fatal (input_file);
1087
1088   if (unlink_on_exit != NULL)
1089     unlink (unlink_on_exit);
1090
1091   return 0;
1092 }
1093 \f
1094
1095 /* Show a usage message and exit.  */
1096
1097 static void
1098 show_usage (FILE *file, int status)
1099 {
1100   fprintf (file, _("Usage: %s [option(s)] [in-file [out-file]]\n"), program_name);
1101   fprintf (file, _(" Convert an object file into a NetWare Loadable Module\n"));
1102   fprintf (file, _(" The options are:\n\
1103   -I --input-target=<bfdname>   Set the input binary file format\n\
1104   -O --output-target=<bfdname>  Set the output binary file format\n\
1105   -T --header-file=<file>       Read <file> for NLM header information\n\
1106   -l --linker=<linker>          Use <linker> for any linking\n\
1107   -d --debug                    Display on stderr the linker command line\n\
1108   @<file>                       Read options from <file>.\n\
1109   -h --help                     Display this information\n\
1110   -v --version                  Display the program's version\n\
1111 "));
1112   if (REPORT_BUGS_TO[0] && status == 0)
1113     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1114   exit (status);
1115 }
1116 \f
1117 /* Select the output format based on the input architecture, machine,
1118    and endianness.  This chooses the appropriate NLM target.  */
1119
1120 static const char *
1121 select_output_format (enum bfd_architecture arch, unsigned long mach,
1122                       bfd_boolean bigendian ATTRIBUTE_UNUSED)
1123 {
1124   switch (arch)
1125     {
1126 #ifdef NLMCONV_I386
1127     case bfd_arch_i386:
1128       return "nlm32-i386";
1129 #endif
1130 #ifdef NLMCONV_SPARC
1131     case bfd_arch_sparc:
1132       return "nlm32-sparc";
1133 #endif
1134 #ifdef NLMCONV_ALPHA
1135     case bfd_arch_alpha:
1136       return "nlm32-alpha";
1137 #endif
1138 #ifdef NLMCONV_POWERPC
1139     case bfd_arch_powerpc:
1140       return "nlm32-powerpc";
1141 #endif
1142     default:
1143       fatal (_("support not compiled in for %s"),
1144              bfd_printable_arch_mach (arch, mach));
1145     }
1146   /*NOTREACHED*/
1147 }
1148 \f
1149 /* The BFD sections are copied in two passes.  This function selects
1150    the output section for each input section, and sets up the section
1151    name, size, etc.  */
1152
1153 static void
1154 setup_sections (bfd *inbfd ATTRIBUTE_UNUSED, asection *insec, void *data_ptr)
1155 {
1156   bfd *outbfd = (bfd *) data_ptr;
1157   flagword f;
1158   const char *outname;
1159   asection *outsec;
1160   bfd_vma offset;
1161   bfd_size_type align;
1162   bfd_size_type add;
1163   bfd_size_type secsecsize;
1164
1165   f = bfd_get_section_flags (inbfd, insec);
1166   if (f & SEC_CODE)
1167     outname = NLM_CODE_NAME;
1168   else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1169     outname = NLM_INITIALIZED_DATA_NAME;
1170   else if (f & SEC_ALLOC)
1171     outname = NLM_UNINITIALIZED_DATA_NAME;
1172   else
1173     outname = bfd_section_name (inbfd, insec);
1174
1175   outsec = bfd_get_section_by_name (outbfd, outname);
1176   if (outsec == NULL)
1177     {
1178       outsec = bfd_make_section (outbfd, outname);
1179       if (outsec == NULL)
1180         bfd_fatal (_("make section"));
1181     }
1182
1183   insec->output_section = outsec;
1184
1185   offset = bfd_section_size (outbfd, outsec);
1186   align = 1 << bfd_section_alignment (inbfd, insec);
1187   add = ((offset + align - 1) &~ (align - 1)) - offset;
1188   insec->output_offset = offset + add;
1189
1190   if (! bfd_set_section_size (outbfd, outsec,
1191                               (bfd_section_size (outbfd, outsec)
1192                                + bfd_section_size (inbfd, insec)
1193                                + add)))
1194     bfd_fatal (_("set section size"));
1195
1196   if ((bfd_section_alignment (inbfd, insec)
1197        > bfd_section_alignment (outbfd, outsec))
1198       && ! bfd_set_section_alignment (outbfd, outsec,
1199                                       bfd_section_alignment (inbfd, insec)))
1200     bfd_fatal (_("set section alignment"));
1201
1202   if (! bfd_set_section_flags (outbfd, outsec,
1203                                f | bfd_get_section_flags (outbfd, outsec)))
1204     bfd_fatal (_("set section flags"));
1205
1206   bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1207
1208   /* For each input section we allocate space for an entry in
1209      .nlmsections.  */
1210   secsecsize = bfd_section_size (outbfd, secsec);
1211   secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1212   secsecsize = (secsecsize + 3) &~ 3;
1213   secsecsize += 8;
1214   if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1215     bfd_fatal (_("set .nlmsections size"));
1216 }
1217
1218 /* Copy the section contents.  */
1219
1220 static void
1221 copy_sections (bfd *inbfd, asection *insec, void *data_ptr)
1222 {
1223   static bfd_size_type secsecoff = 0;
1224   bfd *outbfd = (bfd *) data_ptr;
1225   const char *inname;
1226   asection *outsec;
1227   bfd_size_type size;
1228   void *contents;
1229   long reloc_size;
1230   bfd_byte buf[4];
1231   bfd_size_type add;
1232
1233   inname = bfd_section_name (inbfd, insec);
1234
1235   outsec = insec->output_section;
1236   assert (outsec != NULL);
1237
1238   size = bfd_get_section_size (insec);
1239
1240   if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1241     contents = NULL;
1242   else
1243     {
1244       contents = xmalloc (size);
1245       if (! bfd_get_section_contents (inbfd, insec, contents,
1246                                       (file_ptr) 0, size))
1247         bfd_fatal (bfd_get_filename (inbfd));
1248     }
1249
1250   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1251   if (reloc_size < 0)
1252     bfd_fatal (bfd_get_filename (inbfd));
1253   if (reloc_size != 0)
1254     {
1255       arelent **relocs;
1256       long reloc_count;
1257
1258       relocs = (arelent **) xmalloc (reloc_size);
1259       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1260       if (reloc_count < 0)
1261         bfd_fatal (bfd_get_filename (inbfd));
1262       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1263                      size);
1264
1265       /* FIXME: refers to internal BFD fields.  */
1266       if (outsec->orelocation != (arelent **) NULL)
1267         {
1268           bfd_size_type total_count;
1269           arelent **combined;
1270
1271           total_count = reloc_count + outsec->reloc_count;
1272           combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1273           memcpy (combined, outsec->orelocation,
1274                   outsec->reloc_count * sizeof (arelent *));
1275           memcpy (combined + outsec->reloc_count, relocs,
1276                   (size_t) (reloc_count * sizeof (arelent *)));
1277           free (outsec->orelocation);
1278           reloc_count = total_count;
1279           relocs = combined;
1280         }
1281
1282       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1283     }
1284
1285   if (contents != NULL)
1286     {
1287       if (! bfd_set_section_contents (outbfd, outsec, contents,
1288                                       insec->output_offset, size))
1289         bfd_fatal (bfd_get_filename (outbfd));
1290       free (contents);
1291     }
1292
1293   /* Add this section to .nlmsections.  */
1294   if (! bfd_set_section_contents (outbfd, secsec, (void *) inname, secsecoff,
1295                                   strlen (inname) + 1))
1296     bfd_fatal (_("set .nlmsection contents"));
1297   secsecoff += strlen (inname) + 1;
1298
1299   add = ((secsecoff + 3) &~ 3) - secsecoff;
1300   if (add != 0)
1301     {
1302       bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1303       if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1304         bfd_fatal (_("set .nlmsection contents"));
1305       secsecoff += add;
1306     }
1307
1308   if (contents != NULL)
1309     bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1310   else
1311     bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1312   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1313     bfd_fatal (_("set .nlmsection contents"));
1314   secsecoff += 4;
1315
1316   bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1317   if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1318     bfd_fatal (_("set .nlmsection contents"));
1319   secsecoff += 4;
1320 }
1321
1322 /* Some, perhaps all, NetWare targets require changing the relocs used
1323    by the input formats.  */
1324
1325 static void
1326 mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
1327                long *reloc_count_ptr, char *contents,
1328                bfd_size_type contents_size)
1329 {
1330   switch (bfd_get_arch (outbfd))
1331     {
1332 #ifdef NLMCONV_I386
1333     case bfd_arch_i386:
1334       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1335                           contents, contents_size);
1336       break;
1337 #endif
1338 #ifdef NLMCONV_ALPHA
1339     case bfd_arch_alpha:
1340       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1341                            contents, contents_size);
1342       break;
1343 #endif
1344 #ifdef NLMCONV_POWERPC
1345     case bfd_arch_powerpc:
1346       powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1347                              contents, contents_size);
1348       break;
1349 #endif
1350     default:
1351       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1352                              contents, contents_size);
1353       break;
1354     }
1355 }
1356
1357 /* By default all we need to do for relocs is change the address by
1358    the output_offset.  */
1359
1360 static void
1361 default_mangle_relocs (bfd *outbfd ATTRIBUTE_UNUSED, asection *insec,
1362                        arelent ***relocs_ptr, long *reloc_count_ptr,
1363                        char *contents ATTRIBUTE_UNUSED,
1364                        bfd_size_type contents_size ATTRIBUTE_UNUSED)
1365 {
1366   if (insec->output_offset != 0)
1367     {
1368       long reloc_count;
1369       arelent **relocs;
1370       long i;
1371
1372       reloc_count = *reloc_count_ptr;
1373       relocs = *relocs_ptr;
1374       for (i = 0; i < reloc_count; i++, relocs++)
1375         (*relocs)->address += insec->output_offset;
1376     }
1377 }
1378 \f
1379 #ifdef NLMCONV_I386
1380
1381 /* NetWare on the i386 supports a restricted set of relocs, which are
1382    different from those used on other i386 targets.  This routine
1383    converts the relocs.  It is, obviously, very target dependent.  At
1384    the moment, the nlm32-i386 backend performs similar translations;
1385    however, it is more reliable and efficient to do them here.  */
1386
1387 static reloc_howto_type nlm_i386_pcrel_howto =
1388   HOWTO (1,                     /* type */
1389          0,                     /* rightshift */
1390          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1391          32,                    /* bitsize */
1392          TRUE,                  /* pc_relative */
1393          0,                     /* bitpos */
1394          complain_overflow_signed, /* complain_on_overflow */
1395          0,                     /* special_function */
1396          "DISP32",              /* name */
1397          TRUE,                  /* partial_inplace */
1398          0xffffffff,            /* src_mask */
1399          0xffffffff,            /* dst_mask */
1400          TRUE);                 /* pcrel_offset */
1401
1402 static void
1403 i386_mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
1404                     long *reloc_count_ptr, char *contents,
1405                     bfd_size_type contents_size)
1406 {
1407   long reloc_count, i;
1408   arelent **relocs;
1409
1410   reloc_count = *reloc_count_ptr;
1411   relocs = *relocs_ptr;
1412   for (i = 0; i < reloc_count; i++)
1413     {
1414       arelent *rel;
1415       asymbol *sym;
1416       bfd_size_type address;
1417       bfd_vma addend;
1418
1419       rel = *relocs++;
1420       sym = *rel->sym_ptr_ptr;
1421
1422       /* We're moving the relocs from the input section to the output
1423          section, so we must adjust the address accordingly.  */
1424       address = rel->address;
1425       rel->address += insec->output_offset;
1426
1427       /* Note that no serious harm will ensue if we fail to change a
1428          reloc.  The backend will fail when writing out the reloc.  */
1429
1430       /* Make sure this reloc is within the data we have.  We use only
1431          4 byte relocs here, so we insist on having 4 bytes.  */
1432       if (address + 4 > contents_size)
1433         continue;
1434
1435       /* A PC relative reloc entirely within a single section is
1436          completely unnecessary.  This can be generated by ld -r.  */
1437       if (sym == insec->symbol
1438           && rel->howto != NULL
1439           && rel->howto->pc_relative
1440           && ! rel->howto->pcrel_offset)
1441         {
1442           --*reloc_count_ptr;
1443           --relocs;
1444           memmove (relocs, relocs + 1,
1445                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1446           continue;
1447         }
1448
1449       /* Get the amount the relocation will add in.  */
1450       addend = rel->addend + sym->value;
1451
1452       /* NetWare doesn't support PC relative relocs against defined
1453          symbols, so we have to eliminate them by doing the relocation
1454          now.  We can only do this if the reloc is within a single
1455          section.  */
1456       if (rel->howto != NULL
1457           && rel->howto->pc_relative
1458           && bfd_get_section (sym) == insec->output_section)
1459         {
1460           bfd_vma val;
1461
1462           if (rel->howto->pcrel_offset)
1463             addend -= address;
1464
1465           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1466           val += addend;
1467           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1468
1469           --*reloc_count_ptr;
1470           --relocs;
1471           memmove (relocs, relocs + 1,
1472                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1473           continue;
1474         }
1475
1476       /* NetWare doesn't support reloc addends, so we get rid of them
1477          here by simply adding them into the object data.  We handle
1478          the symbol value, if any, the same way.  */
1479       if (addend != 0
1480           && rel->howto != NULL
1481           && rel->howto->rightshift == 0
1482           && rel->howto->size == 2
1483           && rel->howto->bitsize == 32
1484           && rel->howto->bitpos == 0
1485           && rel->howto->src_mask == 0xffffffff
1486           && rel->howto->dst_mask == 0xffffffff)
1487         {
1488           bfd_vma val;
1489
1490           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1491           val += addend;
1492           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1493
1494           /* Adjust the reloc for the changes we just made.  */
1495           rel->addend = 0;
1496           if (! bfd_is_und_section (bfd_get_section (sym)))
1497             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1498         }
1499
1500       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1501          pc_relative relocs accordingly.  We are going to change the
1502          howto field, so we can only do this if the current one is
1503          compatible.  We should check that special_function is NULL
1504          here, but at the moment coff-i386 uses a special_function
1505          which does not affect what we are doing here.  */
1506       if (rel->howto != NULL
1507           && rel->howto->pc_relative
1508           && ! rel->howto->pcrel_offset
1509           && rel->howto->rightshift == 0
1510           && rel->howto->size == 2
1511           && rel->howto->bitsize == 32
1512           && rel->howto->bitpos == 0
1513           && rel->howto->src_mask == 0xffffffff
1514           && rel->howto->dst_mask == 0xffffffff)
1515         {
1516           bfd_vma val;
1517
1518           /* When pcrel_offset is not set, it means that the negative
1519              of the address of the memory location is stored in the
1520              memory location.  We must add it back in.  */
1521           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1522           val += address;
1523           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1524
1525           /* We must change to a new howto.  */
1526           rel->howto = &nlm_i386_pcrel_howto;
1527         }
1528     }
1529 }
1530
1531 #endif /* NLMCONV_I386 */
1532 \f
1533 #ifdef NLMCONV_ALPHA
1534
1535 /* On the Alpha the first reloc for every section must be a special
1536    relocs which hold the GP address.  Also, the first reloc in the
1537    file must be a special reloc which holds the address of the .lita
1538    section.  */
1539
1540 static reloc_howto_type nlm32_alpha_nw_howto =
1541   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1542          0,                     /* rightshift */
1543          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1544          0,                     /* bitsize */
1545          FALSE,                 /* pc_relative */
1546          0,                     /* bitpos */
1547          complain_overflow_dont, /* complain_on_overflow */
1548          0,                     /* special_function */
1549          "NW_RELOC",            /* name */
1550          FALSE,                 /* partial_inplace */
1551          0,                     /* src_mask */
1552          0,                     /* dst_mask */
1553          FALSE);                /* pcrel_offset */
1554
1555 static void
1556 alpha_mangle_relocs (bfd *outbfd, asection *insec,
1557                      arelent ***relocs_ptr, long *reloc_count_ptr,
1558                      char *contents ATTRIBUTE_UNUSED,
1559                      bfd_size_type contents_size ATTRIBUTE_UNUSED)
1560 {
1561   long old_reloc_count;
1562   arelent **old_relocs;
1563   arelent **relocs;
1564
1565   old_reloc_count = *reloc_count_ptr;
1566   old_relocs = *relocs_ptr;
1567   relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1568   *relocs_ptr = relocs;
1569
1570   if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1571     {
1572       bfd *inbfd;
1573       asection *lita_section;
1574
1575       inbfd = insec->owner;
1576       lita_section = bfd_get_section_by_name (inbfd, _LITA);
1577       if (lita_section != (asection *) NULL)
1578         {
1579           nlm_alpha_backend_data (outbfd)->lita_address =
1580             bfd_get_section_vma (inbfd, lita_section);
1581           nlm_alpha_backend_data (outbfd)->lita_size =
1582             bfd_section_size (inbfd, lita_section);
1583         }
1584       else
1585         {
1586           /* Avoid outputting this reloc again.  */
1587           nlm_alpha_backend_data (outbfd)->lita_address = 4;
1588         }
1589
1590       *relocs = (arelent *) xmalloc (sizeof (arelent));
1591       (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1592       (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1593       (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1594       (*relocs)->howto = &nlm32_alpha_nw_howto;
1595       ++relocs;
1596       ++(*reloc_count_ptr);
1597     }
1598
1599   /* Get the GP value from bfd.  */
1600   if (nlm_alpha_backend_data (outbfd)->gp == 0)
1601     nlm_alpha_backend_data (outbfd)->gp =
1602       bfd_ecoff_get_gp_value (insec->owner);
1603
1604   *relocs = (arelent *) xmalloc (sizeof (arelent));
1605   (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1606   (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1607   (*relocs)->addend = 0;
1608   (*relocs)->howto = &nlm32_alpha_nw_howto;
1609   ++relocs;
1610   ++(*reloc_count_ptr);
1611
1612   memcpy (relocs, old_relocs, (size_t) old_reloc_count * sizeof (arelent *));
1613   relocs[old_reloc_count] = (arelent *) NULL;
1614
1615   free (old_relocs);
1616
1617   if (insec->output_offset != 0)
1618     {
1619       bfd_size_type i;
1620
1621       for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
1622         (*relocs)->address += insec->output_offset;
1623     }
1624 }
1625
1626 #endif /* NLMCONV_ALPHA */
1627 \f
1628 #ifdef NLMCONV_POWERPC
1629
1630 /* We keep a linked list of stubs which we must build.  Because BFD
1631    requires us to know the sizes of all sections before we can set the
1632    contents of any, we must figure out which stubs we want to build
1633    before we can actually build any of them.  */
1634
1635 struct powerpc_stub
1636 {
1637   /* Next stub in linked list.  */
1638   struct powerpc_stub *next;
1639
1640   /* Symbol whose value is the start of the stub.  This is a symbol
1641      whose name begins with `.'.  */
1642   asymbol *start;
1643
1644   /* Symbol we are going to create a reloc against.  This is a symbol
1645      with the same name as START but without the leading `.'.  */
1646   asymbol *reloc;
1647
1648   /* The TOC index for this stub.  This is the index into the TOC
1649      section at which the reloc is created.  */
1650   unsigned int toc_index;
1651 };
1652
1653 /* The linked list of stubs.  */
1654
1655 static struct powerpc_stub *powerpc_stubs;
1656
1657 /* This is what a stub looks like.  The first instruction will get
1658    adjusted with the correct TOC index.  */
1659
1660 static unsigned long powerpc_stub_insns[] =
1661 {
1662   0x81820000,           /* lwz   r12,0(r2) */
1663   0x90410014,           /* stw   r2,20(r1) */
1664   0x800c0000,           /* lwz   r0,0(r12) */
1665   0x804c0004,           /* lwz   r2,r(r12) */
1666   0x7c0903a6,           /* mtctr r0 */
1667   0x4e800420,           /* bctr */
1668   0,                    /* Traceback table.  */
1669   0xc8000,
1670   0
1671 };
1672
1673 #define POWERPC_STUB_INSN_COUNT \
1674   (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1675
1676 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1677
1678 /* Each stub uses a four byte TOC entry.  */
1679 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1680
1681 /* The original size of the .got section.  */
1682 static bfd_size_type powerpc_initial_got_size;
1683
1684 /* Look for all undefined symbols beginning with `.', and prepare to
1685    build a stub for each one.  */
1686
1687 static void
1688 powerpc_build_stubs (bfd *inbfd, bfd *outbfd ATTRIBUTE_UNUSED,
1689                      asymbol ***symbols_ptr, long *symcount_ptr)
1690 {
1691   asection *stub_sec;
1692   asection *got_sec;
1693   unsigned int got_base;
1694   long i;
1695   long symcount;
1696   long stubcount;
1697
1698   /* Make a section to hold stubs.  We don't set SEC_HAS_CONTENTS for
1699      the section to prevent copy_sections from reading from it.  */
1700   stub_sec = bfd_make_section_with_flags (inbfd, ".stubs",
1701                                           (SEC_CODE
1702                                            | SEC_RELOC
1703                                            | SEC_ALLOC
1704                                            | SEC_LOAD));
1705   if (stub_sec == (asection *) NULL
1706       || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1707     bfd_fatal (".stubs");
1708
1709   /* Get the TOC section, which is named .got.  */
1710   got_sec = bfd_get_section_by_name (inbfd, ".got");
1711   if (got_sec == (asection *) NULL)
1712     {
1713       got_sec = bfd_make_section_with_flags (inbfd, ".got",
1714                                              (SEC_DATA
1715                                               | SEC_RELOC
1716                                               | SEC_ALLOC
1717                                               | SEC_LOAD
1718                                               | SEC_HAS_CONTENTS));
1719       if (got_sec == (asection *) NULL
1720           || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1721         bfd_fatal (".got");
1722     }
1723
1724   powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1725   got_base = powerpc_initial_got_size;
1726   got_base = (got_base + 3) &~ 3;
1727
1728   stubcount = 0;
1729
1730   symcount = *symcount_ptr;
1731   for (i = 0; i < symcount; i++)
1732     {
1733       asymbol *sym;
1734       asymbol *newsym;
1735       char *newname;
1736       struct powerpc_stub *item;
1737
1738       sym = (*symbols_ptr)[i];
1739
1740       /* We must make a stub for every undefined symbol whose name
1741          starts with '.'.  */
1742       if (bfd_asymbol_name (sym)[0] != '.'
1743           || ! bfd_is_und_section (bfd_get_section (sym)))
1744         continue;
1745
1746       /* Make a new undefined symbol with the same name but without
1747          the leading `.'.  */
1748       newsym = xmalloc (sizeof (asymbol));
1749       *newsym = *sym;
1750       newname = xmalloc (strlen (bfd_asymbol_name (sym)));
1751       strcpy (newname, bfd_asymbol_name (sym) + 1);
1752       newsym->name = newname;
1753
1754       /* Define the `.' symbol to be in the stub section.  */
1755       sym->section = stub_sec;
1756       sym->value = stubcount * POWERPC_STUB_SIZE;
1757       /* We set the BSF_DYNAMIC flag here so that we can check it when
1758          we are mangling relocs.  FIXME: This is a hack.  */
1759       sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1760
1761       /* Add this stub to the linked list.  */
1762       item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1763       item->start = sym;
1764       item->reloc = newsym;
1765       item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1766
1767       item->next = powerpc_stubs;
1768       powerpc_stubs = item;
1769
1770       ++stubcount;
1771     }
1772
1773   if (stubcount > 0)
1774     {
1775       asymbol **s;
1776       struct powerpc_stub *l;
1777
1778       /* Add the new symbols we just created to the symbol table.  */
1779       *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1780                                             ((symcount + stubcount)
1781                                              * sizeof (asymbol)));
1782       *symcount_ptr += stubcount;
1783       s = &(*symbols_ptr)[symcount];
1784       for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1785         *s++ = l->reloc;
1786
1787       /* Set the size of the .stubs section and increase the size of
1788          the .got section.  */
1789       if (! bfd_set_section_size (inbfd, stub_sec,
1790                                   stubcount * POWERPC_STUB_SIZE)
1791           || ! bfd_set_section_size (inbfd, got_sec,
1792                                      (got_base
1793                                       + (stubcount
1794                                          * POWERPC_STUB_TOC_ENTRY_SIZE))))
1795         bfd_fatal (_("stub section sizes"));
1796     }
1797 }
1798
1799 /* Resolve all the stubs for PowerPC NetWare.  We fill in the contents
1800    of the output section, and create new relocs in the TOC.  */
1801
1802 static void
1803 powerpc_resolve_stubs (bfd *inbfd, bfd *outbfd)
1804 {
1805   bfd_byte buf[POWERPC_STUB_SIZE];
1806   unsigned int i;
1807   unsigned int stubcount;
1808   arelent **relocs;
1809   asection *got_sec;
1810   arelent **r;
1811   struct powerpc_stub *l;
1812
1813   if (powerpc_stubs == (struct powerpc_stub *) NULL)
1814     return;
1815
1816   for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1817     bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1818
1819   got_sec = bfd_get_section_by_name (inbfd, ".got");
1820   assert (got_sec != (asection *) NULL);
1821   assert (got_sec->output_section->orelocation == (arelent **) NULL);
1822
1823   stubcount = 0;
1824   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1825     ++stubcount;
1826   relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1827
1828   r = relocs;
1829   for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1830     {
1831       arelent *reloc;
1832
1833       /* Adjust the first instruction to use the right TOC index.  */
1834       bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1835
1836       /* Write this stub out.  */
1837       if (! bfd_set_section_contents (outbfd,
1838                                       bfd_get_section (l->start),
1839                                       buf,
1840                                       l->start->value,
1841                                       POWERPC_STUB_SIZE))
1842         bfd_fatal (_("writing stub"));
1843
1844       /* Create a new reloc for the TOC entry.  */
1845       reloc = (arelent *) xmalloc (sizeof (arelent));
1846       reloc->sym_ptr_ptr = &l->reloc;
1847       reloc->address = l->toc_index + got_sec->output_offset;
1848       reloc->addend = 0;
1849       reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1850
1851       *r++ = reloc;
1852     }
1853
1854   bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1855 }
1856
1857 /* Adjust relocation entries for PowerPC NetWare.  We do not output
1858    TOC relocations.  The object code already contains the offset from
1859    the TOC pointer.  When the function is called, the TOC register,
1860    r2, will be set to the correct TOC value, so there is no need for
1861    any further reloc.  */
1862
1863 static void
1864 powerpc_mangle_relocs (bfd *outbfd, asection *insec,
1865                        arelent ***relocs_ptr,
1866                        long *reloc_count_ptr, char *contents,
1867                        bfd_size_type contents_size ATTRIBUTE_UNUSED)
1868 {
1869   reloc_howto_type *toc_howto;
1870   long reloc_count;
1871   arelent **relocs;
1872   long i;
1873
1874   toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1875   if (toc_howto == (reloc_howto_type *) NULL)
1876     abort ();
1877
1878   /* If this is the .got section, clear out all the contents beyond
1879      the initial size.  We must do this here because copy_sections is
1880      going to write out whatever we return in the contents field.  */
1881   if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1882     memset (contents + powerpc_initial_got_size, 0,
1883             (size_t) (bfd_get_section_size (insec) - powerpc_initial_got_size));
1884
1885   reloc_count = *reloc_count_ptr;
1886   relocs = *relocs_ptr;
1887   for (i = 0; i < reloc_count; i++)
1888     {
1889       arelent *rel;
1890       asymbol *sym;
1891       bfd_vma sym_value;
1892
1893       rel = *relocs++;
1894       sym = *rel->sym_ptr_ptr;
1895
1896       /* Convert any relocs against the .bss section into relocs
1897          against the .data section.  */
1898       if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1899                   NLM_UNINITIALIZED_DATA_NAME) == 0)
1900         {
1901           asection *datasec;
1902
1903           datasec = bfd_get_section_by_name (outbfd,
1904                                              NLM_INITIALIZED_DATA_NAME);
1905           if (datasec != NULL)
1906             {
1907               rel->addend += (bfd_get_section_vma (outbfd,
1908                                                    bfd_get_section (sym))
1909                               + sym->value);
1910               rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1911               sym = *rel->sym_ptr_ptr;
1912             }
1913         }
1914
1915       /* We must be able to resolve all PC relative relocs at this
1916          point.  If we get a branch to an undefined symbol we build a
1917          stub, since NetWare will resolve undefined symbols into a
1918          pointer to a function descriptor.  */
1919       if (rel->howto->pc_relative)
1920         {
1921           /* This check for whether a symbol is in the same section as
1922              the reloc will be wrong if there is a PC relative reloc
1923              between two sections both of which were placed in the
1924              same output section.  This should not happen.  */
1925           if (bfd_get_section (sym) != insec->output_section)
1926             non_fatal (_("unresolved PC relative reloc against %s"),
1927                        bfd_asymbol_name (sym));
1928           else
1929             {
1930               bfd_vma val;
1931
1932               assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1933               val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1934               val = ((val &~ rel->howto->dst_mask)
1935                      | (((val & rel->howto->src_mask)
1936                          + (sym->value - rel->address)
1937                          + rel->addend)
1938                         & rel->howto->dst_mask));
1939               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1940
1941               /* If this reloc is against an stubbed symbol and the
1942                  next instruction is
1943                      cror 31,31,31
1944                  then we replace the next instruction with
1945                      lwz  r2,20(r1)
1946                  This reloads the TOC pointer after a stub call.  */
1947               if (bfd_asymbol_name (sym)[0] == '.'
1948                   && (sym->flags & BSF_DYNAMIC) != 0
1949                   && (bfd_get_32 (outbfd,
1950                                   (bfd_byte *) contents + rel->address + 4)
1951                       == 0x4ffffb82)) /* cror 31,31,31 */
1952                 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1953                             (bfd_byte *) contents + rel->address + 4);
1954
1955               --*reloc_count_ptr;
1956               --relocs;
1957               memmove (relocs, relocs + 1,
1958                        (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1959               continue;
1960             }
1961         }
1962
1963       /* When considering a TOC reloc, we do not want to include the
1964          symbol value.  The symbol will be start of the TOC section
1965          (which is named .got).  We do want to include the addend.  */
1966       if (rel->howto == toc_howto)
1967         sym_value = 0;
1968       else
1969         sym_value = sym->value;
1970
1971       /* If this is a relocation against a symbol with a value, or
1972          there is a reloc addend, we need to update the addend in the
1973          object file.  */
1974       if (sym_value + rel->addend != 0)
1975         {
1976           bfd_vma val;
1977
1978           switch (rel->howto->size)
1979             {
1980             case 1:
1981               val = bfd_get_16 (outbfd,
1982                                 (bfd_byte *) contents + rel->address);
1983               val = ((val &~ rel->howto->dst_mask)
1984                      | (((val & rel->howto->src_mask)
1985                          + sym_value
1986                          + rel->addend)
1987                         & rel->howto->dst_mask));
1988               if ((bfd_signed_vma) val < - 0x8000
1989                   || (bfd_signed_vma) val >= 0x8000)
1990                 non_fatal (_("overflow when adjusting relocation against %s"),
1991                            bfd_asymbol_name (sym));
1992               bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1993               break;
1994
1995             case 2:
1996               val = bfd_get_32 (outbfd,
1997                                 (bfd_byte *) contents + rel->address);
1998               val = ((val &~ rel->howto->dst_mask)
1999                      | (((val & rel->howto->src_mask)
2000                          + sym_value
2001                          + rel->addend)
2002                         & rel->howto->dst_mask));
2003               bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2004               break;
2005
2006             default:
2007               abort ();
2008             }
2009
2010           if (! bfd_is_und_section (bfd_get_section (sym)))
2011             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2012           rel->addend = 0;
2013         }
2014
2015       /* Now that we have incorporated the addend, remove any TOC
2016          relocs.  */
2017       if (rel->howto == toc_howto)
2018         {
2019           --*reloc_count_ptr;
2020           --relocs;
2021           memmove (relocs, relocs + 1,
2022                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
2023           continue;
2024         }
2025
2026       rel->address += insec->output_offset;
2027     }
2028 }
2029
2030 #endif /* NLMCONV_POWERPC */
2031 \f
2032 /* Name of linker.  */
2033 #ifndef LD_NAME
2034 #define LD_NAME "ld"
2035 #endif
2036
2037 /* The user has specified several input files.  Invoke the linker to
2038    link them all together, and convert and delete the resulting output
2039    file.  */
2040
2041 static char *
2042 link_inputs (struct string_list *inputs, char *ld, char * mfile)
2043 {
2044   size_t c;
2045   struct string_list *q;
2046   char **argv;
2047   size_t i;
2048   int pid;
2049   int status;
2050   char *errfmt;
2051   char *errarg;
2052
2053   c = 0;
2054   for (q = inputs; q != NULL; q = q->next)
2055     ++c;
2056
2057   argv = (char **) alloca ((c + 7) * sizeof (char *));
2058
2059 #ifndef __MSDOS__
2060   if (ld == NULL)
2061     {
2062       char *p;
2063
2064       /* Find the linker to invoke based on how nlmconv was run.  */
2065       p = program_name + strlen (program_name);
2066       while (p != program_name)
2067         {
2068           if (p[-1] == '/')
2069             {
2070               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2071               memcpy (ld, program_name, p - program_name);
2072               strcpy (ld + (p - program_name), LD_NAME);
2073               break;
2074             }
2075           --p;
2076         }
2077     }
2078 #endif
2079
2080   if (ld == NULL)
2081     ld = (char *) LD_NAME;
2082
2083   unlink_on_exit = make_temp_file (".O");
2084
2085   argv[0] = ld;
2086   argv[1] = (char *) "-Ur";
2087   argv[2] = (char *) "-o";
2088   argv[3] = unlink_on_exit;
2089   /* If we have been given the name of a mapfile and that
2090      name is not 'stderr' then pass it on to the linker.  */
2091   if (mfile
2092       && * mfile
2093       && strcmp (mfile, "stderr") == 0)
2094     {
2095       argv[4] = (char *) "-Map";
2096       argv[5] = mfile;
2097       i = 6;
2098     }
2099   else
2100     i = 4;
2101
2102   for (q = inputs; q != NULL; q = q->next, i++)
2103     argv[i] = q->string;
2104   argv[i] = NULL;
2105
2106   if (debug)
2107     {
2108       for (i = 0; argv[i] != NULL; i++)
2109         fprintf (stderr, " %s", argv[i]);
2110       fprintf (stderr, "\n");
2111     }
2112
2113   pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2114                   PEXECUTE_SEARCH | PEXECUTE_ONE);
2115   if (pid == -1)
2116     {
2117       fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2118       fprintf (stderr, errfmt, errarg);
2119       unlink (unlink_on_exit);
2120       exit (1);
2121     }
2122
2123   if (pwait (pid, &status, 0) < 0)
2124     {
2125       perror ("pwait");
2126       unlink (unlink_on_exit);
2127       exit (1);
2128     }
2129
2130   if (status != 0)
2131     {
2132       non_fatal (_("Execution of %s failed"), ld);
2133       unlink (unlink_on_exit);
2134       exit (1);
2135     }
2136
2137   return unlink_on_exit;
2138 }