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>
39 #include "libiberty.h"
42 /* Internal BFD NLM header. */
46 /* Needed for Alpha support. */
48 #include "coff/ecoff.h"
50 /* If strerror is just a macro, we want to use the one from libiberty
51 since it will handle undefined values. */
53 extern char *strerror ();
56 extern struct tm
*localtime ();
60 extern char *getenv ();
73 /* Global variables. */
75 /* The name used to invoke the program. */
78 /* The version number. */
79 extern char *program_version
;
81 /* Local variables. */
83 /* Whether to print out debugging information (currently just controls
84 whether it prints the linker command if there is one). */
87 /* The symbol table. */
88 static asymbol
**symbols
;
90 /* A section we create in the output file to hold pointers to where
91 the sections of the input file end up. We will put a pointer to
92 this section in the NLM header. These is an entry for each input
93 section. The format is
94 null terminated section name
95 zeroes to adjust to 4 byte boundary
96 4 byte section data file pointer
98 We don't need a version number. The way we find this information
99 is by finding a stamp in the NLM header information. If we need to
100 change the format of this information, we can simply change the
102 static asection
*secsec
;
104 /* A temporary file name to be unlinked on exit. Actually, for most
105 errors, we leave it around. It's not clear whether that is helpful
107 static char *unlink_on_exit
;
109 /* The list of long options. */
110 static struct option long_options
[] =
112 { "debug", no_argument
, 0, 'd' },
113 { "header-file", required_argument
, 0, 'T' },
114 { "help", no_argument
, 0, 'h' },
115 { "input-target", required_argument
, 0, 'I' },
116 { "input-format", required_argument
, 0, 'I' }, /* Obsolete */
117 { "linker", required_argument
, 0, 'l' },
118 { "output-target", required_argument
, 0, 'O' },
119 { "output-format", required_argument
, 0, 'O' }, /* Obsolete */
120 { "version", no_argument
, 0, 'V' },
121 { NULL
, no_argument
, 0, 0 }
124 /* Local routines. */
126 static void show_help
PARAMS ((void));
127 static void show_usage
PARAMS ((FILE *, int));
128 static const char *select_output_format
PARAMS ((enum bfd_architecture
,
129 unsigned long, boolean
));
130 static void setup_sections
PARAMS ((bfd
*, asection
*, PTR
));
131 static void copy_sections
PARAMS ((bfd
*, asection
*, PTR
));
132 static void mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
135 static void i386_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
138 static void alpha_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
141 /* start-sanitize-powerpc-netware */
142 static void powerpc_build_stubs
PARAMS ((bfd
*, bfd
*, asymbol
***, long *));
143 static void powerpc_resolve_stubs
PARAMS ((bfd
*, bfd
*));
144 static void powerpc_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
147 /* end-sanitize-powerpc-netware */
148 static void default_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
151 static char *link_inputs
PARAMS ((struct string_list
*, char *));
152 static const char *choose_temp_base_try
PARAMS ((const char *,
154 static void choose_temp_base
PARAMS ((void));
155 static int pexecute
PARAMS ((char *, char *[]));
157 /* The main routine. */
165 char *input_file
= NULL
;
166 const char *input_format
= NULL
;
167 const char *output_format
= NULL
;
168 const char *header_file
= NULL
;
170 Nlm_Internal_Fixed_Header fixed_hdr_struct
;
171 Nlm_Internal_Variable_Header var_hdr_struct
;
172 Nlm_Internal_Version_Header version_hdr_struct
;
173 Nlm_Internal_Copyright_Header copyright_hdr_struct
;
174 Nlm_Internal_Extended_Header extended_hdr_struct
;
177 asymbol
**newsyms
, **outsyms
;
178 long symcount
, newsymalloc
, newsymcount
;
180 asection
*text_sec
, *bss_sec
, *data_sec
;
185 char inlead
, outlead
;
186 boolean gotstart
, gotexit
, gotcheck
;
188 FILE *custom_data
, *help_data
, *message_data
, *rpc_data
, *shared_data
;
189 size_t custom_size
, help_size
, message_size
, module_size
, rpc_size
;
190 asection
*custom_section
, *help_section
, *message_section
, *module_section
;
191 asection
*rpc_section
, *shared_section
;
193 size_t shared_offset
, shared_size
;
194 Nlm_Internal_Fixed_Header sharedhdr
;
199 program_name
= argv
[0];
200 xmalloc_set_program_name (program_name
);
204 while ((opt
= getopt_long (argc
, argv
, "dhI:l:O:T:V", long_options
,
217 input_format
= optarg
;
223 output_format
= optarg
;
226 header_file
= optarg
;
229 printf ("GNU %s version %s\n", program_name
, program_version
);
235 show_usage (stderr
, 1);
240 /* The input and output files may be named on the command line. */
244 input_file
= argv
[optind
];
248 output_file
= argv
[optind
];
251 show_usage (stderr
, 1);
252 if (strcmp (input_file
, output_file
) == 0)
255 "%s: input and output files must be different\n",
262 /* Initialize the header information to default values. */
263 fixed_hdr
= &fixed_hdr_struct
;
264 memset ((PTR
) &fixed_hdr_struct
, 0, sizeof fixed_hdr_struct
);
265 var_hdr
= &var_hdr_struct
;
266 memset ((PTR
) &var_hdr_struct
, 0, sizeof var_hdr_struct
);
267 version_hdr
= &version_hdr_struct
;
268 memset ((PTR
) &version_hdr_struct
, 0, sizeof version_hdr_struct
);
269 copyright_hdr
= ©right_hdr_struct
;
270 memset ((PTR
) ©right_hdr_struct
, 0, sizeof copyright_hdr_struct
);
271 extended_hdr
= &extended_hdr_struct
;
272 memset ((PTR
) &extended_hdr_struct
, 0, sizeof extended_hdr_struct
);
273 check_procedure
= NULL
;
276 exit_procedure
= "_Stop";
277 export_symbols
= NULL
;
281 import_symbols
= NULL
;
284 sharelib_file
= NULL
;
285 start_procedure
= "_Prelude";
291 /* Parse the header file (if there is one). */
292 if (header_file
!= NULL
)
294 if (! nlmlex_file (header_file
)
296 || parse_errors
!= 0)
300 if (input_files
!= NULL
)
302 if (input_file
!= NULL
)
305 "%s: input file named both on command line and with INPUT\n",
309 if (input_files
->next
== NULL
)
310 input_file
= input_files
->string
;
312 input_file
= link_inputs (input_files
, ld_arg
);
314 else if (input_file
== NULL
)
316 fprintf (stderr
, "%s: no input file\n", program_name
);
317 show_usage (stderr
, 1);
320 inbfd
= bfd_openr (input_file
, input_format
);
322 bfd_fatal (input_file
);
324 if (! bfd_check_format_matches (inbfd
, bfd_object
, &matching
))
326 bfd_nonfatal (input_file
);
327 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
329 list_matching_formats (matching
);
335 if (output_format
== NULL
)
336 output_format
= select_output_format (bfd_get_arch (inbfd
),
337 bfd_get_mach (inbfd
),
338 inbfd
->xvec
->byteorder_big_p
);
340 assert (output_format
!= NULL
);
342 /* Use the output file named on the command line if it exists.
343 Otherwise use the file named in the OUTPUT statement. */
344 if (output_file
== NULL
)
346 fprintf (stderr
, "%s: no name for output file\n",
348 show_usage (stderr
, 1);
351 outbfd
= bfd_openw (output_file
, output_format
);
353 bfd_fatal (output_file
);
354 if (! bfd_set_format (outbfd
, bfd_object
))
355 bfd_fatal (output_file
);
357 assert (bfd_get_flavour (outbfd
) == bfd_target_nlm_flavour
);
359 if (bfd_arch_get_compatible (inbfd
, outbfd
) == NULL
)
361 "%s: warning:input and output formats are not compatible\n",
364 /* Move the values read from the command file into outbfd. */
365 *nlm_fixed_header (outbfd
) = fixed_hdr_struct
;
366 *nlm_variable_header (outbfd
) = var_hdr_struct
;
367 *nlm_version_header (outbfd
) = version_hdr_struct
;
368 *nlm_copyright_header (outbfd
) = copyright_hdr_struct
;
369 *nlm_extended_header (outbfd
) = extended_hdr_struct
;
371 /* Start copying the input BFD to the output BFD. */
372 if (! bfd_set_file_flags (outbfd
, bfd_get_file_flags (inbfd
)))
373 bfd_fatal (bfd_get_filename (outbfd
));
375 symsize
= bfd_get_symtab_upper_bound (inbfd
);
377 bfd_fatal (input_file
);
378 symbols
= (asymbol
**) xmalloc (symsize
);
379 symcount
= bfd_canonicalize_symtab (inbfd
, symbols
);
381 bfd_fatal (input_file
);
383 /* Make sure we have a .bss section. */
384 bss_sec
= bfd_get_section_by_name (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
387 bss_sec
= bfd_make_section (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
389 || ! bfd_set_section_flags (outbfd
, bss_sec
, SEC_ALLOC
)
390 || ! bfd_set_section_alignment (outbfd
, bss_sec
, 1))
391 bfd_fatal ("make .bss section");
394 /* We store the original section names in the .nlmsections section,
395 so that programs which understand it can resurrect the original
396 sections from the NLM. We will put a pointer to .nlmsections in
397 the NLM header area. */
398 secsec
= bfd_make_section (outbfd
, ".nlmsections");
400 bfd_fatal ("make .nlmsections section");
401 if (! bfd_set_section_flags (outbfd
, secsec
, SEC_HAS_CONTENTS
))
402 bfd_fatal ("set .nlmsections flags");
403 /* start-sanitize-powerpc-netware */
405 /* For PowerPC NetWare we need to build stubs for calls to undefined
406 symbols. Because each stub requires an entry in the TOC section
407 which must be at the same location as other entries in the TOC
408 section, we must do this before determining where the TOC section
409 goes in setup_sections. */
410 if (bfd_get_arch (inbfd
) == bfd_arch_powerpc
)
411 powerpc_build_stubs (inbfd
, outbfd
, &symbols
, &symcount
);
412 /* end-sanitize-powerpc-netware */
414 /* Set up the sections. */
415 bfd_map_over_sections (inbfd
, setup_sections
, (PTR
) outbfd
);
417 text_sec
= bfd_get_section_by_name (outbfd
, NLM_CODE_NAME
);
419 /* The .bss section immediately follows the .data section. */
420 data_sec
= bfd_get_section_by_name (outbfd
, NLM_INITIALIZED_DATA_NAME
);
421 if (data_sec
!= NULL
)
425 vma
= bfd_get_section_size_before_reloc (data_sec
);
426 align
= 1 << bss_sec
->alignment_power
;
427 add
= ((vma
+ align
- 1) &~ (align
- 1)) - vma
;
429 if (! bfd_set_section_vma (outbfd
, bss_sec
, vma
))
430 bfd_fatal ("set .bss vma");
433 bfd_size_type data_size
;
435 data_size
= bfd_get_section_size_before_reloc (data_sec
);
436 if (! bfd_set_section_size (outbfd
, data_sec
, data_size
+ add
))
437 bfd_fatal ("set .data size");
441 /* Adjust symbol information. */
442 inlead
= bfd_get_symbol_leading_char (inbfd
);
443 outlead
= bfd_get_symbol_leading_char (outbfd
);
448 newsyms
= (asymbol
**) xmalloc (newsymalloc
* sizeof (asymbol
*));
451 for (i
= 0; i
< symcount
; i
++)
453 register asymbol
*sym
;
457 /* Add or remove a leading underscore. */
458 if (inlead
!= outlead
)
462 if (bfd_asymbol_name (sym
)[0] == inlead
)
470 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 1);
472 strcpy (new + 1, bfd_asymbol_name (sym
) + 1);
481 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 2);
483 strcpy (new + 1, bfd_asymbol_name (sym
));
488 /* NLM's have an uninitialized data section, but they do not
489 have a common section in the Unix sense. Move all common
490 symbols into the .bss section, and mark them as exported. */
491 if (bfd_is_com_section (bfd_get_section (sym
)))
495 sym
->section
= bss_sec
;
497 sym
->value
= bss_sec
->_raw_size
;
498 bss_sec
->_raw_size
+= size
;
499 align
= 1 << bss_sec
->alignment_power
;
500 bss_sec
->_raw_size
= (bss_sec
->_raw_size
+ align
- 1) &~ (align
- 1);
501 sym
->flags
|= BSF_EXPORT
| BSF_GLOBAL
;
503 else if (bfd_get_section (sym
)->output_section
!= NULL
)
505 /* Move the symbol into the output section. */
506 sym
->value
+= bfd_get_section (sym
)->output_offset
;
507 sym
->section
= bfd_get_section (sym
)->output_section
;
508 /* This is no longer a section symbol. */
509 sym
->flags
&=~ BSF_SECTION_SYM
;
512 /* Force _edata and _end to be defined. This would normally be
513 done by the linker, but the manipulation of the common
514 symbols will confuse it. */
515 if ((sym
->flags
& BSF_DEBUGGING
) == 0
516 && bfd_asymbol_name (sym
)[0] == '_'
517 && bfd_get_section (sym
) == &bfd_und_section
)
519 if (strcmp (bfd_asymbol_name (sym
), "_edata") == 0)
521 sym
->section
= bss_sec
;
524 if (strcmp (bfd_asymbol_name (sym
), "_end") == 0)
526 sym
->section
= bss_sec
;
529 /* start-sanitize-powerpc-netware */
530 /* For PowerPC NetWare, we define __GOT0. This is the start
531 of the .got section. */
532 if (bfd_get_arch (inbfd
) == bfd_arch_powerpc
533 && strcmp (bfd_asymbol_name (sym
), "__GOT0") == 0)
537 got_sec
= bfd_get_section_by_name (inbfd
, ".got");
538 assert (got_sec
!= (asection
*) NULL
);
539 sym
->value
= got_sec
->output_offset
;
540 sym
->section
= got_sec
->output_section
;
542 /* end-sanitize-powerpc-netware */
545 /* If this is a global symbol, check the export list. */
546 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) != 0)
548 register struct string_list
*l
;
551 /* Unfortunately, a symbol can appear multiple times on the
552 export list, with and without prefixes. */
554 for (l
= export_symbols
; l
!= NULL
; l
= l
->next
)
556 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
562 zbase
= strchr (l
->string
, '@');
564 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
566 /* We must add a symbol with this prefix. */
567 if (newsymcount
>= newsymalloc
)
570 newsyms
= ((asymbol
**)
571 xrealloc ((PTR
) newsyms
,
573 * sizeof (asymbol
*))));
575 newsyms
[newsymcount
] =
576 (asymbol
*) xmalloc (sizeof (asymbol
));
577 *newsyms
[newsymcount
] = *sym
;
578 newsyms
[newsymcount
]->name
= l
->string
;
585 /* The unmodified symbol is actually not exported at
587 sym
->flags
&=~ (BSF_GLOBAL
| BSF_EXPORT
);
588 sym
->flags
|= BSF_LOCAL
;
592 /* If it's an undefined symbol, see if it's on the import list.
593 Change the prefix if necessary. */
594 if (bfd_get_section (sym
) == &bfd_und_section
)
596 register struct string_list
*l
;
598 for (l
= import_symbols
; l
!= NULL
; l
= l
->next
)
600 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
606 zbase
= strchr (l
->string
, '@');
608 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
610 sym
->name
= l
->string
;
617 "%s: warning: symbol %s imported but not in import list\n",
618 program_name
, bfd_asymbol_name (sym
));
621 /* See if it's one of the special named symbols. */
622 if ((sym
->flags
& BSF_DEBUGGING
) == 0)
626 /* FIXME: If these symbols are not in the .text section, we
627 add the .text section size to the value. This may not be
628 correct for all targets. I'm not sure how this should
629 really be handled. */
630 if (strcmp (bfd_asymbol_name (sym
), start_procedure
) == 0)
632 val
= bfd_asymbol_value (sym
);
633 if (bfd_get_section (sym
) == data_sec
634 && text_sec
!= (asection
*) NULL
)
635 val
+= bfd_section_size (outbfd
, text_sec
);
636 if (! bfd_set_start_address (outbfd
, val
))
637 bfd_fatal ("set start address");
640 if (strcmp (bfd_asymbol_name (sym
), exit_procedure
) == 0)
642 val
= bfd_asymbol_value (sym
);
643 if (bfd_get_section (sym
) == data_sec
644 && text_sec
!= (asection
*) NULL
)
645 val
+= bfd_section_size (outbfd
, text_sec
);
646 nlm_fixed_header (outbfd
)->exitProcedureOffset
= val
;
649 if (check_procedure
!= NULL
650 && strcmp (bfd_asymbol_name (sym
), check_procedure
) == 0)
652 val
= bfd_asymbol_value (sym
);
653 if (bfd_get_section (sym
) == data_sec
654 && text_sec
!= (asection
*) NULL
)
655 val
+= bfd_section_size (outbfd
, text_sec
);
656 nlm_fixed_header (outbfd
)->checkUnloadProcedureOffset
= val
;
664 endsym
->value
= bfd_get_section_size_before_reloc (bss_sec
);
666 /* FIXME: If any relocs referring to _end use inplace addends,
667 then I think they need to be updated. This is handled by
668 i386_mangle_relocs. Is it needed for any other object
672 if (newsymcount
== 0)
676 outsyms
= (asymbol
**) xmalloc ((symcount
+ newsymcount
+ 1)
677 * sizeof (asymbol
*));
678 memcpy (outsyms
, symbols
, symcount
* sizeof (asymbol
*));
679 memcpy (outsyms
+ symcount
, newsyms
, newsymcount
* sizeof (asymbol
*));
680 outsyms
[symcount
+ newsymcount
] = NULL
;
683 bfd_set_symtab (outbfd
, outsyms
, symcount
+ newsymcount
);
686 fprintf (stderr
, "%s: warning: START procedure %s not defined\n",
687 program_name
, start_procedure
);
689 fprintf (stderr
, "%s: warning: EXIT procedure %s not defined\n",
690 program_name
, exit_procedure
);
691 if (check_procedure
!= NULL
693 fprintf (stderr
, "%s: warning: CHECK procedure %s not defined\n",
694 program_name
, check_procedure
);
696 /* Add additional sections required for the header information. */
697 if (custom_file
!= NULL
)
699 custom_data
= fopen (custom_file
, "r");
700 if (custom_data
== NULL
701 || fstat (fileno (custom_data
), &st
) < 0)
703 fprintf (stderr
, "%s:%s: %s\n", program_name
, custom_file
,
709 custom_size
= st
.st_size
;
710 custom_section
= bfd_make_section (outbfd
, ".nlmcustom");
711 if (custom_section
== NULL
712 || ! bfd_set_section_size (outbfd
, custom_section
, custom_size
)
713 || ! bfd_set_section_flags (outbfd
, custom_section
,
715 bfd_fatal ("custom section");
718 if (help_file
!= NULL
)
720 help_data
= fopen (help_file
, "r");
721 if (help_data
== NULL
722 || fstat (fileno (help_data
), &st
) < 0)
724 fprintf (stderr
, "%s:%s: %s\n", program_name
, help_file
,
730 help_size
= st
.st_size
;
731 help_section
= bfd_make_section (outbfd
, ".nlmhelp");
732 if (help_section
== NULL
733 || ! bfd_set_section_size (outbfd
, help_section
, help_size
)
734 || ! bfd_set_section_flags (outbfd
, help_section
,
736 bfd_fatal ("help section");
737 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
740 if (message_file
!= NULL
)
742 message_data
= fopen (message_file
, "r");
743 if (message_data
== NULL
744 || fstat (fileno (message_data
), &st
) < 0)
746 fprintf (stderr
, "%s:%s: %s\n", program_name
, message_file
,
752 message_size
= st
.st_size
;
753 message_section
= bfd_make_section (outbfd
, ".nlmmessages");
754 if (message_section
== NULL
755 || ! bfd_set_section_size (outbfd
, message_section
, message_size
)
756 || ! bfd_set_section_flags (outbfd
, message_section
,
758 bfd_fatal ("message section");
759 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
764 struct string_list
*l
;
767 for (l
= modules
; l
!= NULL
; l
= l
->next
)
768 module_size
+= strlen (l
->string
) + 1;
769 module_section
= bfd_make_section (outbfd
, ".nlmmodules");
770 if (module_section
== NULL
771 || ! bfd_set_section_size (outbfd
, module_section
, module_size
)
772 || ! bfd_set_section_flags (outbfd
, module_section
,
774 bfd_fatal ("module section");
776 if (rpc_file
!= NULL
)
778 rpc_data
= fopen (rpc_file
, "r");
780 || fstat (fileno (rpc_data
), &st
) < 0)
782 fprintf (stderr
, "%s:%s: %s\n", program_name
, rpc_file
,
788 rpc_size
= st
.st_size
;
789 rpc_section
= bfd_make_section (outbfd
, ".nlmrpc");
790 if (rpc_section
== NULL
791 || ! bfd_set_section_size (outbfd
, rpc_section
, rpc_size
)
792 || ! bfd_set_section_flags (outbfd
, rpc_section
,
794 bfd_fatal ("rpc section");
795 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
798 if (sharelib_file
!= NULL
)
800 sharedbfd
= bfd_openr (sharelib_file
, output_format
);
801 if (sharedbfd
== NULL
802 || ! bfd_check_format (sharedbfd
, bfd_object
))
804 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
805 bfd_errmsg (bfd_get_error ()));
806 sharelib_file
= NULL
;
810 sharedhdr
= *nlm_fixed_header (sharedbfd
);
811 bfd_close (sharedbfd
);
812 shared_data
= fopen (sharelib_file
, "r");
813 if (shared_data
== NULL
814 || (fstat (fileno (shared_data
), &st
) < 0))
816 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
818 sharelib_file
= NULL
;
822 /* If we were clever, we could just copy out the
823 sections of the shared library which we actually
824 need. However, we would have to figure out the sizes
825 of the external and public information, and that can
826 not be done without reading through them. */
827 if (sharedhdr
.uninitializedDataSize
> 0)
829 /* There is no place to record this information. */
831 "%s:%s: warning: shared libraries can not have uninitialized data\n",
832 program_name
, sharelib_file
);
834 shared_offset
= st
.st_size
;
835 if (shared_offset
> sharedhdr
.codeImageOffset
)
836 shared_offset
= sharedhdr
.codeImageOffset
;
837 if (shared_offset
> sharedhdr
.dataImageOffset
)
838 shared_offset
= sharedhdr
.dataImageOffset
;
839 if (shared_offset
> sharedhdr
.relocationFixupOffset
)
840 shared_offset
= sharedhdr
.relocationFixupOffset
;
841 if (shared_offset
> sharedhdr
.externalReferencesOffset
)
842 shared_offset
= sharedhdr
.externalReferencesOffset
;
843 if (shared_offset
> sharedhdr
.publicsOffset
)
844 shared_offset
= sharedhdr
.publicsOffset
;
845 shared_size
= st
.st_size
- shared_offset
;
846 shared_section
= bfd_make_section (outbfd
, ".nlmshared");
847 if (shared_section
== NULL
848 || ! bfd_set_section_size (outbfd
, shared_section
,
850 || ! bfd_set_section_flags (outbfd
, shared_section
,
852 bfd_fatal ("shared section");
853 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
858 /* Check whether a version was given. */
859 if (strncmp (version_hdr
->stamp
, "VeRsIoN#", 8) != 0)
860 fprintf (stderr
, "%s: warning: No version number given\n",
863 /* At least for now, always create an extended header, because that
864 is what NLMLINK does. */
865 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
867 strncpy (nlm_cygnus_section_header (outbfd
)->stamp
, "CyGnUsSeCs", 10);
869 /* If the date was not given, force it in. */
870 if (nlm_version_header (outbfd
)->month
== 0
871 && nlm_version_header (outbfd
)->day
== 0
872 && nlm_version_header (outbfd
)->year
== 0)
878 ptm
= localtime (&now
);
879 nlm_version_header (outbfd
)->month
= ptm
->tm_mon
+ 1;
880 nlm_version_header (outbfd
)->day
= ptm
->tm_mday
;
881 nlm_version_header (outbfd
)->year
= ptm
->tm_year
+ 1900;
882 strncpy (version_hdr
->stamp
, "VeRsIoN#", 8);
884 /* start-sanitize-powerpc-netware */
886 /* Resolve the stubs we build for PowerPC NetWare. */
887 if (bfd_get_arch (inbfd
) == bfd_arch_powerpc
)
888 powerpc_resolve_stubs (inbfd
, outbfd
);
889 /* end-sanitize-powerpc-netware */
891 /* Copy over the sections. */
892 bfd_map_over_sections (inbfd
, copy_sections
, (PTR
) outbfd
);
894 /* Finish up the header information. */
895 if (custom_file
!= NULL
)
899 data
= xmalloc (custom_size
);
900 if (fread (data
, 1, custom_size
, custom_data
) != custom_size
)
901 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, custom_file
,
905 if (! bfd_set_section_contents (outbfd
, custom_section
, data
,
906 (file_ptr
) 0, custom_size
))
907 bfd_fatal ("custom section");
908 nlm_fixed_header (outbfd
)->customDataOffset
=
909 custom_section
->filepos
;
910 nlm_fixed_header (outbfd
)->customDataSize
= custom_size
;
916 /* As a special hack, the backend recognizes a debugInfoOffset
917 of -1 to mean that it should not output any debugging
918 information. This can not be handling by fiddling with the
919 symbol table because exported symbols appear in both the
920 export information and the debugging information. */
921 nlm_fixed_header (outbfd
)->debugInfoOffset
= (file_ptr
) -1;
923 if (map_file
!= NULL
)
925 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
927 if (help_file
!= NULL
)
931 data
= xmalloc (help_size
);
932 if (fread (data
, 1, help_size
, help_data
) != help_size
)
933 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, help_file
,
937 if (! bfd_set_section_contents (outbfd
, help_section
, data
,
938 (file_ptr
) 0, help_size
))
939 bfd_fatal ("help section");
940 nlm_extended_header (outbfd
)->helpFileOffset
=
941 help_section
->filepos
;
942 nlm_extended_header (outbfd
)->helpFileLength
= help_size
;
946 if (message_file
!= NULL
)
950 data
= xmalloc (message_size
);
951 if (fread (data
, 1, message_size
, message_data
) != message_size
)
952 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, message_file
,
956 if (! bfd_set_section_contents (outbfd
, message_section
, data
,
957 (file_ptr
) 0, message_size
))
958 bfd_fatal ("message section");
959 nlm_extended_header (outbfd
)->messageFileOffset
=
960 message_section
->filepos
;
961 nlm_extended_header (outbfd
)->messageFileLength
= message_size
;
963 /* FIXME: Are these offsets correct on all platforms? Are
964 they 32 bits on all platforms? What endianness? */
965 nlm_extended_header (outbfd
)->languageID
=
966 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 106);
967 nlm_extended_header (outbfd
)->messageCount
=
968 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 110);
976 struct string_list
*l
;
979 data
= xmalloc (module_size
);
981 set
= (unsigned char *) data
;
982 for (l
= modules
; l
!= NULL
; l
= l
->next
)
984 *set
= strlen (l
->string
);
985 strncpy (set
+ 1, l
->string
, *set
);
989 if (! bfd_set_section_contents (outbfd
, module_section
, data
,
990 (file_ptr
) 0, module_size
))
991 bfd_fatal ("module section");
992 nlm_fixed_header (outbfd
)->moduleDependencyOffset
=
993 module_section
->filepos
;
994 nlm_fixed_header (outbfd
)->numberOfModuleDependencies
= c
;
996 if (rpc_file
!= NULL
)
1000 data
= xmalloc (rpc_size
);
1001 if (fread (data
, 1, rpc_size
, rpc_data
) != rpc_size
)
1002 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, rpc_file
,
1006 if (! bfd_set_section_contents (outbfd
, rpc_section
, data
,
1007 (file_ptr
) 0, rpc_size
))
1008 bfd_fatal ("rpc section");
1009 nlm_extended_header (outbfd
)->RPCDataOffset
=
1010 rpc_section
->filepos
;
1011 nlm_extended_header (outbfd
)->RPCDataLength
= rpc_size
;
1015 if (sharelib_file
!= NULL
)
1019 data
= xmalloc (shared_size
);
1020 if (fseek (shared_data
, shared_offset
, SEEK_SET
) != 0
1021 || fread (data
, 1, shared_size
, shared_data
) != shared_size
)
1022 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, sharelib_file
,
1026 if (! bfd_set_section_contents (outbfd
, shared_section
, data
,
1027 (file_ptr
) 0, shared_size
))
1028 bfd_fatal ("shared section");
1030 nlm_extended_header (outbfd
)->sharedCodeOffset
=
1031 sharedhdr
.codeImageOffset
- shared_offset
+ shared_section
->filepos
;
1032 nlm_extended_header (outbfd
)->sharedCodeLength
=
1033 sharedhdr
.codeImageSize
;
1034 nlm_extended_header (outbfd
)->sharedDataOffset
=
1035 sharedhdr
.dataImageOffset
- shared_offset
+ shared_section
->filepos
;
1036 nlm_extended_header (outbfd
)->sharedDataLength
=
1037 sharedhdr
.dataImageSize
;
1038 nlm_extended_header (outbfd
)->sharedRelocationFixupOffset
=
1039 (sharedhdr
.relocationFixupOffset
1041 + shared_section
->filepos
);
1042 nlm_extended_header (outbfd
)->sharedRelocationFixupCount
=
1043 sharedhdr
.numberOfRelocationFixups
;
1044 nlm_extended_header (outbfd
)->sharedExternalReferenceOffset
=
1045 (sharedhdr
.externalReferencesOffset
1047 + shared_section
->filepos
);
1048 nlm_extended_header (outbfd
)->sharedExternalReferenceCount
=
1049 sharedhdr
.numberOfExternalReferences
;
1050 nlm_extended_header (outbfd
)->sharedPublicsOffset
=
1051 sharedhdr
.publicsOffset
- shared_offset
+ shared_section
->filepos
;
1052 nlm_extended_header (outbfd
)->sharedPublicsCount
=
1053 sharedhdr
.numberOfPublics
;
1054 nlm_extended_header (outbfd
)->sharedDebugRecordOffset
=
1055 sharedhdr
.debugInfoOffset
- shared_offset
+ shared_section
->filepos
;
1056 nlm_extended_header (outbfd
)->sharedDebugRecordCount
=
1057 sharedhdr
.numberOfDebugRecords
;
1058 nlm_extended_header (outbfd
)->SharedInitializationOffset
=
1059 sharedhdr
.codeStartOffset
;
1060 nlm_extended_header (outbfd
)->SharedExitProcedureOffset
=
1061 sharedhdr
.exitProcedureOffset
;
1064 len
= strlen (output_file
);
1065 if (len
> NLM_MODULE_NAME_SIZE
- 2)
1066 len
= NLM_MODULE_NAME_SIZE
- 2;
1067 nlm_fixed_header (outbfd
)->moduleName
[0] = len
;
1069 strncpy (nlm_fixed_header (outbfd
)->moduleName
+ 1, output_file
,
1070 NLM_MODULE_NAME_SIZE
- 2);
1071 nlm_fixed_header (outbfd
)->moduleName
[NLM_MODULE_NAME_SIZE
- 1] = '\0';
1072 for (modname
= nlm_fixed_header (outbfd
)->moduleName
;
1075 if (islower (*modname
))
1076 *modname
= toupper (*modname
);
1078 strncpy (nlm_variable_header (outbfd
)->oldThreadName
, " LONG",
1079 NLM_OLD_THREAD_NAME_LENGTH
);
1081 nlm_cygnus_section_header (outbfd
)->offset
= secsec
->filepos
;
1082 nlm_cygnus_section_header (outbfd
)->length
=
1083 bfd_section_size (outbfd
, secsec
);
1085 if (! bfd_close (outbfd
))
1086 bfd_fatal (output_file
);
1087 if (! bfd_close (inbfd
))
1088 bfd_fatal (input_file
);
1090 if (unlink_on_exit
!= NULL
)
1091 unlink (unlink_on_exit
);
1096 /* Display a help message and exit. */
1101 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1103 show_usage (stdout
, 0);
1106 /* Show a usage message and exit. */
1109 show_usage (file
, status
)
1114 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1115 [--input-target=bfdname] [--output-target=bfdname]\n\
1116 [--header-file=file] [--linker=linker] [--debug]\n\
1117 [--help] [--version]\n\
1118 [in-file [out-file]]\n",
1123 /* Select the output format based on the input architecture, machine,
1124 and endianness. This chooses the appropriate NLM target. */
1127 select_output_format (arch
, mach
, bigendian
)
1128 enum bfd_architecture arch
;
1135 return "nlm32-i386";
1136 case bfd_arch_sparc
:
1137 return "nlm32-sparc";
1138 case bfd_arch_alpha
:
1139 return "nlm32-alpha";
1140 /* start-sanitize-powerpc-netware */
1141 case bfd_arch_powerpc
:
1142 return "nlm32-powerpc";
1143 /* end-sanitize-powerpc-netware */
1145 fprintf (stderr
, "%s: no default NLM format for %s\n",
1146 program_name
, bfd_printable_arch_mach (arch
, mach
));
1148 /* Avoid warning. */
1154 /* The BFD sections are copied in two passes. This function selects
1155 the output section for each input section, and sets up the section
1159 setup_sections (inbfd
, insec
, data_ptr
)
1164 bfd
*outbfd
= (bfd
*) data_ptr
;
1166 const char *outname
;
1169 bfd_size_type align
;
1171 bfd_size_type secsecsize
;
1173 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1174 file. However, I don't have a good way to describe this section.
1175 We do want to copy the section when using objcopy. */
1176 if (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
1177 && strcmp (bfd_section_name (inbfd
, insec
), ".reginfo") == 0)
1180 f
= bfd_get_section_flags (inbfd
, insec
);
1182 outname
= NLM_CODE_NAME
;
1183 else if ((f
& SEC_LOAD
) && (f
& SEC_HAS_CONTENTS
))
1184 outname
= NLM_INITIALIZED_DATA_NAME
;
1185 else if (f
& SEC_ALLOC
)
1186 outname
= NLM_UNINITIALIZED_DATA_NAME
;
1188 outname
= bfd_section_name (inbfd
, insec
);
1190 outsec
= bfd_get_section_by_name (outbfd
, outname
);
1193 outsec
= bfd_make_section (outbfd
, outname
);
1195 bfd_fatal ("make section");
1198 insec
->output_section
= outsec
;
1200 offset
= bfd_section_size (outbfd
, outsec
);
1201 align
= 1 << bfd_section_alignment (inbfd
, insec
);
1202 add
= ((offset
+ align
- 1) &~ (align
- 1)) - offset
;
1203 insec
->output_offset
= offset
+ add
;
1205 if (! bfd_set_section_size (outbfd
, outsec
,
1206 (bfd_section_size (outbfd
, outsec
)
1207 + bfd_section_size (inbfd
, insec
)
1209 bfd_fatal ("set section size");
1211 if ((bfd_section_alignment (inbfd
, insec
)
1212 > bfd_section_alignment (outbfd
, outsec
))
1213 && ! bfd_set_section_alignment (outbfd
, outsec
,
1214 bfd_section_alignment (inbfd
, insec
)))
1215 bfd_fatal ("set section alignment");
1217 if (! bfd_set_section_flags (outbfd
, outsec
, f
))
1218 bfd_fatal ("set section flags");
1220 bfd_set_reloc (outbfd
, outsec
, (arelent
**) NULL
, 0);
1222 /* For each input section we allocate space for an entry in
1224 secsecsize
= bfd_section_size (outbfd
, secsec
);
1225 secsecsize
+= strlen (bfd_section_name (inbfd
, insec
)) + 1;
1226 secsecsize
= (secsecsize
+ 3) &~ 3;
1228 if (! bfd_set_section_size (outbfd
, secsec
, secsecsize
))
1229 bfd_fatal ("set .nlmsections size");
1232 /* Copy the section contents. */
1235 copy_sections (inbfd
, insec
, data_ptr
)
1240 static bfd_size_type secsecoff
= 0;
1241 bfd
*outbfd
= (bfd
*) data_ptr
;
1250 inname
= bfd_section_name (inbfd
, insec
);
1252 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1253 file. However, I don't have a good way to describe this section.
1254 We do want to copy the section when using objcopy. */
1255 if (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
1256 && strcmp (inname
, ".reginfo") == 0)
1259 outsec
= insec
->output_section
;
1260 assert (outsec
!= NULL
);
1262 size
= bfd_get_section_size_before_reloc (insec
);
1264 /* FIXME: Why are these necessary? */
1265 insec
->_cooked_size
= insec
->_raw_size
;
1266 insec
->reloc_done
= true;
1268 if ((bfd_get_section_flags (inbfd
, insec
) & SEC_HAS_CONTENTS
) == 0)
1272 contents
= xmalloc (size
);
1273 if (! bfd_get_section_contents (inbfd
, insec
, contents
,
1274 (file_ptr
) 0, size
))
1275 bfd_fatal (bfd_get_filename (inbfd
));
1278 reloc_size
= bfd_get_reloc_upper_bound (inbfd
, insec
);
1280 bfd_fatal (bfd_get_filename (inbfd
));
1281 if (reloc_size
!= 0)
1286 relocs
= (arelent
**) xmalloc (reloc_size
);
1287 reloc_count
= bfd_canonicalize_reloc (inbfd
, insec
, relocs
, symbols
);
1288 if (reloc_count
< 0)
1289 bfd_fatal (bfd_get_filename (inbfd
));
1290 mangle_relocs (outbfd
, insec
, &relocs
, &reloc_count
, (char *) contents
,
1293 /* FIXME: refers to internal BFD fields. */
1294 if (outsec
->orelocation
!= (arelent
**) NULL
)
1296 bfd_size_type total_count
;
1299 total_count
= reloc_count
+ outsec
->reloc_count
;
1300 combined
= (arelent
**) xmalloc (total_count
* sizeof (arelent
));
1301 memcpy (combined
, outsec
->orelocation
,
1302 outsec
->reloc_count
* sizeof (arelent
));
1303 memcpy (combined
+ outsec
->reloc_count
, relocs
,
1304 (size_t) (reloc_count
* sizeof (arelent
)));
1305 free (outsec
->orelocation
);
1306 reloc_count
= total_count
;
1310 bfd_set_reloc (outbfd
, outsec
, relocs
, reloc_count
);
1313 if (contents
!= NULL
)
1315 if (! bfd_set_section_contents (outbfd
, outsec
, contents
,
1316 insec
->output_offset
, size
))
1317 bfd_fatal (bfd_get_filename (outbfd
));
1321 /* Add this section to .nlmsections. */
1322 if (! bfd_set_section_contents (outbfd
, secsec
, (PTR
) inname
, secsecoff
,
1323 strlen (inname
) + 1))
1324 bfd_fatal ("set .nlmsection contents");
1325 secsecoff
+= strlen (inname
) + 1;
1327 add
= ((secsecoff
+ 3) &~ 3) - secsecoff
;
1330 bfd_h_put_32 (outbfd
, (bfd_vma
) 0, buf
);
1331 if (! bfd_set_section_contents (outbfd
, secsec
, buf
, secsecoff
, add
))
1332 bfd_fatal ("set .nlmsection contents");
1336 if (contents
!= NULL
)
1337 bfd_h_put_32 (outbfd
, (bfd_vma
) outsec
->filepos
, buf
);
1339 bfd_h_put_32 (outbfd
, (bfd_vma
) 0, buf
);
1340 if (! bfd_set_section_contents (outbfd
, secsec
, buf
, secsecoff
, 4))
1341 bfd_fatal ("set .nlmsection contents");
1344 bfd_h_put_32 (outbfd
, (bfd_vma
) size
, buf
);
1345 if (! bfd_set_section_contents (outbfd
, secsec
, buf
, secsecoff
, 4))
1346 bfd_fatal ("set .nlmsection contents");
1350 /* Some, perhaps all, NetWare targets require changing the relocs used
1351 by the input formats. */
1354 mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1358 arelent
***relocs_ptr
;
1359 long *reloc_count_ptr
;
1361 bfd_size_type contents_size
;
1363 switch (bfd_get_arch (outbfd
))
1366 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1367 contents
, contents_size
);
1369 case bfd_arch_alpha
:
1370 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1371 contents
, contents_size
);
1373 /* start-sanitize-powerpc-netware */
1374 case bfd_arch_powerpc
:
1375 powerpc_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1376 contents
, contents_size
);
1378 /* end-sanitize-powerpc-netware */
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
;
1413 /* NetWare on the i386 supports a restricted set of relocs, which are
1414 different from those used on other i386 targets. This routine
1415 converts the relocs. It is, obviously, very target dependent. At
1416 the moment, the nlm32-i386 backend performs similar translations;
1417 however, it is more reliable and efficient to do them here. */
1419 static reloc_howto_type nlm_i386_pcrel_howto
=
1420 HOWTO (1, /* type */
1422 2, /* size (0 = byte, 1 = short, 2 = long) */
1424 true, /* pc_relative */
1426 complain_overflow_signed
, /* complain_on_overflow */
1427 0, /* special_function */
1428 "DISP32", /* name */
1429 true, /* partial_inplace */
1430 0xffffffff, /* src_mask */
1431 0xffffffff, /* dst_mask */
1432 true); /* pcrel_offset */
1435 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1439 arelent
***relocs_ptr
;
1440 long *reloc_count_ptr
;
1442 bfd_size_type contents_size
;
1444 long reloc_count
, i
;
1447 reloc_count
= *reloc_count_ptr
;
1448 relocs
= *relocs_ptr
;
1449 for (i
= 0; i
< reloc_count
; i
++)
1453 bfd_size_type address
;
1457 sym
= *rel
->sym_ptr_ptr
;
1459 /* We're moving the relocs from the input section to the output
1460 section, so we must adjust the address accordingly. */
1461 address
= rel
->address
;
1462 rel
->address
+= insec
->output_offset
;
1464 /* Note that no serious harm will ensue if we fail to change a
1465 reloc. The backend will fail when writing out the reloc. */
1467 /* Make sure this reloc is within the data we have. We use only
1468 4 byte relocs here, so we insist on having 4 bytes. */
1469 if (address
+ 4 > contents_size
)
1472 /* A PC relative reloc entirely within a single section is
1473 completely unnecessary. This can be generated by ld -r. */
1474 if (sym
== insec
->symbol
1475 && rel
->howto
!= NULL
1476 && rel
->howto
->pc_relative
1477 && ! rel
->howto
->pcrel_offset
)
1481 memmove (relocs
, relocs
+ 1,
1482 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1486 /* Get the amount the relocation will add in. */
1487 addend
= rel
->addend
+ sym
->value
;
1489 /* NetWare doesn't support PC relative relocs against defined
1490 symbols, so we have to eliminate them by doing the relocation
1491 now. We can only do this if the reloc is within a single
1493 if (rel
->howto
!= NULL
1494 && rel
->howto
->pc_relative
1495 && bfd_get_section (sym
) == insec
->output_section
)
1499 if (rel
->howto
->pcrel_offset
)
1502 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1504 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1508 memmove (relocs
, relocs
+ 1,
1509 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1513 /* NetWare doesn't support reloc addends, so we get rid of them
1514 here by simply adding them into the object data. We handle
1515 the symbol value, if any, the same way. */
1517 && rel
->howto
!= NULL
1518 && rel
->howto
->rightshift
== 0
1519 && rel
->howto
->size
== 2
1520 && rel
->howto
->bitsize
== 32
1521 && rel
->howto
->bitpos
== 0
1522 && rel
->howto
->src_mask
== 0xffffffff
1523 && rel
->howto
->dst_mask
== 0xffffffff)
1527 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1529 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1531 /* Adjust the reloc for the changes we just made. */
1533 if (bfd_get_section (sym
) != &bfd_und_section
)
1534 rel
->sym_ptr_ptr
= bfd_get_section (sym
)->symbol_ptr_ptr
;
1537 /* NetWare uses a reloc with pcrel_offset set. We adjust
1538 pc_relative relocs accordingly. We are going to change the
1539 howto field, so we can only do this if the current one is
1540 compatible. We should check that special_function is NULL
1541 here, but at the moment coff-i386 uses a special_function
1542 which does not affect what we are doing here. */
1543 if (rel
->howto
!= NULL
1544 && rel
->howto
->pc_relative
1545 && ! rel
->howto
->pcrel_offset
1546 && rel
->howto
->rightshift
== 0
1547 && rel
->howto
->size
== 2
1548 && rel
->howto
->bitsize
== 32
1549 && rel
->howto
->bitpos
== 0
1550 && rel
->howto
->src_mask
== 0xffffffff
1551 && rel
->howto
->dst_mask
== 0xffffffff)
1555 /* When pcrel_offset is not set, it means that the negative
1556 of the address of the memory location is stored in the
1557 memory location. We must add it back in. */
1558 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1560 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1562 /* We must change to a new howto. */
1563 rel
->howto
= &nlm_i386_pcrel_howto
;
1568 /* On the Alpha the first reloc for every section must be a special
1569 relocs which hold the GP address. Also, the first reloc in the
1570 file must be a special reloc which holds the address of the .lita
1573 static reloc_howto_type nlm32_alpha_nw_howto
=
1574 HOWTO (ALPHA_R_NW_RELOC
, /* type */
1576 0, /* size (0 = byte, 1 = short, 2 = long) */
1578 false, /* pc_relative */
1580 complain_overflow_dont
, /* complain_on_overflow */
1581 0, /* special_function */
1582 "NW_RELOC", /* name */
1583 false, /* partial_inplace */
1586 false); /* pcrel_offset */
1590 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1594 register arelent
***relocs_ptr
;
1595 long *reloc_count_ptr
;
1597 bfd_size_type contents_size
;
1599 long old_reloc_count
;
1600 arelent
**old_relocs
;
1601 register arelent
**relocs
;
1603 old_reloc_count
= *reloc_count_ptr
;
1604 old_relocs
= *relocs_ptr
;
1605 relocs
= (arelent
**) xmalloc ((old_reloc_count
+ 3) * sizeof (arelent
*));
1606 *relocs_ptr
= relocs
;
1608 if (nlm_alpha_backend_data (outbfd
)->lita_address
== 0)
1611 asection
*lita_section
;
1613 inbfd
= insec
->owner
;
1614 lita_section
= bfd_get_section_by_name (inbfd
, _LITA
);
1615 if (lita_section
!= (asection
*) NULL
)
1617 nlm_alpha_backend_data (outbfd
)->lita_address
=
1618 bfd_get_section_vma (inbfd
, lita_section
);
1619 nlm_alpha_backend_data (outbfd
)->lita_size
=
1620 bfd_section_size (inbfd
, lita_section
);
1624 /* Avoid outputting this reloc again. */
1625 nlm_alpha_backend_data (outbfd
)->lita_address
= 4;
1628 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1629 (*relocs
)->sym_ptr_ptr
= bfd_abs_section
.symbol_ptr_ptr
;
1630 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->lita_address
;
1631 (*relocs
)->addend
= nlm_alpha_backend_data (outbfd
)->lita_size
+ 1;
1632 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1634 ++(*reloc_count_ptr
);
1637 /* Get the GP value from bfd. It is in the .reginfo section. */
1638 if (nlm_alpha_backend_data (outbfd
)->gp
== 0)
1641 asection
*reginfo_sec
;
1642 struct ecoff_reginfo sreginfo
;
1644 inbfd
= insec
->owner
;
1645 assert (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
);
1646 reginfo_sec
= bfd_get_section_by_name (inbfd
, REGINFO
);
1647 if (reginfo_sec
!= (asection
*) NULL
1648 && bfd_get_section_contents (inbfd
, reginfo_sec
,
1649 (PTR
) &sreginfo
, (file_ptr
) 0,
1650 sizeof sreginfo
) != false)
1651 nlm_alpha_backend_data (outbfd
)->gp
= sreginfo
.gp_value
;
1654 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1655 (*relocs
)->sym_ptr_ptr
= bfd_abs_section
.symbol_ptr_ptr
;
1656 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->gp
;
1657 (*relocs
)->addend
= 0;
1658 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1660 ++(*reloc_count_ptr
);
1662 memcpy ((PTR
) relocs
, (PTR
) old_relocs
,
1663 (size_t) old_reloc_count
* sizeof (arelent
*));
1664 relocs
[old_reloc_count
] = (arelent
*) NULL
;
1668 if (insec
->output_offset
!= 0)
1670 register bfd_size_type i
;
1672 for (i
= 0; i
< old_reloc_count
; i
++, relocs
++)
1673 (*relocs
)->address
+= insec
->output_offset
;
1676 /* start-sanitize-powerpc-netware */
1678 /* We keep a linked list of stubs which we must build. Because BFD
1679 requires us to know the sizes of all sections before we can set the
1680 contents of any, we must figure out which stubs we want to build
1681 before we can actually build any of them. */
1685 /* Next stub in linked list. */
1686 struct powerpc_stub
*next
;
1688 /* Symbol whose value is the start of the stub. This is a symbol
1689 whose name begins with `.'. */
1692 /* Symbol we are going to create a reloc against. This is a symbol
1693 with the same name as START but without the leading `.'. */
1696 /* The TOC index for this stub. This is the index into the TOC
1697 section at which the reloc is created. */
1698 unsigned int toc_index
;
1701 /* The linked list of stubs. */
1703 static struct powerpc_stub
*powerpc_stubs
;
1705 /* This is what a stub looks like. The first instruction will get
1706 adjusted with the correct TOC index. */
1708 static unsigned long powerpc_stub_insns
[] =
1710 0x81820000, /* lwz r12,0(r2) */
1711 0x90410014, /* stw r2,20(r1) */
1712 0x800c0000, /* lwz r0,0(r12) */
1713 0x804c0004, /* lwz r2,r(r12) */
1714 0x7c0903a6, /* mtctr r0 */
1715 0x4e800420, /* bctr */
1716 0, /* Traceback table. */
1721 #define POWERPC_STUB_INSN_COUNT \
1722 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1724 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1726 /* Each stub uses a four byte TOC entry. */
1727 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1729 /* The original size of the .got section. */
1730 static bfd_size_type powerpc_initial_got_size
;
1732 /* Look for all undefined symbols beginning with `.', and prepare to
1733 build a stub for each one. */
1736 powerpc_build_stubs (inbfd
, outbfd
, symbols_ptr
, symcount_ptr
)
1739 asymbol
***symbols_ptr
;
1744 unsigned int got_base
;
1749 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1750 the section to prevent copy_sections from reading from it. */
1751 stub_sec
= bfd_make_section (inbfd
, ".stubs");
1752 if (stub_sec
== (asection
*) NULL
1753 || ! bfd_set_section_flags (inbfd
, stub_sec
,
1758 || ! bfd_set_section_alignment (inbfd
, stub_sec
, 2))
1759 bfd_fatal (".stubs");
1761 /* Get the TOC section, which is named .got. */
1762 got_sec
= bfd_get_section_by_name (inbfd
, ".got");
1763 if (got_sec
== (asection
*) NULL
)
1765 got_sec
= bfd_make_section (inbfd
, ".got");
1766 if (got_sec
== (asection
*) NULL
1767 || ! bfd_set_section_flags (inbfd
, got_sec
,
1772 | SEC_HAS_CONTENTS
))
1773 || ! bfd_set_section_alignment (inbfd
, got_sec
, 2))
1777 powerpc_initial_got_size
= bfd_section_size (inbfd
, got_sec
);
1778 got_base
= powerpc_initial_got_size
;
1779 got_base
= (got_base
+ 3) &~ 3;
1783 symcount
= *symcount_ptr
;
1784 for (i
= 0; i
< symcount
; i
++)
1789 struct powerpc_stub
*item
;
1791 sym
= (*symbols_ptr
)[i
];
1793 /* We must make a stub for every undefined symbol whose name
1795 if (bfd_asymbol_name (sym
)[0] != '.'
1796 || bfd_get_section (sym
) != &bfd_und_section
)
1799 /* Make a new undefined symbol with the same name but without
1801 newsym
= (asymbol
*) xmalloc (sizeof (asymbol
));
1803 newname
= (char *) xmalloc (strlen (bfd_asymbol_name (sym
)));
1804 strcpy (newname
, bfd_asymbol_name (sym
) + 1);
1805 newsym
->name
= newname
;
1807 /* Define the `.' symbol to be in the stub section. */
1808 sym
->section
= stub_sec
;
1809 sym
->value
= stubcount
* POWERPC_STUB_SIZE
;
1810 /* We set the BSF_DYNAMIC flag here so that we can check it when
1811 we are mangling relocs. FIXME: This is a hack. */
1812 sym
->flags
= BSF_LOCAL
| BSF_DYNAMIC
;
1814 /* Add this stub to the linked list. */
1815 item
= (struct powerpc_stub
*) xmalloc (sizeof (struct powerpc_stub
));
1817 item
->reloc
= newsym
;
1818 item
->toc_index
= got_base
+ stubcount
* POWERPC_STUB_TOC_ENTRY_SIZE
;
1820 item
->next
= powerpc_stubs
;
1821 powerpc_stubs
= item
;
1829 struct powerpc_stub
*l
;
1831 /* Add the new symbols we just created to the symbol table. */
1832 *symbols_ptr
= (asymbol
**) xrealloc ((char *) *symbols_ptr
,
1833 ((symcount
+ stubcount
)
1834 * sizeof (asymbol
)));
1835 *symcount_ptr
+= stubcount
;
1836 s
= &(*symbols_ptr
)[symcount
];
1837 for (l
= powerpc_stubs
; l
!= (struct powerpc_stub
*) NULL
; l
= l
->next
)
1840 /* Set the size of the .stubs section and increase the size of
1841 the .got section. */
1842 if (! bfd_set_section_size (inbfd
, stub_sec
,
1843 stubcount
* POWERPC_STUB_SIZE
)
1844 || ! bfd_set_section_size (inbfd
, got_sec
,
1847 * POWERPC_STUB_TOC_ENTRY_SIZE
))))
1848 bfd_fatal ("stub section sizes");
1851 /* PowerPC NetWare requires a custom header. We create it here.
1852 The first word is the header version number, currently 1. The
1853 second word is the timestamp of the input file. */
1854 memcpy (nlm_custom_header (outbfd
)->stamp
, "CuStHeAd", 8);
1855 nlm_custom_header (outbfd
)->dataLength
= 8;
1856 nlm_custom_header (outbfd
)->data
= xmalloc (8);
1857 bfd_h_put_32 (outbfd
, (bfd_vma
) 1,
1858 (bfd_byte
*) nlm_custom_header (outbfd
)->data
);
1862 if (stat (bfd_get_filename (inbfd
), &s
) < 0)
1864 bfd_h_put_32 (outbfd
, (bfd_vma
) s
.st_mtime
,
1865 (bfd_byte
*) nlm_custom_header (outbfd
)->data
+ 4);
1869 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1870 of the output section, and create new relocs in the TOC. */
1873 powerpc_resolve_stubs (inbfd
, outbfd
)
1877 bfd_byte buf
[POWERPC_STUB_SIZE
];
1879 unsigned int stubcount
;
1883 struct powerpc_stub
*l
;
1885 if (powerpc_stubs
== (struct powerpc_stub
*) NULL
)
1888 for (i
= 0; i
< POWERPC_STUB_INSN_COUNT
; i
++)
1889 bfd_put_32 (outbfd
, (bfd_vma
) powerpc_stub_insns
[i
], buf
+ i
* 4);
1891 got_sec
= bfd_get_section_by_name (inbfd
, ".got");
1892 assert (got_sec
!= (asection
*) NULL
);
1893 assert (got_sec
->output_section
->orelocation
== (arelent
**) NULL
);
1896 for (l
= powerpc_stubs
; l
!= (struct powerpc_stub
*) NULL
; l
= l
->next
)
1898 relocs
= (arelent
**) xmalloc (stubcount
* sizeof (arelent
*));
1901 for (l
= powerpc_stubs
; l
!= (struct powerpc_stub
*) NULL
; l
= l
->next
)
1905 /* Adjust the first instruction to use the right TOC index. */
1906 bfd_put_32 (outbfd
, (bfd_vma
) powerpc_stub_insns
[0] + l
->toc_index
, buf
);
1908 /* Write this stub out. */
1909 if (! bfd_set_section_contents (outbfd
,
1910 bfd_get_section (l
->start
),
1914 bfd_fatal ("writing stub");
1916 /* Create a new reloc for the TOC entry. */
1917 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1918 reloc
->sym_ptr_ptr
= &l
->reloc
;
1919 reloc
->address
= l
->toc_index
+ got_sec
->output_offset
;
1921 reloc
->howto
= bfd_reloc_type_lookup (inbfd
, BFD_RELOC_32
);
1926 bfd_set_reloc (outbfd
, got_sec
->output_section
, relocs
, stubcount
);
1929 /* Adjust relocation entries for PowerPC NetWare. We do not output
1930 TOC relocations. The object code already contains the offset from
1931 the TOC pointer. When the function is called, the TOC register,
1932 r2, will be set to the correct TOC value, so there is no need for
1933 any further reloc. */
1937 powerpc_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1941 register arelent
***relocs_ptr
;
1942 long *reloc_count_ptr
;
1944 bfd_size_type contents_size
;
1946 const reloc_howto_type
*toc_howto
;
1948 register arelent
**relocs
;
1951 toc_howto
= bfd_reloc_type_lookup (insec
->owner
, BFD_RELOC_PPC_TOC16
);
1952 if (toc_howto
== (reloc_howto_type
*) NULL
)
1955 /* If this is the .got section, clear out all the contents beyond
1956 the initial size. We must do this here because copy_sections is
1957 going to write out whatever we return in the contents field. */
1958 if (strcmp (bfd_get_section_name (insec
->owner
, insec
), ".got") == 0)
1959 memset (contents
+ powerpc_initial_got_size
, 0,
1960 (bfd_get_section_size_after_reloc (insec
)
1961 - powerpc_initial_got_size
));
1963 reloc_count
= *reloc_count_ptr
;
1964 relocs
= *relocs_ptr
;
1965 for (i
= 0; i
< reloc_count
; i
++)
1972 sym
= *rel
->sym_ptr_ptr
;
1974 /* We must be able to resolve all PC relative relocs at this
1975 point. If we get a branch to an undefined symbol we build a
1976 stub, since NetWare will resolve undefined symbols into a
1977 pointer to a function descriptor. */
1978 if (rel
->howto
->pc_relative
)
1980 /* This check for whether a symbol is in the same section as
1981 the reloc will be wrong if there is a PC relative reloc
1982 between two sections both of which were placed in the
1983 same output section. This should not happen. */
1984 if (bfd_get_section (sym
) != insec
->output_section
)
1985 fprintf (stderr
, "%s: unresolved PC relative reloc against %s\n",
1986 program_name
, bfd_asymbol_name (sym
));
1991 assert (rel
->howto
->size
== 2 && rel
->howto
->pcrel_offset
);
1992 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ rel
->address
);
1993 val
= ((val
&~ rel
->howto
->dst_mask
)
1994 | (((val
& rel
->howto
->src_mask
)
1995 + (sym
->value
- rel
->address
)
1997 & rel
->howto
->dst_mask
));
1998 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ rel
->address
);
2000 /* If this reloc is against an stubbed symbol and the
2003 then we replace the next instruction with
2005 This reloads the TOC pointer after a stub call. */
2006 if (bfd_asymbol_name (sym
)[0] == '.'
2007 && (sym
->flags
& BSF_DYNAMIC
) != 0
2008 && (bfd_get_32 (outbfd
,
2009 (bfd_byte
*) contents
+ rel
->address
+ 4)
2010 == 0x4ffffb82)) /* cror 31,31,31 */
2011 bfd_put_32 (outbfd
, (bfd_vma
) 0x80410014, /* lwz r2,20(r1) */
2012 (bfd_byte
*) contents
+ rel
->address
+ 4);
2016 memmove (relocs
, relocs
+ 1,
2017 (size_t) ((reloc_count
- 1) * sizeof (arelent
*)));
2022 /* When considering a TOC reloc, we do not want to include the
2023 symbol value. The symbol will be start of the TOC section
2024 (which is named .got). We do want to include the addend. */
2025 if (rel
->howto
== toc_howto
)
2028 symvalue
= sym
->value
;
2030 /* If this is a relocation against a symbol with a value, or
2031 there is a reloc addend, we need to update the addend in the
2033 if (symvalue
+ rel
->addend
!= 0)
2037 switch (rel
->howto
->size
)
2040 val
= bfd_get_16 (outbfd
,
2041 (bfd_byte
*) contents
+ rel
->address
);
2042 val
= ((val
&~ rel
->howto
->dst_mask
)
2043 | (((val
& rel
->howto
->src_mask
)
2046 & rel
->howto
->dst_mask
));
2047 if ((bfd_signed_vma
) val
< - 0x8000
2048 || (bfd_signed_vma
) val
>= 0x8000)
2050 "%s: overflow when adjusting relocation against %s\n",
2051 program_name
, bfd_asymbol_name (sym
));
2052 bfd_put_16 (outbfd
, val
, (bfd_byte
*) contents
+ rel
->address
);
2056 val
= bfd_get_32 (outbfd
,
2057 (bfd_byte
*) contents
+ rel
->address
);
2058 val
= ((val
&~ rel
->howto
->dst_mask
)
2059 | (((val
& rel
->howto
->src_mask
)
2062 & rel
->howto
->dst_mask
));
2063 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ rel
->address
);
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
;
2088 /* end-sanitize-powerpc-netware */
2090 /* Name of linker. */
2092 #define LD_NAME "ld"
2095 /* Temporary file name base. */
2096 static char *temp_filename
;
2098 /* The user has specified several input files. Invoke the linker to
2099 link them all together, and convert and delete the resulting output
2103 link_inputs (inputs
, ld
)
2104 struct string_list
*inputs
;
2108 struct string_list
*q
;
2115 for (q
= inputs
; q
!= NULL
; q
= q
->next
)
2118 argv
= (char **) alloca (c
+ 5);
2125 /* Find the linker to invoke based on how nlmconv was run. */
2126 p
= program_name
+ strlen (program_name
);
2127 while (p
!= program_name
)
2131 ld
= (char *) xmalloc (p
- program_name
+ strlen (LD_NAME
) + 1);
2132 memcpy (ld
, program_name
, p
- program_name
);
2133 strcpy (ld
+ (p
- program_name
), LD_NAME
);
2142 ld
= (char *) LD_NAME
;
2144 choose_temp_base ();
2146 unlink_on_exit
= xmalloc (strlen (temp_filename
) + 3);
2147 sprintf (unlink_on_exit
, "%s.O", temp_filename
);
2150 argv
[1] = (char *) "-r";
2151 argv
[2] = (char *) "-o";
2152 argv
[3] = unlink_on_exit
;
2154 for (q
= inputs
; q
!= NULL
; q
= q
->next
, i
++)
2155 argv
[i
] = q
->string
;
2160 for (i
= 0; argv
[i
] != NULL
; i
++)
2161 fprintf (stderr
, " %s", argv
[i
]);
2162 fprintf (stderr
, "\n");
2165 pid
= pexecute (ld
, argv
);
2167 if (waitpid (pid
, &status
, 0) < 0)
2170 unlink (unlink_on_exit
);
2176 fprintf (stderr
, "%s: Execution of %s failed\n", program_name
, ld
);
2177 unlink (unlink_on_exit
);
2181 return unlink_on_exit
;
2184 /* Choose a temporary file name. Stolen from gcc.c. */
2187 choose_temp_base_try (try, base
)
2195 else if (try == NULL
)
2197 else if (access (try, R_OK
| W_OK
) != 0)
2207 const char *base
= NULL
;
2210 base
= choose_temp_base_try (getenv ("TMPDIR"), base
);
2211 base
= choose_temp_base_try (getenv ("TMP"), base
);
2212 base
= choose_temp_base_try (getenv ("TEMP"), base
);
2215 base
= choose_temp_base_try (P_tmpdir
, base
);
2218 base
= choose_temp_base_try ("/usr/tmp", base
);
2219 base
= choose_temp_base_try ("/tmp", base
);
2221 /* If all else fails, use the current directory! */
2225 len
= strlen (base
);
2226 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX") + 1);
2227 strcpy (temp_filename
, base
);
2228 if (len
> 0 && temp_filename
[len
-1] != '/')
2229 temp_filename
[len
++] = '/';
2230 strcpy (temp_filename
+ len
, "ccXXXXXX");
2232 mktemp (temp_filename
);
2233 if (*temp_filename
== '\0')
2237 /* Execute a job. Stolen from gcc.c. */
2243 pexecute (program
, argv
)
2251 scmd
= (char *)malloc (strlen (program
) + strlen (temp_filename
) + 10);
2252 rf
= scmd
+ strlen(program
) + 2 + el
;
2253 sprintf (scmd
, "%s.exe @%s.gp", program
, temp_filename
);
2254 argfile
= fopen (rf
, "w");
2256 pfatal_with_name (rf
);
2258 for (i
=1; argv
[i
]; i
++)
2261 for (cp
= argv
[i
]; *cp
; cp
++)
2263 if (*cp
== '"' || *cp
== '\'' || *cp
== '\\' || isspace (*cp
))
2264 fputc ('\\', argfile
);
2265 fputc (*cp
, argfile
);
2267 fputc ('\n', argfile
);
2278 return MIN_FATAL_STATUS
<< 8;
2284 #else /* not __MSDOS__ */
2287 pexecute (program
, argv
)
2292 int retries
, sleep_interval
;
2294 /* Fork a subprocess; wait and retry if it fails. */
2296 for (retries
= 0; retries
< 4; retries
++)
2301 sleep (sleep_interval
);
2302 sleep_interval
*= 2;
2318 /* Exec the program. */
2319 execvp (program
, argv
);
2326 /* Return child's process number. */
2331 #endif /* not __MSDOS__ */
2335 pexecute (program
, argv
)
2339 return spawnvp (1, program
, argv
);
2341 #endif /* not OS2 */