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
;
176 program_name
= argv
[0];
180 while ((opt
= getopt_long (argc
, argv
, "dhI:l:O:T:V", long_options
,
193 input_format
= optarg
;
199 output_format
= optarg
;
202 header_file
= optarg
;
205 printf ("GNU %s version %s\n", program_name
, program_version
);
211 show_usage (stderr
, 1);
216 /* The input and output files may be named on the command line. */
220 input_file
= argv
[optind
];
224 output_file
= argv
[optind
];
227 show_usage (stderr
, 1);
228 if (strcmp (input_file
, output_file
) == 0)
231 "%s: input and output files must be different\n",
238 /* Initialize the header information to default values. */
239 fixed_hdr
= &fixed_hdr_struct
;
240 memset ((PTR
) &fixed_hdr_struct
, 0, sizeof fixed_hdr_struct
);
241 var_hdr
= &var_hdr_struct
;
242 memset ((PTR
) &var_hdr_struct
, 0, sizeof var_hdr_struct
);
243 version_hdr
= &version_hdr_struct
;
244 memset ((PTR
) &version_hdr_struct
, 0, sizeof version_hdr_struct
);
245 copyright_hdr
= ©right_hdr_struct
;
246 memset ((PTR
) ©right_hdr_struct
, 0, sizeof copyright_hdr_struct
);
247 extended_hdr
= &extended_hdr_struct
;
248 memset ((PTR
) &extended_hdr_struct
, 0, sizeof extended_hdr_struct
);
249 check_procedure
= NULL
;
252 exit_procedure
= "_Stop";
253 export_symbols
= NULL
;
257 import_symbols
= NULL
;
260 sharelib_file
= NULL
;
261 start_procedure
= "_Prelude";
267 /* Parse the header file (if there is one). */
268 if (header_file
!= NULL
)
270 if (! nlmlex_file (header_file
)
272 || parse_errors
!= 0)
276 if (input_files
!= NULL
)
278 if (input_file
!= NULL
)
281 "%s: input file named both on command line and with INPUT\n",
285 if (input_files
->next
== NULL
)
286 input_file
= input_files
->string
;
288 input_file
= link_inputs (input_files
, ld_arg
);
290 else if (input_file
== NULL
)
292 fprintf (stderr
, "%s: no input file\n", program_name
);
293 show_usage (stderr
, 1);
296 inbfd
= bfd_openr (input_file
, input_format
);
298 bfd_fatal (input_file
);
300 if (! bfd_check_format_matches (inbfd
, bfd_object
, &matching
))
302 bfd_nonfatal (input_file
);
303 if (bfd_error
== file_ambiguously_recognized
)
305 list_matching_formats (matching
);
311 if (output_format
== NULL
)
312 output_format
= select_output_format (bfd_get_arch (inbfd
),
313 bfd_get_mach (inbfd
),
314 inbfd
->xvec
->byteorder_big_p
);
316 assert (output_format
!= NULL
);
318 /* Use the output file named on the command line if it exists.
319 Otherwise use the file named in the OUTPUT statement. */
320 if (output_file
== NULL
)
322 fprintf (stderr
, "%s: no name for output file\n",
324 show_usage (stderr
, 1);
327 outbfd
= bfd_openw (output_file
, output_format
);
329 bfd_fatal (output_file
);
330 if (! bfd_set_format (outbfd
, bfd_object
))
331 bfd_fatal (output_file
);
333 assert (bfd_get_flavour (outbfd
) == bfd_target_nlm_flavour
);
335 if (bfd_arch_get_compatible (inbfd
, outbfd
) == NULL
)
337 "%s: warning:input and output formats are not compatible\n",
340 /* Move the values read from the command file into outbfd. */
341 *nlm_fixed_header (outbfd
) = fixed_hdr_struct
;
342 *nlm_variable_header (outbfd
) = var_hdr_struct
;
343 *nlm_version_header (outbfd
) = version_hdr_struct
;
344 *nlm_copyright_header (outbfd
) = copyright_hdr_struct
;
345 *nlm_extended_header (outbfd
) = extended_hdr_struct
;
347 /* Start copying the input BFD to the output BFD. */
348 if (! bfd_set_file_flags (outbfd
, bfd_get_file_flags (inbfd
)))
349 bfd_fatal (bfd_get_filename (outbfd
));
351 symbols
= (asymbol
**) xmalloc (get_symtab_upper_bound (inbfd
));
352 symcount
= bfd_canonicalize_symtab (inbfd
, symbols
);
354 /* Make sure we have a .bss section. */
355 bss_sec
= bfd_get_section_by_name (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
358 bss_sec
= bfd_make_section (outbfd
, NLM_UNINITIALIZED_DATA_NAME
);
360 || ! bfd_set_section_flags (outbfd
, bss_sec
, SEC_ALLOC
)
361 || ! bfd_set_section_alignment (outbfd
, bss_sec
, 1))
362 bfd_fatal ("make .bss section");
365 /* Set up the sections. */
366 bfd_map_over_sections (inbfd
, setup_sections
, (PTR
) outbfd
);
368 /* The .bss section immediately follows the .data section. */
369 data_sec
= bfd_get_section_by_name (outbfd
, NLM_INITIALIZED_DATA_NAME
);
370 if (data_sec
!= NULL
)
374 vma
= bfd_get_section_size_before_reloc (data_sec
);
375 align
= 1 << bss_sec
->alignment_power
;
376 add
= ((vma
+ align
- 1) &~ (align
- 1)) - vma
;
378 if (! bfd_set_section_vma (outbfd
, bss_sec
, vma
))
379 bfd_fatal ("set .bss vma");
382 bfd_size_type data_size
;
384 data_size
= bfd_get_section_size_before_reloc (data_sec
);
385 if (! bfd_set_section_size (outbfd
, data_sec
, data_size
+ add
))
386 bfd_fatal ("set .data size");
390 /* Adjust symbol information. */
391 inlead
= bfd_get_symbol_leading_char (inbfd
);
392 outlead
= bfd_get_symbol_leading_char (outbfd
);
397 newsyms
= (asymbol
**) xmalloc (newsymalloc
* sizeof (asymbol
*));
400 for (i
= 0; i
< symcount
; i
++)
402 register asymbol
*sym
;
406 /* Add or remove a leading underscore. */
407 if (inlead
!= outlead
)
411 if (bfd_asymbol_name (sym
)[0] == inlead
)
419 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 1);
421 strcpy (new + 1, bfd_asymbol_name (sym
) + 1);
430 new = xmalloc (strlen (bfd_asymbol_name (sym
)) + 2);
432 strcpy (new + 1, bfd_asymbol_name (sym
));
437 /* NLM's have an uninitialized data section, but they do not
438 have a common section in the Unix sense. Move all common
439 symbols into the .bss section, and mark them as exported. */
440 if (bfd_is_com_section (bfd_get_section (sym
)))
444 sym
->section
= bss_sec
;
446 sym
->value
= bss_sec
->_raw_size
;
447 bss_sec
->_raw_size
+= size
;
448 align
= 1 << bss_sec
->alignment_power
;
449 bss_sec
->_raw_size
= (bss_sec
->_raw_size
+ align
- 1) &~ (align
- 1);
450 sym
->flags
|= BSF_EXPORT
| BSF_GLOBAL
;
452 else if (bfd_get_section (sym
)->output_section
!= NULL
)
454 /* Move the symbol into the output section. */
455 sym
->value
+= bfd_get_section (sym
)->output_offset
;
456 sym
->section
= bfd_get_section (sym
)->output_section
;
457 /* This is no longer a section symbol. */
458 sym
->flags
&=~ BSF_SECTION_SYM
;
461 /* Force _edata and _end to be defined. This would normally be
462 done by the linker, but the manipulation of the common
463 symbols will confuse it. */
464 if (bfd_asymbol_name (sym
)[0] == '_'
465 && bfd_get_section (sym
) == &bfd_und_section
)
467 if (strcmp (bfd_asymbol_name (sym
), "_edata") == 0)
469 sym
->section
= bss_sec
;
472 if (strcmp (bfd_asymbol_name (sym
), "_end") == 0)
474 sym
->section
= bss_sec
;
479 /* If this is a global symbol, check the export list. */
480 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) != 0)
482 register struct string_list
*l
;
485 /* Unfortunately, a symbol can appear multiple times on the
486 export list, with and without prefixes. */
488 for (l
= export_symbols
; l
!= NULL
; l
= l
->next
)
490 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
496 zbase
= strchr (l
->string
, '@');
498 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
500 /* We must add a symbol with this prefix. */
501 if (newsymcount
>= newsymalloc
)
504 newsyms
= ((asymbol
**)
505 xrealloc ((PTR
) newsyms
,
507 * sizeof (asymbol
*))));
509 newsyms
[newsymcount
] =
510 (asymbol
*) xmalloc (sizeof (asymbol
));
511 *newsyms
[newsymcount
] = *sym
;
512 newsyms
[newsymcount
]->name
= l
->string
;
519 /* The unmodified symbol is actually not exported at
521 sym
->flags
&=~ (BSF_GLOBAL
| BSF_EXPORT
);
522 sym
->flags
|= BSF_LOCAL
;
526 /* If it's an undefined symbol, see if it's on the import list.
527 Change the prefix if necessary. */
528 if (bfd_get_section (sym
) == &bfd_und_section
)
530 register struct string_list
*l
;
532 for (l
= import_symbols
; l
!= NULL
; l
= l
->next
)
534 if (strcmp (l
->string
, bfd_asymbol_name (sym
)) == 0)
540 zbase
= strchr (l
->string
, '@');
542 && strcmp (zbase
+ 1, bfd_asymbol_name (sym
)) == 0)
544 sym
->name
= l
->string
;
551 "%s: warning: symbol %s imported but not in import list\n",
552 program_name
, bfd_asymbol_name (sym
));
555 /* See if it's one of the special named symbols. */
556 if (strcmp (bfd_asymbol_name (sym
), start_procedure
) == 0)
558 if (! bfd_set_start_address (outbfd
, bfd_asymbol_value (sym
)))
559 bfd_fatal ("set start address");
562 if (strcmp (bfd_asymbol_name (sym
), exit_procedure
) == 0)
564 nlm_fixed_header (outbfd
)->exitProcedureOffset
=
565 bfd_asymbol_value (sym
);
568 if (check_procedure
!= NULL
569 && strcmp (bfd_asymbol_name (sym
), check_procedure
) == 0)
571 nlm_fixed_header (outbfd
)->checkUnloadProcedureOffset
=
572 bfd_asymbol_value (sym
);
578 endsym
->value
= bfd_get_section_size_before_reloc (bss_sec
);
580 if (newsymcount
== 0)
584 outsyms
= (asymbol
**) xmalloc ((symcount
+ newsymcount
+ 1)
585 * sizeof (asymbol
*));
586 memcpy (outsyms
, symbols
, symcount
* sizeof (asymbol
*));
587 memcpy (outsyms
+ symcount
, newsyms
, newsymcount
* sizeof (asymbol
*));
588 outsyms
[symcount
+ newsymcount
] = NULL
;
591 bfd_set_symtab (outbfd
, outsyms
, symcount
+ newsymcount
);
594 fprintf (stderr
, "%s: warning: START procedure %s not defined\n",
595 program_name
, start_procedure
);
597 fprintf (stderr
, "%s: warning: EXIT procedure %s not defined\n",
598 program_name
, exit_procedure
);
599 if (check_procedure
!= NULL
601 fprintf (stderr
, "%s: warning: CHECK procedure %s not defined\n",
602 program_name
, check_procedure
);
604 /* Add additional sections required for the header information. */
605 if (custom_file
!= NULL
)
607 custom_data
= fopen (custom_file
, "r");
608 if (custom_data
== NULL
609 || fstat (fileno (custom_data
), &st
) < 0)
611 fprintf (stderr
, "%s:%s: %s\n", program_name
, custom_file
,
617 custom_size
= st
.st_size
;
618 custom_section
= bfd_make_section (outbfd
, ".nlmcustom");
619 if (custom_section
== NULL
620 || ! bfd_set_section_size (outbfd
, custom_section
, custom_size
)
621 || ! bfd_set_section_flags (outbfd
, custom_section
,
623 bfd_fatal ("custom section");
626 if (help_file
!= NULL
)
628 help_data
= fopen (help_file
, "r");
629 if (help_data
== NULL
630 || fstat (fileno (help_data
), &st
) < 0)
632 fprintf (stderr
, "%s:%s: %s\n", program_name
, help_file
,
638 help_size
= st
.st_size
;
639 help_section
= bfd_make_section (outbfd
, ".nlmhelp");
640 if (help_section
== NULL
641 || ! bfd_set_section_size (outbfd
, help_section
, help_size
)
642 || ! bfd_set_section_flags (outbfd
, help_section
,
644 bfd_fatal ("help section");
645 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
648 if (message_file
!= NULL
)
650 message_data
= fopen (message_file
, "r");
651 if (message_data
== NULL
652 || fstat (fileno (message_data
), &st
) < 0)
654 fprintf (stderr
, "%s:%s: %s\n", program_name
, message_file
,
660 message_size
= st
.st_size
;
661 message_section
= bfd_make_section (outbfd
, ".nlmmessages");
662 if (message_section
== NULL
663 || ! bfd_set_section_size (outbfd
, message_section
, message_size
)
664 || ! bfd_set_section_flags (outbfd
, message_section
,
666 bfd_fatal ("message section");
667 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
672 struct string_list
*l
;
675 for (l
= modules
; l
!= NULL
; l
= l
->next
)
676 module_size
+= strlen (l
->string
) + 1;
677 module_section
= bfd_make_section (outbfd
, ".nlmmodules");
678 if (module_section
== NULL
679 || ! bfd_set_section_size (outbfd
, module_section
, module_size
)
680 || ! bfd_set_section_flags (outbfd
, module_section
,
682 bfd_fatal ("module section");
684 if (rpc_file
!= NULL
)
686 rpc_data
= fopen (rpc_file
, "r");
688 || fstat (fileno (rpc_data
), &st
) < 0)
690 fprintf (stderr
, "%s:%s: %s\n", program_name
, rpc_file
,
696 rpc_size
= st
.st_size
;
697 rpc_section
= bfd_make_section (outbfd
, ".nlmrpc");
698 if (rpc_section
== NULL
699 || ! bfd_set_section_size (outbfd
, rpc_section
, rpc_size
)
700 || ! bfd_set_section_flags (outbfd
, rpc_section
,
702 bfd_fatal ("rpc section");
703 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
706 if (sharelib_file
!= NULL
)
708 sharedbfd
= bfd_openr (sharelib_file
, output_format
);
709 if (sharedbfd
== NULL
710 || ! bfd_check_format (sharedbfd
, bfd_object
))
712 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
713 bfd_errmsg (bfd_error
));
714 sharelib_file
= NULL
;
718 sharedhdr
= *nlm_fixed_header (sharedbfd
);
719 bfd_close (sharedbfd
);
720 shared_data
= fopen (sharelib_file
, "r");
721 if (shared_data
== NULL
722 || (fstat (fileno (shared_data
), &st
) < 0))
724 fprintf (stderr
, "%s:%s: %s\n", program_name
, sharelib_file
,
726 sharelib_file
= NULL
;
730 /* If we were clever, we could just copy out the
731 sections of the shared library which we actually
732 need. However, we would have to figure out the sizes
733 of the external and public information, and that can
734 not be done without reading through them. */
735 if (sharedhdr
.uninitializedDataSize
> 0)
737 /* There is no place to record this information. */
739 "%s:%s: warning: shared libraries can not have uninitialized data\n",
740 program_name
, sharelib_file
);
742 shared_offset
= st
.st_size
;
743 if (shared_offset
> sharedhdr
.codeImageOffset
)
744 shared_offset
= sharedhdr
.codeImageOffset
;
745 if (shared_offset
> sharedhdr
.dataImageOffset
)
746 shared_offset
= sharedhdr
.dataImageOffset
;
747 if (shared_offset
> sharedhdr
.relocationFixupOffset
)
748 shared_offset
= sharedhdr
.relocationFixupOffset
;
749 if (shared_offset
> sharedhdr
.externalReferencesOffset
)
750 shared_offset
= sharedhdr
.externalReferencesOffset
;
751 if (shared_offset
> sharedhdr
.publicsOffset
)
752 shared_offset
= sharedhdr
.publicsOffset
;
753 shared_size
= st
.st_size
- shared_offset
;
754 shared_section
= bfd_make_section (outbfd
, ".nlmshared");
755 if (shared_section
== NULL
756 || ! bfd_set_section_size (outbfd
, shared_section
,
758 || ! bfd_set_section_flags (outbfd
, shared_section
,
760 bfd_fatal ("shared section");
761 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
766 /* Check whether a version was given. */
767 if (strncmp (version_hdr
->stamp
, "VeRsIoN#", 8) != 0)
768 fprintf (stderr
, "%s: warning: No version number given\n",
771 /* At least for now, always create an extended header, because that
772 is what NLMLINK does. */
773 strncpy (nlm_extended_header (outbfd
)->stamp
, "MeSsAgEs", 8);
775 /* If the date was not given, force it in. */
776 if (nlm_version_header (outbfd
)->month
== 0
777 && nlm_version_header (outbfd
)->day
== 0
778 && nlm_version_header (outbfd
)->year
== 0)
784 ptm
= localtime (&now
);
785 nlm_version_header (outbfd
)->month
= ptm
->tm_mon
+ 1;
786 nlm_version_header (outbfd
)->day
= ptm
->tm_mday
;
787 nlm_version_header (outbfd
)->year
= ptm
->tm_year
+ 1900;
788 strncpy (version_hdr
->stamp
, "VeRsIoN#", 8);
791 /* Copy over the sections. */
792 bfd_map_over_sections (inbfd
, copy_sections
, (PTR
) outbfd
);
794 /* Finish up the header information. */
795 if (custom_file
!= NULL
)
799 data
= xmalloc (custom_size
);
800 if (fread (data
, 1, custom_size
, custom_data
) != custom_size
)
801 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, custom_file
,
805 if (! bfd_set_section_contents (outbfd
, custom_section
, data
,
806 (file_ptr
) 0, custom_size
))
807 bfd_fatal ("custom section");
808 nlm_fixed_header (outbfd
)->customDataOffset
=
809 custom_section
->filepos
;
810 nlm_fixed_header (outbfd
)->customDataSize
= custom_size
;
816 /* As a special hack, the backend recognizes a debugInfoOffset
817 of -1 to mean that it should not output any debugging
818 information. This can not be handling by fiddling with the
819 symbol table because exported symbols appear in both the
820 export information and the debugging information. */
821 nlm_fixed_header (outbfd
)->debugInfoOffset
= (file_ptr
) -1;
823 if (map_file
!= NULL
)
825 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
827 if (help_file
!= NULL
)
831 data
= xmalloc (help_size
);
832 if (fread (data
, 1, help_size
, help_data
) != help_size
)
833 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, help_file
,
837 if (! bfd_set_section_contents (outbfd
, help_section
, data
,
838 (file_ptr
) 0, help_size
))
839 bfd_fatal ("help section");
840 nlm_extended_header (outbfd
)->helpFileOffset
=
841 help_section
->filepos
;
842 nlm_extended_header (outbfd
)->helpFileLength
= help_size
;
846 if (message_file
!= NULL
)
850 data
= xmalloc (message_size
);
851 if (fread (data
, 1, message_size
, message_data
) != message_size
)
852 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, message_file
,
856 if (! bfd_set_section_contents (outbfd
, message_section
, data
,
857 (file_ptr
) 0, message_size
))
858 bfd_fatal ("message section");
859 nlm_extended_header (outbfd
)->messageFileOffset
=
860 message_section
->filepos
;
861 nlm_extended_header (outbfd
)->messageFileLength
= message_size
;
863 /* FIXME: Are these offsets correct on all platforms? Are
864 they 32 bits on all platforms? What endianness? */
865 nlm_extended_header (outbfd
)->languageID
=
866 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 106);
867 nlm_extended_header (outbfd
)->messageCount
=
868 bfd_h_get_32 (outbfd
, (bfd_byte
*) data
+ 110);
876 struct string_list
*l
;
879 data
= xmalloc (module_size
);
881 set
= (unsigned char *) data
;
882 for (l
= modules
; l
!= NULL
; l
= l
->next
)
884 *set
= strlen (l
->string
);
885 strncpy (set
+ 1, l
->string
, *set
);
889 if (! bfd_set_section_contents (outbfd
, module_section
, data
,
890 (file_ptr
) 0, module_size
))
891 bfd_fatal ("module section");
892 nlm_fixed_header (outbfd
)->moduleDependencyOffset
=
893 module_section
->filepos
;
894 nlm_fixed_header (outbfd
)->numberOfModuleDependencies
= c
;
896 if (rpc_file
!= NULL
)
900 data
= xmalloc (rpc_size
);
901 if (fread (data
, 1, rpc_size
, rpc_data
) != rpc_size
)
902 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, rpc_file
,
906 if (! bfd_set_section_contents (outbfd
, rpc_section
, data
,
907 (file_ptr
) 0, rpc_size
))
908 bfd_fatal ("rpc section");
909 nlm_extended_header (outbfd
)->RPCDataOffset
=
910 rpc_section
->filepos
;
911 nlm_extended_header (outbfd
)->RPCDataLength
= rpc_size
;
915 if (sharelib_file
!= NULL
)
919 data
= xmalloc (shared_size
);
920 if (fseek (shared_data
, shared_offset
, SEEK_SET
) != 0
921 || fread (data
, 1, shared_size
, shared_data
) != shared_size
)
922 fprintf (stderr
, "%s:%s: read: %s\n", program_name
, sharelib_file
,
926 if (! bfd_set_section_contents (outbfd
, shared_section
, data
,
927 (file_ptr
) 0, shared_size
))
928 bfd_fatal ("shared section");
930 nlm_extended_header (outbfd
)->sharedCodeOffset
=
931 sharedhdr
.codeImageOffset
- shared_offset
+ shared_section
->filepos
;
932 nlm_extended_header (outbfd
)->sharedCodeLength
=
933 sharedhdr
.codeImageSize
;
934 nlm_extended_header (outbfd
)->sharedDataOffset
=
935 sharedhdr
.dataImageOffset
- shared_offset
+ shared_section
->filepos
;
936 nlm_extended_header (outbfd
)->sharedDataLength
=
937 sharedhdr
.dataImageSize
;
938 nlm_extended_header (outbfd
)->sharedRelocationFixupOffset
=
939 (sharedhdr
.relocationFixupOffset
941 + shared_section
->filepos
);
942 nlm_extended_header (outbfd
)->sharedRelocationFixupCount
=
943 sharedhdr
.numberOfRelocationFixups
;
944 nlm_extended_header (outbfd
)->sharedExternalReferenceOffset
=
945 (sharedhdr
.externalReferencesOffset
947 + shared_section
->filepos
);
948 nlm_extended_header (outbfd
)->sharedExternalReferenceCount
=
949 sharedhdr
.numberOfExternalReferences
;
950 nlm_extended_header (outbfd
)->sharedPublicsOffset
=
951 sharedhdr
.publicsOffset
- shared_offset
+ shared_section
->filepos
;
952 nlm_extended_header (outbfd
)->sharedPublicsCount
=
953 sharedhdr
.numberOfPublics
;
954 nlm_extended_header (outbfd
)->sharedDebugRecordOffset
=
955 sharedhdr
.debugInfoOffset
- shared_offset
+ shared_section
->filepos
;
956 nlm_extended_header (outbfd
)->sharedDebugRecordCount
=
957 sharedhdr
.numberOfDebugRecords
;
958 nlm_extended_header (outbfd
)->SharedInitializationOffset
=
959 sharedhdr
.codeStartOffset
;
960 nlm_extended_header (outbfd
)->SharedExitProcedureOffset
=
961 sharedhdr
.exitProcedureOffset
;
964 len
= strlen (output_file
);
965 if (len
> NLM_MODULE_NAME_SIZE
- 2)
966 len
= NLM_MODULE_NAME_SIZE
- 2;
967 nlm_fixed_header (outbfd
)->moduleName
[0] = len
;
969 strncpy (nlm_fixed_header (outbfd
)->moduleName
+ 1, output_file
,
970 NLM_MODULE_NAME_SIZE
- 2);
971 nlm_fixed_header (outbfd
)->moduleName
[NLM_MODULE_NAME_SIZE
- 1] = '\0';
972 for (modname
= nlm_fixed_header (outbfd
)->moduleName
;
975 if (islower (*modname
))
976 *modname
= toupper (*modname
);
978 strncpy (nlm_variable_header (outbfd
)->oldThreadName
, " LONG",
979 NLM_OLD_THREAD_NAME_LENGTH
);
981 if (! bfd_close (outbfd
))
982 bfd_fatal (output_file
);
983 if (! bfd_close (inbfd
))
984 bfd_fatal (input_file
);
986 if (unlink_on_exit
!= NULL
)
987 unlink (unlink_on_exit
);
992 /* Display a help message and exit. */
997 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
999 show_usage (stdout
, 0);
1002 /* Show a usage message and exit. */
1005 show_usage (file
, status
)
1010 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1011 [--input-target=bfdname] [--output-target=bfdname]\n\
1012 [--header-file=file] [--linker=linker] [--debug]\n\
1013 [--help] [--version]\n\
1014 [in-file [out-file]]\n",
1019 /* Select the output format based on the input architecture, machine,
1020 and endianness. This chooses the appropriate NLM target. */
1023 select_output_format (arch
, mach
, bigendian
)
1024 enum bfd_architecture arch
;
1031 return "nlm32-i386";
1032 case bfd_arch_sparc
:
1033 return "nlm32-sparc";
1034 case bfd_arch_alpha
:
1035 return "nlm32-alpha";
1037 fprintf (stderr
, "%s: no default NLM format for %s\n",
1038 program_name
, bfd_printable_arch_mach (arch
, mach
));
1040 /* Avoid warning. */
1046 /* The BFD sections are copied in two passes. This function selects
1047 the output section for each input section, and sets up the section
1051 setup_sections (inbfd
, insec
, data_ptr
)
1056 bfd
*outbfd
= (bfd
*) data_ptr
;
1058 const char *outname
;
1061 bfd_size_type align
;
1064 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1065 file. However, I don't have a good way to describe this section.
1066 We do want to copy the section when using objcopy. */
1067 if (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
1068 && strcmp (bfd_section_name (inbfd
, insec
), ".reginfo") == 0)
1071 f
= bfd_get_section_flags (inbfd
, insec
);
1073 outname
= NLM_CODE_NAME
;
1074 else if ((f
& SEC_LOAD
) && (f
& SEC_HAS_CONTENTS
))
1075 outname
= NLM_INITIALIZED_DATA_NAME
;
1076 else if (f
& SEC_ALLOC
)
1077 outname
= NLM_UNINITIALIZED_DATA_NAME
;
1079 outname
= bfd_section_name (inbfd
, insec
);
1081 outsec
= bfd_get_section_by_name (outbfd
, outname
);
1084 outsec
= bfd_make_section (outbfd
, outname
);
1086 bfd_fatal ("make section");
1089 insec
->output_section
= outsec
;
1091 offset
= bfd_section_size (outbfd
, outsec
);
1092 align
= 1 << bfd_section_alignment (inbfd
, insec
);
1093 add
= ((offset
+ align
- 1) &~ (align
- 1)) - offset
;
1094 insec
->output_offset
= offset
+ add
;
1096 if (! bfd_set_section_size (outbfd
, outsec
,
1097 (bfd_section_size (outbfd
, outsec
)
1098 + bfd_section_size (inbfd
, insec
)
1100 bfd_fatal ("set section size");
1102 if ((bfd_section_alignment (inbfd
, insec
)
1103 > bfd_section_alignment (outbfd
, outsec
))
1104 && ! bfd_set_section_alignment (outbfd
, outsec
,
1105 bfd_section_alignment (inbfd
, insec
)))
1106 bfd_fatal ("set section alignment");
1108 if (! bfd_set_section_flags (outbfd
, outsec
, f
))
1109 bfd_fatal ("set section flags");
1111 bfd_set_reloc (outbfd
, outsec
, (arelent
**) NULL
, 0);
1114 /* Copy the section contents. */
1117 copy_sections (inbfd
, insec
, data_ptr
)
1122 bfd
*outbfd
= (bfd
*) data_ptr
;
1126 bfd_size_type reloc_size
;
1128 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1129 file. However, I don't have a good way to describe this section.
1130 We do want to copy the section when using objcopy. */
1131 if (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
1132 && strcmp (bfd_section_name (inbfd
, insec
), ".reginfo") == 0)
1135 outsec
= insec
->output_section
;
1136 assert (outsec
!= NULL
);
1138 size
= bfd_get_section_size_before_reloc (insec
);
1142 /* FIXME: Why are these necessary? */
1143 insec
->_cooked_size
= insec
->_raw_size
;
1144 insec
->reloc_done
= true;
1146 if ((bfd_get_section_flags (inbfd
, insec
) & SEC_HAS_CONTENTS
) == 0)
1150 contents
= xmalloc (size
);
1151 if (! bfd_get_section_contents (inbfd
, insec
, contents
,
1152 (file_ptr
) 0, size
))
1153 bfd_fatal (bfd_get_filename (inbfd
));
1156 reloc_size
= bfd_get_reloc_upper_bound (inbfd
, insec
);
1157 if (reloc_size
!= 0)
1160 bfd_size_type reloc_count
;
1162 relocs
= (arelent
**) xmalloc (reloc_size
);
1163 reloc_count
= bfd_canonicalize_reloc (inbfd
, insec
, relocs
, symbols
);
1164 mangle_relocs (outbfd
, insec
, &relocs
, &reloc_count
, (char *) contents
,
1167 /* FIXME: refers to internal BFD fields. */
1168 if (outsec
->orelocation
!= (arelent
**) NULL
)
1170 bfd_size_type total_count
;
1173 total_count
= reloc_count
+ outsec
->reloc_count
;
1174 combined
= (arelent
**) xmalloc (total_count
* sizeof (arelent
));
1175 memcpy (combined
, outsec
->orelocation
,
1176 outsec
->reloc_count
* sizeof (arelent
));
1177 memcpy (combined
+ outsec
->reloc_count
, relocs
,
1178 (size_t) (reloc_count
* sizeof (arelent
)));
1179 free (outsec
->orelocation
);
1180 reloc_count
= total_count
;
1184 bfd_set_reloc (outbfd
, outsec
, relocs
, reloc_count
);
1187 if (contents
!= NULL
)
1189 if (! bfd_set_section_contents (outbfd
, outsec
, contents
,
1190 insec
->output_offset
, size
))
1191 bfd_fatal (bfd_get_filename (outbfd
));
1196 /* Some, perhaps all, NetWare targets require changing the relocs used
1197 by the input formats. */
1200 mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1204 arelent
***relocs_ptr
;
1205 bfd_size_type
*reloc_count_ptr
;
1207 bfd_size_type contents_size
;
1209 switch (bfd_get_arch (outbfd
))
1212 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1213 contents
, contents_size
);
1215 case bfd_arch_alpha
:
1216 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1217 contents
, contents_size
);
1220 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
,
1221 contents
, contents_size
);
1226 /* By default all we need to do for relocs is change the address by
1227 the output_offset. */
1231 default_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1235 arelent
***relocs_ptr
;
1236 bfd_size_type
*reloc_count_ptr
;
1238 bfd_size_type contents_size
;
1240 if (insec
->output_offset
!= 0)
1242 bfd_size_type reloc_count
;
1243 register arelent
**relocs
;
1244 register bfd_size_type i
;
1246 reloc_count
= *reloc_count_ptr
;
1247 relocs
= *relocs_ptr
;
1248 for (i
= 0; i
< reloc_count
; i
++, relocs
++)
1249 (*relocs
)->address
+= insec
->output_offset
;
1253 /* NetWare on the i386 supports a restricted set of relocs, which are
1254 different from those used on other i386 targets. This routine
1255 converts the relocs. It is, obviously, very target dependent. At
1256 the moment, the nlm32-i386 backend performs similar translations;
1257 however, it is more reliable and efficient to do them here. */
1259 static reloc_howto_type nlm_i386_pcrel_howto
=
1260 HOWTO (1, /* type */
1262 2, /* size (0 = byte, 1 = short, 2 = long) */
1264 true, /* pc_relative */
1266 complain_overflow_signed
, /* complain_on_overflow */
1267 0, /* special_function */
1268 "DISP32", /* name */
1269 true, /* partial_inplace */
1270 0xffffffff, /* src_mask */
1271 0xffffffff, /* dst_mask */
1272 true); /* pcrel_offset */
1275 i386_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1279 arelent
***relocs_ptr
;
1280 bfd_size_type
*reloc_count_ptr
;
1282 bfd_size_type contents_size
;
1284 bfd_size_type reloc_count
, i
;
1287 reloc_count
= *reloc_count_ptr
;
1288 relocs
= *relocs_ptr
;
1289 for (i
= 0; i
< reloc_count
; i
++)
1293 bfd_size_type address
;
1297 sym
= *rel
->sym_ptr_ptr
;
1299 /* We're moving the relocs from the input section to the output
1300 section, so we must adjust the address accordingly. */
1301 address
= rel
->address
;
1302 rel
->address
+= insec
->output_offset
;
1304 /* Note that no serious harm will ensue if we fail to change a
1305 reloc. The backend will fail when writing out the reloc. */
1307 /* Make sure this reloc is within the data we have. We use only
1308 4 byte relocs here, so we insist on having 4 bytes. */
1309 if (address
+ 4 > contents_size
)
1312 /* A PC relative reloc entirely within a single section is
1313 completely unnecessary. This can be generated by ld -r. */
1314 if (sym
== insec
->symbol
1315 && rel
->howto
!= NULL
1316 && rel
->howto
->pc_relative
1317 && ! rel
->howto
->pcrel_offset
)
1321 memmove (relocs
, relocs
+ 1,
1322 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1326 /* Get the amount the relocation will add in. */
1327 addend
= rel
->addend
+ sym
->value
;
1329 /* NetWare doesn't support PC relative relocs against defined
1330 symbols, so we have to eliminate them by doing the relocation
1331 now. We can only do this if the reloc is within a single
1333 if (rel
->howto
!= NULL
1334 && rel
->howto
->pc_relative
1335 && bfd_get_section (sym
) == insec
->output_section
)
1339 if (rel
->howto
->pcrel_offset
)
1342 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1344 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1348 memmove (relocs
, relocs
+ 1,
1349 (size_t) ((reloc_count
- i
) * sizeof (arelent
*)));
1353 /* NetWare doesn't support reloc addends, so we get rid of them
1354 here by simply adding them into the object data. We handle
1355 the symbol value, if any, the same way. */
1357 && rel
->howto
!= NULL
1358 && rel
->howto
->rightshift
== 0
1359 && rel
->howto
->size
== 2
1360 && rel
->howto
->bitsize
== 32
1361 && rel
->howto
->bitpos
== 0
1362 && rel
->howto
->src_mask
== 0xffffffff
1363 && rel
->howto
->dst_mask
== 0xffffffff)
1367 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1369 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1371 /* Adjust the reloc for the changes we just made. */
1373 if (bfd_get_section (sym
) != &bfd_und_section
)
1374 rel
->sym_ptr_ptr
= bfd_get_section (sym
)->symbol_ptr_ptr
;
1377 /* NetWare uses a reloc with pcrel_offset set. We adjust
1378 pc_relative relocs accordingly. We are going to change the
1379 howto field, so we can only do this if the current one is
1380 compatible. We should check that special_function is NULL
1381 here, but at the moment coff-i386 uses a special_function
1382 which does not affect what we are doing here. */
1383 if (rel
->howto
!= NULL
1384 && rel
->howto
->pc_relative
1385 && ! rel
->howto
->pcrel_offset
1386 && rel
->howto
->rightshift
== 0
1387 && rel
->howto
->size
== 2
1388 && rel
->howto
->bitsize
== 32
1389 && rel
->howto
->bitpos
== 0
1390 && rel
->howto
->src_mask
== 0xffffffff
1391 && rel
->howto
->dst_mask
== 0xffffffff)
1395 /* When pcrel_offset is not set, it means that the negative
1396 of the address of the memory location is stored in the
1397 memory location. We must add it back in. */
1398 val
= bfd_get_32 (outbfd
, (bfd_byte
*) contents
+ address
);
1400 bfd_put_32 (outbfd
, val
, (bfd_byte
*) contents
+ address
);
1402 /* We must change to a new howto. */
1403 rel
->howto
= &nlm_i386_pcrel_howto
;
1408 /* On the Alpha the first reloc for every section must be a special
1409 relocs which hold the GP address. Also, the first reloc in the
1410 file must be a special reloc which holds the address of the .lita
1413 static reloc_howto_type nlm32_alpha_nw_howto
=
1414 HOWTO (ALPHA_R_NW_RELOC
, /* type */
1416 0, /* size (0 = byte, 1 = short, 2 = long) */
1418 false, /* pc_relative */
1420 complain_overflow_dont
, /* complain_on_overflow */
1421 0, /* special_function */
1422 "NW_RELOC", /* name */
1423 false, /* partial_inplace */
1426 false); /* pcrel_offset */
1430 alpha_mangle_relocs (outbfd
, insec
, relocs_ptr
, reloc_count_ptr
, contents
,
1434 register arelent
***relocs_ptr
;
1435 bfd_size_type
*reloc_count_ptr
;
1437 bfd_size_type contents_size
;
1439 bfd_size_type old_reloc_count
;
1440 arelent
**old_relocs
;
1441 register arelent
**relocs
;
1443 old_reloc_count
= *reloc_count_ptr
;
1444 old_relocs
= *relocs_ptr
;
1445 relocs
= (arelent
**) xmalloc ((old_reloc_count
+ 3) * sizeof (arelent
*));
1446 *relocs_ptr
= relocs
;
1448 if (nlm_alpha_backend_data (outbfd
)->lita_address
== 0)
1451 asection
*lita_section
;
1453 inbfd
= insec
->owner
;
1454 lita_section
= bfd_get_section_by_name (inbfd
, _LITA
);
1455 if (lita_section
!= (asection
*) NULL
)
1457 nlm_alpha_backend_data (outbfd
)->lita_address
=
1458 bfd_get_section_vma (inbfd
, lita_section
);
1459 nlm_alpha_backend_data (outbfd
)->lita_size
=
1460 bfd_section_size (inbfd
, lita_section
);
1464 /* Avoid outputting this reloc again. */
1465 nlm_alpha_backend_data (outbfd
)->lita_address
= 4;
1468 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1469 (*relocs
)->sym_ptr_ptr
= bfd_abs_section
.symbol_ptr_ptr
;
1470 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->lita_address
;
1471 (*relocs
)->addend
= nlm_alpha_backend_data (outbfd
)->lita_size
+ 1;
1472 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1474 ++(*reloc_count_ptr
);
1477 /* Get the GP value from bfd. It is in the .reginfo section. */
1478 if (nlm_alpha_backend_data (outbfd
)->gp
== 0)
1481 asection
*reginfo_sec
;
1482 struct ecoff_reginfo sreginfo
;
1484 inbfd
= insec
->owner
;
1485 assert (bfd_get_flavour (inbfd
) == bfd_target_ecoff_flavour
);
1486 reginfo_sec
= bfd_get_section_by_name (inbfd
, REGINFO
);
1487 if (reginfo_sec
!= (asection
*) NULL
1488 && bfd_get_section_contents (inbfd
, reginfo_sec
,
1489 (PTR
) &sreginfo
, (file_ptr
) 0,
1490 sizeof sreginfo
) != false)
1491 nlm_alpha_backend_data (outbfd
)->gp
= sreginfo
.gp_value
;
1494 *relocs
= (arelent
*) xmalloc (sizeof (arelent
));
1495 (*relocs
)->sym_ptr_ptr
= bfd_abs_section
.symbol_ptr_ptr
;
1496 (*relocs
)->address
= nlm_alpha_backend_data (outbfd
)->gp
;
1497 (*relocs
)->addend
= 0;
1498 (*relocs
)->howto
= &nlm32_alpha_nw_howto
;
1500 ++(*reloc_count_ptr
);
1502 memcpy ((PTR
) relocs
, (PTR
) old_relocs
,
1503 (size_t) old_reloc_count
* sizeof (arelent
*));
1504 relocs
[old_reloc_count
] = (arelent
*) NULL
;
1508 if (insec
->output_offset
!= 0)
1510 register bfd_size_type i
;
1512 for (i
= 0; i
< old_reloc_count
; i
++, relocs
++)
1513 (*relocs
)->address
+= insec
->output_offset
;
1517 /* Name of linker. */
1519 #define LD_NAME "ld"
1522 /* Temporary file name base. */
1523 static char *temp_filename
;
1525 /* The user has specified several input files. Invoke the linker to
1526 link them all together, and convert and delete the resulting output
1530 link_inputs (inputs
, ld
)
1531 struct string_list
*inputs
;
1535 struct string_list
*q
;
1542 for (q
= inputs
; q
!= NULL
; q
= q
->next
)
1545 argv
= (char **) alloca (c
+ 5);
1552 /* Find the linker to invoke based on how nlmconv was run. */
1553 p
= program_name
+ strlen (program_name
);
1554 while (p
!= program_name
)
1558 ld
= (char *) xmalloc (p
- program_name
+ strlen (LD_NAME
) + 1);
1559 memcpy (ld
, program_name
, p
- program_name
);
1560 strcpy (ld
+ (p
- program_name
), LD_NAME
);
1569 ld
= (char *) LD_NAME
;
1571 choose_temp_base ();
1573 unlink_on_exit
= xmalloc (strlen (temp_filename
) + 3);
1574 sprintf (unlink_on_exit
, "%s.O", temp_filename
);
1577 argv
[1] = (char *) "-r";
1578 argv
[2] = (char *) "-o";
1579 argv
[3] = unlink_on_exit
;
1581 for (q
= inputs
; q
!= NULL
; q
= q
->next
, i
++)
1582 argv
[i
] = q
->string
;
1587 for (i
= 0; argv
[i
] != NULL
; i
++)
1588 fprintf (stderr
, " %s", argv
[i
]);
1589 fprintf (stderr
, "\n");
1592 pid
= pexecute (ld
, argv
);
1594 if (waitpid (pid
, &status
, 0) < 0)
1597 unlink (unlink_on_exit
);
1603 fprintf (stderr
, "%s: Execution of %s failed\n", program_name
, ld
);
1604 unlink (unlink_on_exit
);
1608 return unlink_on_exit
;
1611 /* Choose a temporary file name. Stolen from gcc.c. */
1614 choose_temp_base_try (try, base
)
1622 else if (try == NULL
)
1624 else if (access (try, R_OK
| W_OK
) != 0)
1634 const char *base
= NULL
;
1637 base
= choose_temp_base_try (getenv ("TMPDIR"), base
);
1638 base
= choose_temp_base_try (getenv ("TMP"), base
);
1639 base
= choose_temp_base_try (getenv ("TEMP"), base
);
1642 base
= choose_temp_base_try (P_tmpdir
, base
);
1645 base
= choose_temp_base_try ("/usr/tmp", base
);
1646 base
= choose_temp_base_try ("/tmp", base
);
1648 /* If all else fails, use the current directory! */
1652 len
= strlen (base
);
1653 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX") + 1);
1654 strcpy (temp_filename
, base
);
1655 if (len
> 0 && temp_filename
[len
-1] != '/')
1656 temp_filename
[len
++] = '/';
1657 strcpy (temp_filename
+ len
, "ccXXXXXX");
1659 mktemp (temp_filename
);
1660 if (*temp_filename
== '\0')
1664 /* Execute a job. Stolen from gcc.c. */
1670 pexecute (program
, argv
)
1678 scmd
= (char *)malloc (strlen (program
) + strlen (temp_filename
) + 10);
1679 rf
= scmd
+ strlen(program
) + 2 + el
;
1680 sprintf (scmd
, "%s.exe @%s.gp", program
, temp_filename
);
1681 argfile
= fopen (rf
, "w");
1683 pfatal_with_name (rf
);
1685 for (i
=1; argv
[i
]; i
++)
1688 for (cp
= argv
[i
]; *cp
; cp
++)
1690 if (*cp
== '"' || *cp
== '\'' || *cp
== '\\' || isspace (*cp
))
1691 fputc ('\\', argfile
);
1692 fputc (*cp
, argfile
);
1694 fputc ('\n', argfile
);
1705 return MIN_FATAL_STATUS
<< 8;
1711 #else /* not __MSDOS__ */
1714 pexecute (program
, argv
)
1719 int retries
, sleep_interval
;
1721 /* Fork a subprocess; wait and retry if it fails. */
1723 for (retries
= 0; retries
< 4; retries
++)
1728 sleep (sleep_interval
);
1729 sleep_interval
*= 2;
1745 /* Exec the program. */
1746 execvp (program
, argv
);
1753 /* Return child's process number. */
1758 #endif /* not __MSDOS__ */
1762 pexecute (program
, argv
)
1766 return spawnvp (1, program
, argv
);
1768 #endif /* not OS2 */