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-format", required_argument, 0, 'I' },
101 { "linker", required_argument, 0, 'l' },
102 { "output-format", required_argument, 0, 'O' },
103 { "version", no_argument, 0, 'V' },
104 { NULL, no_argument, 0, 0 }
107 /* Local routines. */
109 static void show_help PARAMS ((void));
110 static void show_usage PARAMS ((FILE *, int));
111 static const char *select_output_format PARAMS ((enum bfd_architecture,
112 unsigned long, boolean));
113 static void setup_sections PARAMS ((bfd *, asection *, PTR));
114 static void copy_sections PARAMS ((bfd *, asection *, PTR));
115 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
116 bfd_size_type *, char *,
118 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
119 bfd_size_type *, char *,
121 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
122 bfd_size_type *, char *,
124 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
125 bfd_size_type *, char *,
127 static char *link_inputs PARAMS ((struct string_list *, char *));
128 static const char *choose_temp_base_try PARAMS ((const char *,
130 static void choose_temp_base PARAMS ((void));
131 static int pexecute PARAMS ((char *, char *[]));
133 /* The main routine. */
141 char *input_file = NULL;
142 const char *input_format = NULL;
143 const char *output_format = NULL;
144 const char *header_file = NULL;
146 Nlm_Internal_Fixed_Header fixed_hdr_struct;
147 Nlm_Internal_Variable_Header var_hdr_struct;
148 Nlm_Internal_Version_Header version_hdr_struct;
149 Nlm_Internal_Copyright_Header copyright_hdr_struct;
150 Nlm_Internal_Extended_Header extended_hdr_struct;
153 asymbol **newsyms, **outsyms;
154 unsigned int symcount, newsymalloc, newsymcount;
155 asection *bss_sec, *data_sec;
160 char inlead, outlead;
161 boolean gotstart, gotexit, gotcheck;
163 FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
164 size_t custom_size, help_size, message_size, module_size, rpc_size;
165 asection *custom_section, *help_section, *message_section, *module_section;
166 asection *rpc_section, *shared_section;
168 size_t shared_offset, shared_size;
169 Nlm_Internal_Fixed_Header sharedhdr;
173 program_name = argv[0];
177 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
190 input_format = optarg;
196 output_format = optarg;
199 header_file = optarg;
202 printf ("GNU %s version %s\n", program_name, program_version);
208 show_usage (stderr, 1);
213 /* The input and output files may be named on the command line. */
217 input_file = argv[optind];
221 output_file = argv[optind];
224 show_usage (stderr, 1);
225 if (strcmp (input_file, output_file) == 0)
228 "%s: input and output files must be different\n",
235 /* Initialize the header information to default values. */
236 fixed_hdr = &fixed_hdr_struct;
237 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
238 var_hdr = &var_hdr_struct;
239 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
240 version_hdr = &version_hdr_struct;
241 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
242 copyright_hdr = ©right_hdr_struct;
243 memset ((PTR) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
244 extended_hdr = &extended_hdr_struct;
245 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
246 check_procedure = NULL;
249 exit_procedure = "_Stop";
250 export_symbols = NULL;
254 import_symbols = NULL;
257 sharelib_file = NULL;
258 start_procedure = "_Prelude";
264 /* Parse the header file (if there is one). */
265 if (header_file != NULL)
267 if (! nlmlex_file (header_file)
269 || parse_errors != 0)
273 if (input_files != NULL)
275 if (input_file != NULL)
278 "%s: input file named both on command line and with INPUT\n",
282 if (input_files->next == NULL)
283 input_file = input_files->string;
285 input_file = link_inputs (input_files, ld_arg);
287 else if (input_file == NULL)
289 fprintf (stderr, "%s: no input file\n", program_name);
290 show_usage (stderr, 1);
293 inbfd = bfd_openr (input_file, input_format);
295 bfd_fatal (input_file);
297 if (! bfd_check_format (inbfd, bfd_object))
298 bfd_fatal (input_file);
300 if (output_format == NULL)
301 output_format = select_output_format (bfd_get_arch (inbfd),
302 bfd_get_mach (inbfd),
303 inbfd->xvec->byteorder_big_p);
305 assert (output_format != NULL);
307 /* Use the output file named on the command line if it exists.
308 Otherwise use the file named in the OUTPUT statement. */
309 if (output_file == NULL)
311 fprintf (stderr, "%s: no name for output file\n",
313 show_usage (stderr, 1);
316 outbfd = bfd_openw (output_file, output_format);
318 bfd_fatal (output_file);
319 if (! bfd_set_format (outbfd, bfd_object))
320 bfd_fatal (output_file);
322 assert (outbfd->xvec->flavour == bfd_target_nlm_flavour);
324 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
326 "%s: warning:input and output formats are not compatible\n",
329 /* Move the values read from the command file into outbfd. */
330 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
331 *nlm_variable_header (outbfd) = var_hdr_struct;
332 *nlm_version_header (outbfd) = version_hdr_struct;
333 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
334 *nlm_extended_header (outbfd) = extended_hdr_struct;
336 /* Start copying the input BFD to the output BFD. */
337 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
338 bfd_fatal (bfd_get_filename (outbfd));
340 symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
341 symcount = bfd_canonicalize_symtab (inbfd, symbols);
343 /* Make sure we have a .bss section. */
344 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
347 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
349 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
350 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
351 bfd_fatal ("make .bss section");
354 /* Set up the sections. */
355 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
357 /* The .bss section immediately follows the .data section. */
358 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
359 if (data_sec != NULL)
363 vma = bfd_get_section_size_before_reloc (data_sec);
364 align = 1 << bss_sec->alignment_power;
365 add = ((vma + align - 1) &~ (align - 1)) - vma;
367 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
368 bfd_fatal ("set .bss vma");
371 bfd_size_type data_size;
373 data_size = bfd_get_section_size_before_reloc (data_sec);
374 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
375 bfd_fatal ("set .data size");
379 /* Adjust symbol information. */
380 inlead = bfd_get_symbol_leading_char (inbfd);
381 outlead = bfd_get_symbol_leading_char (outbfd);
386 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
389 for (i = 0; i < symcount; i++)
391 register asymbol *sym;
395 /* Add or remove a leading underscore. */
396 if (inlead != outlead)
400 if (bfd_asymbol_name (sym)[0] == inlead)
408 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
410 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
419 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
421 strcpy (new + 1, bfd_asymbol_name (sym));
426 /* NLM's have an uninitialized data section, but they do not
427 have a common section in the Unix sense. Move all common
428 symbols into the .bss section, and mark them as exported. */
429 if (bfd_is_com_section (bfd_get_section (sym)))
433 sym->section = bss_sec;
435 sym->value = bss_sec->_raw_size;
436 bss_sec->_raw_size += size;
437 align = 1 << bss_sec->alignment_power;
438 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
439 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
441 else if (bfd_get_section (sym)->output_section != NULL)
443 /* Move the symbol into the output section. */
444 sym->value += bfd_get_section (sym)->output_offset;
445 sym->section = bfd_get_section (sym)->output_section;
446 /* This is no longer a section symbol. */
447 sym->flags &=~ BSF_SECTION_SYM;
450 /* Force _edata and _end to be defined. This would normally be
451 done by the linker, but the manipulation of the common
452 symbols will confuse it. */
453 if (bfd_asymbol_name (sym)[0] == '_'
454 && bfd_get_section (sym) == &bfd_und_section)
456 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
458 sym->section = bss_sec;
461 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
463 sym->section = bss_sec;
468 /* If this is a global symbol, check the export list. */
469 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
471 register struct string_list *l;
474 /* Unfortunately, a symbol can appear multiple times on the
475 export list, with and without prefixes. */
477 for (l = export_symbols; l != NULL; l = l->next)
479 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
485 zbase = strchr (l->string, '@');
487 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
489 /* We must add a symbol with this prefix. */
490 if (newsymcount >= newsymalloc)
493 newsyms = ((asymbol **)
496 * sizeof (asymbol *))));
498 newsyms[newsymcount] =
499 (asymbol *) xmalloc (sizeof (asymbol));
500 *newsyms[newsymcount] = *sym;
501 newsyms[newsymcount]->name = l->string;
508 /* The unmodified symbol is actually not exported at
510 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
511 sym->flags |= BSF_LOCAL;
515 /* If it's an undefined symbol, see if it's on the import list.
516 Change the prefix if necessary. */
517 if (bfd_get_section (sym) == &bfd_und_section)
519 register struct string_list *l;
521 for (l = import_symbols; l != NULL; l = l->next)
523 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
529 zbase = strchr (l->string, '@');
531 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
533 sym->name = l->string;
540 "%s: warning: symbol %s imported but not in import list\n",
541 program_name, bfd_asymbol_name (sym));
544 /* See if it's one of the special named symbols. */
545 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
547 if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
548 bfd_fatal ("set start address");
551 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
553 nlm_fixed_header (outbfd)->exitProcedureOffset =
554 bfd_asymbol_value (sym);
557 if (check_procedure != NULL
558 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
560 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
561 bfd_asymbol_value (sym);
567 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
569 if (newsymcount == 0)
573 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
574 * sizeof (asymbol *));
575 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
576 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
577 outsyms[symcount + newsymcount] = NULL;
580 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
583 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
584 program_name, start_procedure);
586 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
587 program_name, exit_procedure);
588 if (check_procedure != NULL
590 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
591 program_name, check_procedure);
593 /* Add additional sections required for the header information. */
594 if (custom_file != NULL)
596 custom_data = fopen (custom_file, "r");
597 if (custom_data == NULL
598 || fstat (fileno (custom_data), &st) < 0)
600 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
606 custom_size = st.st_size;
607 custom_section = bfd_make_section (outbfd, ".nlmcustom");
608 if (custom_section == NULL
609 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
610 || ! bfd_set_section_flags (outbfd, custom_section,
612 bfd_fatal ("custom section");
615 if (help_file != NULL)
617 help_data = fopen (help_file, "r");
618 if (help_data == NULL
619 || fstat (fileno (help_data), &st) < 0)
621 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
627 help_size = st.st_size;
628 help_section = bfd_make_section (outbfd, ".nlmhelp");
629 if (help_section == NULL
630 || ! bfd_set_section_size (outbfd, help_section, help_size)
631 || ! bfd_set_section_flags (outbfd, help_section,
633 bfd_fatal ("help section");
634 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
637 if (message_file != NULL)
639 message_data = fopen (message_file, "r");
640 if (message_data == NULL
641 || fstat (fileno (message_data), &st) < 0)
643 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
649 message_size = st.st_size;
650 message_section = bfd_make_section (outbfd, ".nlmmessages");
651 if (message_section == NULL
652 || ! bfd_set_section_size (outbfd, message_section, message_size)
653 || ! bfd_set_section_flags (outbfd, message_section,
655 bfd_fatal ("message section");
656 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
661 struct string_list *l;
664 for (l = modules; l != NULL; l = l->next)
665 module_size += strlen (l->string) + 1;
666 module_section = bfd_make_section (outbfd, ".nlmmodules");
667 if (module_section == NULL
668 || ! bfd_set_section_size (outbfd, module_section, module_size)
669 || ! bfd_set_section_flags (outbfd, module_section,
671 bfd_fatal ("module section");
673 if (rpc_file != NULL)
675 rpc_data = fopen (rpc_file, "r");
677 || fstat (fileno (rpc_data), &st) < 0)
679 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
685 rpc_size = st.st_size;
686 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
687 if (rpc_section == NULL
688 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
689 || ! bfd_set_section_flags (outbfd, rpc_section,
691 bfd_fatal ("rpc section");
692 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
695 if (sharelib_file != NULL)
697 sharedbfd = bfd_openr (sharelib_file, output_format);
698 if (sharedbfd == NULL
699 || ! bfd_check_format (sharedbfd, bfd_object))
701 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
702 bfd_errmsg (bfd_error));
703 sharelib_file = NULL;
707 sharedhdr = *nlm_fixed_header (sharedbfd);
708 bfd_close (sharedbfd);
709 shared_data = fopen (sharelib_file, "r");
710 if (shared_data == NULL
711 || (fstat (fileno (shared_data), &st) < 0))
713 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
715 sharelib_file = NULL;
719 /* If we were clever, we could just copy out the
720 sections of the shared library which we actually
721 need. However, we would have to figure out the sizes
722 of the external and public information, and that can
723 not be done without reading through them. */
724 shared_offset = st.st_size;
725 if (shared_offset > sharedhdr.codeImageOffset)
726 shared_offset = sharedhdr.codeImageOffset;
727 if (shared_offset > sharedhdr.dataImageOffset)
728 shared_offset = sharedhdr.dataImageOffset;
729 if (shared_offset > sharedhdr.relocationFixupOffset)
730 shared_offset = sharedhdr.relocationFixupOffset;
731 if (shared_offset > sharedhdr.externalReferencesOffset)
732 shared_offset = sharedhdr.externalReferencesOffset;
733 if (shared_offset > sharedhdr.publicsOffset)
734 shared_offset = sharedhdr.publicsOffset;
735 shared_size = st.st_size - shared_offset;
736 shared_section = bfd_make_section (outbfd, ".nlmshared");
737 if (shared_section == NULL
738 || ! bfd_set_section_size (outbfd, shared_section,
740 || ! bfd_set_section_flags (outbfd, shared_section,
742 bfd_fatal ("shared section");
743 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
748 /* Check whether a version was given. */
749 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
750 fprintf (stderr, "%s: warning: No version number given\n",
753 /* At least for now, always create an extended header, because that
754 is what NLMLINK does. */
755 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
757 /* If the date was not given, force it in. */
758 if (nlm_version_header (outbfd)->month == 0
759 && nlm_version_header (outbfd)->day == 0
760 && nlm_version_header (outbfd)->year == 0)
766 ptm = localtime (&now);
767 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
768 nlm_version_header (outbfd)->day = ptm->tm_mday;
769 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
770 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
773 /* Copy over the sections. */
774 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
776 /* Finish up the header information. */
777 if (custom_file != NULL)
781 data = xmalloc (custom_size);
782 if (fread (data, 1, custom_size, custom_data) != custom_size)
783 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
787 if (! bfd_set_section_contents (outbfd, custom_section, data,
788 (file_ptr) 0, custom_size))
789 bfd_fatal ("custom section");
790 nlm_fixed_header (outbfd)->customDataOffset =
791 custom_section->filepos;
792 nlm_fixed_header (outbfd)->customDataSize = custom_size;
798 /* As a special hack, the backend recognizes a debugInfoOffset
799 of -1 to mean that it should not output any debugging
800 information. This can not be handling by fiddling with the
801 symbol table because exported symbols appear in both the
802 export information and the debugging information. */
803 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
805 if (map_file != NULL)
807 "%s: MAP and FULLMAP are not supported; try ld -M\n",
809 if (help_file != NULL)
813 data = xmalloc (help_size);
814 if (fread (data, 1, help_size, help_data) != help_size)
815 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
819 if (! bfd_set_section_contents (outbfd, help_section, data,
820 (file_ptr) 0, help_size))
821 bfd_fatal ("help section");
822 nlm_extended_header (outbfd)->helpFileOffset =
823 help_section->filepos;
824 nlm_extended_header (outbfd)->helpFileLength = help_size;
828 if (message_file != NULL)
832 data = xmalloc (message_size);
833 if (fread (data, 1, message_size, message_data) != message_size)
834 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
838 if (! bfd_set_section_contents (outbfd, message_section, data,
839 (file_ptr) 0, message_size))
840 bfd_fatal ("message section");
841 nlm_extended_header (outbfd)->messageFileOffset =
842 message_section->filepos;
843 nlm_extended_header (outbfd)->messageFileLength = message_size;
845 /* FIXME: Are these offsets correct on all platforms? Are
846 they 32 bits on all platforms? What endianness? */
847 nlm_extended_header (outbfd)->languageID =
848 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
849 nlm_extended_header (outbfd)->messageCount =
850 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
858 struct string_list *l;
861 data = xmalloc (module_size);
863 set = (unsigned char *) data;
864 for (l = modules; l != NULL; l = l->next)
866 *set = strlen (l->string);
867 strncpy (set + 1, l->string, *set);
871 if (! bfd_set_section_contents (outbfd, module_section, data,
872 (file_ptr) 0, module_size))
873 bfd_fatal ("module section");
874 nlm_fixed_header (outbfd)->moduleDependencyOffset =
875 module_section->filepos;
876 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
878 if (rpc_file != NULL)
882 data = xmalloc (rpc_size);
883 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
884 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
888 if (! bfd_set_section_contents (outbfd, rpc_section, data,
889 (file_ptr) 0, rpc_size))
890 bfd_fatal ("rpc section");
891 nlm_extended_header (outbfd)->RPCDataOffset =
892 rpc_section->filepos;
893 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
897 if (sharelib_file != NULL)
901 data = xmalloc (shared_size);
902 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
903 || fread (data, 1, shared_size, shared_data) != shared_size)
904 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
908 if (! bfd_set_section_contents (outbfd, shared_section, data,
909 (file_ptr) 0, shared_size))
910 bfd_fatal ("shared section");
912 nlm_extended_header (outbfd)->sharedCodeOffset =
913 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
914 nlm_extended_header (outbfd)->sharedCodeLength =
915 sharedhdr.codeImageSize;
916 nlm_extended_header (outbfd)->sharedDataOffset =
917 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
918 nlm_extended_header (outbfd)->sharedDataLength =
919 sharedhdr.dataImageSize;
920 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
921 (sharedhdr.relocationFixupOffset
923 + shared_section->filepos);
924 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
925 sharedhdr.numberOfRelocationFixups;
926 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
927 (sharedhdr.externalReferencesOffset
929 + shared_section->filepos);
930 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
931 sharedhdr.numberOfExternalReferences;
932 nlm_extended_header (outbfd)->sharedPublicsOffset =
933 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
934 nlm_extended_header (outbfd)->sharedPublicsCount =
935 sharedhdr.numberOfPublics;
936 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
937 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
938 nlm_extended_header (outbfd)->sharedDebugRecordCount =
939 sharedhdr.numberOfDebugRecords;
940 nlm_extended_header (outbfd)->SharedInitializationOffset =
941 sharedhdr.codeStartOffset;
942 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
943 sharedhdr.exitProcedureOffset;
946 len = strlen (output_file);
947 if (len > NLM_MODULE_NAME_SIZE - 2)
948 len = NLM_MODULE_NAME_SIZE - 2;
949 nlm_fixed_header (outbfd)->moduleName[0] = len;
951 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
952 NLM_MODULE_NAME_SIZE - 2);
953 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
954 for (modname = nlm_fixed_header (outbfd)->moduleName;
957 if (islower (*modname))
958 *modname = toupper (*modname);
960 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
961 NLM_OLD_THREAD_NAME_LENGTH);
963 if (! bfd_close (outbfd))
964 bfd_fatal (output_file);
965 if (! bfd_close (inbfd))
966 bfd_fatal (input_file);
968 if (unlink_on_exit != NULL)
969 unlink (unlink_on_exit);
974 /* Display a help message and exit. */
979 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
981 show_usage (stdout, 0);
984 /* Show a usage message and exit. */
987 show_usage (file, status)
992 Usage: %s [-dhV] [-I format] [-O format] [-T header-file] [-l linker]\n\
993 [--input-format=format] [--output-format=format]\n\
994 [--header-file=file] [--linker=linker] [--debug]\n\
995 [--help] [--version]\n\
996 [in-file [out-file]]\n",
1001 /* Select the output format based on the input architecture, machine,
1002 and endianness. This chooses the appropriate NLM target. */
1005 select_output_format (arch, mach, bigendian)
1006 enum bfd_architecture arch;
1013 return "nlm32-i386";
1014 case bfd_arch_sparc:
1015 return "nlm32-sparc";
1016 case bfd_arch_alpha:
1017 return "nlm32-alpha";
1019 fprintf (stderr, "%s: no default NLM format for %s\n",
1020 program_name, bfd_printable_arch_mach (arch, mach));
1022 /* Avoid warning. */
1028 /* The BFD sections are copied in two passes. This function selects
1029 the output section for each input section, and sets up the section
1033 setup_sections (inbfd, insec, data_ptr)
1038 bfd *outbfd = (bfd *) data_ptr;
1040 const char *outname;
1043 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1044 file. However, I don't have a good way to describe this section.
1045 We do want to copy the section when using objcopy. */
1046 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1047 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1050 f = bfd_get_section_flags (inbfd, insec);
1052 outname = NLM_CODE_NAME;
1053 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1054 outname = NLM_INITIALIZED_DATA_NAME;
1055 else if (f & SEC_ALLOC)
1056 outname = NLM_UNINITIALIZED_DATA_NAME;
1058 outname = bfd_section_name (inbfd, insec);
1060 outsec = bfd_get_section_by_name (outbfd, outname);
1063 outsec = bfd_make_section (outbfd, outname);
1065 bfd_fatal ("make section");
1068 insec->output_section = outsec;
1069 insec->output_offset = bfd_section_size (outbfd, outsec);
1071 if (! bfd_set_section_size (outbfd, outsec,
1072 (bfd_section_size (outbfd, outsec)
1073 + bfd_section_size (inbfd, insec))))
1074 bfd_fatal ("set section size");
1076 if ((bfd_section_alignment (inbfd, insec)
1077 > bfd_section_alignment (outbfd, outsec))
1078 && ! bfd_set_section_alignment (outbfd, outsec,
1079 bfd_section_alignment (inbfd, insec)))
1080 bfd_fatal ("set section alignment");
1082 if (! bfd_set_section_flags (outbfd, outsec, f))
1083 bfd_fatal ("set section flags");
1085 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1088 /* Copy the section contents. */
1091 copy_sections (inbfd, insec, data_ptr)
1096 bfd *outbfd = (bfd *) data_ptr;
1100 bfd_size_type reloc_size;
1102 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1103 file. However, I don't have a good way to describe this section.
1104 We do want to copy the section when using objcopy. */
1105 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1106 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1109 outsec = insec->output_section;
1110 assert (outsec != NULL);
1112 size = bfd_get_section_size_before_reloc (insec);
1116 /* FIXME: Why are these necessary? */
1117 insec->_cooked_size = insec->_raw_size;
1118 insec->reloc_done = true;
1120 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1124 contents = xmalloc (size);
1125 if (! bfd_get_section_contents (inbfd, insec, contents,
1126 (file_ptr) 0, size))
1127 bfd_fatal (bfd_get_filename (inbfd));
1130 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1131 if (reloc_size != 0)
1134 bfd_size_type reloc_count;
1136 relocs = (arelent **) xmalloc (reloc_size);
1137 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1138 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1141 /* FIXME: refers to internal BFD fields. */
1142 if (outsec->orelocation != (arelent **) NULL)
1144 bfd_size_type total_count;
1147 total_count = reloc_count + outsec->reloc_count;
1148 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1149 memcpy (combined, outsec->orelocation,
1150 outsec->reloc_count * sizeof (arelent));
1151 memcpy (combined + outsec->reloc_count, relocs,
1152 (size_t) (reloc_count * sizeof (arelent)));
1153 free (outsec->orelocation);
1154 reloc_count = total_count;
1158 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1161 if (contents != NULL)
1163 if (! bfd_set_section_contents (outbfd, outsec, contents,
1164 insec->output_offset, size))
1165 bfd_fatal (bfd_get_filename (outbfd));
1170 /* Some, perhaps all, NetWare targets require changing the relocs used
1171 by the input formats. */
1174 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1178 arelent ***relocs_ptr;
1179 bfd_size_type *reloc_count_ptr;
1181 bfd_size_type contents_size;
1183 switch (bfd_get_arch (outbfd))
1186 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1187 contents, contents_size);
1189 case bfd_arch_alpha:
1190 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1191 contents, contents_size);
1194 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1195 contents, contents_size);
1200 /* By default all we need to do for relocs is change the address by
1201 the output_offset. */
1205 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1209 arelent ***relocs_ptr;
1210 bfd_size_type *reloc_count_ptr;
1212 bfd_size_type contents_size;
1214 if (insec->output_offset != 0)
1216 bfd_size_type reloc_count;
1217 register arelent **relocs;
1218 register bfd_size_type i;
1220 reloc_count = *reloc_count_ptr;
1221 relocs = *relocs_ptr;
1222 for (i = 0; i < reloc_count; i++, relocs++)
1223 (*relocs)->address += insec->output_offset;
1227 /* NetWare on the i386 supports a restricted set of relocs, which are
1228 different from those used on other i386 targets. This routine
1229 converts the relocs. It is, obviously, very target dependent. At
1230 the moment, the nlm32-i386 backend performs similar translations;
1231 however, it is more reliable and efficient to do them here. */
1233 static reloc_howto_type nlm_i386_pcrel_howto =
1234 HOWTO (1, /* type */
1236 2, /* size (0 = byte, 1 = short, 2 = long) */
1238 true, /* pc_relative */
1240 complain_overflow_signed, /* complain_on_overflow */
1241 0, /* special_function */
1242 "DISP32", /* name */
1243 true, /* partial_inplace */
1244 0xffffffff, /* src_mask */
1245 0xffffffff, /* dst_mask */
1246 true); /* pcrel_offset */
1249 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1253 arelent ***relocs_ptr;
1254 bfd_size_type *reloc_count_ptr;
1256 bfd_size_type contents_size;
1258 bfd_size_type reloc_count, i;
1261 reloc_count = *reloc_count_ptr;
1262 relocs = *relocs_ptr;
1263 for (i = 0; i < reloc_count; i++)
1267 bfd_size_type address;
1271 sym = *rel->sym_ptr_ptr;
1273 /* We're moving the relocs from the input section to the output
1274 section, so we must adjust the address accordingly. */
1275 address = rel->address;
1276 rel->address += insec->output_offset;
1278 /* Note that no serious harm will ensue if we fail to change a
1279 reloc. The backend will fail when writing out the reloc. */
1281 /* Make sure this reloc is within the data we have. We use only
1282 4 byte relocs here, so we insist on having 4 bytes. */
1283 if (address + 4 > contents_size)
1286 /* A PC relative reloc entirely within a single section is
1287 completely unnecessary. This can be generated by ld -r. */
1288 if (sym == insec->symbol
1289 && rel->howto != NULL
1290 && rel->howto->pc_relative
1291 && ! rel->howto->pcrel_offset)
1295 memmove (relocs, relocs + 1,
1296 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1300 /* Get the amount the relocation will add in. */
1301 addend = rel->addend + sym->value;
1303 /* NetWare doesn't support PC relative relocs against defined
1304 symbols, so we have to eliminate them by doing the relocation
1305 now. We can only do this if the reloc is within a single
1307 if (rel->howto != NULL
1308 && rel->howto->pc_relative
1309 && bfd_get_section (sym) == insec->output_section)
1313 if (rel->howto->pcrel_offset)
1316 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1318 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1322 memmove (relocs, relocs + 1,
1323 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1327 /* NetWare doesn't support reloc addends, so we get rid of them
1328 here by simply adding them into the object data. We handle
1329 the symbol value, if any, the same way. */
1331 && rel->howto != NULL
1332 && rel->howto->rightshift == 0
1333 && rel->howto->size == 2
1334 && rel->howto->bitsize == 32
1335 && rel->howto->bitpos == 0
1336 && rel->howto->src_mask == 0xffffffff
1337 && rel->howto->dst_mask == 0xffffffff)
1341 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1343 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1345 /* Adjust the reloc for the changes we just made. */
1347 if (bfd_get_section (sym) != &bfd_und_section)
1348 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1351 /* NetWare uses a reloc with pcrel_offset set. We adjust
1352 pc_relative relocs accordingly. We are going to change the
1353 howto field, so we can only do this if the current one is
1354 compatible. We should check that special_function is NULL
1355 here, but at the moment coff-i386 uses a special_function
1356 which does not affect what we are doing here. */
1357 if (rel->howto != NULL
1358 && rel->howto->pc_relative
1359 && ! rel->howto->pcrel_offset
1360 && rel->howto->rightshift == 0
1361 && rel->howto->size == 2
1362 && rel->howto->bitsize == 32
1363 && rel->howto->bitpos == 0
1364 && rel->howto->src_mask == 0xffffffff
1365 && rel->howto->dst_mask == 0xffffffff)
1369 /* When pcrel_offset is not set, it means that the negative
1370 of the address of the memory location is stored in the
1371 memory location. We must add it back in. */
1372 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1374 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1376 /* We must change to a new howto. */
1377 rel->howto = &nlm_i386_pcrel_howto;
1382 /* On the Alpha the first reloc for every section must be a special
1383 relocs which hold the GP address. Also, the first reloc in the
1384 file must be a special reloc which holds the address of the .lita
1387 static reloc_howto_type nlm32_alpha_nw_howto =
1388 HOWTO (ALPHA_R_NW_RELOC, /* type */
1390 0, /* size (0 = byte, 1 = short, 2 = long) */
1392 false, /* pc_relative */
1394 complain_overflow_dont, /* complain_on_overflow */
1395 0, /* special_function */
1396 "NW_RELOC", /* name */
1397 false, /* partial_inplace */
1400 false); /* pcrel_offset */
1404 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1408 register arelent ***relocs_ptr;
1409 bfd_size_type *reloc_count_ptr;
1411 bfd_size_type contents_size;
1413 bfd_size_type old_reloc_count;
1414 arelent **old_relocs;
1415 register arelent **relocs;
1417 old_reloc_count = *reloc_count_ptr;
1418 old_relocs = *relocs_ptr;
1419 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1420 *relocs_ptr = relocs;
1422 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1425 asection *lita_section;
1427 inbfd = insec->owner;
1428 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1429 if (lita_section != (asection *) NULL)
1431 nlm_alpha_backend_data (outbfd)->lita_address =
1432 bfd_get_section_vma (inbfd, lita_section);
1433 nlm_alpha_backend_data (outbfd)->lita_size =
1434 bfd_section_size (inbfd, lita_section);
1438 /* Avoid outputting this reloc again. */
1439 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1442 *relocs = (arelent *) xmalloc (sizeof (arelent));
1443 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1444 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1445 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1446 (*relocs)->howto = &nlm32_alpha_nw_howto;
1448 ++(*reloc_count_ptr);
1451 /* Get the GP value from bfd. It is in the .reginfo section. */
1452 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1455 asection *reginfo_sec;
1456 struct ecoff_reginfo sreginfo;
1458 inbfd = insec->owner;
1459 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1460 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1461 if (reginfo_sec != (asection *) NULL
1462 && bfd_get_section_contents (inbfd, reginfo_sec,
1463 (PTR) &sreginfo, (file_ptr) 0,
1464 sizeof sreginfo) != false)
1465 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
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)->gp;
1471 (*relocs)->addend = 0;
1472 (*relocs)->howto = &nlm32_alpha_nw_howto;
1474 ++(*reloc_count_ptr);
1476 memcpy ((PTR) relocs, (PTR) old_relocs,
1477 (size_t) old_reloc_count * sizeof (arelent *));
1478 relocs[old_reloc_count] = (arelent *) NULL;
1482 if (insec->output_offset != 0)
1484 register bfd_size_type i;
1486 for (i = 0; i < old_reloc_count; i++, relocs++)
1487 (*relocs)->address += insec->output_offset;
1491 /* Name of linker. */
1493 #define LD_NAME "ld"
1496 /* Temporary file name base. */
1497 static char *temp_filename;
1499 /* The user has specified several input files. Invoke the linker to
1500 link them all together, and convert and delete the resulting output
1504 link_inputs (inputs, ld)
1505 struct string_list *inputs;
1509 struct string_list *q;
1516 for (q = inputs; q != NULL; q = q->next)
1519 argv = (char **) alloca (c + 5);
1526 /* Find the linker to invoke based on how nlmconv was run. */
1527 p = program_name + strlen (program_name);
1528 while (p != program_name)
1532 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
1533 memcpy (ld, program_name, p - program_name);
1534 strcpy (ld + (p - program_name), LD_NAME);
1543 ld = (char *) LD_NAME;
1545 choose_temp_base ();
1547 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
1548 sprintf (unlink_on_exit, "%s.O", temp_filename);
1551 argv[1] = (char *) "-r";
1552 argv[2] = (char *) "-o";
1553 argv[3] = unlink_on_exit;
1555 for (q = inputs; q != NULL; q = q->next, i++)
1556 argv[i] = q->string;
1561 for (i = 0; argv[i] != NULL; i++)
1562 fprintf (stderr, " %s", argv[i]);
1563 fprintf (stderr, "\n");
1566 pid = pexecute (ld, argv);
1568 if (waitpid (pid, &status, 0) < 0)
1571 unlink (unlink_on_exit);
1577 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
1578 unlink (unlink_on_exit);
1582 return unlink_on_exit;
1585 /* Choose a temporary file name. Stolen from gcc.c. */
1588 choose_temp_base_try (try, base)
1596 else if (try == NULL)
1598 else if (access (try, R_OK | W_OK) != 0)
1608 const char *base = NULL;
1611 base = choose_temp_base_try (getenv ("TMPDIR"), base);
1612 base = choose_temp_base_try (getenv ("TMP"), base);
1613 base = choose_temp_base_try (getenv ("TEMP"), base);
1616 base = choose_temp_base_try (P_tmpdir, base);
1619 base = choose_temp_base_try ("/usr/tmp", base);
1620 base = choose_temp_base_try ("/tmp", base);
1622 /* If all else fails, use the current directory! */
1626 len = strlen (base);
1627 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
1628 strcpy (temp_filename, base);
1629 if (len > 0 && temp_filename[len-1] != '/')
1630 temp_filename[len++] = '/';
1631 strcpy (temp_filename + len, "ccXXXXXX");
1633 mktemp (temp_filename);
1634 if (*temp_filename == '\0')
1638 /* Execute a job. Stolen from gcc.c. */
1644 pexecute (program, argv)
1652 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
1653 rf = scmd + strlen(program) + 2 + el;
1654 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
1655 argfile = fopen (rf, "w");
1657 pfatal_with_name (rf);
1659 for (i=1; argv[i]; i++)
1662 for (cp = argv[i]; *cp; cp++)
1664 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
1665 fputc ('\\', argfile);
1666 fputc (*cp, argfile);
1668 fputc ('\n', argfile);
1679 return MIN_FATAL_STATUS << 8;
1685 #else /* not __MSDOS__ */
1688 pexecute (program, argv)
1693 int retries, sleep_interval;
1695 /* Fork a subprocess; wait and retry if it fails. */
1697 for (retries = 0; retries < 4; retries++)
1702 sleep (sleep_interval);
1703 sleep_interval *= 2;
1719 /* Exec the program. */
1720 execvp (program, argv);
1727 /* Return child's process number. */
1732 #endif /* not __MSDOS__ */
1736 pexecute (program, argv)
1740 return spawnvp (1, program, argv);
1742 #endif /* not OS2 */