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>
41 /* Internal BFD NLM header. */
45 /* Needed for Alpha support. */
47 #include "coff/ecoff.h"
49 /* If strerror is just a macro, we want to use the one from libiberty
50 since it will handle undefined values. */
52 extern char *strerror ();
55 extern struct tm
*localtime ();
59 extern char *getenv ();
72 /* Global variables. */
74 /* The name used to invoke the program. */
77 /* The version number. */
78 extern char *program_version
;
80 /* Local variables. */
82 /* Whether to print out debugging information (currently just controls
83 whether it prints the linker command if there is one). */
86 /* The symbol table. */
87 static asymbol
**symbols
;
89 /* A temporary file name to be unlinked on exit. Actually, for most
90 errors, we leave it around. It's not clear whether that is helpful
92 static char *unlink_on_exit
;
94 /* The list of long options. */
95 static struct option long_options
[] =
97 { "debug", no_argument
, 0, 'd' },
98 { "header-file", required_argument
, 0, 'T' },
99 { "help", no_argument
, 0, 'h' },
100 { "input-target", required_argument
, 0, 'I' },
101 { "input-format", required_argument
, 0, 'I' }, /* Obsolete */
102 { "linker", required_argument
, 0, 'l' },
103 { "output-target", required_argument
, 0, 'O' },
104 { "output-format", required_argument
, 0, 'O' }, /* Obsolete */
105 { "version", no_argument
, 0, 'V' },
106 { NULL
, no_argument
, 0, 0 }
109 /* Local routines. */
111 static void show_help
PARAMS ((void));
112 static void show_usage
PARAMS ((FILE *, int));
113 static const char *select_output_format
PARAMS ((enum bfd_architecture
,
114 unsigned long, boolean
));
115 static void setup_sections
PARAMS ((bfd
*, asection
*, PTR
));
116 static void copy_sections
PARAMS ((bfd
*, asection
*, PTR
));
117 static void mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
118 bfd_size_type
*, char *,
120 static void i386_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
121 bfd_size_type
*, char *,
123 static void alpha_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
124 bfd_size_type
*, char *,
126 static void default_mangle_relocs
PARAMS ((bfd
*, asection
*, arelent
***,
127 bfd_size_type
*, char *,
129 static char *link_inputs
PARAMS ((struct string_list
*, char *));
130 static const char *choose_temp_base_try
PARAMS ((const char *,
132 static void choose_temp_base
PARAMS ((void));
133 static int pexecute
PARAMS ((char *, char *[]));
135 /* The main routine. */
143 char *input_file
= NULL
;
144 const char *input_format
= NULL
;
145 const char *output_format
= NULL
;
146 const char *header_file
= NULL
;
148 Nlm_Internal_Fixed_Header fixed_hdr_struct
;
149 Nlm_Internal_Variable_Header var_hdr_struct
;
150 Nlm_Internal_Version_Header version_hdr_struct
;
151 Nlm_Internal_Copyright_Header copyright_hdr_struct
;
152 Nlm_Internal_Extended_Header extended_hdr_struct
;
155 asymbol
**newsyms
, **outsyms
;
156 unsigned int symcount
, newsymalloc
, newsymcount
;
157 asection
*bss_sec
, *data_sec
;
162 char inlead
, outlead
;
163 boolean gotstart
, gotexit
, gotcheck
;
165 FILE *custom_data
, *help_data
, *message_data
, *rpc_data
, *shared_data
;
166 size_t custom_size
, help_size
, message_size
, module_size
, rpc_size
;
167 asection
*custom_section
, *help_section
, *message_section
, *module_section
;
168 asection
*rpc_section
, *shared_section
;
170 size_t shared_offset
, shared_size
;
171 Nlm_Internal_Fixed_Header sharedhdr
;
175 program_name
= argv
[0];
179 while ((opt
= getopt_long (argc
, argv
, "dhI:l:O:T:V", long_options
,
192 input_format
= optarg
;
198 output_format
= optarg
;
201 header_file
= optarg
;
204 printf ("GNU %s version %s\n", program_name
, program_version
);
210 show_usage (stderr
, 1);
215 /* The input and output files may be named on the command line. */
219 input_file
= argv
[optind
];
223 output_file
= argv
[optind
];
226 show_usage (stderr
, 1);
227 if (strcmp (input_file
, output_file
) == 0)
230 "%s: input and output files must be different\n",
237 /* Initialize the header information to default values. */
238 fixed_hdr
= &fixed_hdr_struct
;
239 memset ((PTR
) &fixed_hdr_struct
, 0, sizeof fixed_hdr_struct
);
240 var_hdr
= &var_hdr_struct
;
241 memset ((PTR
) &var_hdr_struct
, 0, sizeof var_hdr_struct
);
242 version_hdr
= &version_hdr_struct
;
243 memset ((PTR
) &version_hdr_struct
, 0, sizeof version_hdr_struct
);
244 copyright_hdr
= ©right_hdr_struct
;
245 memset ((PTR
) ©right_hdr_struct
, 0, sizeof copyright_hdr_struct
);
246 extended_hdr
= &extended_hdr_struct
;
247 memset ((PTR
) &extended_hdr_struct
, 0, sizeof extended_hdr_struct
);
248 check_procedure
= NULL
;
251 exit_procedure
= "_Stop";
252 export_symbols
= NULL
;
256 import_symbols
= NULL
;
259 sharelib_file
= NULL
;
260 start_procedure
= "_Prelude";
266 /* Parse the header file (if there is one). */
267 if (header_file
!= NULL
)
269 if (! nlmlex_file (header_file
)
271 || parse_errors
!= 0)
275 if (input_files
!= NULL
)
277 if (input_file
!= NULL
)
280 "%s: input file named both on command line and with INPUT\n",
284 if (input_files
->next
== NULL
)
285 input_file
= input_files
->string
;
287 input_file
= link_inputs (input_files
, ld_arg
);
289 else if (input_file
== NULL
)
291 fprintf (stderr
, "%s: no input file\n", program_name
);
292 show_usage (stderr
, 1);
295 inbfd
= bfd_openr (input_file
, input_format
);
297 bfd_fatal (input_file
);
299 if (! bfd_check_format (inbfd
, bfd_object
))
300 bfd_fatal (input_file
);
302 if (output_format
== NULL
)
303 output_format
= select_output_format (bfd_get_arch (inbfd
),
304 bfd_get_mach (inbfd
),
305 inbfd
->xvec
->byteorder_big_p
);
307 assert (output_format
!= NULL
);
309 /* Use the output file named on the command line if it exists.
310 Otherwise use the file named in the OUTPUT statement. */
311 if (output_file
== NULL
)
313 fprintf (stderr
, "%s: no name for output file\n",
315 show_usage (stderr
, 1);
318 outbfd
= bfd_openw (output_file
, output_format
);
320 bfd_fatal (output_file
);
321 if (! bfd_set_format (outbfd
, bfd_object
))
322 bfd_fatal (output_file
);
324 assert (outbfd
->xvec
->flavour
== bfd_target_nlm_flavour
);
326 if (bfd_arch_get_compatible (inbfd
, outbfd
) == NULL
)
328 "%s: warning:input and output formats are not compatible\n",
331 /* Move the values read from the command file into outbfd. */
332 *nlm_fixed_header (outbfd
) = fixed_hdr_struct
;
333 *nlm_variable_header (outbfd
) = var_hdr_struct
;
334 *nlm_version_header (outbfd
) = version_hdr_struct
;
335 *nlm_copyright_header (outbfd
) = copyright_hdr_struct
;
336 *nlm_extended_header (outbfd
) = extended_hdr_struct
;
338 /* Start copying the input BFD to the output BFD. */
339 if (! bfd_set_file_flags (outbfd
, bfd_get_file_flags (inbfd
)))
340 bfd_fatal (bfd_get_filename (outbfd
));
342 symbols
= (asymbol
**) xmalloc (get_symtab_upper_bound (inbfd
));
343 symcount
= bfd_canonicalize_symtab (inbfd
, symbols
);
345 /* Make sure we have a .bss section. */
346 bss_sec
= bfd_get_section_by_name (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
349 bss_sec
= bfd_make_section (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
351 || ! bfd_set_section_flags (outbfd
, bss_sec
, SEC_ALLOC
)
352 || ! bfd_set_section_alignment (outbfd
, bss_sec
, 1))
353 bfd_fatal ("make .bss section");
356 /* Set up the sections. */
357 bfd_map_over_sections (inbfd
, setup_sections
, (PTR
) outbfd
);
359 /* The .bss section immediately follows the .data section. */
360 data_sec
= bfd_get_section_by_name (outbfd
, NLM_INITIALIZED_DATA_NAME
);
361 if (data_sec
!= NULL
)
365 vma
= bfd_get_section_size_before_reloc (data_sec
);
366 align
= 1 << bss_sec
->alignment_power
;
367 add
= ((vma
+ align
- 1) &~ (align
- 1)) - vma
;
369 if (! bfd_set_section_vma (outbfd
, bss_sec
, vma
))
370 bfd_fatal ("set .bss vma");
373 bfd_size_type data_size
;
375 data_size
= bfd_get_section_size_before_reloc (data_sec
);
376 if (! bfd_set_section_size (outbfd
, data_sec
, data_size
+ add
))
377 bfd_fatal ("set .data size");
381 /* Adjust symbol information. */
382 inlead
= bfd_get_symbol_leading_char (inbfd
);
383 outlead
= bfd_get_symbol_leading_char (outbfd
);
388 newsyms
= (asymbol
**) xmalloc (newsymalloc
* sizeof (asymbol
*));
391 for (i
= 0; i
< symcount
; i
++)
393 register asymbol
*sym
;
397 /* Add or remove a leading underscore. */
398 if (inlead
!= outlead
)
402 if (bfd_asymbol_name (sym
)[0] == inlead
)
410 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 1);
412 strcpy (new + 1, bfd_asymbol_name (sym
) + 1);
421 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 2);
423 strcpy (new + 1, bfd_asymbol_name (sym
));
428 /* NLM's have an uninitialized data section, but they do not
429 have a common section in the Unix sense. Move all common
430 symbols into the .bss section, and mark them as exported. */
431 if (bfd_is_com_section (bfd_get_section (sym
)))
435 sym
->section
= bss_sec
;
437 sym
->value
= bss_sec
->_raw_size
;
438 bss_sec
->_raw_size
+= size
;
439 align
= 1 << bss_sec
->alignment_power
;
440 bss_sec
->_raw_size
= (bss_sec
->_raw_size
+ align
- 1) &~ (align
- 1);
441 sym
->flags
|= BSF_EXPORT
| BSF_GLOBAL
;
443 else if (bfd_get_section (sym
)->output_section
!= NULL
)
445 /* Move the symbol into the output section. */
446 sym
->value
+= bfd_get_section (sym
)->output_offset
;
447 sym
->section
= bfd_get_section (sym
)->output_section
;
448 /* This is no longer a section symbol. */
449 sym
->flags
&=~ BSF_SECTION_SYM
;
452 /* Force _edata and _end to be defined. This would normally be
453 done by the linker, but the manipulation of the common
454 symbols will confuse it. */
455 if (bfd_asymbol_name (sym
)[0] == '_'
456 && bfd_get_section (sym
) == &bfd_und_section
)
458 if (strcmp (bfd_asymbol_name (sym
), "_edata") == 0)
460 sym
->section
= bss_sec
;
463 if (strcmp (bfd_asymbol_name (sym
), "_end") == 0)
465 sym
->section
= bss_sec
;
470 /* If this is a global symbol, check the export list. */
471 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) != 0)
473 register struct string_list
*l
;
476 /* Unfortunately, a symbol can appear multiple times on the
477 export list, with and without prefixes. */
479 for (l
= export_symbols
; l
!= NULL
; l
= l
->next
)
481 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
487 zbase
= strchr (l
->string
, '@');
489 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
491 /* We must add a symbol with this prefix. */
492 if (newsymcount
>= newsymalloc
)
495 newsyms
= ((asymbol
**)
498 * sizeof (asymbol
*))));
500 newsyms
[newsymcount
] =
501 (asymbol
*) xmalloc (sizeof (asymbol
));
502 *newsyms
[newsymcount
] = *sym
;
503 newsyms
[newsymcount
]->name
= l
->string
;
510 /* The unmodified symbol is actually not exported at
512 sym
->flags
&=~ (BSF_GLOBAL
| BSF_EXPORT
);
513 sym
->flags
|= BSF_LOCAL
;
517 /* If it's an undefined symbol, see if it's on the import list.
518 Change the prefix if necessary. */
519 if (bfd_get_section (sym
) == &bfd_und_section
)
521 register struct string_list
*l
;
523 for (l
= import_symbols
; l
!= NULL
; l
= l
->next
)
525 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
531 zbase
= strchr (l
->string
, '@');
533 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
535 sym
->name
= l
->string
;
542 "%s: warning: symbol %s imported but not in import list\n",
543 program_name
, bfd_asymbol_name (sym
));
546 /* See if it's one of the special named symbols. */
547 if (strcmp (bfd_asymbol_name (sym
), start_procedure
) == 0)
549 if (! bfd_set_start_address (outbfd
, bfd_asymbol_value (sym
)))
550 bfd_fatal ("set start address");
553 if (strcmp (bfd_asymbol_name (sym
), exit_procedure
) == 0)
555 nlm_fixed_header (outbfd
)->exitProcedureOffset
=
556 bfd_asymbol_value (sym
);
559 if (check_procedure
!= NULL
560 && strcmp (bfd_asymbol_name (sym
), check_procedure
) == 0)
562 nlm_fixed_header (outbfd
)->checkUnloadProcedureOffset
=
563 bfd_asymbol_value (sym
);
569 endsym
->value
= bfd_get_section_size_before_reloc (bss_sec
);
571 if (newsymcount
== 0)
575 outsyms
= (asymbol
**) xmalloc ((symcount
+ newsymcount
+ 1)
576 * sizeof (asymbol
*));
577 memcpy (outsyms
, symbols
, symcount
* sizeof (asymbol
*));
578 memcpy (outsyms
+ symcount
, newsyms
, newsymcount
* sizeof (asymbol
*));
579 outsyms
[symcount
+ newsymcount
] = NULL
;
582 bfd_set_symtab (outbfd
, outsyms
, symcount
+ newsymcount
);
585 fprintf (stderr
, "%s: warning: START procedure %s not defined\n",
586 program_name
, start_procedure
);
588 fprintf (stderr
, "%s: warning: EXIT procedure %s not defined\n",
589 program_name
, exit_procedure
);
590 if (check_procedure
!= NULL
592 fprintf (stderr
, "%s: warning: CHECK procedure %s not defined\n",
593 program_name
, check_procedure
);
595 /* Add additional sections required for the header information. */
596 if (custom_file
!= NULL
)
598 custom_data
= fopen (custom_file
, "r");
599 if (custom_data
== NULL
600 || fstat (fileno (custom_data
), &st
) < 0)
602 fprintf (stderr
, "%s:%s: %s\n", program_name
, custom_file
,
608 custom_size
= st
.st_size
;
609 custom_section
= bfd_make_section (outbfd
, ".nlmcustom");
610 if (custom_section
== NULL
611 || ! bfd_set_section_size (outbfd
, custom_section
, custom_size
)
612 || ! bfd_set_section_flags (outbfd
, custom_section
,
614 bfd_fatal ("custom section");
617 if (help_file
!= NULL
)
619 help_data
= fopen (help_file
, "r");
620 if (help_data
== NULL
621 || fstat (fileno (help_data
), &st
) < 0)
623 fprintf (stderr
, "%s:%s: %s\n", program_name
, help_file
,
629 help_size
= st
.st_size
;
630 help_section
= bfd_make_section (outbfd
, ".nlmhelp");
631 if (help_section
== NULL
632 || ! bfd_set_section_size (outbfd
, help_section
, help_size
)
633 || ! bfd_set_section_flags (outbfd
, help_section
,
635 bfd_fatal ("help section");
636 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
639 if (message_file
!= NULL
)
641 message_data
= fopen (message_file
, "r");
642 if (message_data
== NULL
643 || fstat (fileno (message_data
), &st
) < 0)
645 fprintf (stderr
, "%s:%s: %s\n", program_name
, message_file
,
651 message_size
= st
.st_size
;
652 message_section
= bfd_make_section (outbfd
, ".nlmmessages");
653 if (message_section
== NULL
654 || ! bfd_set_section_size (outbfd
, message_section
, message_size
)
655 || ! bfd_set_section_flags (outbfd
, message_section
,
657 bfd_fatal ("message section");
658 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
663 struct string_list
*l
;
666 for (l
= modules
; l
!= NULL
; l
= l
->next
)
667 module_size
+= strlen (l
->string
) + 1;
668 module_section
= bfd_make_section (outbfd
, ".nlmmodules");
669 if (module_section
== NULL
670 || ! bfd_set_section_size (outbfd
, module_section
, module_size
)
671 || ! bfd_set_section_flags (outbfd
, module_section
,
673 bfd_fatal ("module section");
675 if (rpc_file
!= NULL
)
677 rpc_data
= fopen (rpc_file
, "r");
679 || fstat (fileno (rpc_data
), &st
) < 0)
681 fprintf (stderr
, "%s:%s: %s\n", program_name
, rpc_file
,
687 rpc_size
= st
.st_size
;
688 rpc_section
= bfd_make_section (outbfd
, ".nlmrpc");
689 if (rpc_section
== NULL
690 || ! bfd_set_section_size (outbfd
, rpc_section
, rpc_size
)
691 || ! bfd_set_section_flags (outbfd
, rpc_section
,
693 bfd_fatal ("rpc section");
694 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
697 if (sharelib_file
!= NULL
)
699 sharedbfd
= bfd_openr (sharelib_file
, output_format
);
700 if (sharedbfd
== NULL
701 || ! bfd_check_format (sharedbfd
, bfd_object
))
703 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
704 bfd_errmsg (bfd_error
));
705 sharelib_file
= NULL
;
709 sharedhdr
= *nlm_fixed_header (sharedbfd
);
710 bfd_close (sharedbfd
);
711 shared_data
= fopen (sharelib_file
, "r");
712 if (shared_data
== NULL
713 || (fstat (fileno (shared_data
), &st
) < 0))
715 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
717 sharelib_file
= NULL
;
721 /* If we were clever, we could just copy out the
722 sections of the shared library which we actually
723 need. However, we would have to figure out the sizes
724 of the external and public information, and that can
725 not be done without reading through them. */
726 if (sharedhdr
.uninitializedDataSize
> 0)
728 /* There is no place to record this information. */
730 "%s:%s: warning: shared libraries can not have uninitialized data\n",
731 program_name
, sharelib_file
);
733 shared_offset
= st
.st_size
;
734 if (shared_offset
> sharedhdr
.codeImageOffset
)
735 shared_offset
= sharedhdr
.codeImageOffset
;
736 if (shared_offset
> sharedhdr
.dataImageOffset
)
737 shared_offset
= sharedhdr
.dataImageOffset
;
738 if (shared_offset
> sharedhdr
.relocationFixupOffset
)
739 shared_offset
= sharedhdr
.relocationFixupOffset
;
740 if (shared_offset
> sharedhdr
.externalReferencesOffset
)
741 shared_offset
= sharedhdr
.externalReferencesOffset
;
742 if (shared_offset
> sharedhdr
.publicsOffset
)
743 shared_offset
= sharedhdr
.publicsOffset
;
744 shared_size
= st
.st_size
- shared_offset
;
745 shared_section
= bfd_make_section (outbfd
, ".nlmshared");
746 if (shared_section
== NULL
747 || ! bfd_set_section_size (outbfd
, shared_section
,
749 || ! bfd_set_section_flags (outbfd
, shared_section
,
751 bfd_fatal ("shared section");
752 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
757 /* Check whether a version was given. */
758 if (strncmp (version_hdr
->stamp
, "VeRsIoN#", 8) != 0)
759 fprintf (stderr
, "%s: warning: No version number given\n",
762 /* At least for now, always create an extended header, because that
763 is what NLMLINK does. */
764 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
766 /* If the date was not given, force it in. */
767 if (nlm_version_header (outbfd
)->month
== 0
768 && nlm_version_header (outbfd
)->day
== 0
769 && nlm_version_header (outbfd
)->year
== 0)
775 ptm
= localtime (&now
);
776 nlm_version_header (outbfd
)->month
= ptm
->tm_mon
+ 1;
777 nlm_version_header (outbfd
)->day
= ptm
->tm_mday
;
778 nlm_version_header (outbfd
)->year
= ptm
->tm_year
+ 1900;
779 strncpy (version_hdr
->stamp
, "VeRsIoN#", 8);
782 /* Copy over the sections. */
783 bfd_map_over_sections (inbfd
, copy_sections
, (PTR
) outbfd
);
785 /* Finish up the header information. */
786 if (custom_file
!= NULL
)
790 data
= xmalloc (custom_size
);
791 if (fread (data
, 1, custom_size
, custom_data
) != custom_size
)
792 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, custom_file
,
796 if (! bfd_set_section_contents (outbfd
, custom_section
, data
,
797 (file_ptr
) 0, custom_size
))
798 bfd_fatal ("custom section");
799 nlm_fixed_header (outbfd
)->customDataOffset
=
800 custom_section
->filepos
;
801 nlm_fixed_header (outbfd
)->customDataSize
= custom_size
;
807 /* As a special hack, the backend recognizes a debugInfoOffset
808 of -1 to mean that it should not output any debugging
809 information. This can not be handling by fiddling with the
810 symbol table because exported symbols appear in both the
811 export information and the debugging information. */
812 nlm_fixed_header (outbfd
)->debugInfoOffset
= (file_ptr
) -1;
814 if (map_file
!= NULL
)
816 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
818 if (help_file
!= NULL
)
822 data
= xmalloc (help_size
);
823 if (fread (data
, 1, help_size
, help_data
) != help_size
)
824 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, help_file
,
828 if (! bfd_set_section_contents (outbfd
, help_section
, data
,
829 (file_ptr
) 0, help_size
))
830 bfd_fatal ("help section");
831 nlm_extended_header (outbfd
)->helpFileOffset
=
832 help_section
->filepos
;
833 nlm_extended_header (outbfd
)->helpFileLength
= help_size
;
837 if (message_file
!= NULL
)
841 data
= xmalloc (message_size
);
842 if (fread (data
, 1, message_size
, message_data
) != message_size
)
843 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, message_file
,
847 if (! bfd_set_section_contents (outbfd
, message_section
, data
,
848 (file_ptr
) 0, message_size
))
849 bfd_fatal ("message section");
850 nlm_extended_header (outbfd
)->messageFileOffset
=
851 message_section
->filepos
;
852 nlm_extended_header (outbfd
)->messageFileLength
= message_size
;
854 /* FIXME: Are these offsets correct on all platforms? Are
855 they 32 bits on all platforms? What endianness? */
856 nlm_extended_header (outbfd
)->languageID
=
857 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 106);
858 nlm_extended_header (outbfd
)->messageCount
=
859 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 110);
867 struct string_list
*l
;
870 data
= xmalloc (module_size
);
872 set
= (unsigned char *) data
;
873 for (l
= modules
; l
!= NULL
; l
= l
->next
)
875 *set
= strlen (l
->string
);
876 strncpy (set
+ 1, l
->string
, *set
);
880 if (! bfd_set_section_contents (outbfd
, module_section
, data
,
881 (file_ptr
) 0, module_size
))
882 bfd_fatal ("module section");
883 nlm_fixed_header (outbfd
)->moduleDependencyOffset
=
884 module_section
->filepos
;
885 nlm_fixed_header (outbfd
)->numberOfModuleDependencies
= c
;
887 if (rpc_file
!= NULL
)
891 data
= xmalloc (rpc_size
);
892 if (fread (data
, 1, rpc_size
, rpc_data
) != rpc_size
)
893 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, rpc_file
,
897 if (! bfd_set_section_contents (outbfd
, rpc_section
, data
,
898 (file_ptr
) 0, rpc_size
))
899 bfd_fatal ("rpc section");
900 nlm_extended_header (outbfd
)->RPCDataOffset
=
901 rpc_section
->filepos
;
902 nlm_extended_header (outbfd
)->RPCDataLength
= rpc_size
;
906 if (sharelib_file
!= NULL
)
910 data
= xmalloc (shared_size
);
911 if (fseek (shared_data
, shared_offset
, SEEK_SET
) != 0
912 || fread (data
, 1, shared_size
, shared_data
) != shared_size
)
913 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, sharelib_file
,
917 if (! bfd_set_section_contents (outbfd
, shared_section
, data
,
918 (file_ptr
) 0, shared_size
))
919 bfd_fatal ("shared section");
921 nlm_extended_header (outbfd
)->sharedCodeOffset
=
922 sharedhdr
.codeImageOffset
- shared_offset
+ shared_section
->filepos
;
923 nlm_extended_header (outbfd
)->sharedCodeLength
=
924 sharedhdr
.codeImageSize
;
925 nlm_extended_header (outbfd
)->sharedDataOffset
=
926 sharedhdr
.dataImageOffset
- shared_offset
+ shared_section
->filepos
;
927 nlm_extended_header (outbfd
)->sharedDataLength
=
928 sharedhdr
.dataImageSize
;
929 nlm_extended_header (outbfd
)->sharedRelocationFixupOffset
=
930 (sharedhdr
.relocationFixupOffset
932 + shared_section
->filepos
);
933 nlm_extended_header (outbfd
)->sharedRelocationFixupCount
=
934 sharedhdr
.numberOfRelocationFixups
;
935 nlm_extended_header (outbfd
)->sharedExternalReferenceOffset
=
936 (sharedhdr
.externalReferencesOffset
938 + shared_section
->filepos
);
939 nlm_extended_header (outbfd
)->sharedExternalReferenceCount
=
940 sharedhdr
.numberOfExternalReferences
;
941 nlm_extended_header (outbfd
)->sharedPublicsOffset
=
942 sharedhdr
.publicsOffset
- shared_offset
+ shared_section
->filepos
;
943 nlm_extended_header (outbfd
)->sharedPublicsCount
=
944 sharedhdr
.numberOfPublics
;
945 nlm_extended_header (outbfd
)->sharedDebugRecordOffset
=
946 sharedhdr
.debugInfoOffset
- shared_offset
+ shared_section
->filepos
;
947 nlm_extended_header (outbfd
)->sharedDebugRecordCount
=
948 sharedhdr
.numberOfDebugRecords
;
949 nlm_extended_header (outbfd
)->SharedInitializationOffset
=
950 sharedhdr
.codeStartOffset
;
951 nlm_extended_header (outbfd
)->SharedExitProcedureOffset
=
952 sharedhdr
.exitProcedureOffset
;
955 len
= strlen (output_file
);
956 if (len
> NLM_MODULE_NAME_SIZE
- 2)
957 len
= NLM_MODULE_NAME_SIZE
- 2;
958 nlm_fixed_header (outbfd
)->moduleName
[0] = len
;
960 strncpy (nlm_fixed_header (outbfd
)->moduleName
+ 1, output_file
,
961 NLM_MODULE_NAME_SIZE
- 2);
962 nlm_fixed_header (outbfd
)->moduleName
[NLM_MODULE_NAME_SIZE
- 1] = '\0';
963 for (modname
= nlm_fixed_header (outbfd
)->moduleName
;
966 if (islower (*modname
))
967 *modname
= toupper (*modname
);
969 strncpy (nlm_variable_header (outbfd
)->oldThreadName
, " LONG",
970 NLM_OLD_THREAD_NAME_LENGTH
);
972 if (! bfd_close (outbfd
))
973 bfd_fatal (output_file
);
974 if (! bfd_close (inbfd
))
975 bfd_fatal (input_file
);
977 if (unlink_on_exit
!= NULL
)
978 unlink (unlink_on_exit
);
983 /* Display a help message and exit. */
988 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
990 show_usage (stdout
, 0);
993 /* Show a usage message and exit. */
996 show_usage (file
, status
)
1001 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1002 [--input-target=bfdname] [--output-target=bfdname]\n\
1003 [--header-file=file] [--linker=linker] [--debug]\n\
1004 [--help] [--version]\n\
1005 [in-file [out-file]]\n",
1010 /* Select the output format based on the input architecture, machine,
1011 and endianness. This chooses the appropriate NLM target. */
1014 select_output_format (arch
, mach
, bigendian
)
1015 enum bfd_architecture arch
;
1022 return "nlm32-i386";
1023 case bfd_arch_sparc
:
1024 return "nlm32-sparc";
1025 case bfd_arch_alpha
:
1026 return "nlm32-alpha";
1028 fprintf (stderr
, "%s: no default NLM format for %s\n",
1029 program_name
, bfd_printable_arch_mach (arch
, mach
));
1031 /* Avoid warning. */
1037 /* The BFD sections are copied in two passes. This function selects
1038 the output section for each input section, and sets up the section
1042 setup_sections (inbfd
, insec
, data_ptr
)
1047 bfd
*outbfd
= (bfd
*) data_ptr
;
1049 const char *outname
;
1052 bfd_size_type align
;
1055 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1056 file. However, I don't have a good way to describe this section.
1057 We do want to copy the section when using objcopy. */
1058 if (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
1059 && strcmp (bfd_section_name (inbfd
, insec
), ".reginfo") == 0)
1062 f
= bfd_get_section_flags (inbfd
, insec
);
1064 outname
= NLM_CODE_NAME
;
1065 else if ((f
& SEC_LOAD
) && (f
& SEC_HAS_CONTENTS
))
1066 outname
= NLM_INITIALIZED_DATA_NAME
;
1067 else if (f
& SEC_ALLOC
)
1068 outname
= NLM_UNINITIALIZED_DATA_NAME
;
1070 outname
= bfd_section_name (inbfd
, insec
);
1072 outsec
= bfd_get_section_by_name (outbfd
, outname
);
1075 outsec
= bfd_make_section (outbfd
, outname
);
1077 bfd_fatal ("make section");
1080 insec
->output_section
= outsec
;
1082 offset
= bfd_section_size (outbfd
, outsec
);
1083 align
= 1 << bfd_section_alignment (inbfd
, insec
);
1084 add
= ((offset
+ align
- 1) &~ (align
- 1)) - offset
;
1085 insec
->output_offset
= offset
+ add
;
1087 if (! bfd_set_section_size (outbfd
, outsec
,
1088 (bfd_section_size (outbfd
, outsec
)
1089 + bfd_section_size (inbfd
, insec
)
1091 bfd_fatal ("set section size");
1093 if ((bfd_section_alignment (inbfd
, insec
)
1094 > bfd_section_alignment (outbfd
, outsec
))
1095 && ! bfd_set_section_alignment (outbfd
, outsec
,
1096 bfd_section_alignment (inbfd
, insec
)))
1097 bfd_fatal ("set section alignment");
1099 if (! bfd_set_section_flags (outbfd
, outsec
, f
))
1100 bfd_fatal ("set section flags");
1102 bfd_set_reloc (outbfd
, outsec
, (arelent
**) NULL
, 0);
1105 /* Copy the section contents. */
1108 copy_sections (inbfd
, insec
, data_ptr
)
1113 bfd
*outbfd
= (bfd
*) data_ptr
;
1117 bfd_size_type reloc_size
;
1119 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1120 file. However, I don't have a good way to describe this section.
1121 We do want to copy the section when using objcopy. */
1122 if (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
1123 && strcmp (bfd_section_name (inbfd
, insec
), ".reginfo") == 0)
1126 outsec
= insec
->output_section
;
1127 assert (outsec
!= NULL
);
1129 size
= bfd_get_section_size_before_reloc (insec
);
1133 /* FIXME: Why are these necessary? */
1134 insec
->_cooked_size
= insec
->_raw_size
;
1135 insec
->reloc_done
= true;
1137 if ((bfd_get_section_flags (inbfd
, insec
) & SEC_HAS_CONTENTS
) == 0)
1141 contents
= xmalloc (size
);
1142 if (! bfd_get_section_contents (inbfd
, insec
, contents
,
1143 (file_ptr
) 0, size
))
1144 bfd_fatal (bfd_get_filename (inbfd
));
1147 reloc_size
= bfd_get_reloc_upper_bound (inbfd
, insec
);
1148 if (reloc_size
!= 0)
1151 bfd_size_type reloc_count
;
1153 relocs
= (arelent
**) xmalloc (reloc_size
);
1154 reloc_count
= bfd_canonicalize_reloc (inbfd
, insec
, relocs
, symbols
);
1155 mangle_relocs (outbfd
, insec
, &relocs
, &reloc_count
, (char *) contents
,
1158 /* FIXME: refers to internal BFD fields. */
1159 if (outsec
->orelocation
!= (arelent
**) NULL
)
1161 bfd_size_type total_count
;
1164 total_count
= reloc_count
+ outsec
->reloc_count
;
1165 combined
= (arelent
**) xmalloc (total_count
* sizeof (arelent
));
1166 memcpy (combined
, outsec
->orelocation
,
1167 outsec
->reloc_count
* sizeof (arelent
));
1168 memcpy (combined
+ outsec
->reloc_count
, relocs
,
1169 (size_t) (reloc_count
* sizeof (arelent
)));
1170 free (outsec
->orelocation
);
1171 reloc_count
= total_count
;
1175 bfd_set_reloc (outbfd
, outsec
, relocs
, reloc_count
);
1178 if (contents
!= NULL
)
1180 if (! bfd_set_section_contents (outbfd
, outsec
, contents
,
1181 insec
->output_offset
, size
))
1182 bfd_fatal (bfd_get_filename (outbfd
));
1187 /* Some, perhaps all, NetWare targets require changing the relocs used
1188 by the input formats. */
1191 mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1195 arelent
***relocs_ptr
;
1196 bfd_size_type
*reloc_count_ptr
;
1198 bfd_size_type contents_size
;
1200 switch (bfd_get_arch (outbfd
))
1203 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1204 contents
, contents_size
);
1206 case bfd_arch_alpha
:
1207 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1208 contents
, contents_size
);
1211 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1212 contents
, contents_size
);
1217 /* By default all we need to do for relocs is change the address by
1218 the output_offset. */
1222 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1226 arelent
***relocs_ptr
;
1227 bfd_size_type
*reloc_count_ptr
;
1229 bfd_size_type contents_size
;
1231 if (insec
->output_offset
!= 0)
1233 bfd_size_type reloc_count
;
1234 register arelent
**relocs
;
1235 register bfd_size_type i
;
1237 reloc_count
= *reloc_count_ptr
;
1238 relocs
= *relocs_ptr
;
1239 for (i
= 0; i
< reloc_count
; i
++, relocs
++)
1240 (*relocs
)->address
+= insec
->output_offset
;
1244 /* NetWare on the i386 supports a restricted set of relocs, which are
1245 different from those used on other i386 targets. This routine
1246 converts the relocs. It is, obviously, very target dependent. At
1247 the moment, the nlm32-i386 backend performs similar translations;
1248 however, it is more reliable and efficient to do them here. */
1250 static reloc_howto_type nlm_i386_pcrel_howto
=
1251 HOWTO (1, /* type */
1253 2, /* size (0 = byte, 1 = short, 2 = long) */
1255 true, /* pc_relative */
1257 complain_overflow_signed
, /* complain_on_overflow */
1258 0, /* special_function */
1259 "DISP32", /* name */
1260 true, /* partial_inplace */
1261 0xffffffff, /* src_mask */
1262 0xffffffff, /* dst_mask */
1263 true); /* pcrel_offset */
1266 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1270 arelent
***relocs_ptr
;
1271 bfd_size_type
*reloc_count_ptr
;
1273 bfd_size_type contents_size
;
1275 bfd_size_type reloc_count
, i
;
1278 reloc_count
= *reloc_count_ptr
;
1279 relocs
= *relocs_ptr
;
1280 for (i
= 0; i
< reloc_count
; i
++)
1284 bfd_size_type address
;
1288 sym
= *rel
->sym_ptr_ptr
;
1290 /* We're moving the relocs from the input section to the output
1291 section, so we must adjust the address accordingly. */
1292 address
= rel
->address
;
1293 rel
->address
+= insec
->output_offset
;
1295 /* Note that no serious harm will ensue if we fail to change a
1296 reloc. The backend will fail when writing out the reloc. */
1298 /* Make sure this reloc is within the data we have. We use only
1299 4 byte relocs here, so we insist on having 4 bytes. */
1300 if (address
+ 4 > contents_size
)
1303 /* A PC relative reloc entirely within a single section is
1304 completely unnecessary. This can be generated by ld -r. */
1305 if (sym
== insec
->symbol
1306 && rel
->howto
!= NULL
1307 && rel
->howto
->pc_relative
1308 && ! rel
->howto
->pcrel_offset
)
1312 memmove (relocs
, relocs
+ 1,
1313 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1317 /* Get the amount the relocation will add in. */
1318 addend
= rel
->addend
+ sym
->value
;
1320 /* NetWare doesn't support PC relative relocs against defined
1321 symbols, so we have to eliminate them by doing the relocation
1322 now. We can only do this if the reloc is within a single
1324 if (rel
->howto
!= NULL
1325 && rel
->howto
->pc_relative
1326 && bfd_get_section (sym
) == insec
->output_section
)
1330 if (rel
->howto
->pcrel_offset
)
1333 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1335 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1339 memmove (relocs
, relocs
+ 1,
1340 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1344 /* NetWare doesn't support reloc addends, so we get rid of them
1345 here by simply adding them into the object data. We handle
1346 the symbol value, if any, the same way. */
1348 && rel
->howto
!= NULL
1349 && rel
->howto
->rightshift
== 0
1350 && rel
->howto
->size
== 2
1351 && rel
->howto
->bitsize
== 32
1352 && rel
->howto
->bitpos
== 0
1353 && rel
->howto
->src_mask
== 0xffffffff
1354 && rel
->howto
->dst_mask
== 0xffffffff)
1358 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1360 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1362 /* Adjust the reloc for the changes we just made. */
1364 if (bfd_get_section (sym
) != &bfd_und_section
)
1365 rel
->sym_ptr_ptr
= bfd_get_section (sym
)->symbol_ptr_ptr
;
1368 /* NetWare uses a reloc with pcrel_offset set. We adjust
1369 pc_relative relocs accordingly. We are going to change the
1370 howto field, so we can only do this if the current one is
1371 compatible. We should check that special_function is NULL
1372 here, but at the moment coff-i386 uses a special_function
1373 which does not affect what we are doing here. */
1374 if (rel
->howto
!= NULL
1375 && rel
->howto
->pc_relative
1376 && ! rel
->howto
->pcrel_offset
1377 && rel
->howto
->rightshift
== 0
1378 && rel
->howto
->size
== 2
1379 && rel
->howto
->bitsize
== 32
1380 && rel
->howto
->bitpos
== 0
1381 && rel
->howto
->src_mask
== 0xffffffff
1382 && rel
->howto
->dst_mask
== 0xffffffff)
1386 /* When pcrel_offset is not set, it means that the negative
1387 of the address of the memory location is stored in the
1388 memory location. We must add it back in. */
1389 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1391 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1393 /* We must change to a new howto. */
1394 rel
->howto
= &nlm_i386_pcrel_howto
;
1399 /* On the Alpha the first reloc for every section must be a special
1400 relocs which hold the GP address. Also, the first reloc in the
1401 file must be a special reloc which holds the address of the .lita
1404 static reloc_howto_type nlm32_alpha_nw_howto
=
1405 HOWTO (ALPHA_R_NW_RELOC
, /* type */
1407 0, /* size (0 = byte, 1 = short, 2 = long) */
1409 false, /* pc_relative */
1411 complain_overflow_dont
, /* complain_on_overflow */
1412 0, /* special_function */
1413 "NW_RELOC", /* name */
1414 false, /* partial_inplace */
1417 false); /* pcrel_offset */
1421 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1425 register arelent
***relocs_ptr
;
1426 bfd_size_type
*reloc_count_ptr
;
1428 bfd_size_type contents_size
;
1430 bfd_size_type old_reloc_count
;
1431 arelent
**old_relocs
;
1432 register arelent
**relocs
;
1434 old_reloc_count
= *reloc_count_ptr
;
1435 old_relocs
= *relocs_ptr
;
1436 relocs
= (arelent
**) xmalloc ((old_reloc_count
+ 3) * sizeof (arelent
*));
1437 *relocs_ptr
= relocs
;
1439 if (nlm_alpha_backend_data (outbfd
)->lita_address
== 0)
1442 asection
*lita_section
;
1444 inbfd
= insec
->owner
;
1445 lita_section
= bfd_get_section_by_name (inbfd
, _LITA
);
1446 if (lita_section
!= (asection
*) NULL
)
1448 nlm_alpha_backend_data (outbfd
)->lita_address
=
1449 bfd_get_section_vma (inbfd
, lita_section
);
1450 nlm_alpha_backend_data (outbfd
)->lita_size
=
1451 bfd_section_size (inbfd
, lita_section
);
1455 /* Avoid outputting this reloc again. */
1456 nlm_alpha_backend_data (outbfd
)->lita_address
= 4;
1459 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1460 (*relocs
)->sym_ptr_ptr
= bfd_abs_section
.symbol_ptr_ptr
;
1461 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->lita_address
;
1462 (*relocs
)->addend
= nlm_alpha_backend_data (outbfd
)->lita_size
+ 1;
1463 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1465 ++(*reloc_count_ptr
);
1468 /* Get the GP value from bfd. It is in the .reginfo section. */
1469 if (nlm_alpha_backend_data (outbfd
)->gp
== 0)
1472 asection
*reginfo_sec
;
1473 struct ecoff_reginfo sreginfo
;
1475 inbfd
= insec
->owner
;
1476 assert (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
);
1477 reginfo_sec
= bfd_get_section_by_name (inbfd
, REGINFO
);
1478 if (reginfo_sec
!= (asection
*) NULL
1479 && bfd_get_section_contents (inbfd
, reginfo_sec
,
1480 (PTR
) &sreginfo
, (file_ptr
) 0,
1481 sizeof sreginfo
) != false)
1482 nlm_alpha_backend_data (outbfd
)->gp
= sreginfo
.gp_value
;
1485 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1486 (*relocs
)->sym_ptr_ptr
= bfd_abs_section
.symbol_ptr_ptr
;
1487 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->gp
;
1488 (*relocs
)->addend
= 0;
1489 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1491 ++(*reloc_count_ptr
);
1493 memcpy ((PTR
) relocs
, (PTR
) old_relocs
,
1494 (size_t) old_reloc_count
* sizeof (arelent
*));
1495 relocs
[old_reloc_count
] = (arelent
*) NULL
;
1499 if (insec
->output_offset
!= 0)
1501 register bfd_size_type i
;
1503 for (i
= 0; i
< old_reloc_count
; i
++, relocs
++)
1504 (*relocs
)->address
+= insec
->output_offset
;
1508 /* Name of linker. */
1510 #define LD_NAME "ld"
1513 /* Temporary file name base. */
1514 static char *temp_filename
;
1516 /* The user has specified several input files. Invoke the linker to
1517 link them all together, and convert and delete the resulting output
1521 link_inputs (inputs
, ld
)
1522 struct string_list
*inputs
;
1526 struct string_list
*q
;
1533 for (q
= inputs
; q
!= NULL
; q
= q
->next
)
1536 argv
= (char **) alloca (c
+ 5);
1543 /* Find the linker to invoke based on how nlmconv was run. */
1544 p
= program_name
+ strlen (program_name
);
1545 while (p
!= program_name
)
1549 ld
= (char *) xmalloc (p
- program_name
+ strlen (LD_NAME
) + 1);
1550 memcpy (ld
, program_name
, p
- program_name
);
1551 strcpy (ld
+ (p
- program_name
), LD_NAME
);
1560 ld
= (char *) LD_NAME
;
1562 choose_temp_base ();
1564 unlink_on_exit
= xmalloc (strlen (temp_filename
) + 3);
1565 sprintf (unlink_on_exit
, "%s.O", temp_filename
);
1568 argv
[1] = (char *) "-r";
1569 argv
[2] = (char *) "-o";
1570 argv
[3] = unlink_on_exit
;
1572 for (q
= inputs
; q
!= NULL
; q
= q
->next
, i
++)
1573 argv
[i
] = q
->string
;
1578 for (i
= 0; argv
[i
] != NULL
; i
++)
1579 fprintf (stderr
, " %s", argv
[i
]);
1580 fprintf (stderr
, "\n");
1583 pid
= pexecute (ld
, argv
);
1585 if (waitpid (pid
, &status
, 0) < 0)
1588 unlink (unlink_on_exit
);
1594 fprintf (stderr
, "%s: Execution of %s failed\n", program_name
, ld
);
1595 unlink (unlink_on_exit
);
1599 return unlink_on_exit
;
1602 /* Choose a temporary file name. Stolen from gcc.c. */
1605 choose_temp_base_try (try, base
)
1613 else if (try == NULL
)
1615 else if (access (try, R_OK
| W_OK
) != 0)
1625 const char *base
= NULL
;
1628 base
= choose_temp_base_try (getenv ("TMPDIR"), base
);
1629 base
= choose_temp_base_try (getenv ("TMP"), base
);
1630 base
= choose_temp_base_try (getenv ("TEMP"), base
);
1633 base
= choose_temp_base_try (P_tmpdir
, base
);
1636 base
= choose_temp_base_try ("/usr/tmp", base
);
1637 base
= choose_temp_base_try ("/tmp", base
);
1639 /* If all else fails, use the current directory! */
1643 len
= strlen (base
);
1644 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX") + 1);
1645 strcpy (temp_filename
, base
);
1646 if (len
> 0 && temp_filename
[len
-1] != '/')
1647 temp_filename
[len
++] = '/';
1648 strcpy (temp_filename
+ len
, "ccXXXXXX");
1650 mktemp (temp_filename
);
1651 if (*temp_filename
== '\0')
1655 /* Execute a job. Stolen from gcc.c. */
1661 pexecute (program
, argv
)
1669 scmd
= (char *)malloc (strlen (program
) + strlen (temp_filename
) + 10);
1670 rf
= scmd
+ strlen(program
) + 2 + el
;
1671 sprintf (scmd
, "%s.exe @%s.gp", program
, temp_filename
);
1672 argfile
= fopen (rf
, "w");
1674 pfatal_with_name (rf
);
1676 for (i
=1; argv
[i
]; i
++)
1679 for (cp
= argv
[i
]; *cp
; cp
++)
1681 if (*cp
== '"' || *cp
== '\'' || *cp
== '\\' || isspace (*cp
))
1682 fputc ('\\', argfile
);
1683 fputc (*cp
, argfile
);
1685 fputc ('\n', argfile
);
1696 return MIN_FATAL_STATUS
<< 8;
1702 #else /* not __MSDOS__ */
1705 pexecute (program
, argv
)
1710 int retries
, sleep_interval
;
1712 /* Fork a subprocess; wait and retry if it fails. */
1714 for (retries
= 0; retries
< 4; retries
++)
1719 sleep (sleep_interval
);
1720 sleep_interval
*= 2;
1736 /* Exec the program. */
1737 execvp (program
, argv
);
1744 /* Return child's process number. */
1749 #endif /* not __MSDOS__ */
1753 pexecute (program
, argv
)
1757 return spawnvp (1, program
, argv
);
1759 #endif /* not OS2 */