* nlmconv.c (long_options): Changed --header-info to --header-file
[external/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 <assert.h>
36 #include <getopt.h>
37 #include <bfd.h>
38 #include "sysdep.h"
39 #include "bucomm.h"
40 /* Internal BFD NLM header.  */
41 #include "libnlm.h"
42 #include "nlmconv.h"
43
44 /* Needed for Alpha support.  */
45 #include "coff/sym.h"
46 #include "coff/ecoff.h"
47
48 /* If strerror is just a macro, we want to use the one from libiberty
49    since it will handle undefined values.  */
50 #undef strerror
51 extern char *strerror ();
52
53 #ifndef localtime
54 extern struct tm *localtime ();
55 #endif
56
57 #ifndef SEEK_SET
58 #define SEEK_SET 0
59 #endif
60 \f
61 /* Global variables.  */
62
63 /* The name used to invoke the program.  */
64 char *program_name;
65
66 /* The version number.  */
67 extern char *program_version;
68
69 /* Local variables.  */
70
71 /* The symbol table.  */
72 static asymbol **symbols;
73
74 /* The list of long options.  */
75 static struct option long_options[] =
76 {
77   { "header-file", required_argument, 0, 'T' },
78   { "help", no_argument, 0, 'h' },
79   { "input-format", required_argument, 0, 'I' },
80   { "output-format", required_argument, 0, 'O' },
81   { "version", no_argument, 0, 'V' },
82   { NULL, no_argument, 0, 0 }
83 };
84
85 /* Local routines.  */
86
87 static void show_help PARAMS ((void));
88 static void show_usage PARAMS ((FILE *, int));
89 static const char *select_output_format PARAMS ((enum bfd_architecture,
90                                                  unsigned long, boolean));
91 static void setup_sections PARAMS ((bfd *, asection *, PTR));
92 static void copy_sections PARAMS ((bfd *, asection *, PTR));
93 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
94                                    bfd_size_type *, char *,
95                                    bfd_size_type));
96 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
97                                         bfd_size_type *, char *,
98                                         bfd_size_type));
99 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
100                                          bfd_size_type *, char *,
101                                          bfd_size_type));
102 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
103                                            bfd_size_type *, char *,
104                                            bfd_size_type));
105 \f
106 /* The main routine.  */
107
108 int
109 main (argc, argv)
110      int argc;
111      char **argv;
112 {
113   int opt;
114   const char *input_format = NULL;
115   const char *output_format = NULL;
116   const char *header_file = NULL;
117   bfd *inbfd;
118   bfd *outbfd;
119   asymbol **newsyms, **outsyms;
120   unsigned int symcount, newsymalloc, newsymcount;
121   asection *bss_sec, *data_sec;
122   bfd_vma vma;
123   bfd_size_type align;
124   asymbol *endsym;
125   unsigned int i;
126   char inlead, outlead;
127   boolean gotstart, gotexit, gotcheck;
128   struct stat st;
129   FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
130   size_t custom_size, help_size, message_size, module_size, rpc_size;
131   asection *custom_section, *help_section, *message_section, *module_section;
132   asection *rpc_section, *shared_section;
133   bfd *sharedbfd;
134   size_t shared_offset, shared_size;
135   Nlm_Internal_Fixed_Header sharedhdr;
136   int len;
137   char *modname;
138
139   program_name = argv[0];
140
141   bfd_init ();
142
143   while ((opt = getopt_long (argc, argv, "hI:O:T:V", long_options, (int *) 0))
144          != EOF)
145     {
146       switch (opt)
147         {
148         case 'h':
149           show_help ();
150           /*NOTREACHED*/
151         case 'I':
152           input_format = optarg;
153           break;
154         case 'O':
155           output_format = optarg;
156           break;
157         case 'T':
158           header_file = optarg;
159           break;
160         case 'V':
161           printf ("GNU %s version %s\n", program_name, program_version);
162           exit (0);
163           /*NOTREACHED*/
164         case 0:
165           break;
166         default:
167           show_usage (stderr, 1);
168           /*NOTREACHED*/
169         }
170     }
171
172   if (optind + 2 != argc)
173     show_usage (stderr, 1);
174
175   if (strcmp (argv[optind], argv[optind + 1]) == 0)
176     {
177       fprintf (stderr, "%s: input and output files must be different\n",
178                program_name);
179       exit (1);
180     }
181
182   inbfd = bfd_openr (argv[optind], input_format);
183   if (inbfd == NULL)
184     bfd_fatal (argv[optind]);
185
186   if (! bfd_check_format (inbfd, bfd_object))
187     bfd_fatal (argv[optind]);
188
189   if (output_format == NULL)
190     output_format = select_output_format (bfd_get_arch (inbfd),
191                                           bfd_get_mach (inbfd),
192                                           inbfd->xvec->byteorder_big_p);
193
194   assert (output_format != NULL);
195   outbfd = bfd_openw (argv[optind + 1], output_format);
196   if (outbfd == NULL)
197     bfd_fatal (argv[optind + 1]);
198   if (! bfd_set_format (outbfd, bfd_object))
199     bfd_fatal (argv[optind + 1]);
200
201   assert (outbfd->xvec->flavour == bfd_target_nlm_flavour);
202
203   if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
204     fprintf (stderr,
205              "%s: warning:input and output formats are not compatible\n",
206              program_name);
207
208   /* Initialize the header information to default values.  */
209   fixed_hdr = nlm_fixed_header (outbfd);
210   var_hdr = nlm_variable_header (outbfd);
211   version_hdr = nlm_version_header (outbfd);
212   copyright_hdr = nlm_copyright_header (outbfd);
213   extended_hdr = nlm_extended_header (outbfd);
214   check_procedure = NULL;
215   custom_file = NULL;
216   debug_info = false;
217   exit_procedure = "_Stop";
218   export_symbols = NULL;
219   map_file = NULL;
220   full_map = false;
221   help_file = NULL;
222   import_symbols = NULL;
223   message_file = NULL;
224   modules = NULL;
225   sharelib_file = NULL;
226   start_procedure = "_Prelude";
227   verbose = false;
228   rpc_file = NULL;
229
230   parse_errors = 0;
231
232   /* Parse the header file (if there is one).  */
233   if (header_file != NULL)
234     {
235       if (! nlmlex_file (header_file)
236           || yyparse () != 0
237           || parse_errors != 0)
238         exit (1);
239     }
240
241   /* Start copying the input BFD to the output BFD.  */
242   if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
243     bfd_fatal (bfd_get_filename (outbfd));
244
245   symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
246   symcount = bfd_canonicalize_symtab (inbfd, symbols);
247
248   /* Make sure we have a .bss section.  */
249   bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
250   if (bss_sec == NULL)
251     {
252       bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
253       if (bss_sec == NULL
254           || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
255           || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
256         bfd_fatal ("make .bss section");
257     }
258
259   /* Set up the sections.  */
260   bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
261
262   /* The .bss section immediately follows the .data section.  */
263   data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
264   if (data_sec != NULL)
265     {
266       bfd_size_type add;
267
268       vma = bfd_get_section_size_before_reloc (data_sec);
269       align = 1 << bss_sec->alignment_power;
270       add = ((vma + align - 1) &~ (align - 1)) - vma;
271       vma += add;
272       if (! bfd_set_section_vma (outbfd, bss_sec, vma))
273         bfd_fatal ("set .bss vma");
274       if (add != 0)
275         {
276           bfd_size_type data_size;
277
278           data_size = bfd_get_section_size_before_reloc (data_sec);
279           if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
280             bfd_fatal ("set .data size");
281         }
282     }
283
284   /* Adjust symbol information.  */
285   inlead = bfd_get_symbol_leading_char (inbfd);
286   outlead = bfd_get_symbol_leading_char (outbfd);
287   gotstart = false;
288   gotexit = false;
289   gotcheck = false;
290   newsymalloc = 10;
291   newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
292   newsymcount = 0;
293   endsym = NULL;
294   for (i = 0; i < symcount; i++)
295     {
296       register asymbol *sym;
297
298       sym = symbols[i];
299
300       /* Add or remove a leading underscore.  */
301       if (inlead != outlead)
302         {
303           if (inlead != '\0')
304             {
305               if (bfd_asymbol_name (sym)[0] == inlead)
306                 {
307                   if (outlead == '\0')
308                     ++sym->name;
309                   else
310                     {
311                       char *new;
312
313                       new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
314                       new[0] = outlead;
315                       strcpy (new + 1, bfd_asymbol_name (sym) + 1);
316                       sym->name = new;
317                     }
318                 }
319             }
320           else
321             {
322               char *new;
323
324               new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
325               new[0] = outlead;
326               strcpy (new + 1, bfd_asymbol_name (sym));
327               sym->name = new;
328             }
329         }
330
331       /* NLM's have an uninitialized data section, but they do not
332          have a common section in the Unix sense.  Move all common
333          symbols into the .bss section, and mark them as exported.  */
334       if (bfd_is_com_section (bfd_get_section (sym)))
335         {
336           bfd_vma size;
337
338           sym->section = bss_sec;
339           size = sym->value;
340           sym->value = bss_sec->_raw_size;
341           bss_sec->_raw_size += size;
342           align = 1 << bss_sec->alignment_power;
343           bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
344           sym->flags |= BSF_EXPORT | BSF_GLOBAL;
345         }
346       else if (bfd_get_section (sym)->output_section != NULL)
347         {
348           /* Move the symbol into the output section.  */
349           sym->value += bfd_get_section (sym)->output_offset;
350           sym->section = bfd_get_section (sym)->output_section;
351           /* This is no longer a section symbol.  */
352           sym->flags &=~ BSF_SECTION_SYM;
353         }
354
355       /* Force _edata and _end to be defined.  This would normally be
356          done by the linker, but the manipulation of the common
357          symbols will confuse it.  */
358       if (bfd_asymbol_name (sym)[0] == '_'
359           && bfd_get_section (sym) == &bfd_und_section)
360         {
361           if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
362             {
363               sym->section = bss_sec;
364               sym->value = 0;
365             }
366           if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
367             {
368               sym->section = bss_sec;
369               endsym = sym;
370             }
371         }
372
373       /* If this is a global symbol, check the export list.  */
374       if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
375         {
376           register struct string_list *l;
377           int found_simple;
378
379           /* Unfortunately, a symbol can appear multiple times on the
380              export list, with and without prefixes.  */
381           found_simple = 0;
382           for (l = export_symbols; l != NULL; l = l->next)
383             {
384               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
385                 found_simple = 1;
386               else
387                 {
388                   char *zbase;
389
390                   zbase = strchr (l->string, '@');
391                   if (zbase != NULL
392                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
393                     {
394                       /* We must add a symbol with this prefix.  */
395                       if (newsymcount >= newsymalloc)
396                         {
397                           newsymalloc += 10;
398                           newsyms = ((asymbol **)
399                                      xrealloc (newsyms,
400                                                (newsymalloc
401                                                 * sizeof (asymbol *))));
402                         }
403                       newsyms[newsymcount] =
404                         (asymbol *) xmalloc (sizeof (asymbol));
405                       *newsyms[newsymcount] = *sym;
406                       newsyms[newsymcount]->name = l->string;
407                       ++newsymcount;
408                     }
409                 }
410             }
411           if (! found_simple)
412             {
413               /* The unmodified symbol is actually not exported at
414                  all.  */
415               sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
416               sym->flags |= BSF_LOCAL;
417             }
418         }
419
420       /* If it's an undefined symbol, see if it's on the import list.
421          Change the prefix if necessary.  */
422       if (bfd_get_section (sym) == &bfd_und_section
423           && import_symbols != NULL)
424         {
425           register struct string_list *l;
426
427           for (l = import_symbols; l != NULL; l = l->next)
428             {
429               if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
430                 break;
431               else
432                 {
433                   char *zbase;
434
435                   zbase = strchr (l->string, '@');
436                   if (zbase != NULL
437                       && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
438                     {
439                       sym->name = l->string;
440                       break;
441                     }
442                 }
443             }
444           if (l == NULL)
445             fprintf (stderr,
446                      "%s: warning: symbol %s imported but not in import list\n",
447                      program_name, bfd_asymbol_name (sym));
448         }
449         
450       /* See if it's one of the special named symbols.  */
451       if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
452         {
453           if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
454             bfd_fatal ("set start address");
455           gotstart = true;
456         }
457       if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
458         {
459           nlm_fixed_header (outbfd)->exitProcedureOffset =
460             bfd_asymbol_value (sym);
461           gotexit = true;
462         }
463       if (check_procedure != NULL
464           && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
465         {
466           nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
467             bfd_asymbol_value (sym);
468           gotcheck = true;
469         }
470     }
471
472   if (endsym != NULL)
473     endsym->value = bfd_get_section_size_before_reloc (bss_sec);
474
475   if (newsymcount == 0)
476     outsyms = symbols;
477   else
478     {
479       outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
480                                       * sizeof (asymbol *));
481       memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
482       memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
483       outsyms[symcount + newsymcount] = NULL;
484     }
485
486   bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
487     
488   if (! gotstart)
489     fprintf (stderr, "%s: warning: START procedure %s not defined\n",
490              program_name, start_procedure);
491   if (! gotexit)
492     fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
493              program_name, exit_procedure);
494   if (check_procedure != NULL
495       && ! gotcheck)
496     fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
497              program_name, check_procedure);
498
499   /* Add additional sections required for the header information.  */
500   if (custom_file != NULL)
501     {
502       custom_data = fopen (custom_file, "r");
503       if (custom_data == NULL
504           || fstat (fileno (custom_data), &st) < 0)
505         {
506           fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
507                    strerror (errno));
508           custom_file = NULL;
509         }
510       else
511         {
512           custom_size = st.st_size;
513           custom_section = bfd_make_section (outbfd, ".nlmcustom");
514           if (custom_section == NULL
515               || ! bfd_set_section_size (outbfd, custom_section, custom_size)
516               || ! bfd_set_section_flags (outbfd, custom_section,
517                                           SEC_HAS_CONTENTS))
518             bfd_fatal ("custom section");
519         }
520     }
521   if (help_file != NULL)
522     {
523       help_data = fopen (help_file, "r");
524       if (help_data == NULL
525           || fstat (fileno (help_data), &st) < 0)
526         {
527           fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
528                    strerror (errno));
529           help_file = NULL;
530         }
531       else
532         {
533           help_size = st.st_size;
534           help_section = bfd_make_section (outbfd, ".nlmhelp");
535           if (help_section == NULL
536               || ! bfd_set_section_size (outbfd, help_section, help_size)
537               || ! bfd_set_section_flags (outbfd, help_section,
538                                           SEC_HAS_CONTENTS))
539             bfd_fatal ("help section");
540           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
541         }
542     }
543   if (message_file != NULL)
544     {
545       message_data = fopen (message_file, "r");
546       if (message_data == NULL
547           || fstat (fileno (message_data), &st) < 0)
548         {
549           fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
550                    strerror (errno));
551           message_file = NULL;
552         }
553       else
554         {
555           message_size = st.st_size;
556           message_section = bfd_make_section (outbfd, ".nlmmessages");
557           if (message_section == NULL
558               || ! bfd_set_section_size (outbfd, message_section, message_size)
559               || ! bfd_set_section_flags (outbfd, message_section,
560                                           SEC_HAS_CONTENTS))
561             bfd_fatal ("message section");
562           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
563         }
564     }
565   if (modules != NULL)
566     {
567       struct string_list *l;
568
569       module_size = 0;
570       for (l = modules; l != NULL; l = l->next)
571         module_size += strlen (l->string) + 1;
572       module_section = bfd_make_section (outbfd, ".nlmmodules");
573       if (module_section == NULL
574           || ! bfd_set_section_size (outbfd, module_section, module_size)
575           || ! bfd_set_section_flags (outbfd, module_section,
576                                       SEC_HAS_CONTENTS))
577         bfd_fatal ("module section");
578     }
579   if (rpc_file != NULL)
580     {
581       rpc_data = fopen (rpc_file, "r");
582       if (rpc_data == NULL
583           || fstat (fileno (rpc_data), &st) < 0)
584         {
585           fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
586                    strerror (errno));
587           rpc_file = NULL;
588         }
589       else
590         {
591           rpc_size = st.st_size;
592           rpc_section = bfd_make_section (outbfd, ".nlmrpc");
593           if (rpc_section == NULL
594               || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
595               || ! bfd_set_section_flags (outbfd, rpc_section,
596                                           SEC_HAS_CONTENTS))
597             bfd_fatal ("rpc section");
598           strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
599         }
600     }
601   if (sharelib_file != NULL)
602     {
603       sharedbfd = bfd_openr (sharelib_file, output_format);
604       if (sharedbfd == NULL
605           || ! bfd_check_format (sharedbfd, bfd_object))
606         {
607           fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
608                    bfd_errmsg (bfd_error));
609           sharelib_file = NULL;
610         }
611       else
612         {
613           sharedhdr = *nlm_fixed_header (sharedbfd);
614           bfd_close (sharedbfd);
615           shared_data = fopen (sharelib_file, "r");
616           if (shared_data == NULL
617               || (fstat (fileno (shared_data), &st) < 0))
618             {
619               fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
620                        strerror (errno));
621               sharelib_file = NULL;
622             }
623           else
624             {
625               /* If we were clever, we could just copy out the
626                  sections of the shared library which we actually
627                  need.  However, we would have to figure out the sizes
628                  of the external and public information, and that can
629                  not be done without reading through them.  */
630               shared_offset = st.st_size;
631               if (shared_offset > sharedhdr.codeImageOffset)
632                 shared_offset = sharedhdr.codeImageOffset;
633               if (shared_offset > sharedhdr.dataImageOffset)
634                 shared_offset = sharedhdr.dataImageOffset;
635               if (shared_offset > sharedhdr.relocationFixupOffset)
636                 shared_offset = sharedhdr.relocationFixupOffset;
637               if (shared_offset > sharedhdr.externalReferencesOffset)
638                 shared_offset = sharedhdr.externalReferencesOffset;
639               if (shared_offset > sharedhdr.publicsOffset)
640                 shared_offset = sharedhdr.publicsOffset;
641               shared_size = st.st_size - shared_offset;
642               shared_section = bfd_make_section (outbfd, ".nlmshared");
643               if (shared_section == NULL
644                   || ! bfd_set_section_size (outbfd, shared_section,
645                                              shared_size)
646                   || ! bfd_set_section_flags (outbfd, shared_section,
647                                               SEC_HAS_CONTENTS))
648                 bfd_fatal ("shared section");
649               strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
650             }
651         }
652     }
653
654   /* Check whether a version was given.  */
655   if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
656     fprintf (stderr, "%s: warning: No version number given\n",
657              program_name);
658
659   /* At least for now, always create an extended header, because that
660      is what NLMLINK does.  */
661   strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
662
663   /* If the date was not given, force it in.  */
664   if (nlm_version_header (outbfd)->month == 0
665       && nlm_version_header (outbfd)->day == 0
666       && nlm_version_header (outbfd)->year == 0)
667     {
668       time_t now;
669       struct tm *ptm;
670
671       time (&now);
672       ptm = localtime (&now);
673       nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
674       nlm_version_header (outbfd)->day = ptm->tm_mday;
675       nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
676       strncpy (version_hdr->stamp, "VeRsIoN#", 8);
677     }
678
679   /* Copy over the sections.  */
680   bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
681
682   /* Finish up the header information.  */
683   if (custom_file != NULL)
684     {
685       PTR data;
686
687       data = xmalloc (custom_size);
688       if (fread (data, 1, custom_size, custom_data) != custom_size)
689         fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
690                  strerror (errno));
691       else
692         {
693           if (! bfd_set_section_contents (outbfd, custom_section, data,
694                                           (file_ptr) 0, custom_size))
695             bfd_fatal ("custom section");
696           nlm_fixed_header (outbfd)->customDataOffset =
697             custom_section->filepos;
698           nlm_fixed_header (outbfd)->customDataSize = custom_size;
699         }
700       free (data);
701     }
702   if (! debug_info)
703     {
704       /* As a special hack, the backend recognizes a debugInfoOffset
705          of -1 to mean that it should not output any debugging
706          information.  This can not be handling by fiddling with the
707          symbol table because exported symbols appear in both the
708          export information and the debugging information.  */
709       nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
710     }
711   if (map_file != NULL)
712     fprintf (stderr,
713              "%s: MAP and FULLMAP are not supported; try ld -M\n",
714              program_name);
715   if (help_file != NULL)
716     {
717       PTR data;
718
719       data = xmalloc (help_size);
720       if (fread (data, 1, help_size, help_data) != help_size)
721         fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
722                  strerror (errno));
723       else
724         {
725           if (! bfd_set_section_contents (outbfd, help_section, data,
726                                           (file_ptr) 0, help_size))
727             bfd_fatal ("help section");
728           nlm_extended_header (outbfd)->helpFileOffset =
729             help_section->filepos;
730           nlm_extended_header (outbfd)->helpFileLength = help_size;
731         }
732       free (data);
733     }
734   if (message_file != NULL)
735     {
736       PTR data;
737
738       data = xmalloc (message_size);
739       if (fread (data, 1, message_size, message_data) != message_size)
740         fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
741                  strerror (errno));
742       else
743         {
744           if (! bfd_set_section_contents (outbfd, message_section, data,
745                                           (file_ptr) 0, message_size))
746             bfd_fatal ("message section");
747           nlm_extended_header (outbfd)->messageFileOffset =
748             message_section->filepos;
749           nlm_extended_header (outbfd)->messageFileLength = message_size;
750
751           /* FIXME: Are these offsets correct on all platforms?  Are
752              they 32 bits on all platforms?  What endianness?  */
753           nlm_extended_header (outbfd)->languageID =
754             bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
755           nlm_extended_header (outbfd)->messageCount =
756             bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
757         }
758       free (data);
759     }
760   if (modules != NULL)
761     {
762       PTR data;
763       unsigned char *set;
764       struct string_list *l;
765       bfd_size_type c;
766
767       data = xmalloc (module_size);
768       c = 0;
769       set = (unsigned char *) data;
770       for (l = modules; l != NULL; l = l->next)
771         {
772           *set = strlen (l->string);
773           strncpy (set + 1, l->string, *set);
774           set += *set + 1;
775           ++c;
776         }
777       if (! bfd_set_section_contents (outbfd, module_section, data,
778                                       (file_ptr) 0, module_size))
779         bfd_fatal ("module section");
780       nlm_fixed_header (outbfd)->moduleDependencyOffset =
781         module_section->filepos;
782       nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
783     }
784   if (rpc_file != NULL)
785     {
786       PTR data;
787
788       data = xmalloc (rpc_size);
789       if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
790         fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
791                  strerror (errno));
792       else
793         {
794           if (! bfd_set_section_contents (outbfd, rpc_section, data,
795                                           (file_ptr) 0, rpc_size))
796             bfd_fatal ("rpc section");
797           nlm_extended_header (outbfd)->RPCDataOffset =
798             rpc_section->filepos;
799           nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
800         }
801       free (data);
802     }
803   if (sharelib_file != NULL)
804     {
805       PTR data;
806
807       data = xmalloc (shared_size);
808       if (fseek (shared_data, shared_offset, SEEK_SET) != 0
809           || fread (data, 1, shared_size, shared_data) != shared_size)
810         fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
811                  strerror (errno));
812       else
813         {
814           if (! bfd_set_section_contents (outbfd, shared_section, data,
815                                           (file_ptr) 0, shared_size))
816             bfd_fatal ("shared section");
817         }
818       nlm_extended_header (outbfd)->sharedCodeOffset =
819         sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
820       nlm_extended_header (outbfd)->sharedCodeLength =
821         sharedhdr.codeImageSize;
822       nlm_extended_header (outbfd)->sharedDataOffset =
823         sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
824       nlm_extended_header (outbfd)->sharedDataLength =
825         sharedhdr.dataImageSize;
826       nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
827         (sharedhdr.relocationFixupOffset
828          - shared_offset
829          + shared_section->filepos);
830       nlm_extended_header (outbfd)->sharedRelocationFixupCount =
831         sharedhdr.numberOfRelocationFixups;
832       nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
833         (sharedhdr.externalReferencesOffset
834          - shared_offset
835          + shared_section->filepos);
836       nlm_extended_header (outbfd)->sharedExternalReferenceCount =
837         sharedhdr.numberOfExternalReferences;
838       nlm_extended_header (outbfd)->sharedPublicsOffset =
839         sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
840       nlm_extended_header (outbfd)->sharedPublicsCount =
841         sharedhdr.numberOfPublics;
842       nlm_extended_header (outbfd)->sharedDebugRecordOffset =
843         sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
844       nlm_extended_header (outbfd)->sharedDebugRecordCount =
845         sharedhdr.numberOfDebugRecords;
846       nlm_extended_header (outbfd)->SharedInitializationOffset =
847         sharedhdr.codeStartOffset;
848       nlm_extended_header (outbfd)->SharedExitProcedureOffset =
849         sharedhdr.exitProcedureOffset;
850       free (data);
851     }
852   len = strlen (argv[optind + 1]);
853   if (len > NLM_MODULE_NAME_SIZE - 2)
854     len = NLM_MODULE_NAME_SIZE - 2;
855   nlm_fixed_header (outbfd)->moduleName[0] = len;
856
857   strncpy (nlm_fixed_header (outbfd)->moduleName + 1, argv[optind + 1],
858            NLM_MODULE_NAME_SIZE - 2);
859   nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
860   for (modname = nlm_fixed_header (outbfd)->moduleName;
861        *modname != '\0';
862        modname++)
863     if (islower (*modname))
864       *modname = toupper (*modname);
865
866   strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
867            NLM_OLD_THREAD_NAME_LENGTH);
868
869   if (! bfd_close (outbfd))
870     bfd_fatal (argv[optind + 1]);
871   if (! bfd_close (inbfd))
872     bfd_fatal (argv[optind]);
873
874   return 0;
875 }
876 \f
877 /* Display a help message and exit.  */
878
879 static void
880 show_help ()
881 {
882   printf ("%s: Convert an object file into a NetWare Loadable Module\n",
883           program_name);
884   show_usage (stdout, 0);
885 }
886
887 /* Show a usage message and exit.  */
888
889 static void
890 show_usage (file, status)
891      FILE *file;
892      int status;
893 {
894   fprintf (file, "\
895 Usage: %s [-hV] [-I format] [-O format] [-T header-file]\n\
896        [--input-format=format] [--output-format=format]\n\
897        [--header-file=file] [--help] [--version]\n\
898        in-file out-file\n",
899            program_name);
900   exit (status);
901 }
902 \f
903 /* Select the output format based on the input architecture, machine,
904    and endianness.  This chooses the appropriate NLM target.  */
905
906 static const char *
907 select_output_format (arch, mach, bigendian)
908      enum bfd_architecture arch;
909      unsigned long mach;
910      boolean bigendian;
911 {
912   switch (arch)
913     {
914     case bfd_arch_i386:
915       return "nlm32-i386";
916     case bfd_arch_sparc:
917       return "nlm32-sparc";
918     case bfd_arch_alpha:
919       return "nlm32-alpha";
920     default:
921       fprintf (stderr, "%s: no default NLM format for %s\n",
922                program_name, bfd_printable_arch_mach (arch, mach));
923       exit (1);
924       /* Avoid warning.  */
925       return NULL;
926     }
927   /*NOTREACHED*/
928 }
929 \f
930 /* The BFD sections are copied in two passes.  This function selects
931    the output section for each input section, and sets up the section
932    name, size, etc.  */
933
934 static void
935 setup_sections (inbfd, insec, data_ptr)
936      bfd *inbfd;
937      asection *insec;
938      PTR data_ptr;
939 {
940   bfd *outbfd = (bfd *) data_ptr;
941   flagword f;
942   const char *outname;
943   asection *outsec;
944
945   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
946      file.  However, I don't have a good way to describe this section.
947      We do want to copy the section when using objcopy.  */
948   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
949       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
950     return;
951
952   f = bfd_get_section_flags (inbfd, insec);
953   if (f & SEC_CODE)
954     outname = NLM_CODE_NAME;
955   else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
956     outname = NLM_INITIALIZED_DATA_NAME;
957   else if (f & SEC_ALLOC)
958     outname = NLM_UNINITIALIZED_DATA_NAME;
959   else
960     outname = bfd_section_name (inbfd, insec);
961
962   outsec = bfd_get_section_by_name (outbfd, outname);
963   if (outsec == NULL)
964     {
965       outsec = bfd_make_section (outbfd, outname);
966       if (outsec == NULL)
967         bfd_fatal ("make section");
968     }
969
970   insec->output_section = outsec;
971   insec->output_offset = bfd_section_size (outbfd, outsec);
972
973   if (! bfd_set_section_size (outbfd, outsec,
974                               (bfd_section_size (outbfd, outsec)
975                                + bfd_section_size (inbfd, insec))))
976     bfd_fatal ("set section size");
977
978   if ((bfd_section_alignment (inbfd, insec)
979        > bfd_section_alignment (outbfd, outsec))
980       && ! bfd_set_section_alignment (outbfd, outsec,
981                                       bfd_section_alignment (inbfd, insec)))
982     bfd_fatal ("set section alignment");
983
984   if (! bfd_set_section_flags (outbfd, outsec, f))
985     bfd_fatal ("set section flags");
986
987   bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
988 }
989
990 /* Copy the section contents.  */
991
992 static void
993 copy_sections (inbfd, insec, data_ptr)
994      bfd *inbfd;
995      asection *insec;
996      PTR data_ptr;
997 {
998   bfd *outbfd = (bfd *) data_ptr;
999   asection *outsec;
1000   bfd_size_type size;
1001   PTR contents;
1002   bfd_size_type reloc_size;
1003
1004   /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1005      file.  However, I don't have a good way to describe this section.
1006      We do want to copy the section when using objcopy.  */
1007   if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1008       && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1009     return;
1010
1011   outsec = insec->output_section;
1012   assert (outsec != NULL);
1013
1014   size = bfd_get_section_size_before_reloc (insec);
1015   if (size == 0)
1016     return;
1017
1018   /* FIXME: Why are these necessary?  */
1019   insec->_cooked_size = insec->_raw_size;
1020   insec->reloc_done = true;
1021
1022   if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1023     contents = NULL;
1024   else
1025     {
1026       contents = xmalloc (size);
1027       if (! bfd_get_section_contents (inbfd, insec, contents,
1028                                       (file_ptr) 0, size))
1029         bfd_fatal (bfd_get_filename (inbfd));
1030     }
1031
1032   reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1033   if (reloc_size != 0)
1034     {
1035       arelent **relocs;
1036       bfd_size_type reloc_count;
1037
1038       relocs = (arelent **) xmalloc (reloc_size);
1039       reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1040       mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1041                      size);
1042
1043       /* FIXME: refers to internal BFD fields.  */
1044       if (outsec->orelocation != (arelent **) NULL)
1045         {
1046           bfd_size_type total_count;
1047           arelent **combined;
1048
1049           total_count = reloc_count + outsec->reloc_count;
1050           combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1051           memcpy (combined, outsec->orelocation,
1052                   outsec->reloc_count * sizeof (arelent));
1053           memcpy (combined + outsec->reloc_count, relocs,
1054                   (size_t) (reloc_count * sizeof (arelent)));
1055           free (outsec->orelocation);
1056           reloc_count = total_count;
1057           relocs = combined;
1058         }
1059
1060       bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1061     }
1062
1063   if (contents != NULL)
1064     {
1065       if (! bfd_set_section_contents (outbfd, outsec, contents,
1066                                       insec->output_offset, size))
1067         bfd_fatal (bfd_get_filename (outbfd));
1068       free (contents);
1069     }
1070 }
1071
1072 /* Some, perhaps all, NetWare targets require changing the relocs used
1073    by the input formats.  */
1074
1075 static void
1076 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1077                contents_size)
1078      bfd *outbfd;
1079      asection *insec;
1080      arelent ***relocs_ptr;
1081      bfd_size_type *reloc_count_ptr;
1082      char *contents;
1083      bfd_size_type contents_size;
1084 {
1085   switch (bfd_get_arch (outbfd))
1086     {
1087     case bfd_arch_i386:
1088       i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1089                           contents, contents_size);
1090       break;
1091     case bfd_arch_alpha:
1092       alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1093                            contents, contents_size);
1094       break;
1095     default:
1096       default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1097                              contents, contents_size);
1098       break;
1099     }
1100 }
1101
1102 /* By default all we need to do for relocs is change the address by
1103    the output_offset.  */
1104
1105 /*ARGSUSED*/
1106 static void
1107 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1108                        contents_size)
1109      bfd *outbfd;
1110      asection *insec;
1111      arelent ***relocs_ptr;
1112      bfd_size_type *reloc_count_ptr;
1113      char *contents;
1114      bfd_size_type contents_size;
1115 {
1116   if (insec->output_offset != 0)
1117     {
1118       bfd_size_type reloc_count;
1119       register arelent **relocs;
1120       register bfd_size_type i;
1121
1122       reloc_count = *reloc_count_ptr;
1123       relocs = *relocs_ptr;
1124       for (i = 0; i < reloc_count; i++, relocs++)
1125         (*relocs)->address += insec->output_offset;
1126     }
1127 }
1128
1129 /* NetWare on the i386 supports a restricted set of relocs, which are
1130    different from those used on other i386 targets.  This routine
1131    converts the relocs.  It is, obviously, very target dependent.  At
1132    the moment, the nlm32-i386 backend performs similar translations;
1133    however, it is more reliable and efficient to do them here.  */
1134
1135 static reloc_howto_type nlm_i386_pcrel_howto =
1136   HOWTO (1,                     /* type */
1137          0,                     /* rightshift */
1138          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1139          32,                    /* bitsize */
1140          true,                  /* pc_relative */
1141          0,                     /* bitpos */
1142          complain_overflow_signed, /* complain_on_overflow */
1143          0,                     /* special_function */
1144          "DISP32",              /* name */
1145          true,                  /* partial_inplace */
1146          0xffffffff,            /* src_mask */
1147          0xffffffff,            /* dst_mask */
1148          true);                 /* pcrel_offset */
1149
1150 static void
1151 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1152                     contents_size)
1153      bfd *outbfd;
1154      asection *insec;
1155      arelent ***relocs_ptr;
1156      bfd_size_type *reloc_count_ptr;
1157      char *contents;
1158      bfd_size_type contents_size;
1159 {
1160   bfd_size_type reloc_count, i;
1161   arelent **relocs;
1162
1163   reloc_count = *reloc_count_ptr;
1164   relocs = *relocs_ptr;
1165   for (i = 0; i < reloc_count; i++)
1166     {
1167       arelent *rel;
1168       asymbol *sym;
1169       bfd_size_type address;
1170       bfd_vma addend;
1171
1172       rel = *relocs++;
1173       sym = *rel->sym_ptr_ptr;
1174
1175       /* We're moving the relocs from the input section to the output
1176          section, so we must adjust the address accordingly.  */
1177       address = rel->address;
1178       rel->address += insec->output_offset;
1179
1180       /* Note that no serious harm will ensue if we fail to change a
1181          reloc.  The backend will fail when writing out the reloc.  */
1182
1183       /* Make sure this reloc is within the data we have.  We use only
1184          4 byte relocs here, so we insist on having 4 bytes.  */
1185       if (address + 4 > contents_size)
1186         continue;
1187
1188       /* A PC relative reloc entirely within a single section is
1189          completely unnecessary.  This can be generated by ld -r.  */
1190       if (sym == insec->symbol
1191           && rel->howto != NULL
1192           && rel->howto->pc_relative
1193           && ! rel->howto->pcrel_offset)
1194         {
1195           --*reloc_count_ptr;
1196           --relocs;
1197           memmove (relocs, relocs + 1,
1198                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1199           continue;
1200         }
1201
1202       /* Get the amount the relocation will add in.  */
1203       addend = rel->addend + sym->value;
1204
1205       /* NetWare doesn't support PC relative relocs against defined
1206          symbols, so we have to eliminate them by doing the relocation
1207          now.  We can only do this if the reloc is within a single
1208          section.  */
1209       if (rel->howto != NULL
1210           && rel->howto->pc_relative
1211           && bfd_get_section (sym) == insec->output_section)
1212         {
1213           bfd_vma val;
1214
1215           if (rel->howto->pcrel_offset)
1216             addend -= address;
1217
1218           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1219           val += addend;
1220           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1221
1222           --*reloc_count_ptr;
1223           --relocs;
1224           memmove (relocs, relocs + 1,
1225                    (size_t) ((reloc_count - i) * sizeof (arelent *)));
1226           continue;
1227         }
1228
1229       /* NetWare doesn't support reloc addends, so we get rid of them
1230          here by simply adding them into the object data.  We handle
1231          the symbol value, if any, the same way.  */
1232       if (addend != 0
1233           && rel->howto != NULL
1234           && rel->howto->rightshift == 0
1235           && rel->howto->size == 2
1236           && rel->howto->bitsize == 32
1237           && rel->howto->bitpos == 0
1238           && rel->howto->src_mask == 0xffffffff
1239           && rel->howto->dst_mask == 0xffffffff)
1240         {
1241           bfd_vma val;
1242
1243           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1244           val += addend;
1245           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1246
1247           /* Adjust the reloc for the changes we just made.  */
1248           rel->addend = 0;
1249           if (bfd_get_section (sym) != &bfd_und_section)
1250             rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1251         }
1252
1253       /* NetWare uses a reloc with pcrel_offset set.  We adjust
1254          pc_relative relocs accordingly.  We are going to change the
1255          howto field, so we can only do this if the current one is
1256          compatible.  We should check that special_function is NULL
1257          here, but at the moment coff-i386 uses a special_function
1258          which does not affect what we are doing here.  */
1259       if (rel->howto != NULL
1260           && rel->howto->pc_relative
1261           && ! rel->howto->pcrel_offset
1262           && rel->howto->rightshift == 0
1263           && rel->howto->size == 2
1264           && rel->howto->bitsize == 32
1265           && rel->howto->bitpos == 0
1266           && rel->howto->src_mask == 0xffffffff
1267           && rel->howto->dst_mask == 0xffffffff)
1268         {
1269           bfd_vma val;
1270
1271           /* When pcrel_offset is not set, it means that the negative
1272              of the address of the memory location is stored in the
1273              memory location.  We must add it back in.  */
1274           val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1275           val += address;
1276           bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1277
1278           /* We must change to a new howto.  */
1279           rel->howto = &nlm_i386_pcrel_howto;
1280         }
1281     }
1282 }
1283
1284 /* On the Alpha the first reloc for every section must be a special
1285    relocs which hold the GP address.  Also, the first reloc in the
1286    file must be a special reloc which holds the address of the .lita
1287    section.  */
1288
1289 static reloc_howto_type nlm32_alpha_nw_howto =
1290   HOWTO (ALPHA_R_NW_RELOC,      /* type */
1291          0,                     /* rightshift */
1292          0,                     /* size (0 = byte, 1 = short, 2 = long) */
1293          0,                     /* bitsize */
1294          false,                 /* pc_relative */
1295          0,                     /* bitpos */
1296          complain_overflow_dont, /* complain_on_overflow */
1297          0,                     /* special_function */
1298          "NW_RELOC",            /* name */
1299          false,                 /* partial_inplace */
1300          0,                     /* src_mask */
1301          0,                     /* dst_mask */
1302          false);                /* pcrel_offset */
1303
1304 /*ARGSUSED*/
1305 static void
1306 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1307                      contents_size)
1308      bfd *outbfd;
1309      asection *insec;
1310      register arelent ***relocs_ptr;
1311      bfd_size_type *reloc_count_ptr;
1312      char *contents;
1313      bfd_size_type contents_size;
1314 {
1315   bfd_size_type old_reloc_count;
1316   arelent **old_relocs;
1317   register arelent **relocs;
1318
1319   old_reloc_count = *reloc_count_ptr;
1320   old_relocs = *relocs_ptr;
1321   relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1322   *relocs_ptr = relocs;
1323
1324   if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1325     {
1326       bfd *inbfd;
1327       asection *lita_section;
1328
1329       inbfd = insec->owner;
1330       lita_section = bfd_get_section_by_name (inbfd, _LITA);
1331       if (lita_section != (asection *) NULL)
1332         {
1333           nlm_alpha_backend_data (outbfd)->lita_address =
1334             bfd_get_section_vma (inbfd, lita_section);
1335           nlm_alpha_backend_data (outbfd)->lita_size =
1336             bfd_section_size (inbfd, lita_section);
1337         }
1338       else
1339         {
1340           /* Avoid outputting this reloc again.  */
1341           nlm_alpha_backend_data (outbfd)->lita_address = 4;
1342         }
1343
1344       *relocs = (arelent *) xmalloc (sizeof (arelent));
1345       (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1346       (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1347       (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1348       (*relocs)->howto = &nlm32_alpha_nw_howto;
1349       ++relocs;
1350       ++(*reloc_count_ptr);
1351     }
1352
1353   /* Get the GP value from bfd.  It is in the .reginfo section.  */
1354   if (nlm_alpha_backend_data (outbfd)->gp == 0)
1355     {
1356       bfd *inbfd;
1357       asection *reginfo_sec;
1358       struct ecoff_reginfo sreginfo;
1359
1360       inbfd = insec->owner;
1361       assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1362       reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1363       if (reginfo_sec != (asection *) NULL
1364           && bfd_get_section_contents (inbfd, reginfo_sec,
1365                                        (PTR) &sreginfo, (file_ptr) 0,
1366                                        sizeof sreginfo) != false)
1367         nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1368     }
1369
1370   *relocs = (arelent *) xmalloc (sizeof (arelent));
1371   (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1372   (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1373   (*relocs)->addend = 0;
1374   (*relocs)->howto = &nlm32_alpha_nw_howto;
1375   ++relocs;
1376   ++(*reloc_count_ptr);
1377
1378   memcpy ((PTR) relocs, (PTR) old_relocs,
1379           (size_t) old_reloc_count * sizeof (arelent *));
1380   relocs[old_reloc_count] = (arelent *) NULL;
1381
1382   free (old_relocs);
1383
1384   if (insec->output_offset != 0)
1385     {
1386       register bfd_size_type i;
1387
1388       for (i = 0; i < old_reloc_count; i++, relocs++)
1389         (*relocs)->address += insec->output_offset;
1390     }
1391 }