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];
177 xmalloc_set_program_name (program_name);
181 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
194 input_format = optarg;
200 output_format = optarg;
203 header_file = optarg;
206 printf ("GNU %s version %s\n", program_name, program_version);
212 show_usage (stderr, 1);
217 /* The input and output files may be named on the command line. */
221 input_file = argv[optind];
225 output_file = argv[optind];
228 show_usage (stderr, 1);
229 if (strcmp (input_file, output_file) == 0)
232 "%s: input and output files must be different\n",
239 /* Initialize the header information to default values. */
240 fixed_hdr = &fixed_hdr_struct;
241 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
242 var_hdr = &var_hdr_struct;
243 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
244 version_hdr = &version_hdr_struct;
245 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
246 copyright_hdr = ©right_hdr_struct;
247 memset ((PTR) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
248 extended_hdr = &extended_hdr_struct;
249 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
250 check_procedure = NULL;
253 exit_procedure = "_Stop";
254 export_symbols = NULL;
258 import_symbols = NULL;
261 sharelib_file = NULL;
262 start_procedure = "_Prelude";
268 /* Parse the header file (if there is one). */
269 if (header_file != NULL)
271 if (! nlmlex_file (header_file)
273 || parse_errors != 0)
277 if (input_files != NULL)
279 if (input_file != NULL)
282 "%s: input file named both on command line and with INPUT\n",
286 if (input_files->next == NULL)
287 input_file = input_files->string;
289 input_file = link_inputs (input_files, ld_arg);
291 else if (input_file == NULL)
293 fprintf (stderr, "%s: no input file\n", program_name);
294 show_usage (stderr, 1);
297 inbfd = bfd_openr (input_file, input_format);
299 bfd_fatal (input_file);
301 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
303 bfd_nonfatal (input_file);
304 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
306 list_matching_formats (matching);
312 if (output_format == NULL)
313 output_format = select_output_format (bfd_get_arch (inbfd),
314 bfd_get_mach (inbfd),
315 inbfd->xvec->byteorder_big_p);
317 assert (output_format != NULL);
319 /* Use the output file named on the command line if it exists.
320 Otherwise use the file named in the OUTPUT statement. */
321 if (output_file == NULL)
323 fprintf (stderr, "%s: no name for output file\n",
325 show_usage (stderr, 1);
328 outbfd = bfd_openw (output_file, output_format);
330 bfd_fatal (output_file);
331 if (! bfd_set_format (outbfd, bfd_object))
332 bfd_fatal (output_file);
334 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
336 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
338 "%s: warning:input and output formats are not compatible\n",
341 /* Move the values read from the command file into outbfd. */
342 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
343 *nlm_variable_header (outbfd) = var_hdr_struct;
344 *nlm_version_header (outbfd) = version_hdr_struct;
345 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
346 *nlm_extended_header (outbfd) = extended_hdr_struct;
348 /* Start copying the input BFD to the output BFD. */
349 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
350 bfd_fatal (bfd_get_filename (outbfd));
352 symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
353 symcount = bfd_canonicalize_symtab (inbfd, symbols);
355 /* Make sure we have a .bss section. */
356 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
359 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
361 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
362 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
363 bfd_fatal ("make .bss section");
366 /* Set up the sections. */
367 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
369 /* The .bss section immediately follows the .data section. */
370 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
371 if (data_sec != NULL)
375 vma = bfd_get_section_size_before_reloc (data_sec);
376 align = 1 << bss_sec->alignment_power;
377 add = ((vma + align - 1) &~ (align - 1)) - vma;
379 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
380 bfd_fatal ("set .bss vma");
383 bfd_size_type data_size;
385 data_size = bfd_get_section_size_before_reloc (data_sec);
386 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
387 bfd_fatal ("set .data size");
391 /* Adjust symbol information. */
392 inlead = bfd_get_symbol_leading_char (inbfd);
393 outlead = bfd_get_symbol_leading_char (outbfd);
398 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
401 for (i = 0; i < symcount; i++)
403 register asymbol *sym;
407 /* Add or remove a leading underscore. */
408 if (inlead != outlead)
412 if (bfd_asymbol_name (sym)[0] == inlead)
420 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
422 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
431 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
433 strcpy (new + 1, bfd_asymbol_name (sym));
438 /* NLM's have an uninitialized data section, but they do not
439 have a common section in the Unix sense. Move all common
440 symbols into the .bss section, and mark them as exported. */
441 if (bfd_is_com_section (bfd_get_section (sym)))
445 sym->section = bss_sec;
447 sym->value = bss_sec->_raw_size;
448 bss_sec->_raw_size += size;
449 align = 1 << bss_sec->alignment_power;
450 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
451 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
453 else if (bfd_get_section (sym)->output_section != NULL)
455 /* Move the symbol into the output section. */
456 sym->value += bfd_get_section (sym)->output_offset;
457 sym->section = bfd_get_section (sym)->output_section;
458 /* This is no longer a section symbol. */
459 sym->flags &=~ BSF_SECTION_SYM;
462 /* Force _edata and _end to be defined. This would normally be
463 done by the linker, but the manipulation of the common
464 symbols will confuse it. */
465 if (bfd_asymbol_name (sym)[0] == '_'
466 && bfd_get_section (sym) == &bfd_und_section)
468 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
470 sym->section = bss_sec;
473 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
475 sym->section = bss_sec;
480 /* If this is a global symbol, check the export list. */
481 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
483 register struct string_list *l;
486 /* Unfortunately, a symbol can appear multiple times on the
487 export list, with and without prefixes. */
489 for (l = export_symbols; l != NULL; l = l->next)
491 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
497 zbase = strchr (l->string, '@');
499 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
501 /* We must add a symbol with this prefix. */
502 if (newsymcount >= newsymalloc)
505 newsyms = ((asymbol **)
506 xrealloc ((PTR) newsyms,
508 * sizeof (asymbol *))));
510 newsyms[newsymcount] =
511 (asymbol *) xmalloc (sizeof (asymbol));
512 *newsyms[newsymcount] = *sym;
513 newsyms[newsymcount]->name = l->string;
520 /* The unmodified symbol is actually not exported at
522 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
523 sym->flags |= BSF_LOCAL;
527 /* If it's an undefined symbol, see if it's on the import list.
528 Change the prefix if necessary. */
529 if (bfd_get_section (sym) == &bfd_und_section)
531 register struct string_list *l;
533 for (l = import_symbols; l != NULL; l = l->next)
535 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
541 zbase = strchr (l->string, '@');
543 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
545 sym->name = l->string;
552 "%s: warning: symbol %s imported but not in import list\n",
553 program_name, bfd_asymbol_name (sym));
556 /* See if it's one of the special named symbols. */
557 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
559 if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
560 bfd_fatal ("set start address");
563 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
565 nlm_fixed_header (outbfd)->exitProcedureOffset =
566 bfd_asymbol_value (sym);
569 if (check_procedure != NULL
570 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
572 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
573 bfd_asymbol_value (sym);
579 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
581 if (newsymcount == 0)
585 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
586 * sizeof (asymbol *));
587 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
588 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
589 outsyms[symcount + newsymcount] = NULL;
592 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
595 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
596 program_name, start_procedure);
598 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
599 program_name, exit_procedure);
600 if (check_procedure != NULL
602 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
603 program_name, check_procedure);
605 /* Add additional sections required for the header information. */
606 if (custom_file != NULL)
608 custom_data = fopen (custom_file, "r");
609 if (custom_data == NULL
610 || fstat (fileno (custom_data), &st) < 0)
612 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
618 custom_size = st.st_size;
619 custom_section = bfd_make_section (outbfd, ".nlmcustom");
620 if (custom_section == NULL
621 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
622 || ! bfd_set_section_flags (outbfd, custom_section,
624 bfd_fatal ("custom section");
627 if (help_file != NULL)
629 help_data = fopen (help_file, "r");
630 if (help_data == NULL
631 || fstat (fileno (help_data), &st) < 0)
633 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
639 help_size = st.st_size;
640 help_section = bfd_make_section (outbfd, ".nlmhelp");
641 if (help_section == NULL
642 || ! bfd_set_section_size (outbfd, help_section, help_size)
643 || ! bfd_set_section_flags (outbfd, help_section,
645 bfd_fatal ("help section");
646 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
649 if (message_file != NULL)
651 message_data = fopen (message_file, "r");
652 if (message_data == NULL
653 || fstat (fileno (message_data), &st) < 0)
655 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
661 message_size = st.st_size;
662 message_section = bfd_make_section (outbfd, ".nlmmessages");
663 if (message_section == NULL
664 || ! bfd_set_section_size (outbfd, message_section, message_size)
665 || ! bfd_set_section_flags (outbfd, message_section,
667 bfd_fatal ("message section");
668 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
673 struct string_list *l;
676 for (l = modules; l != NULL; l = l->next)
677 module_size += strlen (l->string) + 1;
678 module_section = bfd_make_section (outbfd, ".nlmmodules");
679 if (module_section == NULL
680 || ! bfd_set_section_size (outbfd, module_section, module_size)
681 || ! bfd_set_section_flags (outbfd, module_section,
683 bfd_fatal ("module section");
685 if (rpc_file != NULL)
687 rpc_data = fopen (rpc_file, "r");
689 || fstat (fileno (rpc_data), &st) < 0)
691 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
697 rpc_size = st.st_size;
698 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
699 if (rpc_section == NULL
700 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
701 || ! bfd_set_section_flags (outbfd, rpc_section,
703 bfd_fatal ("rpc section");
704 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
707 if (sharelib_file != NULL)
709 sharedbfd = bfd_openr (sharelib_file, output_format);
710 if (sharedbfd == NULL
711 || ! bfd_check_format (sharedbfd, bfd_object))
713 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
714 bfd_errmsg (bfd_get_error ()));
715 sharelib_file = NULL;
719 sharedhdr = *nlm_fixed_header (sharedbfd);
720 bfd_close (sharedbfd);
721 shared_data = fopen (sharelib_file, "r");
722 if (shared_data == NULL
723 || (fstat (fileno (shared_data), &st) < 0))
725 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
727 sharelib_file = NULL;
731 /* If we were clever, we could just copy out the
732 sections of the shared library which we actually
733 need. However, we would have to figure out the sizes
734 of the external and public information, and that can
735 not be done without reading through them. */
736 if (sharedhdr.uninitializedDataSize > 0)
738 /* There is no place to record this information. */
740 "%s:%s: warning: shared libraries can not have uninitialized data\n",
741 program_name, sharelib_file);
743 shared_offset = st.st_size;
744 if (shared_offset > sharedhdr.codeImageOffset)
745 shared_offset = sharedhdr.codeImageOffset;
746 if (shared_offset > sharedhdr.dataImageOffset)
747 shared_offset = sharedhdr.dataImageOffset;
748 if (shared_offset > sharedhdr.relocationFixupOffset)
749 shared_offset = sharedhdr.relocationFixupOffset;
750 if (shared_offset > sharedhdr.externalReferencesOffset)
751 shared_offset = sharedhdr.externalReferencesOffset;
752 if (shared_offset > sharedhdr.publicsOffset)
753 shared_offset = sharedhdr.publicsOffset;
754 shared_size = st.st_size - shared_offset;
755 shared_section = bfd_make_section (outbfd, ".nlmshared");
756 if (shared_section == NULL
757 || ! bfd_set_section_size (outbfd, shared_section,
759 || ! bfd_set_section_flags (outbfd, shared_section,
761 bfd_fatal ("shared section");
762 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
767 /* Check whether a version was given. */
768 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
769 fprintf (stderr, "%s: warning: No version number given\n",
772 /* At least for now, always create an extended header, because that
773 is what NLMLINK does. */
774 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
776 /* If the date was not given, force it in. */
777 if (nlm_version_header (outbfd)->month == 0
778 && nlm_version_header (outbfd)->day == 0
779 && nlm_version_header (outbfd)->year == 0)
785 ptm = localtime (&now);
786 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
787 nlm_version_header (outbfd)->day = ptm->tm_mday;
788 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
789 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
792 /* Copy over the sections. */
793 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
795 /* Finish up the header information. */
796 if (custom_file != NULL)
800 data = xmalloc (custom_size);
801 if (fread (data, 1, custom_size, custom_data) != custom_size)
802 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
806 if (! bfd_set_section_contents (outbfd, custom_section, data,
807 (file_ptr) 0, custom_size))
808 bfd_fatal ("custom section");
809 nlm_fixed_header (outbfd)->customDataOffset =
810 custom_section->filepos;
811 nlm_fixed_header (outbfd)->customDataSize = custom_size;
817 /* As a special hack, the backend recognizes a debugInfoOffset
818 of -1 to mean that it should not output any debugging
819 information. This can not be handling by fiddling with the
820 symbol table because exported symbols appear in both the
821 export information and the debugging information. */
822 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
824 if (map_file != NULL)
826 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
828 if (help_file != NULL)
832 data = xmalloc (help_size);
833 if (fread (data, 1, help_size, help_data) != help_size)
834 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
838 if (! bfd_set_section_contents (outbfd, help_section, data,
839 (file_ptr) 0, help_size))
840 bfd_fatal ("help section");
841 nlm_extended_header (outbfd)->helpFileOffset =
842 help_section->filepos;
843 nlm_extended_header (outbfd)->helpFileLength = help_size;
847 if (message_file != NULL)
851 data = xmalloc (message_size);
852 if (fread (data, 1, message_size, message_data) != message_size)
853 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
857 if (! bfd_set_section_contents (outbfd, message_section, data,
858 (file_ptr) 0, message_size))
859 bfd_fatal ("message section");
860 nlm_extended_header (outbfd)->messageFileOffset =
861 message_section->filepos;
862 nlm_extended_header (outbfd)->messageFileLength = message_size;
864 /* FIXME: Are these offsets correct on all platforms? Are
865 they 32 bits on all platforms? What endianness? */
866 nlm_extended_header (outbfd)->languageID =
867 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
868 nlm_extended_header (outbfd)->messageCount =
869 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
877 struct string_list *l;
880 data = xmalloc (module_size);
882 set = (unsigned char *) data;
883 for (l = modules; l != NULL; l = l->next)
885 *set = strlen (l->string);
886 strncpy (set + 1, l->string, *set);
890 if (! bfd_set_section_contents (outbfd, module_section, data,
891 (file_ptr) 0, module_size))
892 bfd_fatal ("module section");
893 nlm_fixed_header (outbfd)->moduleDependencyOffset =
894 module_section->filepos;
895 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
897 if (rpc_file != NULL)
901 data = xmalloc (rpc_size);
902 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
903 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
907 if (! bfd_set_section_contents (outbfd, rpc_section, data,
908 (file_ptr) 0, rpc_size))
909 bfd_fatal ("rpc section");
910 nlm_extended_header (outbfd)->RPCDataOffset =
911 rpc_section->filepos;
912 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
916 if (sharelib_file != NULL)
920 data = xmalloc (shared_size);
921 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
922 || fread (data, 1, shared_size, shared_data) != shared_size)
923 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
927 if (! bfd_set_section_contents (outbfd, shared_section, data,
928 (file_ptr) 0, shared_size))
929 bfd_fatal ("shared section");
931 nlm_extended_header (outbfd)->sharedCodeOffset =
932 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
933 nlm_extended_header (outbfd)->sharedCodeLength =
934 sharedhdr.codeImageSize;
935 nlm_extended_header (outbfd)->sharedDataOffset =
936 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
937 nlm_extended_header (outbfd)->sharedDataLength =
938 sharedhdr.dataImageSize;
939 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
940 (sharedhdr.relocationFixupOffset
942 + shared_section->filepos);
943 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
944 sharedhdr.numberOfRelocationFixups;
945 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
946 (sharedhdr.externalReferencesOffset
948 + shared_section->filepos);
949 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
950 sharedhdr.numberOfExternalReferences;
951 nlm_extended_header (outbfd)->sharedPublicsOffset =
952 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
953 nlm_extended_header (outbfd)->sharedPublicsCount =
954 sharedhdr.numberOfPublics;
955 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
956 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
957 nlm_extended_header (outbfd)->sharedDebugRecordCount =
958 sharedhdr.numberOfDebugRecords;
959 nlm_extended_header (outbfd)->SharedInitializationOffset =
960 sharedhdr.codeStartOffset;
961 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
962 sharedhdr.exitProcedureOffset;
965 len = strlen (output_file);
966 if (len > NLM_MODULE_NAME_SIZE - 2)
967 len = NLM_MODULE_NAME_SIZE - 2;
968 nlm_fixed_header (outbfd)->moduleName[0] = len;
970 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
971 NLM_MODULE_NAME_SIZE - 2);
972 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
973 for (modname = nlm_fixed_header (outbfd)->moduleName;
976 if (islower (*modname))
977 *modname = toupper (*modname);
979 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
980 NLM_OLD_THREAD_NAME_LENGTH);
982 if (! bfd_close (outbfd))
983 bfd_fatal (output_file);
984 if (! bfd_close (inbfd))
985 bfd_fatal (input_file);
987 if (unlink_on_exit != NULL)
988 unlink (unlink_on_exit);
993 /* Display a help message and exit. */
998 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1000 show_usage (stdout, 0);
1003 /* Show a usage message and exit. */
1006 show_usage (file, status)
1011 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1012 [--input-target=bfdname] [--output-target=bfdname]\n\
1013 [--header-file=file] [--linker=linker] [--debug]\n\
1014 [--help] [--version]\n\
1015 [in-file [out-file]]\n",
1020 /* Select the output format based on the input architecture, machine,
1021 and endianness. This chooses the appropriate NLM target. */
1024 select_output_format (arch, mach, bigendian)
1025 enum bfd_architecture arch;
1032 return "nlm32-i386";
1033 case bfd_arch_sparc:
1034 return "nlm32-sparc";
1035 case bfd_arch_alpha:
1036 return "nlm32-alpha";
1038 fprintf (stderr, "%s: no default NLM format for %s\n",
1039 program_name, bfd_printable_arch_mach (arch, mach));
1041 /* Avoid warning. */
1047 /* The BFD sections are copied in two passes. This function selects
1048 the output section for each input section, and sets up the section
1052 setup_sections (inbfd, insec, data_ptr)
1057 bfd *outbfd = (bfd *) data_ptr;
1059 const char *outname;
1062 bfd_size_type align;
1065 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1066 file. However, I don't have a good way to describe this section.
1067 We do want to copy the section when using objcopy. */
1068 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1069 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1072 f = bfd_get_section_flags (inbfd, insec);
1074 outname = NLM_CODE_NAME;
1075 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1076 outname = NLM_INITIALIZED_DATA_NAME;
1077 else if (f & SEC_ALLOC)
1078 outname = NLM_UNINITIALIZED_DATA_NAME;
1080 outname = bfd_section_name (inbfd, insec);
1082 outsec = bfd_get_section_by_name (outbfd, outname);
1085 outsec = bfd_make_section (outbfd, outname);
1087 bfd_fatal ("make section");
1090 insec->output_section = outsec;
1092 offset = bfd_section_size (outbfd, outsec);
1093 align = 1 << bfd_section_alignment (inbfd, insec);
1094 add = ((offset + align - 1) &~ (align - 1)) - offset;
1095 insec->output_offset = offset + add;
1097 if (! bfd_set_section_size (outbfd, outsec,
1098 (bfd_section_size (outbfd, outsec)
1099 + bfd_section_size (inbfd, insec)
1101 bfd_fatal ("set section size");
1103 if ((bfd_section_alignment (inbfd, insec)
1104 > bfd_section_alignment (outbfd, outsec))
1105 && ! bfd_set_section_alignment (outbfd, outsec,
1106 bfd_section_alignment (inbfd, insec)))
1107 bfd_fatal ("set section alignment");
1109 if (! bfd_set_section_flags (outbfd, outsec, f))
1110 bfd_fatal ("set section flags");
1112 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1115 /* Copy the section contents. */
1118 copy_sections (inbfd, insec, data_ptr)
1123 bfd *outbfd = (bfd *) data_ptr;
1127 bfd_size_type reloc_size;
1129 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1130 file. However, I don't have a good way to describe this section.
1131 We do want to copy the section when using objcopy. */
1132 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1133 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1136 outsec = insec->output_section;
1137 assert (outsec != NULL);
1139 size = bfd_get_section_size_before_reloc (insec);
1143 /* FIXME: Why are these necessary? */
1144 insec->_cooked_size = insec->_raw_size;
1145 insec->reloc_done = true;
1147 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1151 contents = xmalloc (size);
1152 if (! bfd_get_section_contents (inbfd, insec, contents,
1153 (file_ptr) 0, size))
1154 bfd_fatal (bfd_get_filename (inbfd));
1157 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1158 if (reloc_size != 0)
1161 bfd_size_type reloc_count;
1163 relocs = (arelent **) xmalloc (reloc_size);
1164 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1165 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1168 /* FIXME: refers to internal BFD fields. */
1169 if (outsec->orelocation != (arelent **) NULL)
1171 bfd_size_type total_count;
1174 total_count = reloc_count + outsec->reloc_count;
1175 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1176 memcpy (combined, outsec->orelocation,
1177 outsec->reloc_count * sizeof (arelent));
1178 memcpy (combined + outsec->reloc_count, relocs,
1179 (size_t) (reloc_count * sizeof (arelent)));
1180 free (outsec->orelocation);
1181 reloc_count = total_count;
1185 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1188 if (contents != NULL)
1190 if (! bfd_set_section_contents (outbfd, outsec, contents,
1191 insec->output_offset, size))
1192 bfd_fatal (bfd_get_filename (outbfd));
1197 /* Some, perhaps all, NetWare targets require changing the relocs used
1198 by the input formats. */
1201 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1205 arelent ***relocs_ptr;
1206 bfd_size_type *reloc_count_ptr;
1208 bfd_size_type contents_size;
1210 switch (bfd_get_arch (outbfd))
1213 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1214 contents, contents_size);
1216 case bfd_arch_alpha:
1217 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1218 contents, contents_size);
1221 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1222 contents, contents_size);
1227 /* By default all we need to do for relocs is change the address by
1228 the output_offset. */
1232 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1236 arelent ***relocs_ptr;
1237 bfd_size_type *reloc_count_ptr;
1239 bfd_size_type contents_size;
1241 if (insec->output_offset != 0)
1243 bfd_size_type reloc_count;
1244 register arelent **relocs;
1245 register bfd_size_type i;
1247 reloc_count = *reloc_count_ptr;
1248 relocs = *relocs_ptr;
1249 for (i = 0; i < reloc_count; i++, relocs++)
1250 (*relocs)->address += insec->output_offset;
1254 /* NetWare on the i386 supports a restricted set of relocs, which are
1255 different from those used on other i386 targets. This routine
1256 converts the relocs. It is, obviously, very target dependent. At
1257 the moment, the nlm32-i386 backend performs similar translations;
1258 however, it is more reliable and efficient to do them here. */
1260 static reloc_howto_type nlm_i386_pcrel_howto =
1261 HOWTO (1, /* type */
1263 2, /* size (0 = byte, 1 = short, 2 = long) */
1265 true, /* pc_relative */
1267 complain_overflow_signed, /* complain_on_overflow */
1268 0, /* special_function */
1269 "DISP32", /* name */
1270 true, /* partial_inplace */
1271 0xffffffff, /* src_mask */
1272 0xffffffff, /* dst_mask */
1273 true); /* pcrel_offset */
1276 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1280 arelent ***relocs_ptr;
1281 bfd_size_type *reloc_count_ptr;
1283 bfd_size_type contents_size;
1285 bfd_size_type reloc_count, i;
1288 reloc_count = *reloc_count_ptr;
1289 relocs = *relocs_ptr;
1290 for (i = 0; i < reloc_count; i++)
1294 bfd_size_type address;
1298 sym = *rel->sym_ptr_ptr;
1300 /* We're moving the relocs from the input section to the output
1301 section, so we must adjust the address accordingly. */
1302 address = rel->address;
1303 rel->address += insec->output_offset;
1305 /* Note that no serious harm will ensue if we fail to change a
1306 reloc. The backend will fail when writing out the reloc. */
1308 /* Make sure this reloc is within the data we have. We use only
1309 4 byte relocs here, so we insist on having 4 bytes. */
1310 if (address + 4 > contents_size)
1313 /* A PC relative reloc entirely within a single section is
1314 completely unnecessary. This can be generated by ld -r. */
1315 if (sym == insec->symbol
1316 && rel->howto != NULL
1317 && rel->howto->pc_relative
1318 && ! rel->howto->pcrel_offset)
1322 memmove (relocs, relocs + 1,
1323 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1327 /* Get the amount the relocation will add in. */
1328 addend = rel->addend + sym->value;
1330 /* NetWare doesn't support PC relative relocs against defined
1331 symbols, so we have to eliminate them by doing the relocation
1332 now. We can only do this if the reloc is within a single
1334 if (rel->howto != NULL
1335 && rel->howto->pc_relative
1336 && bfd_get_section (sym) == insec->output_section)
1340 if (rel->howto->pcrel_offset)
1343 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1345 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1349 memmove (relocs, relocs + 1,
1350 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1354 /* NetWare doesn't support reloc addends, so we get rid of them
1355 here by simply adding them into the object data. We handle
1356 the symbol value, if any, the same way. */
1358 && rel->howto != NULL
1359 && rel->howto->rightshift == 0
1360 && rel->howto->size == 2
1361 && rel->howto->bitsize == 32
1362 && rel->howto->bitpos == 0
1363 && rel->howto->src_mask == 0xffffffff
1364 && rel->howto->dst_mask == 0xffffffff)
1368 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1370 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1372 /* Adjust the reloc for the changes we just made. */
1374 if (bfd_get_section (sym) != &bfd_und_section)
1375 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1378 /* NetWare uses a reloc with pcrel_offset set. We adjust
1379 pc_relative relocs accordingly. We are going to change the
1380 howto field, so we can only do this if the current one is
1381 compatible. We should check that special_function is NULL
1382 here, but at the moment coff-i386 uses a special_function
1383 which does not affect what we are doing here. */
1384 if (rel->howto != NULL
1385 && rel->howto->pc_relative
1386 && ! rel->howto->pcrel_offset
1387 && rel->howto->rightshift == 0
1388 && rel->howto->size == 2
1389 && rel->howto->bitsize == 32
1390 && rel->howto->bitpos == 0
1391 && rel->howto->src_mask == 0xffffffff
1392 && rel->howto->dst_mask == 0xffffffff)
1396 /* When pcrel_offset is not set, it means that the negative
1397 of the address of the memory location is stored in the
1398 memory location. We must add it back in. */
1399 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1401 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1403 /* We must change to a new howto. */
1404 rel->howto = &nlm_i386_pcrel_howto;
1409 /* On the Alpha the first reloc for every section must be a special
1410 relocs which hold the GP address. Also, the first reloc in the
1411 file must be a special reloc which holds the address of the .lita
1414 static reloc_howto_type nlm32_alpha_nw_howto =
1415 HOWTO (ALPHA_R_NW_RELOC, /* type */
1417 0, /* size (0 = byte, 1 = short, 2 = long) */
1419 false, /* pc_relative */
1421 complain_overflow_dont, /* complain_on_overflow */
1422 0, /* special_function */
1423 "NW_RELOC", /* name */
1424 false, /* partial_inplace */
1427 false); /* pcrel_offset */
1431 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1435 register arelent ***relocs_ptr;
1436 bfd_size_type *reloc_count_ptr;
1438 bfd_size_type contents_size;
1440 bfd_size_type old_reloc_count;
1441 arelent **old_relocs;
1442 register arelent **relocs;
1444 old_reloc_count = *reloc_count_ptr;
1445 old_relocs = *relocs_ptr;
1446 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1447 *relocs_ptr = relocs;
1449 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1452 asection *lita_section;
1454 inbfd = insec->owner;
1455 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1456 if (lita_section != (asection *) NULL)
1458 nlm_alpha_backend_data (outbfd)->lita_address =
1459 bfd_get_section_vma (inbfd, lita_section);
1460 nlm_alpha_backend_data (outbfd)->lita_size =
1461 bfd_section_size (inbfd, lita_section);
1465 /* Avoid outputting this reloc again. */
1466 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1469 *relocs = (arelent *) xmalloc (sizeof (arelent));
1470 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1471 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1472 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1473 (*relocs)->howto = &nlm32_alpha_nw_howto;
1475 ++(*reloc_count_ptr);
1478 /* Get the GP value from bfd. It is in the .reginfo section. */
1479 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1482 asection *reginfo_sec;
1483 struct ecoff_reginfo sreginfo;
1485 inbfd = insec->owner;
1486 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1487 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1488 if (reginfo_sec != (asection *) NULL
1489 && bfd_get_section_contents (inbfd, reginfo_sec,
1490 (PTR) &sreginfo, (file_ptr) 0,
1491 sizeof sreginfo) != false)
1492 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1495 *relocs = (arelent *) xmalloc (sizeof (arelent));
1496 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1497 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1498 (*relocs)->addend = 0;
1499 (*relocs)->howto = &nlm32_alpha_nw_howto;
1501 ++(*reloc_count_ptr);
1503 memcpy ((PTR) relocs, (PTR) old_relocs,
1504 (size_t) old_reloc_count * sizeof (arelent *));
1505 relocs[old_reloc_count] = (arelent *) NULL;
1509 if (insec->output_offset != 0)
1511 register bfd_size_type i;
1513 for (i = 0; i < old_reloc_count; i++, relocs++)
1514 (*relocs)->address += insec->output_offset;
1518 /* Name of linker. */
1520 #define LD_NAME "ld"
1523 /* Temporary file name base. */
1524 static char *temp_filename;
1526 /* The user has specified several input files. Invoke the linker to
1527 link them all together, and convert and delete the resulting output
1531 link_inputs (inputs, ld)
1532 struct string_list *inputs;
1536 struct string_list *q;
1543 for (q = inputs; q != NULL; q = q->next)
1546 argv = (char **) alloca (c + 5);
1553 /* Find the linker to invoke based on how nlmconv was run. */
1554 p = program_name + strlen (program_name);
1555 while (p != program_name)
1559 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
1560 memcpy (ld, program_name, p - program_name);
1561 strcpy (ld + (p - program_name), LD_NAME);
1570 ld = (char *) LD_NAME;
1572 choose_temp_base ();
1574 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
1575 sprintf (unlink_on_exit, "%s.O", temp_filename);
1578 argv[1] = (char *) "-r";
1579 argv[2] = (char *) "-o";
1580 argv[3] = unlink_on_exit;
1582 for (q = inputs; q != NULL; q = q->next, i++)
1583 argv[i] = q->string;
1588 for (i = 0; argv[i] != NULL; i++)
1589 fprintf (stderr, " %s", argv[i]);
1590 fprintf (stderr, "\n");
1593 pid = pexecute (ld, argv);
1595 if (waitpid (pid, &status, 0) < 0)
1598 unlink (unlink_on_exit);
1604 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
1605 unlink (unlink_on_exit);
1609 return unlink_on_exit;
1612 /* Choose a temporary file name. Stolen from gcc.c. */
1615 choose_temp_base_try (try, base)
1623 else if (try == NULL)
1625 else if (access (try, R_OK | W_OK) != 0)
1635 const char *base = NULL;
1638 base = choose_temp_base_try (getenv ("TMPDIR"), base);
1639 base = choose_temp_base_try (getenv ("TMP"), base);
1640 base = choose_temp_base_try (getenv ("TEMP"), base);
1643 base = choose_temp_base_try (P_tmpdir, base);
1646 base = choose_temp_base_try ("/usr/tmp", base);
1647 base = choose_temp_base_try ("/tmp", base);
1649 /* If all else fails, use the current directory! */
1653 len = strlen (base);
1654 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
1655 strcpy (temp_filename, base);
1656 if (len > 0 && temp_filename[len-1] != '/')
1657 temp_filename[len++] = '/';
1658 strcpy (temp_filename + len, "ccXXXXXX");
1660 mktemp (temp_filename);
1661 if (*temp_filename == '\0')
1665 /* Execute a job. Stolen from gcc.c. */
1671 pexecute (program, argv)
1679 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
1680 rf = scmd + strlen(program) + 2 + el;
1681 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
1682 argfile = fopen (rf, "w");
1684 pfatal_with_name (rf);
1686 for (i=1; argv[i]; i++)
1689 for (cp = argv[i]; *cp; cp++)
1691 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
1692 fputc ('\\', argfile);
1693 fputc (*cp, argfile);
1695 fputc ('\n', argfile);
1706 return MIN_FATAL_STATUS << 8;
1712 #else /* not __MSDOS__ */
1715 pexecute (program, argv)
1720 int retries, sleep_interval;
1722 /* Fork a subprocess; wait and retry if it fails. */
1724 for (retries = 0; retries < 4; retries++)
1729 sleep (sleep_interval);
1730 sleep_interval *= 2;
1746 /* Exec the program. */
1747 execvp (program, argv);
1754 /* Return child's process number. */
1759 #endif /* not __MSDOS__ */
1763 pexecute (program, argv)
1767 return spawnvp (1, program, argv);
1769 #endif /* not OS2 */