1 /* nlmconv.c -- NLM conversion program
2 Copyright (C) 1993, 94, 95, 96, 97, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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. */
27 /* AIX requires this to be the first thing in the file. */
35 #include "libiberty.h"
46 /* Internal BFD NLM header. */
52 #include "coff/ecoff.h"
55 /* If strerror is just a macro, we want to use the one from libiberty
56 since it will handle undefined values. */
58 extern char *strerror ();
61 extern struct tm *localtime ();
74 /* Global variables. */
76 /* The name used to invoke the program. */
79 /* Local variables. */
81 /* Whether to print out debugging information (currently just controls
82 whether it prints the linker command if there is one). */
85 /* The symbol table. */
86 static asymbol **symbols;
88 /* A section we create in the output file to hold pointers to where
89 the sections of the input file end up. We will put a pointer to
90 this section in the NLM header. These is an entry for each input
91 section. The format is
92 null terminated section name
93 zeroes to adjust to 4 byte boundary
94 4 byte section data file pointer
96 We don't need a version number. The way we find this information
97 is by finding a stamp in the NLM header information. If we need to
98 change the format of this information, we can simply change the
100 static asection *secsec;
102 /* A temporary file name to be unlinked on exit. Actually, for most
103 errors, we leave it around. It's not clear whether that is helpful
105 static char *unlink_on_exit;
107 /* The list of long options. */
108 static struct option long_options[] =
110 { "debug", no_argument, 0, 'd' },
111 { "header-file", required_argument, 0, 'T' },
112 { "help", no_argument, 0, 'h' },
113 { "input-target", required_argument, 0, 'I' },
114 { "input-format", required_argument, 0, 'I' }, /* Obsolete */
115 { "linker", required_argument, 0, 'l' },
116 { "output-target", required_argument, 0, 'O' },
117 { "output-format", required_argument, 0, 'O' }, /* Obsolete */
118 { "version", no_argument, 0, 'V' },
119 { NULL, no_argument, 0, 0 }
122 /* Local routines. */
124 static void show_help PARAMS ((void));
125 static void show_usage PARAMS ((FILE *, int));
126 static const char *select_output_format PARAMS ((enum bfd_architecture,
127 unsigned long, boolean));
128 static void setup_sections PARAMS ((bfd *, asection *, PTR));
129 static void copy_sections PARAMS ((bfd *, asection *, PTR));
130 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
133 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
136 static char *link_inputs PARAMS ((struct string_list *, char *));
139 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
145 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
150 #ifdef NLMCONV_POWERPC
151 static void powerpc_build_stubs PARAMS ((bfd *, bfd *, asymbol ***, long *));
152 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
153 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
158 /* The main routine. */
166 char *input_file = NULL;
167 const char *input_format = NULL;
168 const char *output_format = NULL;
169 const char *header_file = NULL;
171 Nlm_Internal_Fixed_Header fixed_hdr_struct;
172 Nlm_Internal_Variable_Header var_hdr_struct;
173 Nlm_Internal_Version_Header version_hdr_struct;
174 Nlm_Internal_Copyright_Header copyright_hdr_struct;
175 Nlm_Internal_Extended_Header extended_hdr_struct;
178 asymbol **newsyms, **outsyms;
179 long symcount, newsymalloc, newsymcount;
181 asection *text_sec, *bss_sec, *data_sec;
186 char inlead, outlead;
187 boolean gotstart, gotexit, gotcheck;
189 FILE *custom_data = NULL;
190 FILE *help_data = NULL;
191 FILE *message_data = NULL;
192 FILE *rpc_data = NULL;
193 FILE *shared_data = NULL;
194 size_t custom_size = 0;
195 size_t help_size = 0;
196 size_t message_size = 0;
197 size_t module_size = 0;
199 asection *custom_section = NULL;
200 asection *help_section = NULL;
201 asection *message_section = NULL;
202 asection *module_section = NULL;
203 asection *rpc_section = NULL;
204 asection *shared_section = NULL;
206 size_t shared_offset = 0;
207 size_t shared_size = 0;
208 Nlm_Internal_Fixed_Header sharedhdr;
213 setlocale (LC_MESSAGES, "");
214 bindtextdomain (PACKAGE, LOCALEDIR);
215 textdomain (PACKAGE);
217 program_name = argv[0];
218 xmalloc_set_program_name (program_name);
221 set_default_bfd_target ();
223 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
236 input_format = optarg;
242 output_format = optarg;
245 header_file = optarg;
248 print_version ("nlmconv");
253 show_usage (stderr, 1);
258 /* The input and output files may be named on the command line. */
262 input_file = argv[optind];
266 output_file = argv[optind];
269 show_usage (stderr, 1);
270 if (strcmp (input_file, output_file) == 0)
273 _("%s: input and output files must be different\n"),
280 /* Initialize the header information to default values. */
281 fixed_hdr = &fixed_hdr_struct;
282 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
283 var_hdr = &var_hdr_struct;
284 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
285 version_hdr = &version_hdr_struct;
286 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
287 copyright_hdr = ©right_hdr_struct;
288 memset ((PTR) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
289 extended_hdr = &extended_hdr_struct;
290 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
291 check_procedure = NULL;
294 exit_procedure = "_Stop";
295 export_symbols = NULL;
299 import_symbols = NULL;
302 sharelib_file = NULL;
303 start_procedure = "_Prelude";
309 /* Parse the header file (if there is one). */
310 if (header_file != NULL)
312 if (! nlmlex_file (header_file)
314 || parse_errors != 0)
318 if (input_files != NULL)
320 if (input_file != NULL)
323 _("%s: input file named both on command line and with INPUT\n"),
327 if (input_files->next == NULL)
328 input_file = input_files->string;
330 input_file = link_inputs (input_files, ld_arg);
332 else if (input_file == NULL)
334 fprintf (stderr, _("%s: no input file\n"), program_name);
335 show_usage (stderr, 1);
338 inbfd = bfd_openr (input_file, input_format);
340 bfd_fatal (input_file);
342 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
344 bfd_nonfatal (input_file);
345 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
347 list_matching_formats (matching);
353 if (output_format == NULL)
354 output_format = select_output_format (bfd_get_arch (inbfd),
355 bfd_get_mach (inbfd),
356 bfd_big_endian (inbfd));
358 assert (output_format != NULL);
360 /* Use the output file named on the command line if it exists.
361 Otherwise use the file named in the OUTPUT statement. */
362 if (output_file == NULL)
364 fprintf (stderr, _("%s: no name for output file\n"),
366 show_usage (stderr, 1);
369 outbfd = bfd_openw (output_file, output_format);
371 bfd_fatal (output_file);
372 if (! bfd_set_format (outbfd, bfd_object))
373 bfd_fatal (output_file);
375 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
377 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
379 _("%s: warning:input and output formats are not compatible\n"),
382 /* Move the values read from the command file into outbfd. */
383 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
384 *nlm_variable_header (outbfd) = var_hdr_struct;
385 *nlm_version_header (outbfd) = version_hdr_struct;
386 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
387 *nlm_extended_header (outbfd) = extended_hdr_struct;
389 /* Start copying the input BFD to the output BFD. */
390 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
391 bfd_fatal (bfd_get_filename (outbfd));
393 symsize = bfd_get_symtab_upper_bound (inbfd);
395 bfd_fatal (input_file);
396 symbols = (asymbol **) xmalloc (symsize);
397 symcount = bfd_canonicalize_symtab (inbfd, symbols);
399 bfd_fatal (input_file);
401 /* Make sure we have a .bss section. */
402 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
405 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
407 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
408 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
409 bfd_fatal (_("make .bss section"));
412 /* We store the original section names in the .nlmsections section,
413 so that programs which understand it can resurrect the original
414 sections from the NLM. We will put a pointer to .nlmsections in
415 the NLM header area. */
416 secsec = bfd_make_section (outbfd, ".nlmsections");
418 bfd_fatal (_("make .nlmsections section"));
419 if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
420 bfd_fatal (_("set .nlmsections flags"));
422 #ifdef NLMCONV_POWERPC
423 /* For PowerPC NetWare we need to build stubs for calls to undefined
424 symbols. Because each stub requires an entry in the TOC section
425 which must be at the same location as other entries in the TOC
426 section, we must do this before determining where the TOC section
427 goes in setup_sections. */
428 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
429 powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
432 /* Set up the sections. */
433 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
435 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
437 /* The .bss section immediately follows the .data section. */
438 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
439 if (data_sec != NULL)
443 vma = bfd_get_section_size_before_reloc (data_sec);
444 align = 1 << bss_sec->alignment_power;
445 add = ((vma + align - 1) &~ (align - 1)) - vma;
447 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
448 bfd_fatal (_("set .bss vma"));
451 bfd_size_type data_size;
453 data_size = bfd_get_section_size_before_reloc (data_sec);
454 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
455 bfd_fatal (_("set .data size"));
459 /* Adjust symbol information. */
460 inlead = bfd_get_symbol_leading_char (inbfd);
461 outlead = bfd_get_symbol_leading_char (outbfd);
466 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
469 for (i = 0; i < symcount; i++)
471 register asymbol *sym;
475 /* Add or remove a leading underscore. */
476 if (inlead != outlead)
480 if (bfd_asymbol_name (sym)[0] == inlead)
488 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
490 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
499 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
501 strcpy (new + 1, bfd_asymbol_name (sym));
506 /* NLM's have an uninitialized data section, but they do not
507 have a common section in the Unix sense. Move all common
508 symbols into the .bss section, and mark them as exported. */
509 if (bfd_is_com_section (bfd_get_section (sym)))
513 sym->section = bss_sec;
515 sym->value = bss_sec->_raw_size;
516 bss_sec->_raw_size += size;
517 align = 1 << bss_sec->alignment_power;
518 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
519 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
521 else if (bfd_get_section (sym)->output_section != NULL)
523 /* Move the symbol into the output section. */
524 sym->value += bfd_get_section (sym)->output_offset;
525 sym->section = bfd_get_section (sym)->output_section;
526 /* This is no longer a section symbol. */
527 sym->flags &=~ BSF_SECTION_SYM;
530 /* Force _edata and _end to be defined. This would normally be
531 done by the linker, but the manipulation of the common
532 symbols will confuse it. */
533 if ((sym->flags & BSF_DEBUGGING) == 0
534 && bfd_asymbol_name (sym)[0] == '_'
535 && bfd_is_und_section (bfd_get_section (sym)))
537 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
539 sym->section = bss_sec;
542 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
544 sym->section = bss_sec;
548 #ifdef NLMCONV_POWERPC
549 /* For PowerPC NetWare, we define __GOT0. This is the start
550 of the .got section. */
551 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
552 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
556 got_sec = bfd_get_section_by_name (inbfd, ".got");
557 assert (got_sec != (asection *) NULL);
558 sym->value = got_sec->output_offset;
559 sym->section = got_sec->output_section;
564 /* If this is a global symbol, check the export list. */
565 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
567 register struct string_list *l;
570 /* Unfortunately, a symbol can appear multiple times on the
571 export list, with and without prefixes. */
573 for (l = export_symbols; l != NULL; l = l->next)
575 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
581 zbase = strchr (l->string, '@');
583 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
585 /* We must add a symbol with this prefix. */
586 if (newsymcount >= newsymalloc)
589 newsyms = ((asymbol **)
590 xrealloc ((PTR) newsyms,
592 * sizeof (asymbol *))));
594 newsyms[newsymcount] =
595 (asymbol *) xmalloc (sizeof (asymbol));
596 *newsyms[newsymcount] = *sym;
597 newsyms[newsymcount]->name = l->string;
604 /* The unmodified symbol is actually not exported at
606 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
607 sym->flags |= BSF_LOCAL;
611 /* If it's an undefined symbol, see if it's on the import list.
612 Change the prefix if necessary. */
613 if (bfd_is_und_section (bfd_get_section (sym)))
615 register struct string_list *l;
617 for (l = import_symbols; l != NULL; l = l->next)
619 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
625 zbase = strchr (l->string, '@');
627 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
629 sym->name = l->string;
636 _("%s: warning: symbol %s imported but not in import list\n"),
637 program_name, bfd_asymbol_name (sym));
640 /* See if it's one of the special named symbols. */
641 if ((sym->flags & BSF_DEBUGGING) == 0)
645 /* FIXME: If these symbols are not in the .text section, we
646 add the .text section size to the value. This may not be
647 correct for all targets. I'm not sure how this should
648 really be handled. */
649 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
651 val = bfd_asymbol_value (sym);
652 if (bfd_get_section (sym) == data_sec
653 && text_sec != (asection *) NULL)
654 val += bfd_section_size (outbfd, text_sec);
655 if (! bfd_set_start_address (outbfd, val))
656 bfd_fatal (_("set start address"));
659 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
661 val = bfd_asymbol_value (sym);
662 if (bfd_get_section (sym) == data_sec
663 && text_sec != (asection *) NULL)
664 val += bfd_section_size (outbfd, text_sec);
665 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
668 if (check_procedure != NULL
669 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
671 val = bfd_asymbol_value (sym);
672 if (bfd_get_section (sym) == data_sec
673 && text_sec != (asection *) NULL)
674 val += bfd_section_size (outbfd, text_sec);
675 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
683 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
685 /* FIXME: If any relocs referring to _end use inplace addends,
686 then I think they need to be updated. This is handled by
687 i386_mangle_relocs. Is it needed for any other object
691 if (newsymcount == 0)
695 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
696 * sizeof (asymbol *));
697 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
698 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
699 outsyms[symcount + newsymcount] = NULL;
702 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
705 fprintf (stderr, _("%s: warning: START procedure %s not defined\n"),
706 program_name, start_procedure);
708 fprintf (stderr, _("%s: warning: EXIT procedure %s not defined\n"),
709 program_name, exit_procedure);
710 if (check_procedure != NULL
712 fprintf (stderr, _("%s: warning: CHECK procedure %s not defined\n"),
713 program_name, check_procedure);
715 /* Add additional sections required for the header information. */
716 if (custom_file != NULL)
718 custom_data = fopen (custom_file, "r");
719 if (custom_data == NULL
720 || fstat (fileno (custom_data), &st) < 0)
722 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
728 custom_size = st.st_size;
729 custom_section = bfd_make_section (outbfd, ".nlmcustom");
730 if (custom_section == NULL
731 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
732 || ! bfd_set_section_flags (outbfd, custom_section,
734 bfd_fatal (_("custom section"));
737 if (help_file != NULL)
739 help_data = fopen (help_file, "r");
740 if (help_data == NULL
741 || fstat (fileno (help_data), &st) < 0)
743 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
749 help_size = st.st_size;
750 help_section = bfd_make_section (outbfd, ".nlmhelp");
751 if (help_section == NULL
752 || ! bfd_set_section_size (outbfd, help_section, help_size)
753 || ! bfd_set_section_flags (outbfd, help_section,
755 bfd_fatal (_("help section"));
756 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
759 if (message_file != NULL)
761 message_data = fopen (message_file, "r");
762 if (message_data == NULL
763 || fstat (fileno (message_data), &st) < 0)
765 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
771 message_size = st.st_size;
772 message_section = bfd_make_section (outbfd, ".nlmmessages");
773 if (message_section == NULL
774 || ! bfd_set_section_size (outbfd, message_section, message_size)
775 || ! bfd_set_section_flags (outbfd, message_section,
777 bfd_fatal (_("message section"));
778 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
783 struct string_list *l;
786 for (l = modules; l != NULL; l = l->next)
787 module_size += strlen (l->string) + 1;
788 module_section = bfd_make_section (outbfd, ".nlmmodules");
789 if (module_section == NULL
790 || ! bfd_set_section_size (outbfd, module_section, module_size)
791 || ! bfd_set_section_flags (outbfd, module_section,
793 bfd_fatal (_("module section"));
795 if (rpc_file != NULL)
797 rpc_data = fopen (rpc_file, "r");
799 || fstat (fileno (rpc_data), &st) < 0)
801 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
807 rpc_size = st.st_size;
808 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
809 if (rpc_section == NULL
810 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
811 || ! bfd_set_section_flags (outbfd, rpc_section,
813 bfd_fatal (_("rpc section"));
814 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
817 if (sharelib_file != NULL)
819 sharedbfd = bfd_openr (sharelib_file, output_format);
820 if (sharedbfd == NULL
821 || ! bfd_check_format (sharedbfd, bfd_object))
823 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
824 bfd_errmsg (bfd_get_error ()));
825 sharelib_file = NULL;
829 sharedhdr = *nlm_fixed_header (sharedbfd);
830 bfd_close (sharedbfd);
831 shared_data = fopen (sharelib_file, "r");
832 if (shared_data == NULL
833 || (fstat (fileno (shared_data), &st) < 0))
835 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
837 sharelib_file = NULL;
841 /* If we were clever, we could just copy out the
842 sections of the shared library which we actually
843 need. However, we would have to figure out the sizes
844 of the external and public information, and that can
845 not be done without reading through them. */
846 if (sharedhdr.uninitializedDataSize > 0)
848 /* There is no place to record this information. */
850 _("%s:%s: warning: shared libraries can not have uninitialized data\n"),
851 program_name, sharelib_file);
853 shared_offset = st.st_size;
854 if (shared_offset > (size_t) sharedhdr.codeImageOffset)
855 shared_offset = sharedhdr.codeImageOffset;
856 if (shared_offset > (size_t) sharedhdr.dataImageOffset)
857 shared_offset = sharedhdr.dataImageOffset;
858 if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
859 shared_offset = sharedhdr.relocationFixupOffset;
860 if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
861 shared_offset = sharedhdr.externalReferencesOffset;
862 if (shared_offset > (size_t) sharedhdr.publicsOffset)
863 shared_offset = sharedhdr.publicsOffset;
864 shared_size = st.st_size - shared_offset;
865 shared_section = bfd_make_section (outbfd, ".nlmshared");
866 if (shared_section == NULL
867 || ! bfd_set_section_size (outbfd, shared_section,
869 || ! bfd_set_section_flags (outbfd, shared_section,
871 bfd_fatal (_("shared section"));
872 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
877 /* Check whether a version was given. */
878 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
879 fprintf (stderr, _("%s: warning: No version number given\n"),
882 /* At least for now, always create an extended header, because that
883 is what NLMLINK does. */
884 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
886 strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
888 /* If the date was not given, force it in. */
889 if (nlm_version_header (outbfd)->month == 0
890 && nlm_version_header (outbfd)->day == 0
891 && nlm_version_header (outbfd)->year == 0)
897 ptm = localtime (&now);
898 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
899 nlm_version_header (outbfd)->day = ptm->tm_mday;
900 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
901 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
904 #ifdef NLMCONV_POWERPC
905 /* Resolve the stubs we build for PowerPC NetWare. */
906 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
907 powerpc_resolve_stubs (inbfd, outbfd);
910 /* Copy over the sections. */
911 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
913 /* Finish up the header information. */
914 if (custom_file != NULL)
918 data = xmalloc (custom_size);
919 if (fread (data, 1, custom_size, custom_data) != custom_size)
920 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, custom_file,
924 if (! bfd_set_section_contents (outbfd, custom_section, data,
925 (file_ptr) 0, custom_size))
926 bfd_fatal (_("custom section"));
927 nlm_fixed_header (outbfd)->customDataOffset =
928 custom_section->filepos;
929 nlm_fixed_header (outbfd)->customDataSize = custom_size;
935 /* As a special hack, the backend recognizes a debugInfoOffset
936 of -1 to mean that it should not output any debugging
937 information. This can not be handling by fiddling with the
938 symbol table because exported symbols appear in both the
939 export information and the debugging information. */
940 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
942 if (map_file != NULL)
944 _("%s: warning: MAP and FULLMAP are not supported; try ld -M\n"),
946 if (help_file != NULL)
950 data = xmalloc (help_size);
951 if (fread (data, 1, help_size, help_data) != help_size)
952 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, help_file,
956 if (! bfd_set_section_contents (outbfd, help_section, data,
957 (file_ptr) 0, help_size))
958 bfd_fatal (_("help section"));
959 nlm_extended_header (outbfd)->helpFileOffset =
960 help_section->filepos;
961 nlm_extended_header (outbfd)->helpFileLength = help_size;
965 if (message_file != NULL)
969 data = xmalloc (message_size);
970 if (fread (data, 1, message_size, message_data) != message_size)
971 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, message_file,
975 if (! bfd_set_section_contents (outbfd, message_section, data,
976 (file_ptr) 0, message_size))
977 bfd_fatal (_("message section"));
978 nlm_extended_header (outbfd)->messageFileOffset =
979 message_section->filepos;
980 nlm_extended_header (outbfd)->messageFileLength = message_size;
982 /* FIXME: Are these offsets correct on all platforms? Are
983 they 32 bits on all platforms? What endianness? */
984 nlm_extended_header (outbfd)->languageID =
985 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
986 nlm_extended_header (outbfd)->messageCount =
987 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
995 struct string_list *l;
998 data = xmalloc (module_size);
1000 set = (unsigned char *) data;
1001 for (l = modules; l != NULL; l = l->next)
1003 *set = strlen (l->string);
1004 strncpy (set + 1, l->string, *set);
1008 if (! bfd_set_section_contents (outbfd, module_section, data,
1009 (file_ptr) 0, module_size))
1010 bfd_fatal (_("module section"));
1011 nlm_fixed_header (outbfd)->moduleDependencyOffset =
1012 module_section->filepos;
1013 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
1015 if (rpc_file != NULL)
1019 data = xmalloc (rpc_size);
1020 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
1021 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, rpc_file,
1025 if (! bfd_set_section_contents (outbfd, rpc_section, data,
1026 (file_ptr) 0, rpc_size))
1027 bfd_fatal (_("rpc section"));
1028 nlm_extended_header (outbfd)->RPCDataOffset =
1029 rpc_section->filepos;
1030 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1034 if (sharelib_file != NULL)
1038 data = xmalloc (shared_size);
1039 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1040 || fread (data, 1, shared_size, shared_data) != shared_size)
1041 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, sharelib_file,
1045 if (! bfd_set_section_contents (outbfd, shared_section, data,
1046 (file_ptr) 0, shared_size))
1047 bfd_fatal (_("shared section"));
1049 nlm_extended_header (outbfd)->sharedCodeOffset =
1050 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1051 nlm_extended_header (outbfd)->sharedCodeLength =
1052 sharedhdr.codeImageSize;
1053 nlm_extended_header (outbfd)->sharedDataOffset =
1054 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1055 nlm_extended_header (outbfd)->sharedDataLength =
1056 sharedhdr.dataImageSize;
1057 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1058 (sharedhdr.relocationFixupOffset
1060 + shared_section->filepos);
1061 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1062 sharedhdr.numberOfRelocationFixups;
1063 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1064 (sharedhdr.externalReferencesOffset
1066 + shared_section->filepos);
1067 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1068 sharedhdr.numberOfExternalReferences;
1069 nlm_extended_header (outbfd)->sharedPublicsOffset =
1070 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1071 nlm_extended_header (outbfd)->sharedPublicsCount =
1072 sharedhdr.numberOfPublics;
1073 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1074 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1075 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1076 sharedhdr.numberOfDebugRecords;
1077 nlm_extended_header (outbfd)->SharedInitializationOffset =
1078 sharedhdr.codeStartOffset;
1079 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1080 sharedhdr.exitProcedureOffset;
1083 len = strlen (output_file);
1084 if (len > NLM_MODULE_NAME_SIZE - 2)
1085 len = NLM_MODULE_NAME_SIZE - 2;
1086 nlm_fixed_header (outbfd)->moduleName[0] = len;
1088 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1089 NLM_MODULE_NAME_SIZE - 2);
1090 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1091 for (modname = nlm_fixed_header (outbfd)->moduleName;
1094 if (islower ((unsigned char) *modname))
1095 *modname = toupper (*modname);
1097 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1098 NLM_OLD_THREAD_NAME_LENGTH);
1100 nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1101 nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1103 if (! bfd_close (outbfd))
1104 bfd_fatal (output_file);
1105 if (! bfd_close (inbfd))
1106 bfd_fatal (input_file);
1108 if (unlink_on_exit != NULL)
1109 unlink (unlink_on_exit);
1114 /* Display a help message and exit. */
1119 printf (_("%s: Convert an object file into a NetWare Loadable Module\n"),
1121 show_usage (stdout, 0);
1124 /* Show a usage message and exit. */
1127 show_usage (file, status)
1132 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1133 [--input-target=bfdname] [--output-target=bfdname]\n\
1134 [--header-file=file] [--linker=linker] [--debug]\n\
1135 [--help] [--version]\n\
1136 [in-file [out-file]]\n"),
1143 /* Select the output format based on the input architecture, machine,
1144 and endianness. This chooses the appropriate NLM target. */
1147 select_output_format (arch, mach, bigendian)
1148 enum bfd_architecture arch;
1156 return "nlm32-i386";
1158 #ifdef NLMCONV_SPARC
1159 case bfd_arch_sparc:
1160 return "nlm32-sparc";
1162 #ifdef NLMCONV_ALPHA
1163 case bfd_arch_alpha:
1164 return "nlm32-alpha";
1166 #ifdef NLMCONV_POWERPC
1167 case bfd_arch_powerpc:
1168 return "nlm32-powerpc";
1171 fprintf (stderr, _("%s: support not compiled in for %s\n"),
1172 program_name, bfd_printable_arch_mach (arch, mach));
1174 /* Avoid warning. */
1180 /* The BFD sections are copied in two passes. This function selects
1181 the output section for each input section, and sets up the section
1185 setup_sections (inbfd, insec, data_ptr)
1190 bfd *outbfd = (bfd *) data_ptr;
1192 const char *outname;
1195 bfd_size_type align;
1197 bfd_size_type secsecsize;
1199 f = bfd_get_section_flags (inbfd, insec);
1201 outname = NLM_CODE_NAME;
1202 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1203 outname = NLM_INITIALIZED_DATA_NAME;
1204 else if (f & SEC_ALLOC)
1205 outname = NLM_UNINITIALIZED_DATA_NAME;
1207 outname = bfd_section_name (inbfd, insec);
1209 outsec = bfd_get_section_by_name (outbfd, outname);
1212 outsec = bfd_make_section (outbfd, outname);
1214 bfd_fatal (_("make section"));
1217 insec->output_section = outsec;
1219 offset = bfd_section_size (outbfd, outsec);
1220 align = 1 << bfd_section_alignment (inbfd, insec);
1221 add = ((offset + align - 1) &~ (align - 1)) - offset;
1222 insec->output_offset = offset + add;
1224 if (! bfd_set_section_size (outbfd, outsec,
1225 (bfd_section_size (outbfd, outsec)
1226 + bfd_section_size (inbfd, insec)
1228 bfd_fatal (_("set section size"));
1230 if ((bfd_section_alignment (inbfd, insec)
1231 > bfd_section_alignment (outbfd, outsec))
1232 && ! bfd_set_section_alignment (outbfd, outsec,
1233 bfd_section_alignment (inbfd, insec)))
1234 bfd_fatal (_("set section alignment"));
1236 if (! bfd_set_section_flags (outbfd, outsec,
1237 f | bfd_get_section_flags (outbfd, outsec)))
1238 bfd_fatal (_("set section flags"));
1240 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1242 /* For each input section we allocate space for an entry in
1244 secsecsize = bfd_section_size (outbfd, secsec);
1245 secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1246 secsecsize = (secsecsize + 3) &~ 3;
1248 if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1249 bfd_fatal (_("set .nlmsections size"));
1252 /* Copy the section contents. */
1255 copy_sections (inbfd, insec, data_ptr)
1260 static bfd_size_type secsecoff = 0;
1261 bfd *outbfd = (bfd *) data_ptr;
1270 inname = bfd_section_name (inbfd, insec);
1272 outsec = insec->output_section;
1273 assert (outsec != NULL);
1275 size = bfd_get_section_size_before_reloc (insec);
1277 /* FIXME: Why are these necessary? */
1278 insec->_cooked_size = insec->_raw_size;
1279 insec->reloc_done = true;
1281 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1285 contents = xmalloc (size);
1286 if (! bfd_get_section_contents (inbfd, insec, contents,
1287 (file_ptr) 0, size))
1288 bfd_fatal (bfd_get_filename (inbfd));
1291 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1293 bfd_fatal (bfd_get_filename (inbfd));
1294 if (reloc_size != 0)
1299 relocs = (arelent **) xmalloc (reloc_size);
1300 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1301 if (reloc_count < 0)
1302 bfd_fatal (bfd_get_filename (inbfd));
1303 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1306 /* FIXME: refers to internal BFD fields. */
1307 if (outsec->orelocation != (arelent **) NULL)
1309 bfd_size_type total_count;
1312 total_count = reloc_count + outsec->reloc_count;
1313 combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1314 memcpy (combined, outsec->orelocation,
1315 outsec->reloc_count * sizeof (arelent *));
1316 memcpy (combined + outsec->reloc_count, relocs,
1317 (size_t) (reloc_count * sizeof (arelent *)));
1318 free (outsec->orelocation);
1319 reloc_count = total_count;
1323 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1326 if (contents != NULL)
1328 if (! bfd_set_section_contents (outbfd, outsec, contents,
1329 insec->output_offset, size))
1330 bfd_fatal (bfd_get_filename (outbfd));
1334 /* Add this section to .nlmsections. */
1335 if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
1336 strlen (inname) + 1))
1337 bfd_fatal (_("set .nlmsection contents"));
1338 secsecoff += strlen (inname) + 1;
1340 add = ((secsecoff + 3) &~ 3) - secsecoff;
1343 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1344 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1345 bfd_fatal (_("set .nlmsection contents"));
1349 if (contents != NULL)
1350 bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1352 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1353 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1354 bfd_fatal (_("set .nlmsection contents"));
1357 bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1358 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1359 bfd_fatal (_("set .nlmsection contents"));
1363 /* Some, perhaps all, NetWare targets require changing the relocs used
1364 by the input formats. */
1367 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1371 arelent ***relocs_ptr;
1372 long *reloc_count_ptr;
1374 bfd_size_type contents_size;
1376 switch (bfd_get_arch (outbfd))
1380 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1381 contents, contents_size);
1384 #ifdef NLMCONV_ALPHA
1385 case bfd_arch_alpha:
1386 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1387 contents, contents_size);
1390 #ifdef NLMCONV_POWERPC
1391 case bfd_arch_powerpc:
1392 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1393 contents, contents_size);
1397 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1398 contents, contents_size);
1403 /* By default all we need to do for relocs is change the address by
1404 the output_offset. */
1408 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1412 arelent ***relocs_ptr;
1413 long *reloc_count_ptr;
1415 bfd_size_type contents_size;
1417 if (insec->output_offset != 0)
1420 register arelent **relocs;
1423 reloc_count = *reloc_count_ptr;
1424 relocs = *relocs_ptr;
1425 for (i = 0; i < reloc_count; i++, relocs++)
1426 (*relocs)->address += insec->output_offset;
1432 /* NetWare on the i386 supports a restricted set of relocs, which are
1433 different from those used on other i386 targets. This routine
1434 converts the relocs. It is, obviously, very target dependent. At
1435 the moment, the nlm32-i386 backend performs similar translations;
1436 however, it is more reliable and efficient to do them here. */
1438 static reloc_howto_type nlm_i386_pcrel_howto =
1439 HOWTO (1, /* type */
1441 2, /* size (0 = byte, 1 = short, 2 = long) */
1443 true, /* pc_relative */
1445 complain_overflow_signed, /* complain_on_overflow */
1446 0, /* special_function */
1447 "DISP32", /* name */
1448 true, /* partial_inplace */
1449 0xffffffff, /* src_mask */
1450 0xffffffff, /* dst_mask */
1451 true); /* pcrel_offset */
1454 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1458 arelent ***relocs_ptr;
1459 long *reloc_count_ptr;
1461 bfd_size_type contents_size;
1463 long reloc_count, i;
1466 reloc_count = *reloc_count_ptr;
1467 relocs = *relocs_ptr;
1468 for (i = 0; i < reloc_count; i++)
1472 bfd_size_type address;
1476 sym = *rel->sym_ptr_ptr;
1478 /* We're moving the relocs from the input section to the output
1479 section, so we must adjust the address accordingly. */
1480 address = rel->address;
1481 rel->address += insec->output_offset;
1483 /* Note that no serious harm will ensue if we fail to change a
1484 reloc. The backend will fail when writing out the reloc. */
1486 /* Make sure this reloc is within the data we have. We use only
1487 4 byte relocs here, so we insist on having 4 bytes. */
1488 if (address + 4 > contents_size)
1491 /* A PC relative reloc entirely within a single section is
1492 completely unnecessary. This can be generated by ld -r. */
1493 if (sym == insec->symbol
1494 && rel->howto != NULL
1495 && rel->howto->pc_relative
1496 && ! rel->howto->pcrel_offset)
1500 memmove (relocs, relocs + 1,
1501 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1505 /* Get the amount the relocation will add in. */
1506 addend = rel->addend + sym->value;
1508 /* NetWare doesn't support PC relative relocs against defined
1509 symbols, so we have to eliminate them by doing the relocation
1510 now. We can only do this if the reloc is within a single
1512 if (rel->howto != NULL
1513 && rel->howto->pc_relative
1514 && bfd_get_section (sym) == insec->output_section)
1518 if (rel->howto->pcrel_offset)
1521 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1523 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1527 memmove (relocs, relocs + 1,
1528 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1532 /* NetWare doesn't support reloc addends, so we get rid of them
1533 here by simply adding them into the object data. We handle
1534 the symbol value, if any, the same way. */
1536 && rel->howto != NULL
1537 && rel->howto->rightshift == 0
1538 && rel->howto->size == 2
1539 && rel->howto->bitsize == 32
1540 && rel->howto->bitpos == 0
1541 && rel->howto->src_mask == 0xffffffff
1542 && rel->howto->dst_mask == 0xffffffff)
1546 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1548 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1550 /* Adjust the reloc for the changes we just made. */
1552 if (! bfd_is_und_section (bfd_get_section (sym)))
1553 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1556 /* NetWare uses a reloc with pcrel_offset set. We adjust
1557 pc_relative relocs accordingly. We are going to change the
1558 howto field, so we can only do this if the current one is
1559 compatible. We should check that special_function is NULL
1560 here, but at the moment coff-i386 uses a special_function
1561 which does not affect what we are doing here. */
1562 if (rel->howto != NULL
1563 && rel->howto->pc_relative
1564 && ! rel->howto->pcrel_offset
1565 && rel->howto->rightshift == 0
1566 && rel->howto->size == 2
1567 && rel->howto->bitsize == 32
1568 && rel->howto->bitpos == 0
1569 && rel->howto->src_mask == 0xffffffff
1570 && rel->howto->dst_mask == 0xffffffff)
1574 /* When pcrel_offset is not set, it means that the negative
1575 of the address of the memory location is stored in the
1576 memory location. We must add it back in. */
1577 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1579 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1581 /* We must change to a new howto. */
1582 rel->howto = &nlm_i386_pcrel_howto;
1587 #endif /* NLMCONV_I386 */
1589 #ifdef NLMCONV_ALPHA
1591 /* On the Alpha the first reloc for every section must be a special
1592 relocs which hold the GP address. Also, the first reloc in the
1593 file must be a special reloc which holds the address of the .lita
1596 static reloc_howto_type nlm32_alpha_nw_howto =
1597 HOWTO (ALPHA_R_NW_RELOC, /* type */
1599 0, /* size (0 = byte, 1 = short, 2 = long) */
1601 false, /* pc_relative */
1603 complain_overflow_dont, /* complain_on_overflow */
1604 0, /* special_function */
1605 "NW_RELOC", /* name */
1606 false, /* partial_inplace */
1609 false); /* pcrel_offset */
1613 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1617 register arelent ***relocs_ptr;
1618 long *reloc_count_ptr;
1620 bfd_size_type contents_size;
1622 long old_reloc_count;
1623 arelent **old_relocs;
1624 register arelent **relocs;
1626 old_reloc_count = *reloc_count_ptr;
1627 old_relocs = *relocs_ptr;
1628 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1629 *relocs_ptr = relocs;
1631 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1634 asection *lita_section;
1636 inbfd = insec->owner;
1637 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1638 if (lita_section != (asection *) NULL)
1640 nlm_alpha_backend_data (outbfd)->lita_address =
1641 bfd_get_section_vma (inbfd, lita_section);
1642 nlm_alpha_backend_data (outbfd)->lita_size =
1643 bfd_section_size (inbfd, lita_section);
1647 /* Avoid outputting this reloc again. */
1648 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1651 *relocs = (arelent *) xmalloc (sizeof (arelent));
1652 (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1653 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1654 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1655 (*relocs)->howto = &nlm32_alpha_nw_howto;
1657 ++(*reloc_count_ptr);
1660 /* Get the GP value from bfd. */
1661 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1662 nlm_alpha_backend_data (outbfd)->gp =
1663 bfd_ecoff_get_gp_value (insec->owner);
1665 *relocs = (arelent *) xmalloc (sizeof (arelent));
1666 (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1667 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1668 (*relocs)->addend = 0;
1669 (*relocs)->howto = &nlm32_alpha_nw_howto;
1671 ++(*reloc_count_ptr);
1673 memcpy ((PTR) relocs, (PTR) old_relocs,
1674 (size_t) old_reloc_count * sizeof (arelent *));
1675 relocs[old_reloc_count] = (arelent *) NULL;
1679 if (insec->output_offset != 0)
1681 register bfd_size_type i;
1683 for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
1684 (*relocs)->address += insec->output_offset;
1688 #endif /* NLMCONV_ALPHA */
1690 #ifdef NLMCONV_POWERPC
1692 /* We keep a linked list of stubs which we must build. Because BFD
1693 requires us to know the sizes of all sections before we can set the
1694 contents of any, we must figure out which stubs we want to build
1695 before we can actually build any of them. */
1699 /* Next stub in linked list. */
1700 struct powerpc_stub *next;
1702 /* Symbol whose value is the start of the stub. This is a symbol
1703 whose name begins with `.'. */
1706 /* Symbol we are going to create a reloc against. This is a symbol
1707 with the same name as START but without the leading `.'. */
1710 /* The TOC index for this stub. This is the index into the TOC
1711 section at which the reloc is created. */
1712 unsigned int toc_index;
1715 /* The linked list of stubs. */
1717 static struct powerpc_stub *powerpc_stubs;
1719 /* This is what a stub looks like. The first instruction will get
1720 adjusted with the correct TOC index. */
1722 static unsigned long powerpc_stub_insns[] =
1724 0x81820000, /* lwz r12,0(r2) */
1725 0x90410014, /* stw r2,20(r1) */
1726 0x800c0000, /* lwz r0,0(r12) */
1727 0x804c0004, /* lwz r2,r(r12) */
1728 0x7c0903a6, /* mtctr r0 */
1729 0x4e800420, /* bctr */
1730 0, /* Traceback table. */
1735 #define POWERPC_STUB_INSN_COUNT \
1736 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1738 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1740 /* Each stub uses a four byte TOC entry. */
1741 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1743 /* The original size of the .got section. */
1744 static bfd_size_type powerpc_initial_got_size;
1746 /* Look for all undefined symbols beginning with `.', and prepare to
1747 build a stub for each one. */
1750 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1753 asymbol ***symbols_ptr;
1758 unsigned int got_base;
1763 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1764 the section to prevent copy_sections from reading from it. */
1765 stub_sec = bfd_make_section (inbfd, ".stubs");
1766 if (stub_sec == (asection *) NULL
1767 || ! bfd_set_section_flags (inbfd, stub_sec,
1772 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1773 bfd_fatal (".stubs");
1775 /* Get the TOC section, which is named .got. */
1776 got_sec = bfd_get_section_by_name (inbfd, ".got");
1777 if (got_sec == (asection *) NULL)
1779 got_sec = bfd_make_section (inbfd, ".got");
1780 if (got_sec == (asection *) NULL
1781 || ! bfd_set_section_flags (inbfd, got_sec,
1786 | SEC_HAS_CONTENTS))
1787 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1791 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1792 got_base = powerpc_initial_got_size;
1793 got_base = (got_base + 3) &~ 3;
1797 symcount = *symcount_ptr;
1798 for (i = 0; i < symcount; i++)
1803 struct powerpc_stub *item;
1805 sym = (*symbols_ptr)[i];
1807 /* We must make a stub for every undefined symbol whose name
1809 if (bfd_asymbol_name (sym)[0] != '.'
1810 || ! bfd_is_und_section (bfd_get_section (sym)))
1813 /* Make a new undefined symbol with the same name but without
1815 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1817 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1818 strcpy (newname, bfd_asymbol_name (sym) + 1);
1819 newsym->name = newname;
1821 /* Define the `.' symbol to be in the stub section. */
1822 sym->section = stub_sec;
1823 sym->value = stubcount * POWERPC_STUB_SIZE;
1824 /* We set the BSF_DYNAMIC flag here so that we can check it when
1825 we are mangling relocs. FIXME: This is a hack. */
1826 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1828 /* Add this stub to the linked list. */
1829 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1831 item->reloc = newsym;
1832 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1834 item->next = powerpc_stubs;
1835 powerpc_stubs = item;
1843 struct powerpc_stub *l;
1845 /* Add the new symbols we just created to the symbol table. */
1846 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1847 ((symcount + stubcount)
1848 * sizeof (asymbol)));
1849 *symcount_ptr += stubcount;
1850 s = &(*symbols_ptr)[symcount];
1851 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1854 /* Set the size of the .stubs section and increase the size of
1855 the .got section. */
1856 if (! bfd_set_section_size (inbfd, stub_sec,
1857 stubcount * POWERPC_STUB_SIZE)
1858 || ! bfd_set_section_size (inbfd, got_sec,
1861 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1862 bfd_fatal (_("stub section sizes"));
1866 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1867 of the output section, and create new relocs in the TOC. */
1870 powerpc_resolve_stubs (inbfd, outbfd)
1874 bfd_byte buf[POWERPC_STUB_SIZE];
1876 unsigned int stubcount;
1880 struct powerpc_stub *l;
1882 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1885 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1886 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1888 got_sec = bfd_get_section_by_name (inbfd, ".got");
1889 assert (got_sec != (asection *) NULL);
1890 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1893 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1895 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1898 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1902 /* Adjust the first instruction to use the right TOC index. */
1903 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1905 /* Write this stub out. */
1906 if (! bfd_set_section_contents (outbfd,
1907 bfd_get_section (l->start),
1911 bfd_fatal (_("writing stub"));
1913 /* Create a new reloc for the TOC entry. */
1914 reloc = (arelent *) xmalloc (sizeof (arelent));
1915 reloc->sym_ptr_ptr = &l->reloc;
1916 reloc->address = l->toc_index + got_sec->output_offset;
1918 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1923 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1926 /* Adjust relocation entries for PowerPC NetWare. We do not output
1927 TOC relocations. The object code already contains the offset from
1928 the TOC pointer. When the function is called, the TOC register,
1929 r2, will be set to the correct TOC value, so there is no need for
1930 any further reloc. */
1934 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1938 register arelent ***relocs_ptr;
1939 long *reloc_count_ptr;
1941 bfd_size_type contents_size;
1943 reloc_howto_type *toc_howto;
1945 register arelent **relocs;
1948 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1949 if (toc_howto == (reloc_howto_type *) NULL)
1952 /* If this is the .got section, clear out all the contents beyond
1953 the initial size. We must do this here because copy_sections is
1954 going to write out whatever we return in the contents field. */
1955 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1956 memset (contents + powerpc_initial_got_size, 0,
1957 (size_t) (bfd_get_section_size_after_reloc (insec)
1958 - powerpc_initial_got_size));
1960 reloc_count = *reloc_count_ptr;
1961 relocs = *relocs_ptr;
1962 for (i = 0; i < reloc_count; i++)
1969 sym = *rel->sym_ptr_ptr;
1971 /* Convert any relocs against the .bss section into relocs
1972 against the .data section. */
1973 if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1974 NLM_UNINITIALIZED_DATA_NAME) == 0)
1978 datasec = bfd_get_section_by_name (outbfd,
1979 NLM_INITIALIZED_DATA_NAME);
1980 if (datasec != NULL)
1982 rel->addend += (bfd_get_section_vma (outbfd,
1983 bfd_get_section (sym))
1985 rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1986 sym = *rel->sym_ptr_ptr;
1990 /* We must be able to resolve all PC relative relocs at this
1991 point. If we get a branch to an undefined symbol we build a
1992 stub, since NetWare will resolve undefined symbols into a
1993 pointer to a function descriptor. */
1994 if (rel->howto->pc_relative)
1996 /* This check for whether a symbol is in the same section as
1997 the reloc will be wrong if there is a PC relative reloc
1998 between two sections both of which were placed in the
1999 same output section. This should not happen. */
2000 if (bfd_get_section (sym) != insec->output_section)
2001 fprintf (stderr, _("%s: unresolved PC relative reloc against %s\n"),
2002 program_name, bfd_asymbol_name (sym));
2007 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
2008 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
2009 val = ((val &~ rel->howto->dst_mask)
2010 | (((val & rel->howto->src_mask)
2011 + (sym->value - rel->address)
2013 & rel->howto->dst_mask));
2014 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2016 /* If this reloc is against an stubbed symbol and the
2019 then we replace the next instruction with
2021 This reloads the TOC pointer after a stub call. */
2022 if (bfd_asymbol_name (sym)[0] == '.'
2023 && (sym->flags & BSF_DYNAMIC) != 0
2024 && (bfd_get_32 (outbfd,
2025 (bfd_byte *) contents + rel->address + 4)
2026 == 0x4ffffb82)) /* cror 31,31,31 */
2027 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
2028 (bfd_byte *) contents + rel->address + 4);
2032 memmove (relocs, relocs + 1,
2033 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
2038 /* When considering a TOC reloc, we do not want to include the
2039 symbol value. The symbol will be start of the TOC section
2040 (which is named .got). We do want to include the addend. */
2041 if (rel->howto == toc_howto)
2044 sym_value = sym->value;
2046 /* If this is a relocation against a symbol with a value, or
2047 there is a reloc addend, we need to update the addend in the
2049 if (sym_value + rel->addend != 0)
2053 switch (rel->howto->size)
2056 val = bfd_get_16 (outbfd,
2057 (bfd_byte *) contents + rel->address);
2058 val = ((val &~ rel->howto->dst_mask)
2059 | (((val & rel->howto->src_mask)
2062 & rel->howto->dst_mask));
2063 if ((bfd_signed_vma) val < - 0x8000
2064 || (bfd_signed_vma) val >= 0x8000)
2066 _("%s: overflow when adjusting relocation against %s\n"),
2067 program_name, bfd_asymbol_name (sym));
2068 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2072 val = bfd_get_32 (outbfd,
2073 (bfd_byte *) contents + rel->address);
2074 val = ((val &~ rel->howto->dst_mask)
2075 | (((val & rel->howto->src_mask)
2078 & rel->howto->dst_mask));
2079 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2086 if (! bfd_is_und_section (bfd_get_section (sym)))
2087 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2091 /* Now that we have incorporated the addend, remove any TOC
2093 if (rel->howto == toc_howto)
2097 memmove (relocs, relocs + 1,
2098 (size_t) ((reloc_count - i) * sizeof (arelent *)));
2102 rel->address += insec->output_offset;
2106 #endif /* NLMCONV_POWERPC */
2108 /* Name of linker. */
2110 #define LD_NAME "ld"
2113 /* Temporary file name base. */
2114 static char *temp_filename;
2116 /* The user has specified several input files. Invoke the linker to
2117 link them all together, and convert and delete the resulting output
2121 link_inputs (inputs, ld)
2122 struct string_list *inputs;
2126 struct string_list *q;
2135 for (q = inputs; q != NULL; q = q->next)
2138 argv = (char **) alloca ((c + 5) * sizeof(char *));
2145 /* Find the linker to invoke based on how nlmconv was run. */
2146 p = program_name + strlen (program_name);
2147 while (p != program_name)
2151 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2152 memcpy (ld, program_name, p - program_name);
2153 strcpy (ld + (p - program_name), LD_NAME);
2162 ld = (char *) LD_NAME;
2164 temp_filename = choose_temp_base ();
2166 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2167 sprintf (unlink_on_exit, "%s.O", temp_filename);
2170 argv[1] = (char *) "-Ur";
2171 argv[2] = (char *) "-o";
2172 argv[3] = unlink_on_exit;
2174 for (q = inputs; q != NULL; q = q->next, i++)
2175 argv[i] = q->string;
2180 for (i = 0; argv[i] != NULL; i++)
2181 fprintf (stderr, " %s", argv[i]);
2182 fprintf (stderr, "\n");
2185 pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2186 PEXECUTE_SEARCH | PEXECUTE_ONE);
2189 fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2190 fprintf (stderr, errfmt, errarg);
2191 unlink (unlink_on_exit);
2195 if (pwait (pid, &status, 0) < 0)
2198 unlink (unlink_on_exit);
2204 fprintf (stderr, _("%s: Execution of %s failed\n"), program_name, ld);
2205 unlink (unlink_on_exit);
2209 return unlink_on_exit;