1 /* nlmconv.c -- NLM conversion program
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
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. */
20 /* Written by Ian Lance Taylor <ian@cygnus.com>.
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. */
33 #include <sys/types.h>
40 /* Internal BFD NLM header. */
44 /* Needed for Alpha support. */
46 #include "coff/ecoff.h"
48 /* If strerror is just a macro, we want to use the one from libiberty
49 since it will handle undefined values. */
51 extern char *strerror ();
54 extern struct tm
*localtime ();
61 /* Global variables. */
63 /* The name used to invoke the program. */
66 /* The version number. */
67 extern char *program_version
;
69 /* Local variables. */
71 /* The symbol table. */
72 static asymbol
**symbols
;
74 /* The list of long options. */
75 static struct option long_options
[] =
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 }
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 *,
96 static void i386_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
97 bfd_size_type
*, char *,
99 static void alpha_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
100 bfd_size_type
*, char *,
102 static void default_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
103 bfd_size_type
*, char *,
106 /* The main routine. */
114 const char *input_format
= NULL
;
115 const char *output_format
= NULL
;
116 const char *header_file
= NULL
;
119 asymbol
**newsyms
, **outsyms
;
120 unsigned int symcount
, newsymalloc
, newsymcount
;
121 asection
*bss_sec
, *data_sec
;
126 char inlead
, outlead
;
127 boolean gotstart
, gotexit
, gotcheck
;
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
;
134 size_t shared_offset
, shared_size
;
135 Nlm_Internal_Fixed_Header sharedhdr
;
139 program_name
= argv
[0];
143 while ((opt
= getopt_long (argc
, argv
, "hI:O:T:V", long_options
, (int *) 0))
152 input_format
= optarg
;
155 output_format
= optarg
;
158 header_file
= optarg
;
161 printf ("GNU %s version %s\n", program_name
, program_version
);
167 show_usage (stderr
, 1);
172 if (optind
+ 2 != argc
)
173 show_usage (stderr
, 1);
175 if (strcmp (argv
[optind
], argv
[optind
+ 1]) == 0)
177 fprintf (stderr
, "%s: input and output files must be different\n",
182 inbfd
= bfd_openr (argv
[optind
], input_format
);
184 bfd_fatal (argv
[optind
]);
186 if (! bfd_check_format (inbfd
, bfd_object
))
187 bfd_fatal (argv
[optind
]);
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
);
194 assert (output_format
!= NULL
);
195 outbfd
= bfd_openw (argv
[optind
+ 1], output_format
);
197 bfd_fatal (argv
[optind
+ 1]);
198 if (! bfd_set_format (outbfd
, bfd_object
))
199 bfd_fatal (argv
[optind
+ 1]);
201 assert (outbfd
->xvec
->flavour
== bfd_target_nlm_flavour
);
203 if (bfd_arch_get_compatible (inbfd
, outbfd
) == NULL
)
205 "%s: warning:input and output formats are not compatible\n",
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
;
217 exit_procedure
= "_Stop";
218 export_symbols
= NULL
;
222 import_symbols
= NULL
;
225 sharelib_file
= NULL
;
226 start_procedure
= "_Prelude";
232 /* Parse the header file (if there is one). */
233 if (header_file
!= NULL
)
235 if (! nlmlex_file (header_file
)
237 || parse_errors
!= 0)
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
));
245 symbols
= (asymbol
**) xmalloc (get_symtab_upper_bound (inbfd
));
246 symcount
= bfd_canonicalize_symtab (inbfd
, symbols
);
248 /* Make sure we have a .bss section. */
249 bss_sec
= bfd_get_section_by_name (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
252 bss_sec
= bfd_make_section (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
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");
259 /* Set up the sections. */
260 bfd_map_over_sections (inbfd
, setup_sections
, (PTR
) outbfd
);
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
)
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
;
272 if (! bfd_set_section_vma (outbfd
, bss_sec
, vma
))
273 bfd_fatal ("set .bss vma");
276 bfd_size_type data_size
;
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");
284 /* Adjust symbol information. */
285 inlead
= bfd_get_symbol_leading_char (inbfd
);
286 outlead
= bfd_get_symbol_leading_char (outbfd
);
291 newsyms
= (asymbol
**) xmalloc (newsymalloc
* sizeof (asymbol
*));
294 for (i
= 0; i
< symcount
; i
++)
296 register asymbol
*sym
;
300 /* Add or remove a leading underscore. */
301 if (inlead
!= outlead
)
305 if (bfd_asymbol_name (sym
)[0] == inlead
)
313 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 1);
315 strcpy (new + 1, bfd_asymbol_name (sym
) + 1);
324 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 2);
326 strcpy (new + 1, bfd_asymbol_name (sym
));
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
)))
338 sym
->section
= bss_sec
;
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
;
346 else if (bfd_get_section (sym
)->output_section
!= NULL
)
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
;
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
)
361 if (strcmp (bfd_asymbol_name (sym
), "_edata") == 0)
363 sym
->section
= bss_sec
;
366 if (strcmp (bfd_asymbol_name (sym
), "_end") == 0)
368 sym
->section
= bss_sec
;
373 /* If this is a global symbol, check the export list. */
374 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) != 0)
376 register struct string_list
*l
;
379 /* Unfortunately, a symbol can appear multiple times on the
380 export list, with and without prefixes. */
382 for (l
= export_symbols
; l
!= NULL
; l
= l
->next
)
384 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
390 zbase
= strchr (l
->string
, '@');
392 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
394 /* We must add a symbol with this prefix. */
395 if (newsymcount
>= newsymalloc
)
398 newsyms
= ((asymbol
**)
401 * sizeof (asymbol
*))));
403 newsyms
[newsymcount
] =
404 (asymbol
*) xmalloc (sizeof (asymbol
));
405 *newsyms
[newsymcount
] = *sym
;
406 newsyms
[newsymcount
]->name
= l
->string
;
413 /* The unmodified symbol is actually not exported at
415 sym
->flags
&=~ (BSF_GLOBAL
| BSF_EXPORT
);
416 sym
->flags
|= BSF_LOCAL
;
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
)
425 register struct string_list
*l
;
427 for (l
= import_symbols
; l
!= NULL
; l
= l
->next
)
429 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
435 zbase
= strchr (l
->string
, '@');
437 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
439 sym
->name
= l
->string
;
446 "%s: warning: symbol %s imported but not in import list\n",
447 program_name
, bfd_asymbol_name (sym
));
450 /* See if it's one of the special named symbols. */
451 if (strcmp (bfd_asymbol_name (sym
), start_procedure
) == 0)
453 if (! bfd_set_start_address (outbfd
, bfd_asymbol_value (sym
)))
454 bfd_fatal ("set start address");
457 if (strcmp (bfd_asymbol_name (sym
), exit_procedure
) == 0)
459 nlm_fixed_header (outbfd
)->exitProcedureOffset
=
460 bfd_asymbol_value (sym
);
463 if (check_procedure
!= NULL
464 && strcmp (bfd_asymbol_name (sym
), check_procedure
) == 0)
466 nlm_fixed_header (outbfd
)->checkUnloadProcedureOffset
=
467 bfd_asymbol_value (sym
);
473 endsym
->value
= bfd_get_section_size_before_reloc (bss_sec
);
475 if (newsymcount
== 0)
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
;
486 bfd_set_symtab (outbfd
, outsyms
, symcount
+ newsymcount
);
489 fprintf (stderr
, "%s: warning: START procedure %s not defined\n",
490 program_name
, start_procedure
);
492 fprintf (stderr
, "%s: warning: EXIT procedure %s not defined\n",
493 program_name
, exit_procedure
);
494 if (check_procedure
!= NULL
496 fprintf (stderr
, "%s: warning: CHECK procedure %s not defined\n",
497 program_name
, check_procedure
);
499 /* Add additional sections required for the header information. */
500 if (custom_file
!= NULL
)
502 custom_data
= fopen (custom_file
, "r");
503 if (custom_data
== NULL
504 || fstat (fileno (custom_data
), &st
) < 0)
506 fprintf (stderr
, "%s:%s: %s\n", program_name
, custom_file
,
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
,
518 bfd_fatal ("custom section");
521 if (help_file
!= NULL
)
523 help_data
= fopen (help_file
, "r");
524 if (help_data
== NULL
525 || fstat (fileno (help_data
), &st
) < 0)
527 fprintf (stderr
, "%s:%s: %s\n", program_name
, help_file
,
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
,
539 bfd_fatal ("help section");
540 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
543 if (message_file
!= NULL
)
545 message_data
= fopen (message_file
, "r");
546 if (message_data
== NULL
547 || fstat (fileno (message_data
), &st
) < 0)
549 fprintf (stderr
, "%s:%s: %s\n", program_name
, message_file
,
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
,
561 bfd_fatal ("message section");
562 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
567 struct string_list
*l
;
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
,
577 bfd_fatal ("module section");
579 if (rpc_file
!= NULL
)
581 rpc_data
= fopen (rpc_file
, "r");
583 || fstat (fileno (rpc_data
), &st
) < 0)
585 fprintf (stderr
, "%s:%s: %s\n", program_name
, rpc_file
,
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
,
597 bfd_fatal ("rpc section");
598 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
601 if (sharelib_file
!= NULL
)
603 sharedbfd
= bfd_openr (sharelib_file
, output_format
);
604 if (sharedbfd
== NULL
605 || ! bfd_check_format (sharedbfd
, bfd_object
))
607 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
608 bfd_errmsg (bfd_error
));
609 sharelib_file
= NULL
;
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))
619 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
621 sharelib_file
= NULL
;
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
,
646 || ! bfd_set_section_flags (outbfd
, shared_section
,
648 bfd_fatal ("shared section");
649 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
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",
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);
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)
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);
679 /* Copy over the sections. */
680 bfd_map_over_sections (inbfd
, copy_sections
, (PTR
) outbfd
);
682 /* Finish up the header information. */
683 if (custom_file
!= NULL
)
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
,
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
;
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;
711 if (map_file
!= NULL
)
713 "%s: MAP and FULLMAP are not supported; try ld -M\n",
715 if (help_file
!= NULL
)
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
,
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
;
734 if (message_file
!= NULL
)
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
,
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
;
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);
764 struct string_list
*l
;
767 data
= xmalloc (module_size
);
769 set
= (unsigned char *) data
;
770 for (l
= modules
; l
!= NULL
; l
= l
->next
)
772 *set
= strlen (l
->string
);
773 strncpy (set
+ 1, l
->string
, *set
);
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
;
784 if (rpc_file
!= NULL
)
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
,
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
;
803 if (sharelib_file
!= NULL
)
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
,
814 if (! bfd_set_section_contents (outbfd
, shared_section
, data
,
815 (file_ptr
) 0, shared_size
))
816 bfd_fatal ("shared section");
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
829 + shared_section
->filepos
);
830 nlm_extended_header (outbfd
)->sharedRelocationFixupCount
=
831 sharedhdr
.numberOfRelocationFixups
;
832 nlm_extended_header (outbfd
)->sharedExternalReferenceOffset
=
833 (sharedhdr
.externalReferencesOffset
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
;
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
;
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
;
863 if (islower (*modname
))
864 *modname
= toupper (*modname
);
866 strncpy (nlm_variable_header (outbfd
)->oldThreadName
, " LONG",
867 NLM_OLD_THREAD_NAME_LENGTH
);
869 if (! bfd_close (outbfd
))
870 bfd_fatal (argv
[optind
+ 1]);
871 if (! bfd_close (inbfd
))
872 bfd_fatal (argv
[optind
]);
877 /* Display a help message and exit. */
882 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
884 show_usage (stdout
, 0);
887 /* Show a usage message and exit. */
890 show_usage (file
, status
)
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\
903 /* Select the output format based on the input architecture, machine,
904 and endianness. This chooses the appropriate NLM target. */
907 select_output_format (arch
, mach
, bigendian
)
908 enum bfd_architecture arch
;
917 return "nlm32-sparc";
919 return "nlm32-alpha";
921 fprintf (stderr
, "%s: no default NLM format for %s\n",
922 program_name
, bfd_printable_arch_mach (arch
, mach
));
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
935 setup_sections (inbfd
, insec
, data_ptr
)
940 bfd
*outbfd
= (bfd
*) data_ptr
;
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)
952 f
= bfd_get_section_flags (inbfd
, insec
);
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
;
960 outname
= bfd_section_name (inbfd
, insec
);
962 outsec
= bfd_get_section_by_name (outbfd
, outname
);
965 outsec
= bfd_make_section (outbfd
, outname
);
967 bfd_fatal ("make section");
970 insec
->output_section
= outsec
;
971 insec
->output_offset
= bfd_section_size (outbfd
, outsec
);
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");
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");
984 if (! bfd_set_section_flags (outbfd
, outsec
, f
))
985 bfd_fatal ("set section flags");
987 bfd_set_reloc (outbfd
, outsec
, (arelent
**) NULL
, 0);
990 /* Copy the section contents. */
993 copy_sections (inbfd
, insec
, data_ptr
)
998 bfd
*outbfd
= (bfd
*) data_ptr
;
1002 bfd_size_type reloc_size
;
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)
1011 outsec
= insec
->output_section
;
1012 assert (outsec
!= NULL
);
1014 size
= bfd_get_section_size_before_reloc (insec
);
1018 /* FIXME: Why are these necessary? */
1019 insec
->_cooked_size
= insec
->_raw_size
;
1020 insec
->reloc_done
= true;
1022 if ((bfd_get_section_flags (inbfd
, insec
) & SEC_HAS_CONTENTS
) == 0)
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
));
1032 reloc_size
= bfd_get_reloc_upper_bound (inbfd
, insec
);
1033 if (reloc_size
!= 0)
1036 bfd_size_type reloc_count
;
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
,
1043 /* FIXME: refers to internal BFD fields. */
1044 if (outsec
->orelocation
!= (arelent
**) NULL
)
1046 bfd_size_type total_count
;
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
;
1060 bfd_set_reloc (outbfd
, outsec
, relocs
, reloc_count
);
1063 if (contents
!= NULL
)
1065 if (! bfd_set_section_contents (outbfd
, outsec
, contents
,
1066 insec
->output_offset
, size
))
1067 bfd_fatal (bfd_get_filename (outbfd
));
1072 /* Some, perhaps all, NetWare targets require changing the relocs used
1073 by the input formats. */
1076 mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1080 arelent
***relocs_ptr
;
1081 bfd_size_type
*reloc_count_ptr
;
1083 bfd_size_type contents_size
;
1085 switch (bfd_get_arch (outbfd
))
1088 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1089 contents
, contents_size
);
1091 case bfd_arch_alpha
:
1092 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1093 contents
, contents_size
);
1096 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1097 contents
, contents_size
);
1102 /* By default all we need to do for relocs is change the address by
1103 the output_offset. */
1107 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1111 arelent
***relocs_ptr
;
1112 bfd_size_type
*reloc_count_ptr
;
1114 bfd_size_type contents_size
;
1116 if (insec
->output_offset
!= 0)
1118 bfd_size_type reloc_count
;
1119 register arelent
**relocs
;
1120 register bfd_size_type i
;
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
;
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. */
1135 static reloc_howto_type nlm_i386_pcrel_howto
=
1136 HOWTO (1, /* type */
1138 2, /* size (0 = byte, 1 = short, 2 = long) */
1140 true, /* pc_relative */
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 */
1151 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1155 arelent
***relocs_ptr
;
1156 bfd_size_type
*reloc_count_ptr
;
1158 bfd_size_type contents_size
;
1160 bfd_size_type reloc_count
, i
;
1163 reloc_count
= *reloc_count_ptr
;
1164 relocs
= *relocs_ptr
;
1165 for (i
= 0; i
< reloc_count
; i
++)
1169 bfd_size_type address
;
1173 sym
= *rel
->sym_ptr_ptr
;
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
;
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. */
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
)
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
)
1197 memmove (relocs
, relocs
+ 1,
1198 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1202 /* Get the amount the relocation will add in. */
1203 addend
= rel
->addend
+ sym
->value
;
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
1209 if (rel
->howto
!= NULL
1210 && rel
->howto
->pc_relative
1211 && bfd_get_section (sym
) == insec
->output_section
)
1215 if (rel
->howto
->pcrel_offset
)
1218 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1220 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1224 memmove (relocs
, relocs
+ 1,
1225 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
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. */
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)
1243 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1245 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1247 /* Adjust the reloc for the changes we just made. */
1249 if (bfd_get_section (sym
) != &bfd_und_section
)
1250 rel
->sym_ptr_ptr
= bfd_get_section (sym
)->symbol_ptr_ptr
;
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)
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
);
1276 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1278 /* We must change to a new howto. */
1279 rel
->howto
= &nlm_i386_pcrel_howto
;
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
1289 static reloc_howto_type nlm32_alpha_nw_howto
=
1290 HOWTO (ALPHA_R_NW_RELOC
, /* type */
1292 0, /* size (0 = byte, 1 = short, 2 = long) */
1294 false, /* pc_relative */
1296 complain_overflow_dont
, /* complain_on_overflow */
1297 0, /* special_function */
1298 "NW_RELOC", /* name */
1299 false, /* partial_inplace */
1302 false); /* pcrel_offset */
1306 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1310 register arelent
***relocs_ptr
;
1311 bfd_size_type
*reloc_count_ptr
;
1313 bfd_size_type contents_size
;
1315 bfd_size_type old_reloc_count
;
1316 arelent
**old_relocs
;
1317 register arelent
**relocs
;
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
;
1324 if (nlm_alpha_backend_data (outbfd
)->lita_address
== 0)
1327 asection
*lita_section
;
1329 inbfd
= insec
->owner
;
1330 lita_section
= bfd_get_section_by_name (inbfd
, _LITA
);
1331 if (lita_section
!= (asection
*) NULL
)
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
);
1340 /* Avoid outputting this reloc again. */
1341 nlm_alpha_backend_data (outbfd
)->lita_address
= 4;
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
;
1350 ++(*reloc_count_ptr
);
1353 /* Get the GP value from bfd. It is in the .reginfo section. */
1354 if (nlm_alpha_backend_data (outbfd
)->gp
== 0)
1357 asection
*reginfo_sec
;
1358 struct ecoff_reginfo sreginfo
;
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
;
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
;
1376 ++(*reloc_count_ptr
);
1378 memcpy ((PTR
) relocs
, (PTR
) old_relocs
,
1379 (size_t) old_reloc_count
* sizeof (arelent
*));
1380 relocs
[old_reloc_count
] = (arelent
*) NULL
;
1384 if (insec
->output_offset
!= 0)
1386 register bfd_size_type i
;
1388 for (i
= 0; i
< old_reloc_count
; i
++, relocs
++)
1389 (*relocs
)->address
+= insec
->output_offset
;