1 /* nlmconv.c -- NLM conversion program
2 Copyright (C) 1993, 94, 95, 96, 1997 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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. */
27 /* AIX requires this to be the first thing in the file. */
35 #include "libiberty.h"
46 /* Internal BFD NLM header. */
52 #include "coff/ecoff.h"
55 /* If strerror is just a macro, we want to use the one from libiberty
56 since it will handle undefined values. */
58 extern char *strerror ();
61 extern struct tm
*localtime ();
74 /* Global variables. */
76 /* The name used to invoke the program. */
79 /* Local variables. */
81 /* Whether to print out debugging information (currently just controls
82 whether it prints the linker command if there is one). */
85 /* The symbol table. */
86 static asymbol
**symbols
;
88 /* A section we create in the output file to hold pointers to where
89 the sections of the input file end up. We will put a pointer to
90 this section in the NLM header. These is an entry for each input
91 section. The format is
92 null terminated section name
93 zeroes to adjust to 4 byte boundary
94 4 byte section data file pointer
96 We don't need a version number. The way we find this information
97 is by finding a stamp in the NLM header information. If we need to
98 change the format of this information, we can simply change the
100 static asection
*secsec
;
102 /* A temporary file name to be unlinked on exit. Actually, for most
103 errors, we leave it around. It's not clear whether that is helpful
105 static char *unlink_on_exit
;
107 /* The list of long options. */
108 static struct option long_options
[] =
110 { "debug", no_argument
, 0, 'd' },
111 { "header-file", required_argument
, 0, 'T' },
112 { "help", no_argument
, 0, 'h' },
113 { "input-target", required_argument
, 0, 'I' },
114 { "input-format", required_argument
, 0, 'I' }, /* Obsolete */
115 { "linker", required_argument
, 0, 'l' },
116 { "output-target", required_argument
, 0, 'O' },
117 { "output-format", required_argument
, 0, 'O' }, /* Obsolete */
118 { "version", no_argument
, 0, 'V' },
119 { NULL
, no_argument
, 0, 0 }
122 /* Local routines. */
124 static void show_help
PARAMS ((void));
125 static void show_usage
PARAMS ((FILE *, int));
126 static const char *select_output_format
PARAMS ((enum bfd_architecture
,
127 unsigned long, boolean
));
128 static void setup_sections
PARAMS ((bfd
*, asection
*, PTR
));
129 static void copy_sections
PARAMS ((bfd
*, asection
*, PTR
));
130 static void mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
133 static void default_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
136 static char *link_inputs
PARAMS ((struct string_list
*, char *));
139 static void i386_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
145 static void alpha_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
150 #ifdef NLMCONV_POWERPC
151 static void powerpc_build_stubs
PARAMS ((bfd
*, bfd
*, asymbol
***, long *));
152 static void powerpc_resolve_stubs
PARAMS ((bfd
*, bfd
*));
153 static void powerpc_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
158 /* The main routine. */
166 char *input_file
= NULL
;
167 const char *input_format
= NULL
;
168 const char *output_format
= NULL
;
169 const char *header_file
= NULL
;
171 Nlm_Internal_Fixed_Header fixed_hdr_struct
;
172 Nlm_Internal_Variable_Header var_hdr_struct
;
173 Nlm_Internal_Version_Header version_hdr_struct
;
174 Nlm_Internal_Copyright_Header copyright_hdr_struct
;
175 Nlm_Internal_Extended_Header extended_hdr_struct
;
178 asymbol
**newsyms
, **outsyms
;
179 long symcount
, newsymalloc
, newsymcount
;
181 asection
*text_sec
, *bss_sec
, *data_sec
;
186 char inlead
, outlead
;
187 boolean gotstart
, gotexit
, gotcheck
;
189 FILE *custom_data
, *help_data
, *message_data
, *rpc_data
, *shared_data
;
190 size_t custom_size
, help_size
, message_size
, module_size
, rpc_size
;
191 asection
*custom_section
, *help_section
, *message_section
, *module_section
;
192 asection
*rpc_section
, *shared_section
;
194 size_t shared_offset
, shared_size
;
195 Nlm_Internal_Fixed_Header sharedhdr
;
200 program_name
= argv
[0];
201 xmalloc_set_program_name (program_name
);
204 set_default_bfd_target ();
206 while ((opt
= getopt_long (argc
, argv
, "dhI:l:O:T:V", long_options
,
219 input_format
= optarg
;
225 output_format
= optarg
;
228 header_file
= optarg
;
231 print_version ("nlmconv");
236 show_usage (stderr
, 1);
241 /* The input and output files may be named on the command line. */
245 input_file
= argv
[optind
];
249 output_file
= argv
[optind
];
252 show_usage (stderr
, 1);
253 if (strcmp (input_file
, output_file
) == 0)
256 "%s: input and output files must be different\n",
263 /* Initialize the header information to default values. */
264 fixed_hdr
= &fixed_hdr_struct
;
265 memset ((PTR
) &fixed_hdr_struct
, 0, sizeof fixed_hdr_struct
);
266 var_hdr
= &var_hdr_struct
;
267 memset ((PTR
) &var_hdr_struct
, 0, sizeof var_hdr_struct
);
268 version_hdr
= &version_hdr_struct
;
269 memset ((PTR
) &version_hdr_struct
, 0, sizeof version_hdr_struct
);
270 copyright_hdr
= ©right_hdr_struct
;
271 memset ((PTR
) ©right_hdr_struct
, 0, sizeof copyright_hdr_struct
);
272 extended_hdr
= &extended_hdr_struct
;
273 memset ((PTR
) &extended_hdr_struct
, 0, sizeof extended_hdr_struct
);
274 check_procedure
= NULL
;
277 exit_procedure
= "_Stop";
278 export_symbols
= NULL
;
282 import_symbols
= NULL
;
285 sharelib_file
= NULL
;
286 start_procedure
= "_Prelude";
292 /* Parse the header file (if there is one). */
293 if (header_file
!= NULL
)
295 if (! nlmlex_file (header_file
)
297 || parse_errors
!= 0)
301 if (input_files
!= NULL
)
303 if (input_file
!= NULL
)
306 "%s: input file named both on command line and with INPUT\n",
310 if (input_files
->next
== NULL
)
311 input_file
= input_files
->string
;
313 input_file
= link_inputs (input_files
, ld_arg
);
315 else if (input_file
== NULL
)
317 fprintf (stderr
, "%s: no input file\n", program_name
);
318 show_usage (stderr
, 1);
321 inbfd
= bfd_openr (input_file
, input_format
);
323 bfd_fatal (input_file
);
325 if (! bfd_check_format_matches (inbfd
, bfd_object
, &matching
))
327 bfd_nonfatal (input_file
);
328 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
330 list_matching_formats (matching
);
336 if (output_format
== NULL
)
337 output_format
= select_output_format (bfd_get_arch (inbfd
),
338 bfd_get_mach (inbfd
),
339 bfd_big_endian (inbfd
));
341 assert (output_format
!= NULL
);
343 /* Use the output file named on the command line if it exists.
344 Otherwise use the file named in the OUTPUT statement. */
345 if (output_file
== NULL
)
347 fprintf (stderr
, "%s: no name for output file\n",
349 show_usage (stderr
, 1);
352 outbfd
= bfd_openw (output_file
, output_format
);
354 bfd_fatal (output_file
);
355 if (! bfd_set_format (outbfd
, bfd_object
))
356 bfd_fatal (output_file
);
358 assert (bfd_get_flavour (outbfd
) == bfd_target_nlm_flavour
);
360 if (bfd_arch_get_compatible (inbfd
, outbfd
) == NULL
)
362 "%s: warning:input and output formats are not compatible\n",
365 /* Move the values read from the command file into outbfd. */
366 *nlm_fixed_header (outbfd
) = fixed_hdr_struct
;
367 *nlm_variable_header (outbfd
) = var_hdr_struct
;
368 *nlm_version_header (outbfd
) = version_hdr_struct
;
369 *nlm_copyright_header (outbfd
) = copyright_hdr_struct
;
370 *nlm_extended_header (outbfd
) = extended_hdr_struct
;
372 /* Start copying the input BFD to the output BFD. */
373 if (! bfd_set_file_flags (outbfd
, bfd_get_file_flags (inbfd
)))
374 bfd_fatal (bfd_get_filename (outbfd
));
376 symsize
= bfd_get_symtab_upper_bound (inbfd
);
378 bfd_fatal (input_file
);
379 symbols
= (asymbol
**) xmalloc (symsize
);
380 symcount
= bfd_canonicalize_symtab (inbfd
, symbols
);
382 bfd_fatal (input_file
);
384 /* Make sure we have a .bss section. */
385 bss_sec
= bfd_get_section_by_name (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
388 bss_sec
= bfd_make_section (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
390 || ! bfd_set_section_flags (outbfd
, bss_sec
, SEC_ALLOC
)
391 || ! bfd_set_section_alignment (outbfd
, bss_sec
, 1))
392 bfd_fatal ("make .bss section");
395 /* We store the original section names in the .nlmsections section,
396 so that programs which understand it can resurrect the original
397 sections from the NLM. We will put a pointer to .nlmsections in
398 the NLM header area. */
399 secsec
= bfd_make_section (outbfd
, ".nlmsections");
401 bfd_fatal ("make .nlmsections section");
402 if (! bfd_set_section_flags (outbfd
, secsec
, SEC_HAS_CONTENTS
))
403 bfd_fatal ("set .nlmsections flags");
405 #ifdef NLMCONV_POWERPC
406 /* For PowerPC NetWare we need to build stubs for calls to undefined
407 symbols. Because each stub requires an entry in the TOC section
408 which must be at the same location as other entries in the TOC
409 section, we must do this before determining where the TOC section
410 goes in setup_sections. */
411 if (bfd_get_arch (inbfd
) == bfd_arch_powerpc
)
412 powerpc_build_stubs (inbfd
, outbfd
, &symbols
, &symcount
);
415 /* Set up the sections. */
416 bfd_map_over_sections (inbfd
, setup_sections
, (PTR
) outbfd
);
418 text_sec
= bfd_get_section_by_name (outbfd
, NLM_CODE_NAME
);
420 /* The .bss section immediately follows the .data section. */
421 data_sec
= bfd_get_section_by_name (outbfd
, NLM_INITIALIZED_DATA_NAME
);
422 if (data_sec
!= NULL
)
426 vma
= bfd_get_section_size_before_reloc (data_sec
);
427 align
= 1 << bss_sec
->alignment_power
;
428 add
= ((vma
+ align
- 1) &~ (align
- 1)) - vma
;
430 if (! bfd_set_section_vma (outbfd
, bss_sec
, vma
))
431 bfd_fatal ("set .bss vma");
434 bfd_size_type data_size
;
436 data_size
= bfd_get_section_size_before_reloc (data_sec
);
437 if (! bfd_set_section_size (outbfd
, data_sec
, data_size
+ add
))
438 bfd_fatal ("set .data size");
442 /* Adjust symbol information. */
443 inlead
= bfd_get_symbol_leading_char (inbfd
);
444 outlead
= bfd_get_symbol_leading_char (outbfd
);
449 newsyms
= (asymbol
**) xmalloc (newsymalloc
* sizeof (asymbol
*));
452 for (i
= 0; i
< symcount
; i
++)
454 register asymbol
*sym
;
458 /* Add or remove a leading underscore. */
459 if (inlead
!= outlead
)
463 if (bfd_asymbol_name (sym
)[0] == inlead
)
471 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 1);
473 strcpy (new + 1, bfd_asymbol_name (sym
) + 1);
482 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 2);
484 strcpy (new + 1, bfd_asymbol_name (sym
));
489 /* NLM's have an uninitialized data section, but they do not
490 have a common section in the Unix sense. Move all common
491 symbols into the .bss section, and mark them as exported. */
492 if (bfd_is_com_section (bfd_get_section (sym
)))
496 sym
->section
= bss_sec
;
498 sym
->value
= bss_sec
->_raw_size
;
499 bss_sec
->_raw_size
+= size
;
500 align
= 1 << bss_sec
->alignment_power
;
501 bss_sec
->_raw_size
= (bss_sec
->_raw_size
+ align
- 1) &~ (align
- 1);
502 sym
->flags
|= BSF_EXPORT
| BSF_GLOBAL
;
504 else if (bfd_get_section (sym
)->output_section
!= NULL
)
506 /* Move the symbol into the output section. */
507 sym
->value
+= bfd_get_section (sym
)->output_offset
;
508 sym
->section
= bfd_get_section (sym
)->output_section
;
509 /* This is no longer a section symbol. */
510 sym
->flags
&=~ BSF_SECTION_SYM
;
513 /* Force _edata and _end to be defined. This would normally be
514 done by the linker, but the manipulation of the common
515 symbols will confuse it. */
516 if ((sym
->flags
& BSF_DEBUGGING
) == 0
517 && bfd_asymbol_name (sym
)[0] == '_'
518 && bfd_is_und_section (bfd_get_section (sym
)))
520 if (strcmp (bfd_asymbol_name (sym
), "_edata") == 0)
522 sym
->section
= bss_sec
;
525 if (strcmp (bfd_asymbol_name (sym
), "_end") == 0)
527 sym
->section
= bss_sec
;
531 #ifdef NLMCONV_POWERPC
532 /* For PowerPC NetWare, we define __GOT0. This is the start
533 of the .got section. */
534 if (bfd_get_arch (inbfd
) == bfd_arch_powerpc
535 && strcmp (bfd_asymbol_name (sym
), "__GOT0") == 0)
539 got_sec
= bfd_get_section_by_name (inbfd
, ".got");
540 assert (got_sec
!= (asection
*) NULL
);
541 sym
->value
= got_sec
->output_offset
;
542 sym
->section
= got_sec
->output_section
;
547 /* If this is a global symbol, check the export list. */
548 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) != 0)
550 register struct string_list
*l
;
553 /* Unfortunately, a symbol can appear multiple times on the
554 export list, with and without prefixes. */
556 for (l
= export_symbols
; l
!= NULL
; l
= l
->next
)
558 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
564 zbase
= strchr (l
->string
, '@');
566 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
568 /* We must add a symbol with this prefix. */
569 if (newsymcount
>= newsymalloc
)
572 newsyms
= ((asymbol
**)
573 xrealloc ((PTR
) newsyms
,
575 * sizeof (asymbol
*))));
577 newsyms
[newsymcount
] =
578 (asymbol
*) xmalloc (sizeof (asymbol
));
579 *newsyms
[newsymcount
] = *sym
;
580 newsyms
[newsymcount
]->name
= l
->string
;
587 /* The unmodified symbol is actually not exported at
589 sym
->flags
&=~ (BSF_GLOBAL
| BSF_EXPORT
);
590 sym
->flags
|= BSF_LOCAL
;
594 /* If it's an undefined symbol, see if it's on the import list.
595 Change the prefix if necessary. */
596 if (bfd_is_und_section (bfd_get_section (sym
)))
598 register struct string_list
*l
;
600 for (l
= import_symbols
; l
!= NULL
; l
= l
->next
)
602 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
608 zbase
= strchr (l
->string
, '@');
610 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
612 sym
->name
= l
->string
;
619 "%s: warning: symbol %s imported but not in import list\n",
620 program_name
, bfd_asymbol_name (sym
));
623 /* See if it's one of the special named symbols. */
624 if ((sym
->flags
& BSF_DEBUGGING
) == 0)
628 /* FIXME: If these symbols are not in the .text section, we
629 add the .text section size to the value. This may not be
630 correct for all targets. I'm not sure how this should
631 really be handled. */
632 if (strcmp (bfd_asymbol_name (sym
), start_procedure
) == 0)
634 val
= bfd_asymbol_value (sym
);
635 if (bfd_get_section (sym
) == data_sec
636 && text_sec
!= (asection
*) NULL
)
637 val
+= bfd_section_size (outbfd
, text_sec
);
638 if (! bfd_set_start_address (outbfd
, val
))
639 bfd_fatal ("set start address");
642 if (strcmp (bfd_asymbol_name (sym
), exit_procedure
) == 0)
644 val
= bfd_asymbol_value (sym
);
645 if (bfd_get_section (sym
) == data_sec
646 && text_sec
!= (asection
*) NULL
)
647 val
+= bfd_section_size (outbfd
, text_sec
);
648 nlm_fixed_header (outbfd
)->exitProcedureOffset
= val
;
651 if (check_procedure
!= NULL
652 && strcmp (bfd_asymbol_name (sym
), check_procedure
) == 0)
654 val
= bfd_asymbol_value (sym
);
655 if (bfd_get_section (sym
) == data_sec
656 && text_sec
!= (asection
*) NULL
)
657 val
+= bfd_section_size (outbfd
, text_sec
);
658 nlm_fixed_header (outbfd
)->checkUnloadProcedureOffset
= val
;
666 endsym
->value
= bfd_get_section_size_before_reloc (bss_sec
);
668 /* FIXME: If any relocs referring to _end use inplace addends,
669 then I think they need to be updated. This is handled by
670 i386_mangle_relocs. Is it needed for any other object
674 if (newsymcount
== 0)
678 outsyms
= (asymbol
**) xmalloc ((symcount
+ newsymcount
+ 1)
679 * sizeof (asymbol
*));
680 memcpy (outsyms
, symbols
, symcount
* sizeof (asymbol
*));
681 memcpy (outsyms
+ symcount
, newsyms
, newsymcount
* sizeof (asymbol
*));
682 outsyms
[symcount
+ newsymcount
] = NULL
;
685 bfd_set_symtab (outbfd
, outsyms
, symcount
+ newsymcount
);
688 fprintf (stderr
, "%s: warning: START procedure %s not defined\n",
689 program_name
, start_procedure
);
691 fprintf (stderr
, "%s: warning: EXIT procedure %s not defined\n",
692 program_name
, exit_procedure
);
693 if (check_procedure
!= NULL
695 fprintf (stderr
, "%s: warning: CHECK procedure %s not defined\n",
696 program_name
, check_procedure
);
698 /* Add additional sections required for the header information. */
699 if (custom_file
!= NULL
)
701 custom_data
= fopen (custom_file
, "r");
702 if (custom_data
== NULL
703 || fstat (fileno (custom_data
), &st
) < 0)
705 fprintf (stderr
, "%s:%s: %s\n", program_name
, custom_file
,
711 custom_size
= st
.st_size
;
712 custom_section
= bfd_make_section (outbfd
, ".nlmcustom");
713 if (custom_section
== NULL
714 || ! bfd_set_section_size (outbfd
, custom_section
, custom_size
)
715 || ! bfd_set_section_flags (outbfd
, custom_section
,
717 bfd_fatal ("custom section");
720 if (help_file
!= NULL
)
722 help_data
= fopen (help_file
, "r");
723 if (help_data
== NULL
724 || fstat (fileno (help_data
), &st
) < 0)
726 fprintf (stderr
, "%s:%s: %s\n", program_name
, help_file
,
732 help_size
= st
.st_size
;
733 help_section
= bfd_make_section (outbfd
, ".nlmhelp");
734 if (help_section
== NULL
735 || ! bfd_set_section_size (outbfd
, help_section
, help_size
)
736 || ! bfd_set_section_flags (outbfd
, help_section
,
738 bfd_fatal ("help section");
739 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
742 if (message_file
!= NULL
)
744 message_data
= fopen (message_file
, "r");
745 if (message_data
== NULL
746 || fstat (fileno (message_data
), &st
) < 0)
748 fprintf (stderr
, "%s:%s: %s\n", program_name
, message_file
,
754 message_size
= st
.st_size
;
755 message_section
= bfd_make_section (outbfd
, ".nlmmessages");
756 if (message_section
== NULL
757 || ! bfd_set_section_size (outbfd
, message_section
, message_size
)
758 || ! bfd_set_section_flags (outbfd
, message_section
,
760 bfd_fatal ("message section");
761 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
766 struct string_list
*l
;
769 for (l
= modules
; l
!= NULL
; l
= l
->next
)
770 module_size
+= strlen (l
->string
) + 1;
771 module_section
= bfd_make_section (outbfd
, ".nlmmodules");
772 if (module_section
== NULL
773 || ! bfd_set_section_size (outbfd
, module_section
, module_size
)
774 || ! bfd_set_section_flags (outbfd
, module_section
,
776 bfd_fatal ("module section");
778 if (rpc_file
!= NULL
)
780 rpc_data
= fopen (rpc_file
, "r");
782 || fstat (fileno (rpc_data
), &st
) < 0)
784 fprintf (stderr
, "%s:%s: %s\n", program_name
, rpc_file
,
790 rpc_size
= st
.st_size
;
791 rpc_section
= bfd_make_section (outbfd
, ".nlmrpc");
792 if (rpc_section
== NULL
793 || ! bfd_set_section_size (outbfd
, rpc_section
, rpc_size
)
794 || ! bfd_set_section_flags (outbfd
, rpc_section
,
796 bfd_fatal ("rpc section");
797 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
800 if (sharelib_file
!= NULL
)
802 sharedbfd
= bfd_openr (sharelib_file
, output_format
);
803 if (sharedbfd
== NULL
804 || ! bfd_check_format (sharedbfd
, bfd_object
))
806 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
807 bfd_errmsg (bfd_get_error ()));
808 sharelib_file
= NULL
;
812 sharedhdr
= *nlm_fixed_header (sharedbfd
);
813 bfd_close (sharedbfd
);
814 shared_data
= fopen (sharelib_file
, "r");
815 if (shared_data
== NULL
816 || (fstat (fileno (shared_data
), &st
) < 0))
818 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
820 sharelib_file
= NULL
;
824 /* If we were clever, we could just copy out the
825 sections of the shared library which we actually
826 need. However, we would have to figure out the sizes
827 of the external and public information, and that can
828 not be done without reading through them. */
829 if (sharedhdr
.uninitializedDataSize
> 0)
831 /* There is no place to record this information. */
833 "%s:%s: warning: shared libraries can not have uninitialized data\n",
834 program_name
, sharelib_file
);
836 shared_offset
= st
.st_size
;
837 if (shared_offset
> sharedhdr
.codeImageOffset
)
838 shared_offset
= sharedhdr
.codeImageOffset
;
839 if (shared_offset
> sharedhdr
.dataImageOffset
)
840 shared_offset
= sharedhdr
.dataImageOffset
;
841 if (shared_offset
> sharedhdr
.relocationFixupOffset
)
842 shared_offset
= sharedhdr
.relocationFixupOffset
;
843 if (shared_offset
> sharedhdr
.externalReferencesOffset
)
844 shared_offset
= sharedhdr
.externalReferencesOffset
;
845 if (shared_offset
> sharedhdr
.publicsOffset
)
846 shared_offset
= sharedhdr
.publicsOffset
;
847 shared_size
= st
.st_size
- shared_offset
;
848 shared_section
= bfd_make_section (outbfd
, ".nlmshared");
849 if (shared_section
== NULL
850 || ! bfd_set_section_size (outbfd
, shared_section
,
852 || ! bfd_set_section_flags (outbfd
, shared_section
,
854 bfd_fatal ("shared section");
855 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
860 /* Check whether a version was given. */
861 if (strncmp (version_hdr
->stamp
, "VeRsIoN#", 8) != 0)
862 fprintf (stderr
, "%s: warning: No version number given\n",
865 /* At least for now, always create an extended header, because that
866 is what NLMLINK does. */
867 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
869 strncpy (nlm_cygnus_ext_header (outbfd
)->stamp
, "CyGnUsEx", 8);
871 /* If the date was not given, force it in. */
872 if (nlm_version_header (outbfd
)->month
== 0
873 && nlm_version_header (outbfd
)->day
== 0
874 && nlm_version_header (outbfd
)->year
== 0)
880 ptm
= localtime (&now
);
881 nlm_version_header (outbfd
)->month
= ptm
->tm_mon
+ 1;
882 nlm_version_header (outbfd
)->day
= ptm
->tm_mday
;
883 nlm_version_header (outbfd
)->year
= ptm
->tm_year
+ 1900;
884 strncpy (version_hdr
->stamp
, "VeRsIoN#", 8);
887 #ifdef NLMCONV_POWERPC
888 /* Resolve the stubs we build for PowerPC NetWare. */
889 if (bfd_get_arch (inbfd
) == bfd_arch_powerpc
)
890 powerpc_resolve_stubs (inbfd
, outbfd
);
893 /* Copy over the sections. */
894 bfd_map_over_sections (inbfd
, copy_sections
, (PTR
) outbfd
);
896 /* Finish up the header information. */
897 if (custom_file
!= NULL
)
901 data
= xmalloc (custom_size
);
902 if (fread (data
, 1, custom_size
, custom_data
) != custom_size
)
903 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, custom_file
,
907 if (! bfd_set_section_contents (outbfd
, custom_section
, data
,
908 (file_ptr
) 0, custom_size
))
909 bfd_fatal ("custom section");
910 nlm_fixed_header (outbfd
)->customDataOffset
=
911 custom_section
->filepos
;
912 nlm_fixed_header (outbfd
)->customDataSize
= custom_size
;
918 /* As a special hack, the backend recognizes a debugInfoOffset
919 of -1 to mean that it should not output any debugging
920 information. This can not be handling by fiddling with the
921 symbol table because exported symbols appear in both the
922 export information and the debugging information. */
923 nlm_fixed_header (outbfd
)->debugInfoOffset
= (file_ptr
) -1;
925 if (map_file
!= NULL
)
927 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
929 if (help_file
!= NULL
)
933 data
= xmalloc (help_size
);
934 if (fread (data
, 1, help_size
, help_data
) != help_size
)
935 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, help_file
,
939 if (! bfd_set_section_contents (outbfd
, help_section
, data
,
940 (file_ptr
) 0, help_size
))
941 bfd_fatal ("help section");
942 nlm_extended_header (outbfd
)->helpFileOffset
=
943 help_section
->filepos
;
944 nlm_extended_header (outbfd
)->helpFileLength
= help_size
;
948 if (message_file
!= NULL
)
952 data
= xmalloc (message_size
);
953 if (fread (data
, 1, message_size
, message_data
) != message_size
)
954 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, message_file
,
958 if (! bfd_set_section_contents (outbfd
, message_section
, data
,
959 (file_ptr
) 0, message_size
))
960 bfd_fatal ("message section");
961 nlm_extended_header (outbfd
)->messageFileOffset
=
962 message_section
->filepos
;
963 nlm_extended_header (outbfd
)->messageFileLength
= message_size
;
965 /* FIXME: Are these offsets correct on all platforms? Are
966 they 32 bits on all platforms? What endianness? */
967 nlm_extended_header (outbfd
)->languageID
=
968 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 106);
969 nlm_extended_header (outbfd
)->messageCount
=
970 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 110);
978 struct string_list
*l
;
981 data
= xmalloc (module_size
);
983 set
= (unsigned char *) data
;
984 for (l
= modules
; l
!= NULL
; l
= l
->next
)
986 *set
= strlen (l
->string
);
987 strncpy (set
+ 1, l
->string
, *set
);
991 if (! bfd_set_section_contents (outbfd
, module_section
, data
,
992 (file_ptr
) 0, module_size
))
993 bfd_fatal ("module section");
994 nlm_fixed_header (outbfd
)->moduleDependencyOffset
=
995 module_section
->filepos
;
996 nlm_fixed_header (outbfd
)->numberOfModuleDependencies
= c
;
998 if (rpc_file
!= NULL
)
1002 data
= xmalloc (rpc_size
);
1003 if (fread (data
, 1, rpc_size
, rpc_data
) != rpc_size
)
1004 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, rpc_file
,
1008 if (! bfd_set_section_contents (outbfd
, rpc_section
, data
,
1009 (file_ptr
) 0, rpc_size
))
1010 bfd_fatal ("rpc section");
1011 nlm_extended_header (outbfd
)->RPCDataOffset
=
1012 rpc_section
->filepos
;
1013 nlm_extended_header (outbfd
)->RPCDataLength
= rpc_size
;
1017 if (sharelib_file
!= NULL
)
1021 data
= xmalloc (shared_size
);
1022 if (fseek (shared_data
, shared_offset
, SEEK_SET
) != 0
1023 || fread (data
, 1, shared_size
, shared_data
) != shared_size
)
1024 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, sharelib_file
,
1028 if (! bfd_set_section_contents (outbfd
, shared_section
, data
,
1029 (file_ptr
) 0, shared_size
))
1030 bfd_fatal ("shared section");
1032 nlm_extended_header (outbfd
)->sharedCodeOffset
=
1033 sharedhdr
.codeImageOffset
- shared_offset
+ shared_section
->filepos
;
1034 nlm_extended_header (outbfd
)->sharedCodeLength
=
1035 sharedhdr
.codeImageSize
;
1036 nlm_extended_header (outbfd
)->sharedDataOffset
=
1037 sharedhdr
.dataImageOffset
- shared_offset
+ shared_section
->filepos
;
1038 nlm_extended_header (outbfd
)->sharedDataLength
=
1039 sharedhdr
.dataImageSize
;
1040 nlm_extended_header (outbfd
)->sharedRelocationFixupOffset
=
1041 (sharedhdr
.relocationFixupOffset
1043 + shared_section
->filepos
);
1044 nlm_extended_header (outbfd
)->sharedRelocationFixupCount
=
1045 sharedhdr
.numberOfRelocationFixups
;
1046 nlm_extended_header (outbfd
)->sharedExternalReferenceOffset
=
1047 (sharedhdr
.externalReferencesOffset
1049 + shared_section
->filepos
);
1050 nlm_extended_header (outbfd
)->sharedExternalReferenceCount
=
1051 sharedhdr
.numberOfExternalReferences
;
1052 nlm_extended_header (outbfd
)->sharedPublicsOffset
=
1053 sharedhdr
.publicsOffset
- shared_offset
+ shared_section
->filepos
;
1054 nlm_extended_header (outbfd
)->sharedPublicsCount
=
1055 sharedhdr
.numberOfPublics
;
1056 nlm_extended_header (outbfd
)->sharedDebugRecordOffset
=
1057 sharedhdr
.debugInfoOffset
- shared_offset
+ shared_section
->filepos
;
1058 nlm_extended_header (outbfd
)->sharedDebugRecordCount
=
1059 sharedhdr
.numberOfDebugRecords
;
1060 nlm_extended_header (outbfd
)->SharedInitializationOffset
=
1061 sharedhdr
.codeStartOffset
;
1062 nlm_extended_header (outbfd
)->SharedExitProcedureOffset
=
1063 sharedhdr
.exitProcedureOffset
;
1066 len
= strlen (output_file
);
1067 if (len
> NLM_MODULE_NAME_SIZE
- 2)
1068 len
= NLM_MODULE_NAME_SIZE
- 2;
1069 nlm_fixed_header (outbfd
)->moduleName
[0] = len
;
1071 strncpy (nlm_fixed_header (outbfd
)->moduleName
+ 1, output_file
,
1072 NLM_MODULE_NAME_SIZE
- 2);
1073 nlm_fixed_header (outbfd
)->moduleName
[NLM_MODULE_NAME_SIZE
- 1] = '\0';
1074 for (modname
= nlm_fixed_header (outbfd
)->moduleName
;
1077 if (islower (*modname
))
1078 *modname
= toupper (*modname
);
1080 strncpy (nlm_variable_header (outbfd
)->oldThreadName
, " LONG",
1081 NLM_OLD_THREAD_NAME_LENGTH
);
1083 nlm_cygnus_ext_header (outbfd
)->offset
= secsec
->filepos
;
1084 nlm_cygnus_ext_header (outbfd
)->length
= bfd_section_size (outbfd
, secsec
);
1086 if (! bfd_close (outbfd
))
1087 bfd_fatal (output_file
);
1088 if (! bfd_close (inbfd
))
1089 bfd_fatal (input_file
);
1091 if (unlink_on_exit
!= NULL
)
1092 unlink (unlink_on_exit
);
1097 /* Display a help message and exit. */
1102 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1104 show_usage (stdout
, 0);
1107 /* Show a usage message and exit. */
1110 show_usage (file
, status
)
1115 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1116 [--input-target=bfdname] [--output-target=bfdname]\n\
1117 [--header-file=file] [--linker=linker] [--debug]\n\
1118 [--help] [--version]\n\
1119 [in-file [out-file]]\n",
1122 fprintf (file
, "Report bugs to bug-gnu-utils@prep.ai.mit.edu\n");
1126 /* Select the output format based on the input architecture, machine,
1127 and endianness. This chooses the appropriate NLM target. */
1130 select_output_format (arch
, mach
, bigendian
)
1131 enum bfd_architecture arch
;
1139 return "nlm32-i386";
1141 #ifdef NLMCONV_SPARC
1142 case bfd_arch_sparc
:
1143 return "nlm32-sparc";
1145 #ifdef NLMCONV_ALPHA
1146 case bfd_arch_alpha
:
1147 return "nlm32-alpha";
1149 #ifdef NLMCONV_POWERPC
1150 case bfd_arch_powerpc
:
1151 return "nlm32-powerpc";
1154 fprintf (stderr
, "%s: support not compiled in for %s\n",
1155 program_name
, bfd_printable_arch_mach (arch
, mach
));
1157 /* Avoid warning. */
1163 /* The BFD sections are copied in two passes. This function selects
1164 the output section for each input section, and sets up the section
1168 setup_sections (inbfd
, insec
, data_ptr
)
1173 bfd
*outbfd
= (bfd
*) data_ptr
;
1175 const char *outname
;
1178 bfd_size_type align
;
1180 bfd_size_type secsecsize
;
1182 f
= bfd_get_section_flags (inbfd
, insec
);
1184 outname
= NLM_CODE_NAME
;
1185 else if ((f
& SEC_LOAD
) && (f
& SEC_HAS_CONTENTS
))
1186 outname
= NLM_INITIALIZED_DATA_NAME
;
1187 else if (f
& SEC_ALLOC
)
1188 outname
= NLM_UNINITIALIZED_DATA_NAME
;
1190 outname
= bfd_section_name (inbfd
, insec
);
1192 outsec
= bfd_get_section_by_name (outbfd
, outname
);
1195 outsec
= bfd_make_section (outbfd
, outname
);
1197 bfd_fatal ("make section");
1200 insec
->output_section
= outsec
;
1202 offset
= bfd_section_size (outbfd
, outsec
);
1203 align
= 1 << bfd_section_alignment (inbfd
, insec
);
1204 add
= ((offset
+ align
- 1) &~ (align
- 1)) - offset
;
1205 insec
->output_offset
= offset
+ add
;
1207 if (! bfd_set_section_size (outbfd
, outsec
,
1208 (bfd_section_size (outbfd
, outsec
)
1209 + bfd_section_size (inbfd
, insec
)
1211 bfd_fatal ("set section size");
1213 if ((bfd_section_alignment (inbfd
, insec
)
1214 > bfd_section_alignment (outbfd
, outsec
))
1215 && ! bfd_set_section_alignment (outbfd
, outsec
,
1216 bfd_section_alignment (inbfd
, insec
)))
1217 bfd_fatal ("set section alignment");
1219 if (! bfd_set_section_flags (outbfd
, outsec
,
1220 f
| bfd_get_section_flags (outbfd
, outsec
)))
1221 bfd_fatal ("set section flags");
1223 bfd_set_reloc (outbfd
, outsec
, (arelent
**) NULL
, 0);
1225 /* For each input section we allocate space for an entry in
1227 secsecsize
= bfd_section_size (outbfd
, secsec
);
1228 secsecsize
+= strlen (bfd_section_name (inbfd
, insec
)) + 1;
1229 secsecsize
= (secsecsize
+ 3) &~ 3;
1231 if (! bfd_set_section_size (outbfd
, secsec
, secsecsize
))
1232 bfd_fatal ("set .nlmsections size");
1235 /* Copy the section contents. */
1238 copy_sections (inbfd
, insec
, data_ptr
)
1243 static bfd_size_type secsecoff
= 0;
1244 bfd
*outbfd
= (bfd
*) data_ptr
;
1253 inname
= bfd_section_name (inbfd
, insec
);
1255 outsec
= insec
->output_section
;
1256 assert (outsec
!= NULL
);
1258 size
= bfd_get_section_size_before_reloc (insec
);
1260 /* FIXME: Why are these necessary? */
1261 insec
->_cooked_size
= insec
->_raw_size
;
1262 insec
->reloc_done
= true;
1264 if ((bfd_get_section_flags (inbfd
, insec
) & SEC_HAS_CONTENTS
) == 0)
1268 contents
= xmalloc (size
);
1269 if (! bfd_get_section_contents (inbfd
, insec
, contents
,
1270 (file_ptr
) 0, size
))
1271 bfd_fatal (bfd_get_filename (inbfd
));
1274 reloc_size
= bfd_get_reloc_upper_bound (inbfd
, insec
);
1276 bfd_fatal (bfd_get_filename (inbfd
));
1277 if (reloc_size
!= 0)
1282 relocs
= (arelent
**) xmalloc (reloc_size
);
1283 reloc_count
= bfd_canonicalize_reloc (inbfd
, insec
, relocs
, symbols
);
1284 if (reloc_count
< 0)
1285 bfd_fatal (bfd_get_filename (inbfd
));
1286 mangle_relocs (outbfd
, insec
, &relocs
, &reloc_count
, (char *) contents
,
1289 /* FIXME: refers to internal BFD fields. */
1290 if (outsec
->orelocation
!= (arelent
**) NULL
)
1292 bfd_size_type total_count
;
1295 total_count
= reloc_count
+ outsec
->reloc_count
;
1296 combined
= (arelent
**) xmalloc (total_count
* sizeof (arelent
*));
1297 memcpy (combined
, outsec
->orelocation
,
1298 outsec
->reloc_count
* sizeof (arelent
*));
1299 memcpy (combined
+ outsec
->reloc_count
, relocs
,
1300 (size_t) (reloc_count
* sizeof (arelent
*)));
1301 free (outsec
->orelocation
);
1302 reloc_count
= total_count
;
1306 bfd_set_reloc (outbfd
, outsec
, relocs
, reloc_count
);
1309 if (contents
!= NULL
)
1311 if (! bfd_set_section_contents (outbfd
, outsec
, contents
,
1312 insec
->output_offset
, size
))
1313 bfd_fatal (bfd_get_filename (outbfd
));
1317 /* Add this section to .nlmsections. */
1318 if (! bfd_set_section_contents (outbfd
, secsec
, (PTR
) inname
, secsecoff
,
1319 strlen (inname
) + 1))
1320 bfd_fatal ("set .nlmsection contents");
1321 secsecoff
+= strlen (inname
) + 1;
1323 add
= ((secsecoff
+ 3) &~ 3) - secsecoff
;
1326 bfd_h_put_32 (outbfd
, (bfd_vma
) 0, buf
);
1327 if (! bfd_set_section_contents (outbfd
, secsec
, buf
, secsecoff
, add
))
1328 bfd_fatal ("set .nlmsection contents");
1332 if (contents
!= NULL
)
1333 bfd_h_put_32 (outbfd
, (bfd_vma
) outsec
->filepos
, buf
);
1335 bfd_h_put_32 (outbfd
, (bfd_vma
) 0, buf
);
1336 if (! bfd_set_section_contents (outbfd
, secsec
, buf
, secsecoff
, 4))
1337 bfd_fatal ("set .nlmsection contents");
1340 bfd_h_put_32 (outbfd
, (bfd_vma
) size
, buf
);
1341 if (! bfd_set_section_contents (outbfd
, secsec
, buf
, secsecoff
, 4))
1342 bfd_fatal ("set .nlmsection contents");
1346 /* Some, perhaps all, NetWare targets require changing the relocs used
1347 by the input formats. */
1350 mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1354 arelent
***relocs_ptr
;
1355 long *reloc_count_ptr
;
1357 bfd_size_type contents_size
;
1359 switch (bfd_get_arch (outbfd
))
1363 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1364 contents
, contents_size
);
1367 #ifdef NLMCONV_ALPHA
1368 case bfd_arch_alpha
:
1369 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1370 contents
, contents_size
);
1373 #ifdef NLMCONV_POWERPC
1374 case bfd_arch_powerpc
:
1375 powerpc_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1376 contents
, contents_size
);
1380 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1381 contents
, contents_size
);
1386 /* By default all we need to do for relocs is change the address by
1387 the output_offset. */
1391 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1395 arelent
***relocs_ptr
;
1396 long *reloc_count_ptr
;
1398 bfd_size_type contents_size
;
1400 if (insec
->output_offset
!= 0)
1403 register arelent
**relocs
;
1406 reloc_count
= *reloc_count_ptr
;
1407 relocs
= *relocs_ptr
;
1408 for (i
= 0; i
< reloc_count
; i
++, relocs
++)
1409 (*relocs
)->address
+= insec
->output_offset
;
1415 /* NetWare on the i386 supports a restricted set of relocs, which are
1416 different from those used on other i386 targets. This routine
1417 converts the relocs. It is, obviously, very target dependent. At
1418 the moment, the nlm32-i386 backend performs similar translations;
1419 however, it is more reliable and efficient to do them here. */
1421 static reloc_howto_type nlm_i386_pcrel_howto
=
1422 HOWTO (1, /* type */
1424 2, /* size (0 = byte, 1 = short, 2 = long) */
1426 true, /* pc_relative */
1428 complain_overflow_signed
, /* complain_on_overflow */
1429 0, /* special_function */
1430 "DISP32", /* name */
1431 true, /* partial_inplace */
1432 0xffffffff, /* src_mask */
1433 0xffffffff, /* dst_mask */
1434 true); /* pcrel_offset */
1437 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1441 arelent
***relocs_ptr
;
1442 long *reloc_count_ptr
;
1444 bfd_size_type contents_size
;
1446 long reloc_count
, i
;
1449 reloc_count
= *reloc_count_ptr
;
1450 relocs
= *relocs_ptr
;
1451 for (i
= 0; i
< reloc_count
; i
++)
1455 bfd_size_type address
;
1459 sym
= *rel
->sym_ptr_ptr
;
1461 /* We're moving the relocs from the input section to the output
1462 section, so we must adjust the address accordingly. */
1463 address
= rel
->address
;
1464 rel
->address
+= insec
->output_offset
;
1466 /* Note that no serious harm will ensue if we fail to change a
1467 reloc. The backend will fail when writing out the reloc. */
1469 /* Make sure this reloc is within the data we have. We use only
1470 4 byte relocs here, so we insist on having 4 bytes. */
1471 if (address
+ 4 > contents_size
)
1474 /* A PC relative reloc entirely within a single section is
1475 completely unnecessary. This can be generated by ld -r. */
1476 if (sym
== insec
->symbol
1477 && rel
->howto
!= NULL
1478 && rel
->howto
->pc_relative
1479 && ! rel
->howto
->pcrel_offset
)
1483 memmove (relocs
, relocs
+ 1,
1484 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1488 /* Get the amount the relocation will add in. */
1489 addend
= rel
->addend
+ sym
->value
;
1491 /* NetWare doesn't support PC relative relocs against defined
1492 symbols, so we have to eliminate them by doing the relocation
1493 now. We can only do this if the reloc is within a single
1495 if (rel
->howto
!= NULL
1496 && rel
->howto
->pc_relative
1497 && bfd_get_section (sym
) == insec
->output_section
)
1501 if (rel
->howto
->pcrel_offset
)
1504 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1506 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1510 memmove (relocs
, relocs
+ 1,
1511 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1515 /* NetWare doesn't support reloc addends, so we get rid of them
1516 here by simply adding them into the object data. We handle
1517 the symbol value, if any, the same way. */
1519 && rel
->howto
!= NULL
1520 && rel
->howto
->rightshift
== 0
1521 && rel
->howto
->size
== 2
1522 && rel
->howto
->bitsize
== 32
1523 && rel
->howto
->bitpos
== 0
1524 && rel
->howto
->src_mask
== 0xffffffff
1525 && rel
->howto
->dst_mask
== 0xffffffff)
1529 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1531 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1533 /* Adjust the reloc for the changes we just made. */
1535 if (! bfd_is_und_section (bfd_get_section (sym
)))
1536 rel
->sym_ptr_ptr
= bfd_get_section (sym
)->symbol_ptr_ptr
;
1539 /* NetWare uses a reloc with pcrel_offset set. We adjust
1540 pc_relative relocs accordingly. We are going to change the
1541 howto field, so we can only do this if the current one is
1542 compatible. We should check that special_function is NULL
1543 here, but at the moment coff-i386 uses a special_function
1544 which does not affect what we are doing here. */
1545 if (rel
->howto
!= NULL
1546 && rel
->howto
->pc_relative
1547 && ! rel
->howto
->pcrel_offset
1548 && rel
->howto
->rightshift
== 0
1549 && rel
->howto
->size
== 2
1550 && rel
->howto
->bitsize
== 32
1551 && rel
->howto
->bitpos
== 0
1552 && rel
->howto
->src_mask
== 0xffffffff
1553 && rel
->howto
->dst_mask
== 0xffffffff)
1557 /* When pcrel_offset is not set, it means that the negative
1558 of the address of the memory location is stored in the
1559 memory location. We must add it back in. */
1560 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1562 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1564 /* We must change to a new howto. */
1565 rel
->howto
= &nlm_i386_pcrel_howto
;
1570 #endif /* NLMCONV_I386 */
1572 #ifdef NLMCONV_ALPHA
1574 /* On the Alpha the first reloc for every section must be a special
1575 relocs which hold the GP address. Also, the first reloc in the
1576 file must be a special reloc which holds the address of the .lita
1579 static reloc_howto_type nlm32_alpha_nw_howto
=
1580 HOWTO (ALPHA_R_NW_RELOC
, /* type */
1582 0, /* size (0 = byte, 1 = short, 2 = long) */
1584 false, /* pc_relative */
1586 complain_overflow_dont
, /* complain_on_overflow */
1587 0, /* special_function */
1588 "NW_RELOC", /* name */
1589 false, /* partial_inplace */
1592 false); /* pcrel_offset */
1596 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1600 register arelent
***relocs_ptr
;
1601 long *reloc_count_ptr
;
1603 bfd_size_type contents_size
;
1605 long old_reloc_count
;
1606 arelent
**old_relocs
;
1607 register arelent
**relocs
;
1609 old_reloc_count
= *reloc_count_ptr
;
1610 old_relocs
= *relocs_ptr
;
1611 relocs
= (arelent
**) xmalloc ((old_reloc_count
+ 3) * sizeof (arelent
*));
1612 *relocs_ptr
= relocs
;
1614 if (nlm_alpha_backend_data (outbfd
)->lita_address
== 0)
1617 asection
*lita_section
;
1619 inbfd
= insec
->owner
;
1620 lita_section
= bfd_get_section_by_name (inbfd
, _LITA
);
1621 if (lita_section
!= (asection
*) NULL
)
1623 nlm_alpha_backend_data (outbfd
)->lita_address
=
1624 bfd_get_section_vma (inbfd
, lita_section
);
1625 nlm_alpha_backend_data (outbfd
)->lita_size
=
1626 bfd_section_size (inbfd
, lita_section
);
1630 /* Avoid outputting this reloc again. */
1631 nlm_alpha_backend_data (outbfd
)->lita_address
= 4;
1634 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1635 (*relocs
)->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
1636 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->lita_address
;
1637 (*relocs
)->addend
= nlm_alpha_backend_data (outbfd
)->lita_size
+ 1;
1638 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1640 ++(*reloc_count_ptr
);
1643 /* Get the GP value from bfd. */
1644 if (nlm_alpha_backend_data (outbfd
)->gp
== 0)
1645 nlm_alpha_backend_data (outbfd
)->gp
=
1646 bfd_ecoff_get_gp_value (insec
->owner
);
1648 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1649 (*relocs
)->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
1650 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->gp
;
1651 (*relocs
)->addend
= 0;
1652 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1654 ++(*reloc_count_ptr
);
1656 memcpy ((PTR
) relocs
, (PTR
) old_relocs
,
1657 (size_t) old_reloc_count
* sizeof (arelent
*));
1658 relocs
[old_reloc_count
] = (arelent
*) NULL
;
1662 if (insec
->output_offset
!= 0)
1664 register bfd_size_type i
;
1666 for (i
= 0; i
< old_reloc_count
; i
++, relocs
++)
1667 (*relocs
)->address
+= insec
->output_offset
;
1671 #endif /* NLMCONV_ALPHA */
1673 #ifdef NLMCONV_POWERPC
1675 /* We keep a linked list of stubs which we must build. Because BFD
1676 requires us to know the sizes of all sections before we can set the
1677 contents of any, we must figure out which stubs we want to build
1678 before we can actually build any of them. */
1682 /* Next stub in linked list. */
1683 struct powerpc_stub
*next
;
1685 /* Symbol whose value is the start of the stub. This is a symbol
1686 whose name begins with `.'. */
1689 /* Symbol we are going to create a reloc against. This is a symbol
1690 with the same name as START but without the leading `.'. */
1693 /* The TOC index for this stub. This is the index into the TOC
1694 section at which the reloc is created. */
1695 unsigned int toc_index
;
1698 /* The linked list of stubs. */
1700 static struct powerpc_stub
*powerpc_stubs
;
1702 /* This is what a stub looks like. The first instruction will get
1703 adjusted with the correct TOC index. */
1705 static unsigned long powerpc_stub_insns
[] =
1707 0x81820000, /* lwz r12,0(r2) */
1708 0x90410014, /* stw r2,20(r1) */
1709 0x800c0000, /* lwz r0,0(r12) */
1710 0x804c0004, /* lwz r2,r(r12) */
1711 0x7c0903a6, /* mtctr r0 */
1712 0x4e800420, /* bctr */
1713 0, /* Traceback table. */
1718 #define POWERPC_STUB_INSN_COUNT \
1719 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1721 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1723 /* Each stub uses a four byte TOC entry. */
1724 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1726 /* The original size of the .got section. */
1727 static bfd_size_type powerpc_initial_got_size
;
1729 /* Look for all undefined symbols beginning with `.', and prepare to
1730 build a stub for each one. */
1733 powerpc_build_stubs (inbfd
, outbfd
, symbols_ptr
, symcount_ptr
)
1736 asymbol
***symbols_ptr
;
1741 unsigned int got_base
;
1746 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1747 the section to prevent copy_sections from reading from it. */
1748 stub_sec
= bfd_make_section (inbfd
, ".stubs");
1749 if (stub_sec
== (asection
*) NULL
1750 || ! bfd_set_section_flags (inbfd
, stub_sec
,
1755 || ! bfd_set_section_alignment (inbfd
, stub_sec
, 2))
1756 bfd_fatal (".stubs");
1758 /* Get the TOC section, which is named .got. */
1759 got_sec
= bfd_get_section_by_name (inbfd
, ".got");
1760 if (got_sec
== (asection
*) NULL
)
1762 got_sec
= bfd_make_section (inbfd
, ".got");
1763 if (got_sec
== (asection
*) NULL
1764 || ! bfd_set_section_flags (inbfd
, got_sec
,
1769 | SEC_HAS_CONTENTS
))
1770 || ! bfd_set_section_alignment (inbfd
, got_sec
, 2))
1774 powerpc_initial_got_size
= bfd_section_size (inbfd
, got_sec
);
1775 got_base
= powerpc_initial_got_size
;
1776 got_base
= (got_base
+ 3) &~ 3;
1780 symcount
= *symcount_ptr
;
1781 for (i
= 0; i
< symcount
; i
++)
1786 struct powerpc_stub
*item
;
1788 sym
= (*symbols_ptr
)[i
];
1790 /* We must make a stub for every undefined symbol whose name
1792 if (bfd_asymbol_name (sym
)[0] != '.'
1793 || ! bfd_is_und_section (bfd_get_section (sym
)))
1796 /* Make a new undefined symbol with the same name but without
1798 newsym
= (asymbol
*) xmalloc (sizeof (asymbol
));
1800 newname
= (char *) xmalloc (strlen (bfd_asymbol_name (sym
)));
1801 strcpy (newname
, bfd_asymbol_name (sym
) + 1);
1802 newsym
->name
= newname
;
1804 /* Define the `.' symbol to be in the stub section. */
1805 sym
->section
= stub_sec
;
1806 sym
->value
= stubcount
* POWERPC_STUB_SIZE
;
1807 /* We set the BSF_DYNAMIC flag here so that we can check it when
1808 we are mangling relocs. FIXME: This is a hack. */
1809 sym
->flags
= BSF_LOCAL
| BSF_DYNAMIC
;
1811 /* Add this stub to the linked list. */
1812 item
= (struct powerpc_stub
*) xmalloc (sizeof (struct powerpc_stub
));
1814 item
->reloc
= newsym
;
1815 item
->toc_index
= got_base
+ stubcount
* POWERPC_STUB_TOC_ENTRY_SIZE
;
1817 item
->next
= powerpc_stubs
;
1818 powerpc_stubs
= item
;
1826 struct powerpc_stub
*l
;
1828 /* Add the new symbols we just created to the symbol table. */
1829 *symbols_ptr
= (asymbol
**) xrealloc ((char *) *symbols_ptr
,
1830 ((symcount
+ stubcount
)
1831 * sizeof (asymbol
)));
1832 *symcount_ptr
+= stubcount
;
1833 s
= &(*symbols_ptr
)[symcount
];
1834 for (l
= powerpc_stubs
; l
!= (struct powerpc_stub
*) NULL
; l
= l
->next
)
1837 /* Set the size of the .stubs section and increase the size of
1838 the .got section. */
1839 if (! bfd_set_section_size (inbfd
, stub_sec
,
1840 stubcount
* POWERPC_STUB_SIZE
)
1841 || ! bfd_set_section_size (inbfd
, got_sec
,
1844 * POWERPC_STUB_TOC_ENTRY_SIZE
))))
1845 bfd_fatal ("stub section sizes");
1849 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1850 of the output section, and create new relocs in the TOC. */
1853 powerpc_resolve_stubs (inbfd
, outbfd
)
1857 bfd_byte buf
[POWERPC_STUB_SIZE
];
1859 unsigned int stubcount
;
1863 struct powerpc_stub
*l
;
1865 if (powerpc_stubs
== (struct powerpc_stub
*) NULL
)
1868 for (i
= 0; i
< POWERPC_STUB_INSN_COUNT
; i
++)
1869 bfd_put_32 (outbfd
, (bfd_vma
) powerpc_stub_insns
[i
], buf
+ i
* 4);
1871 got_sec
= bfd_get_section_by_name (inbfd
, ".got");
1872 assert (got_sec
!= (asection
*) NULL
);
1873 assert (got_sec
->output_section
->orelocation
== (arelent
**) NULL
);
1876 for (l
= powerpc_stubs
; l
!= (struct powerpc_stub
*) NULL
; l
= l
->next
)
1878 relocs
= (arelent
**) xmalloc (stubcount
* sizeof (arelent
*));
1881 for (l
= powerpc_stubs
; l
!= (struct powerpc_stub
*) NULL
; l
= l
->next
)
1885 /* Adjust the first instruction to use the right TOC index. */
1886 bfd_put_32 (outbfd
, (bfd_vma
) powerpc_stub_insns
[0] + l
->toc_index
, buf
);
1888 /* Write this stub out. */
1889 if (! bfd_set_section_contents (outbfd
,
1890 bfd_get_section (l
->start
),
1894 bfd_fatal ("writing stub");
1896 /* Create a new reloc for the TOC entry. */
1897 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1898 reloc
->sym_ptr_ptr
= &l
->reloc
;
1899 reloc
->address
= l
->toc_index
+ got_sec
->output_offset
;
1901 reloc
->howto
= bfd_reloc_type_lookup (inbfd
, BFD_RELOC_32
);
1906 bfd_set_reloc (outbfd
, got_sec
->output_section
, relocs
, stubcount
);
1909 /* Adjust relocation entries for PowerPC NetWare. We do not output
1910 TOC relocations. The object code already contains the offset from
1911 the TOC pointer. When the function is called, the TOC register,
1912 r2, will be set to the correct TOC value, so there is no need for
1913 any further reloc. */
1917 powerpc_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1921 register arelent
***relocs_ptr
;
1922 long *reloc_count_ptr
;
1924 bfd_size_type contents_size
;
1926 reloc_howto_type
*toc_howto
;
1928 register arelent
**relocs
;
1931 toc_howto
= bfd_reloc_type_lookup (insec
->owner
, BFD_RELOC_PPC_TOC16
);
1932 if (toc_howto
== (reloc_howto_type
*) NULL
)
1935 /* If this is the .got section, clear out all the contents beyond
1936 the initial size. We must do this here because copy_sections is
1937 going to write out whatever we return in the contents field. */
1938 if (strcmp (bfd_get_section_name (insec
->owner
, insec
), ".got") == 0)
1939 memset (contents
+ powerpc_initial_got_size
, 0,
1940 (size_t) (bfd_get_section_size_after_reloc (insec
)
1941 - powerpc_initial_got_size
));
1943 reloc_count
= *reloc_count_ptr
;
1944 relocs
= *relocs_ptr
;
1945 for (i
= 0; i
< reloc_count
; i
++)
1952 sym
= *rel
->sym_ptr_ptr
;
1954 /* Convert any relocs against the .bss section into relocs
1955 against the .data section. */
1956 if (strcmp (bfd_get_section_name (outbfd
, bfd_get_section (sym
)),
1957 NLM_UNINITIALIZED_DATA_NAME
) == 0)
1961 datasec
= bfd_get_section_by_name (outbfd
,
1962 NLM_INITIALIZED_DATA_NAME
);
1963 if (datasec
!= NULL
)
1965 rel
->addend
+= (bfd_get_section_vma (outbfd
,
1966 bfd_get_section (sym
))
1968 rel
->sym_ptr_ptr
= datasec
->symbol_ptr_ptr
;
1969 sym
= *rel
->sym_ptr_ptr
;
1973 /* We must be able to resolve all PC relative relocs at this
1974 point. If we get a branch to an undefined symbol we build a
1975 stub, since NetWare will resolve undefined symbols into a
1976 pointer to a function descriptor. */
1977 if (rel
->howto
->pc_relative
)
1979 /* This check for whether a symbol is in the same section as
1980 the reloc will be wrong if there is a PC relative reloc
1981 between two sections both of which were placed in the
1982 same output section. This should not happen. */
1983 if (bfd_get_section (sym
) != insec
->output_section
)
1984 fprintf (stderr
, "%s: unresolved PC relative reloc against %s\n",
1985 program_name
, bfd_asymbol_name (sym
));
1990 assert (rel
->howto
->size
== 2 && rel
->howto
->pcrel_offset
);
1991 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ rel
->address
);
1992 val
= ((val
&~ rel
->howto
->dst_mask
)
1993 | (((val
& rel
->howto
->src_mask
)
1994 + (sym
->value
- rel
->address
)
1996 & rel
->howto
->dst_mask
));
1997 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ rel
->address
);
1999 /* If this reloc is against an stubbed symbol and the
2002 then we replace the next instruction with
2004 This reloads the TOC pointer after a stub call. */
2005 if (bfd_asymbol_name (sym
)[0] == '.'
2006 && (sym
->flags
& BSF_DYNAMIC
) != 0
2007 && (bfd_get_32 (outbfd
,
2008 (bfd_byte
*) contents
+ rel
->address
+ 4)
2009 == 0x4ffffb82)) /* cror 31,31,31 */
2010 bfd_put_32 (outbfd
, (bfd_vma
) 0x80410014, /* lwz r2,20(r1) */
2011 (bfd_byte
*) contents
+ rel
->address
+ 4);
2015 memmove (relocs
, relocs
+ 1,
2016 (size_t) ((reloc_count
- 1) * sizeof (arelent
*)));
2021 /* When considering a TOC reloc, we do not want to include the
2022 symbol value. The symbol will be start of the TOC section
2023 (which is named .got). We do want to include the addend. */
2024 if (rel
->howto
== toc_howto
)
2027 sym_value
= sym
->value
;
2029 /* If this is a relocation against a symbol with a value, or
2030 there is a reloc addend, we need to update the addend in the
2032 if (sym_value
+ rel
->addend
!= 0)
2036 switch (rel
->howto
->size
)
2039 val
= bfd_get_16 (outbfd
,
2040 (bfd_byte
*) contents
+ rel
->address
);
2041 val
= ((val
&~ rel
->howto
->dst_mask
)
2042 | (((val
& rel
->howto
->src_mask
)
2045 & rel
->howto
->dst_mask
));
2046 if ((bfd_signed_vma
) val
< - 0x8000
2047 || (bfd_signed_vma
) val
>= 0x8000)
2049 "%s: overflow when adjusting relocation against %s\n",
2050 program_name
, bfd_asymbol_name (sym
));
2051 bfd_put_16 (outbfd
, val
, (bfd_byte
*) contents
+ rel
->address
);
2055 val
= bfd_get_32 (outbfd
,
2056 (bfd_byte
*) contents
+ rel
->address
);
2057 val
= ((val
&~ rel
->howto
->dst_mask
)
2058 | (((val
& rel
->howto
->src_mask
)
2061 & rel
->howto
->dst_mask
));
2062 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ rel
->address
);
2069 if (! bfd_is_und_section (bfd_get_section (sym
)))
2070 rel
->sym_ptr_ptr
= bfd_get_section (sym
)->symbol_ptr_ptr
;
2074 /* Now that we have incorporated the addend, remove any TOC
2076 if (rel
->howto
== toc_howto
)
2080 memmove (relocs
, relocs
+ 1,
2081 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
2085 rel
->address
+= insec
->output_offset
;
2089 #endif /* NLMCONV_POWERPC */
2091 /* Name of linker. */
2093 #define LD_NAME "ld"
2096 /* Temporary file name base. */
2097 static char *temp_filename
;
2099 /* The user has specified several input files. Invoke the linker to
2100 link them all together, and convert and delete the resulting output
2104 link_inputs (inputs
, ld
)
2105 struct string_list
*inputs
;
2109 struct string_list
*q
;
2118 for (q
= inputs
; q
!= NULL
; q
= q
->next
)
2121 argv
= (char **) alloca ((c
+ 5) * sizeof(char *));
2128 /* Find the linker to invoke based on how nlmconv was run. */
2129 p
= program_name
+ strlen (program_name
);
2130 while (p
!= program_name
)
2134 ld
= (char *) xmalloc (p
- program_name
+ strlen (LD_NAME
) + 1);
2135 memcpy (ld
, program_name
, p
- program_name
);
2136 strcpy (ld
+ (p
- program_name
), LD_NAME
);
2145 ld
= (char *) LD_NAME
;
2147 temp_filename
= choose_temp_base ();
2149 unlink_on_exit
= xmalloc (strlen (temp_filename
) + 3);
2150 sprintf (unlink_on_exit
, "%s.O", temp_filename
);
2153 argv
[1] = (char *) "-Ur";
2154 argv
[2] = (char *) "-o";
2155 argv
[3] = unlink_on_exit
;
2157 for (q
= inputs
; q
!= NULL
; q
= q
->next
, i
++)
2158 argv
[i
] = q
->string
;
2163 for (i
= 0; argv
[i
] != NULL
; i
++)
2164 fprintf (stderr
, " %s", argv
[i
]);
2165 fprintf (stderr
, "\n");
2168 pid
= pexecute (ld
, argv
, program_name
, (char *) NULL
, &errfmt
, &errarg
,
2169 PEXECUTE_SEARCH
| PEXECUTE_ONE
);
2172 fprintf (stderr
, "%s: execution of %s failed: ", program_name
, ld
);
2173 fprintf (stderr
, errfmt
, errarg
);
2174 unlink (unlink_on_exit
);
2178 if (pwait (pid
, &status
, 0) < 0)
2181 unlink (unlink_on_exit
);
2187 fprintf (stderr
, "%s: Execution of %s failed\n", program_name
, ld
);
2188 unlink (unlink_on_exit
);
2192 return unlink_on_exit
;