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
518 && import_symbols != NULL)
520 register struct string_list *l;
522 for (l = import_symbols; l != NULL; l = l->next)
524 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
530 zbase = strchr (l->string, '@');
532 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
534 sym->name = l->string;
541 "%s: warning: symbol %s imported but not in import list\n",
542 program_name, bfd_asymbol_name (sym));
545 /* See if it's one of the special named symbols. */
546 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
548 if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
549 bfd_fatal ("set start address");
552 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
554 nlm_fixed_header (outbfd)->exitProcedureOffset =
555 bfd_asymbol_value (sym);
558 if (check_procedure != NULL
559 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
561 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
562 bfd_asymbol_value (sym);
568 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
570 if (newsymcount == 0)
574 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
575 * sizeof (asymbol *));
576 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
577 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
578 outsyms[symcount + newsymcount] = NULL;
581 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
584 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
585 program_name, start_procedure);
587 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
588 program_name, exit_procedure);
589 if (check_procedure != NULL
591 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
592 program_name, check_procedure);
594 /* Add additional sections required for the header information. */
595 if (custom_file != NULL)
597 custom_data = fopen (custom_file, "r");
598 if (custom_data == NULL
599 || fstat (fileno (custom_data), &st) < 0)
601 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
607 custom_size = st.st_size;
608 custom_section = bfd_make_section (outbfd, ".nlmcustom");
609 if (custom_section == NULL
610 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
611 || ! bfd_set_section_flags (outbfd, custom_section,
613 bfd_fatal ("custom section");
616 if (help_file != NULL)
618 help_data = fopen (help_file, "r");
619 if (help_data == NULL
620 || fstat (fileno (help_data), &st) < 0)
622 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
628 help_size = st.st_size;
629 help_section = bfd_make_section (outbfd, ".nlmhelp");
630 if (help_section == NULL
631 || ! bfd_set_section_size (outbfd, help_section, help_size)
632 || ! bfd_set_section_flags (outbfd, help_section,
634 bfd_fatal ("help section");
635 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
638 if (message_file != NULL)
640 message_data = fopen (message_file, "r");
641 if (message_data == NULL
642 || fstat (fileno (message_data), &st) < 0)
644 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
650 message_size = st.st_size;
651 message_section = bfd_make_section (outbfd, ".nlmmessages");
652 if (message_section == NULL
653 || ! bfd_set_section_size (outbfd, message_section, message_size)
654 || ! bfd_set_section_flags (outbfd, message_section,
656 bfd_fatal ("message section");
657 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
662 struct string_list *l;
665 for (l = modules; l != NULL; l = l->next)
666 module_size += strlen (l->string) + 1;
667 module_section = bfd_make_section (outbfd, ".nlmmodules");
668 if (module_section == NULL
669 || ! bfd_set_section_size (outbfd, module_section, module_size)
670 || ! bfd_set_section_flags (outbfd, module_section,
672 bfd_fatal ("module section");
674 if (rpc_file != NULL)
676 rpc_data = fopen (rpc_file, "r");
678 || fstat (fileno (rpc_data), &st) < 0)
680 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
686 rpc_size = st.st_size;
687 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
688 if (rpc_section == NULL
689 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
690 || ! bfd_set_section_flags (outbfd, rpc_section,
692 bfd_fatal ("rpc section");
693 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
696 if (sharelib_file != NULL)
698 sharedbfd = bfd_openr (sharelib_file, output_format);
699 if (sharedbfd == NULL
700 || ! bfd_check_format (sharedbfd, bfd_object))
702 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
703 bfd_errmsg (bfd_error));
704 sharelib_file = NULL;
708 sharedhdr = *nlm_fixed_header (sharedbfd);
709 bfd_close (sharedbfd);
710 shared_data = fopen (sharelib_file, "r");
711 if (shared_data == NULL
712 || (fstat (fileno (shared_data), &st) < 0))
714 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
716 sharelib_file = NULL;
720 /* If we were clever, we could just copy out the
721 sections of the shared library which we actually
722 need. However, we would have to figure out the sizes
723 of the external and public information, and that can
724 not be done without reading through them. */
725 shared_offset = st.st_size;
726 if (shared_offset > sharedhdr.codeImageOffset)
727 shared_offset = sharedhdr.codeImageOffset;
728 if (shared_offset > sharedhdr.dataImageOffset)
729 shared_offset = sharedhdr.dataImageOffset;
730 if (shared_offset > sharedhdr.relocationFixupOffset)
731 shared_offset = sharedhdr.relocationFixupOffset;
732 if (shared_offset > sharedhdr.externalReferencesOffset)
733 shared_offset = sharedhdr.externalReferencesOffset;
734 if (shared_offset > sharedhdr.publicsOffset)
735 shared_offset = sharedhdr.publicsOffset;
736 shared_size = st.st_size - shared_offset;
737 shared_section = bfd_make_section (outbfd, ".nlmshared");
738 if (shared_section == NULL
739 || ! bfd_set_section_size (outbfd, shared_section,
741 || ! bfd_set_section_flags (outbfd, shared_section,
743 bfd_fatal ("shared section");
744 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
749 /* Check whether a version was given. */
750 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
751 fprintf (stderr, "%s: warning: No version number given\n",
754 /* At least for now, always create an extended header, because that
755 is what NLMLINK does. */
756 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
758 /* If the date was not given, force it in. */
759 if (nlm_version_header (outbfd)->month == 0
760 && nlm_version_header (outbfd)->day == 0
761 && nlm_version_header (outbfd)->year == 0)
767 ptm = localtime (&now);
768 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
769 nlm_version_header (outbfd)->day = ptm->tm_mday;
770 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
771 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
774 /* Copy over the sections. */
775 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
777 /* Finish up the header information. */
778 if (custom_file != NULL)
782 data = xmalloc (custom_size);
783 if (fread (data, 1, custom_size, custom_data) != custom_size)
784 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
788 if (! bfd_set_section_contents (outbfd, custom_section, data,
789 (file_ptr) 0, custom_size))
790 bfd_fatal ("custom section");
791 nlm_fixed_header (outbfd)->customDataOffset =
792 custom_section->filepos;
793 nlm_fixed_header (outbfd)->customDataSize = custom_size;
799 /* As a special hack, the backend recognizes a debugInfoOffset
800 of -1 to mean that it should not output any debugging
801 information. This can not be handling by fiddling with the
802 symbol table because exported symbols appear in both the
803 export information and the debugging information. */
804 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
806 if (map_file != NULL)
808 "%s: MAP and FULLMAP are not supported; try ld -M\n",
810 if (help_file != NULL)
814 data = xmalloc (help_size);
815 if (fread (data, 1, help_size, help_data) != help_size)
816 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
820 if (! bfd_set_section_contents (outbfd, help_section, data,
821 (file_ptr) 0, help_size))
822 bfd_fatal ("help section");
823 nlm_extended_header (outbfd)->helpFileOffset =
824 help_section->filepos;
825 nlm_extended_header (outbfd)->helpFileLength = help_size;
829 if (message_file != NULL)
833 data = xmalloc (message_size);
834 if (fread (data, 1, message_size, message_data) != message_size)
835 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
839 if (! bfd_set_section_contents (outbfd, message_section, data,
840 (file_ptr) 0, message_size))
841 bfd_fatal ("message section");
842 nlm_extended_header (outbfd)->messageFileOffset =
843 message_section->filepos;
844 nlm_extended_header (outbfd)->messageFileLength = message_size;
846 /* FIXME: Are these offsets correct on all platforms? Are
847 they 32 bits on all platforms? What endianness? */
848 nlm_extended_header (outbfd)->languageID =
849 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
850 nlm_extended_header (outbfd)->messageCount =
851 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
859 struct string_list *l;
862 data = xmalloc (module_size);
864 set = (unsigned char *) data;
865 for (l = modules; l != NULL; l = l->next)
867 *set = strlen (l->string);
868 strncpy (set + 1, l->string, *set);
872 if (! bfd_set_section_contents (outbfd, module_section, data,
873 (file_ptr) 0, module_size))
874 bfd_fatal ("module section");
875 nlm_fixed_header (outbfd)->moduleDependencyOffset =
876 module_section->filepos;
877 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
879 if (rpc_file != NULL)
883 data = xmalloc (rpc_size);
884 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
885 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
889 if (! bfd_set_section_contents (outbfd, rpc_section, data,
890 (file_ptr) 0, rpc_size))
891 bfd_fatal ("rpc section");
892 nlm_extended_header (outbfd)->RPCDataOffset =
893 rpc_section->filepos;
894 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
898 if (sharelib_file != NULL)
902 data = xmalloc (shared_size);
903 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
904 || fread (data, 1, shared_size, shared_data) != shared_size)
905 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
909 if (! bfd_set_section_contents (outbfd, shared_section, data,
910 (file_ptr) 0, shared_size))
911 bfd_fatal ("shared section");
913 nlm_extended_header (outbfd)->sharedCodeOffset =
914 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
915 nlm_extended_header (outbfd)->sharedCodeLength =
916 sharedhdr.codeImageSize;
917 nlm_extended_header (outbfd)->sharedDataOffset =
918 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
919 nlm_extended_header (outbfd)->sharedDataLength =
920 sharedhdr.dataImageSize;
921 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
922 (sharedhdr.relocationFixupOffset
924 + shared_section->filepos);
925 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
926 sharedhdr.numberOfRelocationFixups;
927 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
928 (sharedhdr.externalReferencesOffset
930 + shared_section->filepos);
931 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
932 sharedhdr.numberOfExternalReferences;
933 nlm_extended_header (outbfd)->sharedPublicsOffset =
934 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
935 nlm_extended_header (outbfd)->sharedPublicsCount =
936 sharedhdr.numberOfPublics;
937 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
938 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
939 nlm_extended_header (outbfd)->sharedDebugRecordCount =
940 sharedhdr.numberOfDebugRecords;
941 nlm_extended_header (outbfd)->SharedInitializationOffset =
942 sharedhdr.codeStartOffset;
943 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
944 sharedhdr.exitProcedureOffset;
947 len = strlen (output_file);
948 if (len > NLM_MODULE_NAME_SIZE - 2)
949 len = NLM_MODULE_NAME_SIZE - 2;
950 nlm_fixed_header (outbfd)->moduleName[0] = len;
952 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
953 NLM_MODULE_NAME_SIZE - 2);
954 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
955 for (modname = nlm_fixed_header (outbfd)->moduleName;
958 if (islower (*modname))
959 *modname = toupper (*modname);
961 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
962 NLM_OLD_THREAD_NAME_LENGTH);
964 if (! bfd_close (outbfd))
965 bfd_fatal (output_file);
966 if (! bfd_close (inbfd))
967 bfd_fatal (input_file);
969 if (unlink_on_exit != NULL)
970 unlink (unlink_on_exit);
975 /* Display a help message and exit. */
980 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
982 show_usage (stdout, 0);
985 /* Show a usage message and exit. */
988 show_usage (file, status)
993 Usage: %s [-dhV] [-I format] [-O format] [-T header-file] [-l linker]\n\
994 [--input-format=format] [--output-format=format]\n\
995 [--header-file=file] [--linker=linker] [--debug]\n\
996 [--help] [--version]\n\
997 [in-file [out-file]]\n",
1002 /* Select the output format based on the input architecture, machine,
1003 and endianness. This chooses the appropriate NLM target. */
1006 select_output_format (arch, mach, bigendian)
1007 enum bfd_architecture arch;
1014 return "nlm32-i386";
1015 case bfd_arch_sparc:
1016 return "nlm32-sparc";
1017 case bfd_arch_alpha:
1018 return "nlm32-alpha";
1020 fprintf (stderr, "%s: no default NLM format for %s\n",
1021 program_name, bfd_printable_arch_mach (arch, mach));
1023 /* Avoid warning. */
1029 /* The BFD sections are copied in two passes. This function selects
1030 the output section for each input section, and sets up the section
1034 setup_sections (inbfd, insec, data_ptr)
1039 bfd *outbfd = (bfd *) data_ptr;
1041 const char *outname;
1044 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1045 file. However, I don't have a good way to describe this section.
1046 We do want to copy the section when using objcopy. */
1047 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1048 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1051 f = bfd_get_section_flags (inbfd, insec);
1053 outname = NLM_CODE_NAME;
1054 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1055 outname = NLM_INITIALIZED_DATA_NAME;
1056 else if (f & SEC_ALLOC)
1057 outname = NLM_UNINITIALIZED_DATA_NAME;
1059 outname = bfd_section_name (inbfd, insec);
1061 outsec = bfd_get_section_by_name (outbfd, outname);
1064 outsec = bfd_make_section (outbfd, outname);
1066 bfd_fatal ("make section");
1069 insec->output_section = outsec;
1070 insec->output_offset = bfd_section_size (outbfd, outsec);
1072 if (! bfd_set_section_size (outbfd, outsec,
1073 (bfd_section_size (outbfd, outsec)
1074 + bfd_section_size (inbfd, insec))))
1075 bfd_fatal ("set section size");
1077 if ((bfd_section_alignment (inbfd, insec)
1078 > bfd_section_alignment (outbfd, outsec))
1079 && ! bfd_set_section_alignment (outbfd, outsec,
1080 bfd_section_alignment (inbfd, insec)))
1081 bfd_fatal ("set section alignment");
1083 if (! bfd_set_section_flags (outbfd, outsec, f))
1084 bfd_fatal ("set section flags");
1086 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1089 /* Copy the section contents. */
1092 copy_sections (inbfd, insec, data_ptr)
1097 bfd *outbfd = (bfd *) data_ptr;
1101 bfd_size_type reloc_size;
1103 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1104 file. However, I don't have a good way to describe this section.
1105 We do want to copy the section when using objcopy. */
1106 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1107 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1110 outsec = insec->output_section;
1111 assert (outsec != NULL);
1113 size = bfd_get_section_size_before_reloc (insec);
1117 /* FIXME: Why are these necessary? */
1118 insec->_cooked_size = insec->_raw_size;
1119 insec->reloc_done = true;
1121 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1125 contents = xmalloc (size);
1126 if (! bfd_get_section_contents (inbfd, insec, contents,
1127 (file_ptr) 0, size))
1128 bfd_fatal (bfd_get_filename (inbfd));
1131 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1132 if (reloc_size != 0)
1135 bfd_size_type reloc_count;
1137 relocs = (arelent **) xmalloc (reloc_size);
1138 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1139 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1142 /* FIXME: refers to internal BFD fields. */
1143 if (outsec->orelocation != (arelent **) NULL)
1145 bfd_size_type total_count;
1148 total_count = reloc_count + outsec->reloc_count;
1149 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1150 memcpy (combined, outsec->orelocation,
1151 outsec->reloc_count * sizeof (arelent));
1152 memcpy (combined + outsec->reloc_count, relocs,
1153 (size_t) (reloc_count * sizeof (arelent)));
1154 free (outsec->orelocation);
1155 reloc_count = total_count;
1159 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1162 if (contents != NULL)
1164 if (! bfd_set_section_contents (outbfd, outsec, contents,
1165 insec->output_offset, size))
1166 bfd_fatal (bfd_get_filename (outbfd));
1171 /* Some, perhaps all, NetWare targets require changing the relocs used
1172 by the input formats. */
1175 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1179 arelent ***relocs_ptr;
1180 bfd_size_type *reloc_count_ptr;
1182 bfd_size_type contents_size;
1184 switch (bfd_get_arch (outbfd))
1187 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1188 contents, contents_size);
1190 case bfd_arch_alpha:
1191 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1192 contents, contents_size);
1195 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1196 contents, contents_size);
1201 /* By default all we need to do for relocs is change the address by
1202 the output_offset. */
1206 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1210 arelent ***relocs_ptr;
1211 bfd_size_type *reloc_count_ptr;
1213 bfd_size_type contents_size;
1215 if (insec->output_offset != 0)
1217 bfd_size_type reloc_count;
1218 register arelent **relocs;
1219 register bfd_size_type i;
1221 reloc_count = *reloc_count_ptr;
1222 relocs = *relocs_ptr;
1223 for (i = 0; i < reloc_count; i++, relocs++)
1224 (*relocs)->address += insec->output_offset;
1228 /* NetWare on the i386 supports a restricted set of relocs, which are
1229 different from those used on other i386 targets. This routine
1230 converts the relocs. It is, obviously, very target dependent. At
1231 the moment, the nlm32-i386 backend performs similar translations;
1232 however, it is more reliable and efficient to do them here. */
1234 static reloc_howto_type nlm_i386_pcrel_howto =
1235 HOWTO (1, /* type */
1237 2, /* size (0 = byte, 1 = short, 2 = long) */
1239 true, /* pc_relative */
1241 complain_overflow_signed, /* complain_on_overflow */
1242 0, /* special_function */
1243 "DISP32", /* name */
1244 true, /* partial_inplace */
1245 0xffffffff, /* src_mask */
1246 0xffffffff, /* dst_mask */
1247 true); /* pcrel_offset */
1250 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1254 arelent ***relocs_ptr;
1255 bfd_size_type *reloc_count_ptr;
1257 bfd_size_type contents_size;
1259 bfd_size_type reloc_count, i;
1262 reloc_count = *reloc_count_ptr;
1263 relocs = *relocs_ptr;
1264 for (i = 0; i < reloc_count; i++)
1268 bfd_size_type address;
1272 sym = *rel->sym_ptr_ptr;
1274 /* We're moving the relocs from the input section to the output
1275 section, so we must adjust the address accordingly. */
1276 address = rel->address;
1277 rel->address += insec->output_offset;
1279 /* Note that no serious harm will ensue if we fail to change a
1280 reloc. The backend will fail when writing out the reloc. */
1282 /* Make sure this reloc is within the data we have. We use only
1283 4 byte relocs here, so we insist on having 4 bytes. */
1284 if (address + 4 > contents_size)
1287 /* A PC relative reloc entirely within a single section is
1288 completely unnecessary. This can be generated by ld -r. */
1289 if (sym == insec->symbol
1290 && rel->howto != NULL
1291 && rel->howto->pc_relative
1292 && ! rel->howto->pcrel_offset)
1296 memmove (relocs, relocs + 1,
1297 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1301 /* Get the amount the relocation will add in. */
1302 addend = rel->addend + sym->value;
1304 /* NetWare doesn't support PC relative relocs against defined
1305 symbols, so we have to eliminate them by doing the relocation
1306 now. We can only do this if the reloc is within a single
1308 if (rel->howto != NULL
1309 && rel->howto->pc_relative
1310 && bfd_get_section (sym) == insec->output_section)
1314 if (rel->howto->pcrel_offset)
1317 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1319 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1323 memmove (relocs, relocs + 1,
1324 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1328 /* NetWare doesn't support reloc addends, so we get rid of them
1329 here by simply adding them into the object data. We handle
1330 the symbol value, if any, the same way. */
1332 && rel->howto != NULL
1333 && rel->howto->rightshift == 0
1334 && rel->howto->size == 2
1335 && rel->howto->bitsize == 32
1336 && rel->howto->bitpos == 0
1337 && rel->howto->src_mask == 0xffffffff
1338 && rel->howto->dst_mask == 0xffffffff)
1342 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1344 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1346 /* Adjust the reloc for the changes we just made. */
1348 if (bfd_get_section (sym) != &bfd_und_section)
1349 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1352 /* NetWare uses a reloc with pcrel_offset set. We adjust
1353 pc_relative relocs accordingly. We are going to change the
1354 howto field, so we can only do this if the current one is
1355 compatible. We should check that special_function is NULL
1356 here, but at the moment coff-i386 uses a special_function
1357 which does not affect what we are doing here. */
1358 if (rel->howto != NULL
1359 && rel->howto->pc_relative
1360 && ! rel->howto->pcrel_offset
1361 && rel->howto->rightshift == 0
1362 && rel->howto->size == 2
1363 && rel->howto->bitsize == 32
1364 && rel->howto->bitpos == 0
1365 && rel->howto->src_mask == 0xffffffff
1366 && rel->howto->dst_mask == 0xffffffff)
1370 /* When pcrel_offset is not set, it means that the negative
1371 of the address of the memory location is stored in the
1372 memory location. We must add it back in. */
1373 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1375 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1377 /* We must change to a new howto. */
1378 rel->howto = &nlm_i386_pcrel_howto;
1383 /* On the Alpha the first reloc for every section must be a special
1384 relocs which hold the GP address. Also, the first reloc in the
1385 file must be a special reloc which holds the address of the .lita
1388 static reloc_howto_type nlm32_alpha_nw_howto =
1389 HOWTO (ALPHA_R_NW_RELOC, /* type */
1391 0, /* size (0 = byte, 1 = short, 2 = long) */
1393 false, /* pc_relative */
1395 complain_overflow_dont, /* complain_on_overflow */
1396 0, /* special_function */
1397 "NW_RELOC", /* name */
1398 false, /* partial_inplace */
1401 false); /* pcrel_offset */
1405 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1409 register arelent ***relocs_ptr;
1410 bfd_size_type *reloc_count_ptr;
1412 bfd_size_type contents_size;
1414 bfd_size_type old_reloc_count;
1415 arelent **old_relocs;
1416 register arelent **relocs;
1418 old_reloc_count = *reloc_count_ptr;
1419 old_relocs = *relocs_ptr;
1420 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1421 *relocs_ptr = relocs;
1423 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1426 asection *lita_section;
1428 inbfd = insec->owner;
1429 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1430 if (lita_section != (asection *) NULL)
1432 nlm_alpha_backend_data (outbfd)->lita_address =
1433 bfd_get_section_vma (inbfd, lita_section);
1434 nlm_alpha_backend_data (outbfd)->lita_size =
1435 bfd_section_size (inbfd, lita_section);
1439 /* Avoid outputting this reloc again. */
1440 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1443 *relocs = (arelent *) xmalloc (sizeof (arelent));
1444 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1445 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1446 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1447 (*relocs)->howto = &nlm32_alpha_nw_howto;
1449 ++(*reloc_count_ptr);
1452 /* Get the GP value from bfd. It is in the .reginfo section. */
1453 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1456 asection *reginfo_sec;
1457 struct ecoff_reginfo sreginfo;
1459 inbfd = insec->owner;
1460 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1461 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1462 if (reginfo_sec != (asection *) NULL
1463 && bfd_get_section_contents (inbfd, reginfo_sec,
1464 (PTR) &sreginfo, (file_ptr) 0,
1465 sizeof sreginfo) != false)
1466 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
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)->gp;
1472 (*relocs)->addend = 0;
1473 (*relocs)->howto = &nlm32_alpha_nw_howto;
1475 ++(*reloc_count_ptr);
1477 memcpy ((PTR) relocs, (PTR) old_relocs,
1478 (size_t) old_reloc_count * sizeof (arelent *));
1479 relocs[old_reloc_count] = (arelent *) NULL;
1483 if (insec->output_offset != 0)
1485 register bfd_size_type i;
1487 for (i = 0; i < old_reloc_count; i++, relocs++)
1488 (*relocs)->address += insec->output_offset;
1492 /* Name of linker. */
1494 #define LD_NAME "ld"
1497 /* Temporary file name base. */
1498 static char *temp_filename;
1500 /* The user has specified several input files. Invoke the linker to
1501 link them all together, and convert and delete the resulting output
1505 link_inputs (inputs, ld)
1506 struct string_list *inputs;
1510 struct string_list *q;
1517 for (q = inputs; q != NULL; q = q->next)
1520 argv = (char **) alloca (c + 5);
1527 /* Find the linker to invoke based on how nlmconv was run. */
1528 p = program_name + strlen (program_name);
1529 while (p != program_name)
1533 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
1534 memcpy (ld, program_name, p - program_name);
1535 strcpy (ld + (p - program_name), LD_NAME);
1544 ld = (char *) LD_NAME;
1546 choose_temp_base ();
1548 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
1549 sprintf (unlink_on_exit, "%s.O", temp_filename);
1552 argv[1] = (char *) "-r";
1553 argv[2] = (char *) "-o";
1554 argv[3] = unlink_on_exit;
1556 for (q = inputs; q != NULL; q = q->next, i++)
1557 argv[i] = q->string;
1562 for (i = 0; argv[i] != NULL; i++)
1563 fprintf (stderr, " %s", argv[i]);
1564 fprintf (stderr, "\n");
1567 pid = pexecute (ld, argv);
1569 if (waitpid (pid, &status, 0) < 0)
1572 unlink (unlink_on_exit);
1578 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
1579 unlink (unlink_on_exit);
1583 return unlink_on_exit;
1586 /* Choose a temporary file name. Stolen from gcc.c. */
1589 choose_temp_base_try (try, base)
1597 else if (try == NULL)
1599 else if (access (try, R_OK | W_OK) != 0)
1609 const char *base = NULL;
1612 base = choose_temp_base_try (getenv ("TMPDIR"), base);
1613 base = choose_temp_base_try (getenv ("TMP"), base);
1614 base = choose_temp_base_try (getenv ("TEMP"), base);
1617 base = choose_temp_base_try (P_tmpdir, base);
1620 base = choose_temp_base_try ("/usr/tmp", base);
1621 base = choose_temp_base_try ("/tmp", base);
1623 /* If all else fails, use the current directory! */
1627 len = strlen (base);
1628 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
1629 strcpy (temp_filename, base);
1630 if (len > 0 && temp_filename[len-1] != '/')
1631 temp_filename[len++] = '/';
1632 strcpy (temp_filename + len, "ccXXXXXX");
1634 mktemp (temp_filename);
1635 if (*temp_filename == '\0')
1639 /* Execute a job. Stolen from gcc.c. */
1645 pexecute (program, argv)
1653 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
1654 rf = scmd + strlen(program) + 2 + el;
1655 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
1656 argfile = fopen (rf, "w");
1658 pfatal_with_name (rf);
1660 for (i=1; argv[i]; i++)
1663 for (cp = argv[i]; *cp; cp++)
1665 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
1666 fputc ('\\', argfile);
1667 fputc (*cp, argfile);
1669 fputc ('\n', argfile);
1680 return MIN_FATAL_STATUS << 8;
1686 #else /* not __MSDOS__ */
1689 pexecute (program, argv)
1694 int retries, sleep_interval;
1696 /* Fork a subprocess; wait and retry if it fails. */
1698 for (retries = 0; retries < 4; retries++)
1703 sleep (sleep_interval);
1704 sleep_interval *= 2;
1720 /* Exec the program. */
1721 execvp (program, argv);
1728 /* Return child's process number. */
1733 #endif /* not __MSDOS__ */
1737 pexecute (program, argv)
1741 return spawnvp (1, program, argv);
1743 #endif /* not OS2 */