* ar.c, bucomm.c, nlmconv.c, nm.c, objcopy.c, objdump.c,
[platform/upstream/binutils.git] / binutils / nlmconv.c
1 /* nlmconv.c -- NLM conversion program
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /* Written by Ian Lance Taylor <ian@cygnus.com>.
21
22    This program can be used to convert any appropriate object file
23    into a NetWare Loadable Module (an NLM).  It will accept a linker
24    specification file which is identical to that accepted by the
25    NetWare linker, NLMLINK, except that the INPUT command, normally
26    used to give a list of object files to link together, is not used.
27    This program will convert only a single object file.  */
28
29 #include <ansidecl.h>
30 #include <stdio.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/file.h>
36 #include <assert.h>
37 #include <getopt.h>
38 #include <bfd.h>
39 #include "sysdep.h"
40 #include "bucomm.h"
41 /* Internal BFD NLM header.  */
42 #include "libnlm.h"
43 #include "nlmconv.h"
44
45 /* Needed for Alpha support.  */
46 #include "coff/sym.h"
47 #include "coff/ecoff.h"
48
49 /* If strerror is just a macro, we want to use the one from libiberty
50    since it will handle undefined values.  */
51 #undef strerror
52 extern char *strerror ();
53
54 #ifndef localtime
55 extern struct tm *localtime ();
56 #endif
57
58 #ifndef getenv
59 extern char *getenv ();
60 #endif
61
62 #ifndef SEEK_SET
63 #define SEEK_SET 0
64 #endif
65
66 #ifndef R_OK
67 #define R_OK 4
68 #define W_OK 2
69 #define X_OK 1
70 #endif
71 \f
72 /* Global variables.  */
73
74 /* The name used to invoke the program.  */
75 char *program_name;
76
77 /* The version number.  */
78 extern char *program_version;
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 temporary file name to be unlinked on exit.  Actually, for most
90    errors, we leave it around.  It's not clear whether that is helpful
91    or not.  */
92 static char *unlink_on_exit;
93
94 /* The list of long options.  */
95 static struct option long_options[] =
96 {
97   { "debug", no_argument, 0, 'd' },
98   { "header-file", required_argument, 0, 'T' },
99   { "help", no_argument, 0, 'h' },
100   { "input-target", required_argument, 0, 'I' },
101   { "input-format", required_argument, 0, 'I' }, /* Obsolete */
102   { "linker", required_argument, 0, 'l' },
103   { "output-target", required_argument, 0, 'O' },
104   { "output-format", required_argument, 0, 'O' }, /* Obsolete */
105   { "version", no_argument, 0, 'V' },
106   { NULL, no_argument, 0, 0 }
107 };
108
109 /* Local routines.  */
110
111 static void show_help PARAMS ((void));
112 static void show_usage PARAMS ((FILE *, int));
113 static const char *select_output_format PARAMS ((enum bfd_architecture,
114                                                  unsigned long, boolean));
115 static void setup_sections PARAMS ((bfd *, asection *, PTR));
116 static void copy_sections PARAMS ((bfd *, asection *, PTR));
117 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
118                                    bfd_size_type *, char *,
119                                    bfd_size_type));
120 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
121                                         bfd_size_type *, char *,
122                                         bfd_size_type));
123 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
124                                          bfd_size_type *, char *,
125                                          bfd_size_type));
126 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
127                                            bfd_size_type *, char *,
128                                            bfd_size_type));
129 static char *link_inputs PARAMS ((struct string_list *, char *));
130 static const char *choose_temp_base_try PARAMS ((const char *,
131                                                  const char *));
132 static void choose_temp_base PARAMS ((void));
133 static int pexecute PARAMS ((char *, char *[]));
134 \f
135 /* The main routine.  */
136
137 int
138 main (argc, argv)
139      int argc;
140      char **argv;
141 {
142   int opt;
143   char *input_file = NULL;
144   const char *input_format = NULL;
145   const char *output_format = NULL;
146   const char *header_file = NULL;
147   char *ld_arg = NULL;
148   Nlm_Internal_Fixed_Header fixed_hdr_struct;
149   Nlm_Internal_Variable_Header var_hdr_struct;
150   Nlm_Internal_Version_Header version_hdr_struct;
151   Nlm_Internal_Copyright_Header copyright_hdr_struct;
152   Nlm_Internal_Extended_Header extended_hdr_struct;
153   bfd *inbfd;
154   bfd *outbfd;
155   asymbol **newsyms, **outsyms;
156   unsigned int symcount, newsymalloc, newsymcount;
157   asection *bss_sec, *data_sec;
158   bfd_vma vma;
159   bfd_size_type align;
160   asymbol *endsym;
161   unsigned int i;
162   char inlead, outlead;
163   boolean gotstart, gotexit, gotcheck;
164   struct stat st;
165   FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
166   size_t custom_size, help_size, message_size, module_size, rpc_size;
167   asection *custom_section, *help_section, *message_section, *module_section;
168   asection *rpc_section, *shared_section;
169   bfd *sharedbfd;
170   size_t shared_offset, shared_size;
171   Nlm_Internal_Fixed_Header sharedhdr;
172   int len;
173   char *modname;
174   char **matching;
175
176   program_name = argv[0];
177   xmalloc_set_program_name (program_name);
178
179   bfd_init ();
180
181   while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
182                              (int *) NULL))
183          != EOF)
184     {
185       switch (opt)
186         {
187         case 'd':
188           debug = 1;
189           break;
190         case 'h':
191           show_help ();
192           /*NOTREACHED*/
193         case 'I':
194           input_format = optarg;
195           break;
196         case 'l':
197           ld_arg = optarg;
198           break;
199         case 'O':
200           output_format = optarg;
201           break;
202         case 'T':
203           header_file = optarg;
204           break;
205         case 'V':
206           printf ("GNU %s version %s\n", program_name, program_version);
207           exit (0);
208           /*NOTREACHED*/
209         case 0:
210           break;
211         default:
212           show_usage (stderr, 1);
213           /*NOTREACHED*/
214         }
215     }
216
217   /* The input and output files may be named on the command line.  */
218   output_file = NULL;
219   if (optind < argc)
220     {
221       input_file = argv[optind];
222       ++optind;
223       if (optind < argc)
224         {
225           output_file = argv[optind];
226           ++optind;
227           if (optind < argc)
228             show_usage (stderr, 1);
229           if (strcmp (input_file, output_file) == 0)
230             {
231               fprintf (stderr,
232                        "%s: input and output files must be different\n",
233                        program_name);
234               exit (1);
235             }
236         }
237     }
238
239   /* Initialize the header information to default values.  */
240   fixed_hdr = &fixed_hdr_struct;
241   memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
242   var_hdr = &var_hdr_struct;
243   memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
244   version_hdr = &version_hdr_struct;
245   memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
246   copyright_hdr = &copyright_hdr_struct;
247   memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
248   extended_hdr = &extended_hdr_struct;
249   memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
250   check_procedure = NULL;
251   custom_file = NULL;
252   debug_info = false;
253   exit_procedure = "_Stop";
254   export_symbols = NULL;
255   map_file = NULL;
256   full_map = false;
257   help_file = NULL;
258   import_symbols = NULL;
259   message_file = NULL;
260   modules = NULL;
261   sharelib_file = NULL;
262   start_procedure = "_Prelude";
263   verbose = false;
264   rpc_file = NULL;
265
266   parse_errors = 0;
267
268   /* Parse the header file (if there is one).  */
269   if (header_file != NULL)
270     {
271       if (! nlmlex_file (header_file)
272           || yyparse () != 0
273           || parse_errors != 0)
274         exit (1);
275     }
276
277   if (input_files != NULL)
278     {
279       if (input_file != NULL)
280         {
281           fprintf (stderr,
282                    "%s: input file named both on command line and with INPUT\n",
283                    program_name);
284           exit (1);
285         }
286       if (input_files->next == NULL)
287         input_file = input_files->string;
288       else
289         input_file = link_inputs (input_files, ld_arg);
290     }
291   else if (input_file == NULL)
292     {
293       fprintf (stderr, "%s: no input file\n", program_name);
294       show_usage (stderr, 1);
295     }
296
297   inbfd = bfd_openr (input_file, input_format);
298   if (inbfd == NULL)
299     bfd_fatal (input_file);
300
301   if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
302     {
303       bfd_nonfatal (input_file);
304       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
305         {
306           list_matching_formats (matching);
307           free (matching);
308         }
309       exit (1);
310     }
311
312   if (output_format == NULL)
313     output_format = select_output_format (bfd_get_arch (inbfd),
314                                           bfd_get_mach (inbfd),
315                                           inbfd->xvec->byteorder_big_p);
316
317   assert (output_format != NULL);
318
319   /* Use the output file named on the command line if it exists.
320      Otherwise use the file named in the OUTPUT statement.  */
321   if (output_file == NULL)
322     {
323       fprintf (stderr, "%s: no name for output file\n",
324                program_name);
325       show_usage (stderr, 1);
326     }
327
328   outbfd = bfd_openw (output_file, output_format);
329   if (outbfd == NULL)
330     bfd_fatal (output_file);
331   if (! bfd_set_format (outbfd, bfd_object))
332     bfd_fatal (output_file);
333
334   assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
335
336   if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
337     fprintf (stderr,
338              "%s: warning:input and output formats are not compatible\n",
339              program_name);
340
341   /* Move the values read from the command file into outbfd.  */
342   *nlm_fixed_header (outbfd) = fixed_hdr_struct;
343   *nlm_variable_header (outbfd) = var_hdr_struct;
344   *nlm_version_header (outbfd) = version_hdr_struct;
345   *nlm_copyright_header (outbfd) = copyright_hdr_struct;
346   *nlm_extended_header (outbfd) = extended_hdr_struct;
347
348   /* Start copying the input BFD to the output BFD.  */
349   if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
350     bfd_fatal (bfd_get_filename (outbfd));
351
352   symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
353   symcount = bfd_canonicalize_symtab (inbfd, symbols);
354
355   /* Make sure we have a .bss section.  */
356   bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
357   if (bss_sec == NULL)
358     {
359       bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
360       if (bss_sec == NULL
361           || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
362           || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
363         bfd_fatal ("make .bss section");
364     }
365
366   /* Set up the sections.  */
367   bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
368
369   /* The .bss section immediately follows the .data section.  */
370   data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
371   if (data_sec != NULL)
372     {
373       bfd_size_type add;
374
375       vma = bfd_get_section_size_before_reloc (data_sec);
376       align = 1 << bss_sec->alignment_power;
377       add = ((vma + align - 1) &~ (align - 1)) - vma;
378       vma += add;
379       if (! bfd_set_section_vma (outbfd, bss_sec, vma))
380         bfd_fatal ("set .bss vma");
381       if (add != 0)
382         {
383           bfd_size_type data_size;
384
385           data_size = bfd_get_section_size_before_reloc (data_sec);
386           if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
387             bfd_fatal ("set .data size");
388         }
389     }
390
391   /* Adjust symbol information.  */
392   inlead = bfd_get_symbol_leading_char (inbfd);
393   outlead = bfd_get_symbol_leading_char (outbfd);
394   gotstart = false;
395   gotexit = false;
396   gotcheck = false;
397   newsymalloc = 10;
398   newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
399   newsymcount = 0;
400   endsym = NULL;
401   for (i = 0; i < symcount; i++)
402     {
403       register asymbol *sym;
404
405       sym = symbols[i];
406
407       /* Add or remove a leading underscore.  */
408       if (inlead != outlead)
409         {
410           if (inlead != '\0')
411             {
412               if (bfd_asymbol_name (sym)[0] == inlead)
413                 {
414                   if (outlead == '\0')
415                     ++sym->name;
416                   else
417                     {
418                       char *new;
419
420                       new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
421                       new[0] = outlead;
422                       strcpy (new + 1, bfd_asymbol_name (sym) + 1);
423                       sym->name = new;
424                     }
425                 }
426             }
427           else
428             {
429               char *new;
430
431               new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
432               new[0] = outlead;
433               strcpy (new + 1, bfd_asymbol_name (sym));
434               sym->name = new;
435             }
436         }
437
438       /* NLM's have an uninitialized data section, but they do not
439          have a common section in the Unix sense.  Move all common
440          symbols into the .bss section, and mark them as exported.  */
441       if (bfd_is_com_section (bfd_get_section (sym)))
442         {
443           bfd_vma size;
444
445           sym->section = bss_sec;
446           size = sym->value;
447           sym->value = bss_sec->_raw_size;
448           bss_sec->_raw_size += size;
449           align = 1 << bss_sec->alignment_power;
450           bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
451           sym->flags |= BSF_EXPORT | BSF_GLOBAL;
452         }
453       else if (bfd_get_section (sym)->output_section != NULL)
454         {
455           /* Move the symbol into the output section.  */
456           sym->value += bfd_get_section (sym)->output_offset;
457           sym->section = bfd_get_section (sym)->output_section;
458           /* This is no longer a section symbol.  */
459           sym->flags &=~ BSF_SECTION_SYM;
460         }
461
462       /* Force _edata and _end to be defined.  This would normally be
463          done by the linker, but the manipulation of the common
464          symbols will confuse it.  */
465       if (bfd_asymbol_name (sym)[0] == '_'
466           && bfd_get_section (sym) == &bfd_und_section)
467         {
468           if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
469             {
470               sym->section = bss_sec;
471               sym->value = 0;
472             }
473           if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
474             {
475               sym->section = bss_sec;
476               endsym = sym;
477             }
478         }
479
480       /* If this is a global symbol, check the export list.  */
481       if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
482         {
483           register struct string_list *l;
484           int found_simple;
485
486           /* Unfortunately, a symbol can appear multiple times on the
487              export list, with and without prefixes.  */
488           found_simple = 0;
489           for (l = export_symbols; l != NULL; l = l->next)
490             {
491               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
492                 found_simple = 1;
493               else
494                 {
495                   char *zbase;
496
497                   zbase = strchr (l->string, '@');
498                   if (zbase != NULL
499                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
500                     {
501                       /* We must add a symbol with this prefix.  */
502                       if (newsymcount >= newsymalloc)
503                         {
504                           newsymalloc += 10;
505                           newsyms = ((asymbol **)
506                                      xrealloc ((PTR) newsyms,
507                                                (newsymalloc
508                                                 * sizeof (asymbol *))));
509                         }
510                       newsyms[newsymcount] =
511                         (asymbol *) xmalloc (sizeof (asymbol));
512                       *newsyms[newsymcount] = *sym;
513                       newsyms[newsymcount]->name = l->string;
514                       ++newsymcount;
515                     }
516                 }
517             }
518           if (! found_simple)
519             {
520               /* The unmodified symbol is actually not exported at
521                  all.  */
522               sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
523               sym->flags |= BSF_LOCAL;
524             }
525         }
526
527       /* If it's an undefined symbol, see if it's on the import list.
528          Change the prefix if necessary.  */
529       if (bfd_get_section (sym) == &bfd_und_section)
530         {
531           register struct string_list *l;
532
533           for (l = import_symbols; l != NULL; l = l->next)
534             {
535               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
536                 break;
537               else
538                 {
539                   char *zbase;
540
541                   zbase = strchr (l->string, '@');
542                   if (zbase != NULL
543                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
544                     {
545                       sym->name = l->string;
546                       break;
547                     }
548                 }
549             }
550           if (l == NULL)
551             fprintf (stderr,
552                      "%s: warning: symbol %s imported but not in import list\n",
553                      program_name, bfd_asymbol_name (sym));
554         }
555         
556       /* See if it's one of the special named symbols.  */
557       if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
558         {
559           if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
560             bfd_fatal ("set start address");
561           gotstart = true;
562         }
563       if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
564         {
565           nlm_fixed_header (outbfd)->exitProcedureOffset =
566             bfd_asymbol_value (sym);
567           gotexit = true;
568         }
569       if (check_procedure != NULL
570           && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
571         {
572           nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
573             bfd_asymbol_value (sym);
574           gotcheck = true;
575         }
576     }
577
578   if (endsym != NULL)
579     endsym->value = bfd_get_section_size_before_reloc (bss_sec);
580
581   if (newsymcount == 0)
582     outsyms = symbols;
583   else
584     {
585       outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
586                                       * sizeof (asymbol *));
587       memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
588       memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
589       outsyms[symcount + newsymcount] = NULL;
590     }
591
592   bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
593     
594   if (! gotstart)
595     fprintf (stderr, "%s: warning: START procedure %s not defined\n",
596              program_name, start_procedure);
597   if (! gotexit)
598     fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
599              program_name, exit_procedure);
600   if (check_procedure != NULL
601       && ! gotcheck)
602     fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
603              program_name, check_procedure);
604
605   /* Add additional sections required for the header information.  */
606   if (custom_file != NULL)
607     {
608       custom_data = fopen (custom_file, "r");
609       if (custom_data == NULL
610           || fstat (fileno (custom_data), &st) < 0)
611         {
612           fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
613                    strerror (errno));
614           custom_file = NULL;
615         }
616       else
617         {
618           custom_size = st.st_size;
619           custom_section = bfd_make_section (outbfd, ".nlmcustom");
620           if (custom_section == NULL
621               || ! bfd_set_section_size (outbfd, custom_section, custom_size)
622               || ! bfd_set_section_flags (outbfd, custom_section,
623                                           SEC_HAS_CONTENTS))
624             bfd_fatal ("custom section");
625         }
626     }
627   if (help_file != NULL)
628     {
629       help_data = fopen (help_file, "r");
630       if (help_data == NULL
631           || fstat (fileno (help_data), &st) < 0)
632         {
633           fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
634                    strerror (errno));
635           help_file = NULL;
636         }
637       else
638         {
639           help_size = st.st_size;
640           help_section = bfd_make_section (outbfd, ".nlmhelp");
641           if (help_section == NULL
642               || ! bfd_set_section_size (outbfd, help_section, help_size)
643               || ! bfd_set_section_flags (outbfd, help_section,
644                                           SEC_HAS_CONTENTS))
645             bfd_fatal ("help section");
646           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
647         }
648     }
649   if (message_file != NULL)
650     {
651       message_data = fopen (message_file, "r");
652       if (message_data == NULL
653           || fstat (fileno (message_data), &st) < 0)
654         {
655           fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
656                    strerror (errno));
657           message_file = NULL;
658         }
659       else
660         {
661           message_size = st.st_size;
662           message_section = bfd_make_section (outbfd, ".nlmmessages");
663           if (message_section == NULL
664               || ! bfd_set_section_size (outbfd, message_section, message_size)
665               || ! bfd_set_section_flags (outbfd, message_section,
666                                           SEC_HAS_CONTENTS))
667             bfd_fatal ("message section");
668           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
669         }
670     }
671   if (modules != NULL)
672     {
673       struct string_list *l;
674
675       module_size = 0;
676       for (l = modules; l != NULL; l = l->next)
677         module_size += strlen (l->string) + 1;
678       module_section = bfd_make_section (outbfd, ".nlmmodules");
679       if (module_section == NULL
680           || ! bfd_set_section_size (outbfd, module_section, module_size)
681           || ! bfd_set_section_flags (outbfd, module_section,
682                                       SEC_HAS_CONTENTS))
683         bfd_fatal ("module section");
684     }
685   if (rpc_file != NULL)
686     {
687       rpc_data = fopen (rpc_file, "r");
688       if (rpc_data == NULL
689           || fstat (fileno (rpc_data), &st) < 0)
690         {
691           fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
692                    strerror (errno));
693           rpc_file = NULL;
694         }
695       else
696         {
697           rpc_size = st.st_size;
698           rpc_section = bfd_make_section (outbfd, ".nlmrpc");
699           if (rpc_section == NULL
700               || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
701               || ! bfd_set_section_flags (outbfd, rpc_section,
702                                           SEC_HAS_CONTENTS))
703             bfd_fatal ("rpc section");
704           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
705         }
706     }
707   if (sharelib_file != NULL)
708     {
709       sharedbfd = bfd_openr (sharelib_file, output_format);
710       if (sharedbfd == NULL
711           || ! bfd_check_format (sharedbfd, bfd_object))
712         {
713           fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
714                    bfd_errmsg (bfd_get_error ()));
715           sharelib_file = NULL;
716         }
717       else
718         {
719           sharedhdr = *nlm_fixed_header (sharedbfd);
720           bfd_close (sharedbfd);
721           shared_data = fopen (sharelib_file, "r");
722           if (shared_data == NULL
723               || (fstat (fileno (shared_data), &st) < 0))
724             {
725               fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
726                        strerror (errno));
727               sharelib_file = NULL;
728             }
729           else
730             {
731               /* If we were clever, we could just copy out the
732                  sections of the shared library which we actually
733                  need.  However, we would have to figure out the sizes
734                  of the external and public information, and that can
735                  not be done without reading through them.  */
736               if (sharedhdr.uninitializedDataSize > 0)
737                 {
738                   /* There is no place to record this information.  */
739                   fprintf (stderr,
740                            "%s:%s: warning: shared libraries can not have uninitialized data\n",
741                            program_name, sharelib_file);
742                 }
743               shared_offset = st.st_size;
744               if (shared_offset > sharedhdr.codeImageOffset)
745                 shared_offset = sharedhdr.codeImageOffset;
746               if (shared_offset > sharedhdr.dataImageOffset)
747                 shared_offset = sharedhdr.dataImageOffset;
748               if (shared_offset > sharedhdr.relocationFixupOffset)
749                 shared_offset = sharedhdr.relocationFixupOffset;
750               if (shared_offset > sharedhdr.externalReferencesOffset)
751                 shared_offset = sharedhdr.externalReferencesOffset;
752               if (shared_offset > sharedhdr.publicsOffset)
753                 shared_offset = sharedhdr.publicsOffset;
754               shared_size = st.st_size - shared_offset;
755               shared_section = bfd_make_section (outbfd, ".nlmshared");
756               if (shared_section == NULL
757                   || ! bfd_set_section_size (outbfd, shared_section,
758                                              shared_size)
759                   || ! bfd_set_section_flags (outbfd, shared_section,
760                                               SEC_HAS_CONTENTS))
761                 bfd_fatal ("shared section");
762               strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
763             }
764         }
765     }
766
767   /* Check whether a version was given.  */
768   if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
769     fprintf (stderr, "%s: warning: No version number given\n",
770              program_name);
771
772   /* At least for now, always create an extended header, because that
773      is what NLMLINK does.  */
774   strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
775
776   /* If the date was not given, force it in.  */
777   if (nlm_version_header (outbfd)->month == 0
778       && nlm_version_header (outbfd)->day == 0
779       && nlm_version_header (outbfd)->year == 0)
780     {
781       time_t now;
782       struct tm *ptm;
783
784       time (&now);
785       ptm = localtime (&now);
786       nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
787       nlm_version_header (outbfd)->day = ptm->tm_mday;
788       nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
789       strncpy (version_hdr->stamp, "VeRsIoN#", 8);
790     }
791
792   /* Copy over the sections.  */
793   bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
794
795   /* Finish up the header information.  */
796   if (custom_file != NULL)
797     {
798       PTR data;
799
800       data = xmalloc (custom_size);
801       if (fread (data, 1, custom_size, custom_data) != custom_size)
802         fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
803                  strerror (errno));
804       else
805         {
806           if (! bfd_set_section_contents (outbfd, custom_section, data,
807                                           (file_ptr) 0, custom_size))
808             bfd_fatal ("custom section");
809           nlm_fixed_header (outbfd)->customDataOffset =
810             custom_section->filepos;
811           nlm_fixed_header (outbfd)->customDataSize = custom_size;
812         }
813       free (data);
814     }
815   if (! debug_info)
816     {
817       /* As a special hack, the backend recognizes a debugInfoOffset
818          of -1 to mean that it should not output any debugging
819          information.  This can not be handling by fiddling with the
820          symbol table because exported symbols appear in both the
821          export information and the debugging information.  */
822       nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
823     }
824   if (map_file != NULL)
825     fprintf (stderr,
826              "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
827              program_name);
828   if (help_file != NULL)
829     {
830       PTR data;
831
832       data = xmalloc (help_size);
833       if (fread (data, 1, help_size, help_data) != help_size)
834         fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
835                  strerror (errno));
836       else
837         {
838           if (! bfd_set_section_contents (outbfd, help_section, data,
839                                           (file_ptr) 0, help_size))
840             bfd_fatal ("help section");
841           nlm_extended_header (outbfd)->helpFileOffset =
842             help_section->filepos;
843           nlm_extended_header (outbfd)->helpFileLength = help_size;
844         }
845       free (data);
846     }
847   if (message_file != NULL)
848     {
849       PTR data;
850
851       data = xmalloc (message_size);
852       if (fread (data, 1, message_size, message_data) != message_size)
853         fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
854                  strerror (errno));
855       else
856         {
857           if (! bfd_set_section_contents (outbfd, message_section, data,
858                                           (file_ptr) 0, message_size))
859             bfd_fatal ("message section");
860           nlm_extended_header (outbfd)->messageFileOffset =
861             message_section->filepos;
862           nlm_extended_header (outbfd)->messageFileLength = message_size;
863
864           /* FIXME: Are these offsets correct on all platforms?  Are
865              they 32 bits on all platforms?  What endianness?  */
866           nlm_extended_header (outbfd)->languageID =
867             bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
868           nlm_extended_header (outbfd)->messageCount =
869             bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
870         }
871       free (data);
872     }
873   if (modules != NULL)
874     {
875       PTR data;
876       unsigned char *set;
877       struct string_list *l;
878       bfd_size_type c;
879
880       data = xmalloc (module_size);
881       c = 0;
882       set = (unsigned char *) data;
883       for (l = modules; l != NULL; l = l->next)
884         {
885           *set = strlen (l->string);
886           strncpy (set + 1, l->string, *set);
887           set += *set + 1;
888           ++c;
889         }
890       if (! bfd_set_section_contents (outbfd, module_section, data,
891                                       (file_ptr) 0, module_size))
892         bfd_fatal ("module section");
893       nlm_fixed_header (outbfd)->moduleDependencyOffset =
894         module_section->filepos;
895       nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
896     }
897   if (rpc_file != NULL)
898     {
899       PTR data;
900
901       data = xmalloc (rpc_size);
902       if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
903         fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
904                  strerror (errno));
905       else
906         {
907           if (! bfd_set_section_contents (outbfd, rpc_section, data,
908                                           (file_ptr) 0, rpc_size))
909             bfd_fatal ("rpc section");
910           nlm_extended_header (outbfd)->RPCDataOffset =
911             rpc_section->filepos;
912           nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
913         }
914       free (data);
915     }
916   if (sharelib_file != NULL)
917     {
918       PTR data;
919
920       data = xmalloc (shared_size);
921       if (fseek (shared_data, shared_offset, SEEK_SET) != 0
922           || fread (data, 1, shared_size, shared_data) != shared_size)
923         fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
924                  strerror (errno));
925       else
926         {
927           if (! bfd_set_section_contents (outbfd, shared_section, data,
928                                           (file_ptr) 0, shared_size))
929             bfd_fatal ("shared section");
930         }
931       nlm_extended_header (outbfd)->sharedCodeOffset =
932         sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
933       nlm_extended_header (outbfd)->sharedCodeLength =
934         sharedhdr.codeImageSize;
935       nlm_extended_header (outbfd)->sharedDataOffset =
936         sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
937       nlm_extended_header (outbfd)->sharedDataLength =
938         sharedhdr.dataImageSize;
939       nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
940         (sharedhdr.relocationFixupOffset
941          - shared_offset
942          + shared_section->filepos);
943       nlm_extended_header (outbfd)->sharedRelocationFixupCount =
944         sharedhdr.numberOfRelocationFixups;
945       nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
946         (sharedhdr.externalReferencesOffset
947          - shared_offset
948          + shared_section->filepos);
949       nlm_extended_header (outbfd)->sharedExternalReferenceCount =
950         sharedhdr.numberOfExternalReferences;
951       nlm_extended_header (outbfd)->sharedPublicsOffset =
952         sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
953       nlm_extended_header (outbfd)->sharedPublicsCount =
954         sharedhdr.numberOfPublics;
955       nlm_extended_header (outbfd)->sharedDebugRecordOffset =
956         sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
957       nlm_extended_header (outbfd)->sharedDebugRecordCount =
958         sharedhdr.numberOfDebugRecords;
959       nlm_extended_header (outbfd)->SharedInitializationOffset =
960         sharedhdr.codeStartOffset;
961       nlm_extended_header (outbfd)->SharedExitProcedureOffset =
962         sharedhdr.exitProcedureOffset;
963       free (data);
964     }
965   len = strlen (output_file);
966   if (len > NLM_MODULE_NAME_SIZE - 2)
967     len = NLM_MODULE_NAME_SIZE - 2;
968   nlm_fixed_header (outbfd)->moduleName[0] = len;
969
970   strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
971            NLM_MODULE_NAME_SIZE - 2);
972   nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
973   for (modname = nlm_fixed_header (outbfd)->moduleName;
974        *modname != '\0';
975        modname++)
976     if (islower (*modname))
977       *modname = toupper (*modname);
978
979   strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
980            NLM_OLD_THREAD_NAME_LENGTH);
981
982   if (! bfd_close (outbfd))
983     bfd_fatal (output_file);
984   if (! bfd_close (inbfd))
985     bfd_fatal (input_file);
986
987   if (unlink_on_exit != NULL)
988     unlink (unlink_on_exit);
989
990   return 0;
991 }
992 \f
993 /* Display a help message and exit.  */
994
995 static void
996 show_help ()
997 {
998   printf ("%s: Convert an object file into a NetWare Loadable Module\n",
999           program_name);
1000   show_usage (stdout, 0);
1001 }
1002
1003 /* Show a usage message and exit.  */
1004
1005 static void
1006 show_usage (file, status)
1007      FILE *file;
1008      int status;
1009 {
1010   fprintf (file, "\
1011 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1012        [--input-target=bfdname] [--output-target=bfdname]\n\
1013        [--header-file=file] [--linker=linker] [--debug]\n\
1014        [--help] [--version]\n\
1015        [in-file [out-file]]\n",
1016            program_name);
1017   exit (status);
1018 }
1019 \f
1020 /* Select the output format based on the input architecture, machine,
1021    and endianness.  This chooses the appropriate NLM target.  */
1022
1023 static const char *
1024 select_output_format (arch, mach, bigendian)
1025      enum bfd_architecture arch;
1026      unsigned long mach;
1027      boolean bigendian;
1028 {
1029   switch (arch)
1030     {
1031     case bfd_arch_i386:
1032       return "nlm32-i386";
1033     case bfd_arch_sparc:
1034       return "nlm32-sparc";
1035     case bfd_arch_alpha:
1036       return "nlm32-alpha";
1037     default:
1038       fprintf (stderr, "%s: no default NLM format for %s\n",
1039                program_name, bfd_printable_arch_mach (arch, mach));
1040       exit (1);
1041       /* Avoid warning.  */
1042       return NULL;
1043     }
1044   /*NOTREACHED*/
1045 }
1046 \f
1047 /* The BFD sections are copied in two passes.  This function selects
1048    the output section for each input section, and sets up the section
1049    name, size, etc.  */
1050
1051 static void
1052 setup_sections (inbfd, insec, data_ptr)
1053      bfd *inbfd;
1054      asection *insec;
1055      PTR data_ptr;
1056 {
1057   bfd *outbfd = (bfd *) data_ptr;
1058   flagword f;
1059   const char *outname;
1060   asection *outsec;
1061   bfd_vma offset;
1062   bfd_size_type align;
1063   bfd_size_type add;
1064
1065   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1066      file.  However, I don't have a good way to describe this section.
1067      We do want to copy the section when using objcopy.  */
1068   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1069       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1070     return;
1071
1072   f = bfd_get_section_flags (inbfd, insec);
1073   if (f & SEC_CODE)
1074     outname = NLM_CODE_NAME;
1075   else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1076     outname = NLM_INITIALIZED_DATA_NAME;
1077   else if (f & SEC_ALLOC)
1078     outname = NLM_UNINITIALIZED_DATA_NAME;
1079   else
1080     outname = bfd_section_name (inbfd, insec);
1081
1082   outsec = bfd_get_section_by_name (outbfd, outname);
1083   if (outsec == NULL)
1084     {
1085       outsec = bfd_make_section (outbfd, outname);
1086       if (outsec == NULL)
1087         bfd_fatal ("make section");
1088     }
1089
1090   insec->output_section = outsec;
1091
1092   offset = bfd_section_size (outbfd, outsec);
1093   align = 1 << bfd_section_alignment (inbfd, insec);
1094   add = ((offset + align - 1) &~ (align - 1)) - offset;
1095   insec->output_offset = offset + add;
1096
1097   if (! bfd_set_section_size (outbfd, outsec,
1098                               (bfd_section_size (outbfd, outsec)
1099                                + bfd_section_size (inbfd, insec)
1100                                + add)))
1101     bfd_fatal ("set section size");
1102
1103   if ((bfd_section_alignment (inbfd, insec)
1104        > bfd_section_alignment (outbfd, outsec))
1105       && ! bfd_set_section_alignment (outbfd, outsec,
1106                                       bfd_section_alignment (inbfd, insec)))
1107     bfd_fatal ("set section alignment");
1108
1109   if (! bfd_set_section_flags (outbfd, outsec, f))
1110     bfd_fatal ("set section flags");
1111
1112   bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1113 }
1114
1115 /* Copy the section contents.  */
1116
1117 static void
1118 copy_sections (inbfd, insec, data_ptr)
1119      bfd *inbfd;
1120      asection *insec;
1121      PTR data_ptr;
1122 {
1123   bfd *outbfd = (bfd *) data_ptr;
1124   asection *outsec;
1125   bfd_size_type size;
1126   PTR contents;
1127   bfd_size_type reloc_size;
1128
1129   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1130      file.  However, I don't have a good way to describe this section.
1131      We do want to copy the section when using objcopy.  */
1132   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1133       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1134     return;
1135
1136   outsec = insec->output_section;
1137   assert (outsec != NULL);
1138
1139   size = bfd_get_section_size_before_reloc (insec);
1140   if (size == 0)
1141     return;
1142
1143   /* FIXME: Why are these necessary?  */
1144   insec->_cooked_size = insec->_raw_size;
1145   insec->reloc_done = true;
1146
1147   if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1148     contents = NULL;
1149   else
1150     {
1151       contents = xmalloc (size);
1152       if (! bfd_get_section_contents (inbfd, insec, contents,
1153                                       (file_ptr) 0, size))
1154         bfd_fatal (bfd_get_filename (inbfd));
1155     }
1156
1157   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1158   if (reloc_size != 0)
1159     {
1160       arelent **relocs;
1161       bfd_size_type reloc_count;
1162
1163       relocs = (arelent **) xmalloc (reloc_size);
1164       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1165       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1166                      size);
1167
1168       /* FIXME: refers to internal BFD fields.  */
1169       if (outsec->orelocation != (arelent **) NULL)
1170         {
1171           bfd_size_type total_count;
1172           arelent **combined;
1173
1174           total_count = reloc_count + outsec->reloc_count;
1175           combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1176           memcpy (combined, outsec->orelocation,
1177                   outsec->reloc_count * sizeof (arelent));
1178           memcpy (combined + outsec->reloc_count, relocs,
1179                   (size_t) (reloc_count * sizeof (arelent)));
1180           free (outsec->orelocation);
1181           reloc_count = total_count;
1182           relocs = combined;
1183         }
1184
1185       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1186     }
1187
1188   if (contents != NULL)
1189     {
1190       if (! bfd_set_section_contents (outbfd, outsec, contents,
1191                                       insec->output_offset, size))
1192         bfd_fatal (bfd_get_filename (outbfd));
1193       free (contents);
1194     }
1195 }
1196
1197 /* Some, perhaps all, NetWare targets require changing the relocs used
1198    by the input formats.  */
1199
1200 static void
1201 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1202                contents_size)
1203      bfd *outbfd;
1204      asection *insec;
1205      arelent ***relocs_ptr;
1206      bfd_size_type *reloc_count_ptr;
1207      char *contents;
1208      bfd_size_type contents_size;
1209 {
1210   switch (bfd_get_arch (outbfd))
1211     {
1212     case bfd_arch_i386:
1213       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1214                           contents, contents_size);
1215       break;
1216     case bfd_arch_alpha:
1217       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1218                            contents, contents_size);
1219       break;
1220     default:
1221       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1222                              contents, contents_size);
1223       break;
1224     }
1225 }
1226
1227 /* By default all we need to do for relocs is change the address by
1228    the output_offset.  */
1229
1230 /*ARGSUSED*/
1231 static void
1232 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1233                        contents_size)
1234      bfd *outbfd;
1235      asection *insec;
1236      arelent ***relocs_ptr;
1237      bfd_size_type *reloc_count_ptr;
1238      char *contents;
1239      bfd_size_type contents_size;
1240 {
1241   if (insec->output_offset != 0)
1242     {
1243       bfd_size_type reloc_count;
1244       register arelent **relocs;
1245       register bfd_size_type i;
1246
1247       reloc_count = *reloc_count_ptr;
1248       relocs = *relocs_ptr;
1249       for (i = 0; i < reloc_count; i++, relocs++)
1250         (*relocs)->address += insec->output_offset;
1251     }
1252 }
1253
1254 /* NetWare on the i386 supports a restricted set of relocs, which are
1255    different from those used on other i386 targets.  This routine
1256    converts the relocs.  It is, obviously, very target dependent.  At
1257    the moment, the nlm32-i386 backend performs similar translations;
1258    however, it is more reliable and efficient to do them here.  */
1259
1260 static reloc_howto_type nlm_i386_pcrel_howto =
1261   HOWTO (1,                     /* type */
1262          0,                     /* rightshift */
1263          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1264          32,                    /* bitsize */
1265          true,                  /* pc_relative */
1266          0,                     /* bitpos */
1267          complain_overflow_signed, /* complain_on_overflow */
1268          0,                     /* special_function */
1269          "DISP32",              /* name */
1270          true,                  /* partial_inplace */
1271          0xffffffff,            /* src_mask */
1272          0xffffffff,            /* dst_mask */
1273          true);                 /* pcrel_offset */
1274
1275 static void
1276 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1277                     contents_size)
1278      bfd *outbfd;
1279      asection *insec;
1280      arelent ***relocs_ptr;
1281      bfd_size_type *reloc_count_ptr;
1282      char *contents;
1283      bfd_size_type contents_size;
1284 {
1285   bfd_size_type reloc_count, i;
1286   arelent **relocs;
1287
1288   reloc_count = *reloc_count_ptr;
1289   relocs = *relocs_ptr;
1290   for (i = 0; i < reloc_count; i++)
1291     {
1292       arelent *rel;
1293       asymbol *sym;
1294       bfd_size_type address;
1295       bfd_vma addend;
1296
1297       rel = *relocs++;
1298       sym = *rel->sym_ptr_ptr;
1299
1300       /* We're moving the relocs from the input section to the output
1301          section, so we must adjust the address accordingly.  */
1302       address = rel->address;
1303       rel->address += insec->output_offset;
1304
1305       /* Note that no serious harm will ensue if we fail to change a
1306          reloc.  The backend will fail when writing out the reloc.  */
1307
1308       /* Make sure this reloc is within the data we have.  We use only
1309          4 byte relocs here, so we insist on having 4 bytes.  */
1310       if (address + 4 > contents_size)
1311         continue;
1312
1313       /* A PC relative reloc entirely within a single section is
1314          completely unnecessary.  This can be generated by ld -r.  */
1315       if (sym == insec->symbol
1316           && rel->howto != NULL
1317           && rel->howto->pc_relative
1318           && ! rel->howto->pcrel_offset)
1319         {
1320           --*reloc_count_ptr;
1321           --relocs;
1322           memmove (relocs, relocs + 1,
1323                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1324           continue;
1325         }
1326
1327       /* Get the amount the relocation will add in.  */
1328       addend = rel->addend + sym->value;
1329
1330       /* NetWare doesn't support PC relative relocs against defined
1331          symbols, so we have to eliminate them by doing the relocation
1332          now.  We can only do this if the reloc is within a single
1333          section.  */
1334       if (rel->howto != NULL
1335           && rel->howto->pc_relative
1336           && bfd_get_section (sym) == insec->output_section)
1337         {
1338           bfd_vma val;
1339
1340           if (rel->howto->pcrel_offset)
1341             addend -= address;
1342
1343           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1344           val += addend;
1345           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1346
1347           --*reloc_count_ptr;
1348           --relocs;
1349           memmove (relocs, relocs + 1,
1350                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1351           continue;
1352         }
1353
1354       /* NetWare doesn't support reloc addends, so we get rid of them
1355          here by simply adding them into the object data.  We handle
1356          the symbol value, if any, the same way.  */
1357       if (addend != 0
1358           && rel->howto != NULL
1359           && rel->howto->rightshift == 0
1360           && rel->howto->size == 2
1361           && rel->howto->bitsize == 32
1362           && rel->howto->bitpos == 0
1363           && rel->howto->src_mask == 0xffffffff
1364           && rel->howto->dst_mask == 0xffffffff)
1365         {
1366           bfd_vma val;
1367
1368           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1369           val += addend;
1370           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1371
1372           /* Adjust the reloc for the changes we just made.  */
1373           rel->addend = 0;
1374           if (bfd_get_section (sym) != &bfd_und_section)
1375             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1376         }
1377
1378       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1379          pc_relative relocs accordingly.  We are going to change the
1380          howto field, so we can only do this if the current one is
1381          compatible.  We should check that special_function is NULL
1382          here, but at the moment coff-i386 uses a special_function
1383          which does not affect what we are doing here.  */
1384       if (rel->howto != NULL
1385           && rel->howto->pc_relative
1386           && ! rel->howto->pcrel_offset
1387           && rel->howto->rightshift == 0
1388           && rel->howto->size == 2
1389           && rel->howto->bitsize == 32
1390           && rel->howto->bitpos == 0
1391           && rel->howto->src_mask == 0xffffffff
1392           && rel->howto->dst_mask == 0xffffffff)
1393         {
1394           bfd_vma val;
1395
1396           /* When pcrel_offset is not set, it means that the negative
1397              of the address of the memory location is stored in the
1398              memory location.  We must add it back in.  */
1399           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1400           val += address;
1401           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1402
1403           /* We must change to a new howto.  */
1404           rel->howto = &nlm_i386_pcrel_howto;
1405         }
1406     }
1407 }
1408
1409 /* On the Alpha the first reloc for every section must be a special
1410    relocs which hold the GP address.  Also, the first reloc in the
1411    file must be a special reloc which holds the address of the .lita
1412    section.  */
1413
1414 static reloc_howto_type nlm32_alpha_nw_howto =
1415   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1416          0,                     /* rightshift */
1417          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1418          0,                     /* bitsize */
1419          false,                 /* pc_relative */
1420          0,                     /* bitpos */
1421          complain_overflow_dont, /* complain_on_overflow */
1422          0,                     /* special_function */
1423          "NW_RELOC",            /* name */
1424          false,                 /* partial_inplace */
1425          0,                     /* src_mask */
1426          0,                     /* dst_mask */
1427          false);                /* pcrel_offset */
1428
1429 /*ARGSUSED*/
1430 static void
1431 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1432                      contents_size)
1433      bfd *outbfd;
1434      asection *insec;
1435      register arelent ***relocs_ptr;
1436      bfd_size_type *reloc_count_ptr;
1437      char *contents;
1438      bfd_size_type contents_size;
1439 {
1440   bfd_size_type old_reloc_count;
1441   arelent **old_relocs;
1442   register arelent **relocs;
1443
1444   old_reloc_count = *reloc_count_ptr;
1445   old_relocs = *relocs_ptr;
1446   relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1447   *relocs_ptr = relocs;
1448
1449   if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1450     {
1451       bfd *inbfd;
1452       asection *lita_section;
1453
1454       inbfd = insec->owner;
1455       lita_section = bfd_get_section_by_name (inbfd, _LITA);
1456       if (lita_section != (asection *) NULL)
1457         {
1458           nlm_alpha_backend_data (outbfd)->lita_address =
1459             bfd_get_section_vma (inbfd, lita_section);
1460           nlm_alpha_backend_data (outbfd)->lita_size =
1461             bfd_section_size (inbfd, lita_section);
1462         }
1463       else
1464         {
1465           /* Avoid outputting this reloc again.  */
1466           nlm_alpha_backend_data (outbfd)->lita_address = 4;
1467         }
1468
1469       *relocs = (arelent *) xmalloc (sizeof (arelent));
1470       (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1471       (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1472       (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1473       (*relocs)->howto = &nlm32_alpha_nw_howto;
1474       ++relocs;
1475       ++(*reloc_count_ptr);
1476     }
1477
1478   /* Get the GP value from bfd.  It is in the .reginfo section.  */
1479   if (nlm_alpha_backend_data (outbfd)->gp == 0)
1480     {
1481       bfd *inbfd;
1482       asection *reginfo_sec;
1483       struct ecoff_reginfo sreginfo;
1484
1485       inbfd = insec->owner;
1486       assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1487       reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1488       if (reginfo_sec != (asection *) NULL
1489           && bfd_get_section_contents (inbfd, reginfo_sec,
1490                                        (PTR) &sreginfo, (file_ptr) 0,
1491                                        sizeof sreginfo) != false)
1492         nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1493     }
1494
1495   *relocs = (arelent *) xmalloc (sizeof (arelent));
1496   (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1497   (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1498   (*relocs)->addend = 0;
1499   (*relocs)->howto = &nlm32_alpha_nw_howto;
1500   ++relocs;
1501   ++(*reloc_count_ptr);
1502
1503   memcpy ((PTR) relocs, (PTR) old_relocs,
1504           (size_t) old_reloc_count * sizeof (arelent *));
1505   relocs[old_reloc_count] = (arelent *) NULL;
1506
1507   free (old_relocs);
1508
1509   if (insec->output_offset != 0)
1510     {
1511       register bfd_size_type i;
1512
1513       for (i = 0; i < old_reloc_count; i++, relocs++)
1514         (*relocs)->address += insec->output_offset;
1515     }
1516 }
1517 \f
1518 /* Name of linker.  */
1519 #ifndef LD_NAME
1520 #define LD_NAME "ld"
1521 #endif
1522
1523 /* Temporary file name base.  */
1524 static char *temp_filename;
1525
1526 /* The user has specified several input files.  Invoke the linker to
1527    link them all together, and convert and delete the resulting output
1528    file.  */
1529
1530 static char *
1531 link_inputs (inputs, ld)
1532      struct string_list *inputs;
1533      char *ld;
1534 {
1535   size_t c;
1536   struct string_list *q;
1537   char **argv;
1538   size_t i;
1539   int pid;
1540   int status;
1541
1542   c = 0;
1543   for (q = inputs; q != NULL; q = q->next)
1544     ++c;
1545
1546   argv = (char **) alloca (c + 5);
1547
1548 #ifndef __MSDOS__
1549   if (ld == NULL)
1550     {
1551       char *p;
1552
1553       /* Find the linker to invoke based on how nlmconv was run.  */
1554       p = program_name + strlen (program_name);
1555       while (p != program_name)
1556         {
1557           if (p[-1] == '/')
1558             {
1559               ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
1560               memcpy (ld, program_name, p - program_name);
1561               strcpy (ld + (p - program_name), LD_NAME);
1562               break;
1563             }
1564           --p;
1565         }
1566     }
1567 #endif
1568
1569   if (ld == NULL)
1570     ld = (char *) LD_NAME;
1571
1572   choose_temp_base ();
1573
1574   unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
1575   sprintf (unlink_on_exit, "%s.O", temp_filename);
1576
1577   argv[0] = ld;
1578   argv[1] = (char *) "-r";
1579   argv[2] = (char *) "-o";
1580   argv[3] = unlink_on_exit;
1581   i = 4;
1582   for (q = inputs; q != NULL; q = q->next, i++)
1583     argv[i] = q->string;
1584   argv[i] = NULL;
1585
1586   if (debug)
1587     {
1588       for (i = 0; argv[i] != NULL; i++)
1589         fprintf (stderr, " %s", argv[i]);
1590       fprintf (stderr, "\n");
1591     }
1592
1593   pid = pexecute (ld, argv);
1594
1595   if (waitpid (pid, &status, 0) < 0)
1596     {
1597       perror ("waitpid");
1598       unlink (unlink_on_exit);
1599       exit (1);
1600     }
1601
1602   if (status != 0)
1603     {
1604       fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
1605       unlink (unlink_on_exit);
1606       exit (1);
1607     }
1608
1609   return unlink_on_exit;
1610 }
1611
1612 /* Choose a temporary file name.  Stolen from gcc.c.  */
1613
1614 static const char *
1615 choose_temp_base_try (try, base)
1616      const char *try;
1617      const char *base;
1618 {
1619   const char *rv;
1620
1621   if (base)
1622     rv = base;
1623   else if (try == NULL)
1624     rv = NULL;
1625   else if (access (try, R_OK | W_OK) != 0)
1626     rv = NULL;
1627   else
1628     rv = try;
1629   return rv;
1630 }
1631
1632 static void
1633 choose_temp_base ()
1634 {
1635   const char *base = NULL;
1636   int len;
1637
1638   base = choose_temp_base_try (getenv ("TMPDIR"), base);
1639   base = choose_temp_base_try (getenv ("TMP"), base);
1640   base = choose_temp_base_try (getenv ("TEMP"), base);
1641
1642 #ifdef P_tmpdir
1643   base = choose_temp_base_try (P_tmpdir, base);
1644 #endif
1645
1646   base = choose_temp_base_try ("/usr/tmp", base);
1647   base = choose_temp_base_try ("/tmp", base);
1648
1649   /* If all else fails, use the current directory! */  
1650   if (base == NULL)
1651     base = "./";
1652
1653   len = strlen (base);
1654   temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
1655   strcpy (temp_filename, base);
1656   if (len > 0 && temp_filename[len-1] != '/')
1657     temp_filename[len++] = '/';
1658   strcpy (temp_filename + len, "ccXXXXXX");
1659
1660   mktemp (temp_filename);
1661   if (*temp_filename == '\0')
1662     abort ();
1663 }
1664
1665 /* Execute a job.  Stolen from gcc.c.  */
1666
1667 #ifndef OS2
1668 #ifdef __MSDOS__
1669
1670 static int
1671 pexecute (program, argv)
1672      char *program;
1673      char *argv[];
1674 {
1675   char *scmd, *rf;
1676   FILE *argfile;
1677   int i;
1678
1679   scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
1680   rf = scmd + strlen(program) + 2 + el;
1681   sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
1682   argfile = fopen (rf, "w");
1683   if (argfile == 0)
1684     pfatal_with_name (rf);
1685
1686   for (i=1; argv[i]; i++)
1687     {
1688       char *cp;
1689       for (cp = argv[i]; *cp; cp++)
1690         {
1691           if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
1692             fputc ('\\', argfile);
1693           fputc (*cp, argfile);
1694         }
1695       fputc ('\n', argfile);
1696     }
1697   fclose (argfile);
1698
1699   i = system (scmd);
1700
1701   remove (rf);
1702   
1703   if (i == -1)
1704     {
1705       perror (program);
1706       return MIN_FATAL_STATUS << 8;
1707     }
1708
1709   return i << 8;
1710 }
1711
1712 #else /* not __MSDOS__ */
1713
1714 static int
1715 pexecute (program, argv)
1716      char *program;
1717      char *argv[];
1718 {
1719   int pid;
1720   int retries, sleep_interval;
1721
1722   /* Fork a subprocess; wait and retry if it fails.  */
1723   sleep_interval = 1;
1724   for (retries = 0; retries < 4; retries++)
1725     {
1726       pid = vfork ();
1727       if (pid >= 0)
1728         break;
1729       sleep (sleep_interval);
1730       sleep_interval *= 2;
1731     }
1732
1733   switch (pid)
1734     {
1735     case -1:
1736 #ifdef vfork
1737       perror ("fork");
1738 #else
1739       perror ("vfork");
1740 #endif
1741       exit (1);
1742       /* NOTREACHED */
1743       return 0;
1744
1745     case 0: /* child */
1746       /* Exec the program.  */
1747       execvp (program, argv);
1748       perror (program);
1749       exit (1);
1750       /* NOTREACHED */
1751       return 0;
1752
1753     default:
1754       /* Return child's process number.  */
1755       return pid;
1756     }
1757 }
1758
1759 #endif /* not __MSDOS__ */
1760 #else /* not OS2 */
1761
1762 static int
1763 pexecute (program, argv)
1764      char *program;
1765      char *argv[];
1766 {
1767   return spawnvp (1, program, argv);
1768 }
1769 #endif /* not OS2 */