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