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. */
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>
39 #include <libiberty.h>
42 /* Internal BFD NLM header. */
46 /* Needed for Alpha support. */
48 #include "coff/ecoff.h"
50 /* If strerror is just a macro, we want to use the one from libiberty
51 since it will handle undefined values. */
53 extern char *strerror ();
56 extern struct tm *localtime ();
60 extern char *getenv ();
73 /* Global variables. */
75 /* The name used to invoke the program. */
78 /* The version number. */
79 extern char *program_version;
81 /* Local variables. */
83 /* Whether to print out debugging information (currently just controls
84 whether it prints the linker command if there is one). */
87 /* The symbol table. */
88 static asymbol **symbols;
90 /* A temporary file name to be unlinked on exit. Actually, for most
91 errors, we leave it around. It's not clear whether that is helpful
93 static char *unlink_on_exit;
95 /* The list of long options. */
96 static struct option long_options[] =
98 { "debug", no_argument, 0, 'd' },
99 { "header-file", required_argument, 0, 'T' },
100 { "help", no_argument, 0, 'h' },
101 { "input-target", required_argument, 0, 'I' },
102 { "input-format", required_argument, 0, 'I' }, /* Obsolete */
103 { "linker", required_argument, 0, 'l' },
104 { "output-target", required_argument, 0, 'O' },
105 { "output-format", required_argument, 0, 'O' }, /* Obsolete */
106 { "version", no_argument, 0, 'V' },
107 { NULL, no_argument, 0, 0 }
110 /* Local routines. */
112 static void show_help PARAMS ((void));
113 static void show_usage PARAMS ((FILE *, int));
114 static const char *select_output_format PARAMS ((enum bfd_architecture,
115 unsigned long, boolean));
116 static void setup_sections PARAMS ((bfd *, asection *, PTR));
117 static void copy_sections PARAMS ((bfd *, asection *, PTR));
118 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
121 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
124 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
127 /* start-sanitize-powerpc-netware */
128 static void powerpc_build_stubs PARAMS ((bfd *, asymbol ***, long *));
129 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
130 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
133 /* end-sanitize-powerpc-netware */
134 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
137 static char *link_inputs PARAMS ((struct string_list *, char *));
138 static const char *choose_temp_base_try PARAMS ((const char *,
140 static void choose_temp_base PARAMS ((void));
141 static int pexecute PARAMS ((char *, char *[]));
143 /* The main routine. */
151 char *input_file = NULL;
152 const char *input_format = NULL;
153 const char *output_format = NULL;
154 const char *header_file = NULL;
156 Nlm_Internal_Fixed_Header fixed_hdr_struct;
157 Nlm_Internal_Variable_Header var_hdr_struct;
158 Nlm_Internal_Version_Header version_hdr_struct;
159 Nlm_Internal_Copyright_Header copyright_hdr_struct;
160 Nlm_Internal_Extended_Header extended_hdr_struct;
163 asymbol **newsyms, **outsyms;
164 long symcount, newsymalloc, newsymcount;
166 asection *text_sec, *bss_sec, *data_sec;
171 char inlead, outlead;
172 boolean gotstart, gotexit, gotcheck;
174 FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
175 size_t custom_size, help_size, message_size, module_size, rpc_size;
176 asection *custom_section, *help_section, *message_section, *module_section;
177 asection *rpc_section, *shared_section;
179 size_t shared_offset, shared_size;
180 Nlm_Internal_Fixed_Header sharedhdr;
185 program_name = argv[0];
186 xmalloc_set_program_name (program_name);
190 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
203 input_format = optarg;
209 output_format = optarg;
212 header_file = optarg;
215 printf ("GNU %s version %s\n", program_name, program_version);
221 show_usage (stderr, 1);
226 /* The input and output files may be named on the command line. */
230 input_file = argv[optind];
234 output_file = argv[optind];
237 show_usage (stderr, 1);
238 if (strcmp (input_file, output_file) == 0)
241 "%s: input and output files must be different\n",
248 /* Initialize the header information to default values. */
249 fixed_hdr = &fixed_hdr_struct;
250 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
251 var_hdr = &var_hdr_struct;
252 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
253 version_hdr = &version_hdr_struct;
254 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
255 copyright_hdr = ©right_hdr_struct;
256 memset ((PTR) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
257 extended_hdr = &extended_hdr_struct;
258 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
259 check_procedure = NULL;
262 exit_procedure = "_Stop";
263 export_symbols = NULL;
267 import_symbols = NULL;
270 sharelib_file = NULL;
271 start_procedure = "_Prelude";
277 /* Parse the header file (if there is one). */
278 if (header_file != NULL)
280 if (! nlmlex_file (header_file)
282 || parse_errors != 0)
286 if (input_files != NULL)
288 if (input_file != NULL)
291 "%s: input file named both on command line and with INPUT\n",
295 if (input_files->next == NULL)
296 input_file = input_files->string;
298 input_file = link_inputs (input_files, ld_arg);
300 else if (input_file == NULL)
302 fprintf (stderr, "%s: no input file\n", program_name);
303 show_usage (stderr, 1);
306 inbfd = bfd_openr (input_file, input_format);
308 bfd_fatal (input_file);
310 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
312 bfd_nonfatal (input_file);
313 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
315 list_matching_formats (matching);
321 if (output_format == NULL)
322 output_format = select_output_format (bfd_get_arch (inbfd),
323 bfd_get_mach (inbfd),
324 inbfd->xvec->byteorder_big_p);
326 assert (output_format != NULL);
328 /* Use the output file named on the command line if it exists.
329 Otherwise use the file named in the OUTPUT statement. */
330 if (output_file == NULL)
332 fprintf (stderr, "%s: no name for output file\n",
334 show_usage (stderr, 1);
337 outbfd = bfd_openw (output_file, output_format);
339 bfd_fatal (output_file);
340 if (! bfd_set_format (outbfd, bfd_object))
341 bfd_fatal (output_file);
343 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
345 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
347 "%s: warning:input and output formats are not compatible\n",
350 /* Move the values read from the command file into outbfd. */
351 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
352 *nlm_variable_header (outbfd) = var_hdr_struct;
353 *nlm_version_header (outbfd) = version_hdr_struct;
354 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
355 *nlm_extended_header (outbfd) = extended_hdr_struct;
357 /* Start copying the input BFD to the output BFD. */
358 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
359 bfd_fatal (bfd_get_filename (outbfd));
361 symsize = bfd_get_symtab_upper_bound (inbfd);
363 bfd_fatal (input_file);
364 symbols = (asymbol **) xmalloc (symsize);
365 symcount = bfd_canonicalize_symtab (inbfd, symbols);
367 bfd_fatal (input_file);
369 /* Make sure we have a .bss section. */
370 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
373 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
375 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
376 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
377 bfd_fatal ("make .bss section");
379 /* start-sanitize-powerpc-netware */
381 /* For PowerPC NetWare we need to build stubs for calls to undefined
382 symbols. Because each stub requires an entry in the TOC section
383 which must be at the same location as other entries in the TOC
384 section, we must do this before determining where the TOC section
385 goes in setup_sections. */
386 powerpc_build_stubs (inbfd, &symbols, &symcount);
387 /* end-sanitize-powerpc-netware */
389 /* Set up the sections. */
390 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
392 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
394 /* The .bss section immediately follows the .data section. */
395 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
396 if (data_sec != NULL)
400 vma = bfd_get_section_size_before_reloc (data_sec);
401 align = 1 << bss_sec->alignment_power;
402 add = ((vma + align - 1) &~ (align - 1)) - vma;
404 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
405 bfd_fatal ("set .bss vma");
408 bfd_size_type data_size;
410 data_size = bfd_get_section_size_before_reloc (data_sec);
411 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
412 bfd_fatal ("set .data size");
416 /* Adjust symbol information. */
417 inlead = bfd_get_symbol_leading_char (inbfd);
418 outlead = bfd_get_symbol_leading_char (outbfd);
423 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
426 for (i = 0; i < symcount; i++)
428 register asymbol *sym;
432 /* Add or remove a leading underscore. */
433 if (inlead != outlead)
437 if (bfd_asymbol_name (sym)[0] == inlead)
445 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
447 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
456 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
458 strcpy (new + 1, bfd_asymbol_name (sym));
463 /* NLM's have an uninitialized data section, but they do not
464 have a common section in the Unix sense. Move all common
465 symbols into the .bss section, and mark them as exported. */
466 if (bfd_is_com_section (bfd_get_section (sym)))
470 sym->section = bss_sec;
472 sym->value = bss_sec->_raw_size;
473 bss_sec->_raw_size += size;
474 align = 1 << bss_sec->alignment_power;
475 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
476 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
478 else if (bfd_get_section (sym)->output_section != NULL)
480 /* Move the symbol into the output section. */
481 sym->value += bfd_get_section (sym)->output_offset;
482 sym->section = bfd_get_section (sym)->output_section;
483 /* This is no longer a section symbol. */
484 sym->flags &=~ BSF_SECTION_SYM;
487 /* Force _edata and _end to be defined. This would normally be
488 done by the linker, but the manipulation of the common
489 symbols will confuse it. */
490 if ((sym->flags & BSF_DEBUGGING) == 0
491 && bfd_asymbol_name (sym)[0] == '_'
492 && bfd_get_section (sym) == &bfd_und_section)
494 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
496 sym->section = bss_sec;
499 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
501 sym->section = bss_sec;
504 /* start-sanitize-powerpc-netware */
505 /* For PowerPC NetWare, we define __GOT0. This is the start
506 of the .got section. */
507 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
508 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
512 got_sec = bfd_get_section_by_name (inbfd, ".got");
513 assert (got_sec != (asection *) NULL);
514 sym->value = got_sec->output_offset;
515 sym->section = got_sec->output_section;
517 /* end-sanitize-powerpc-netware */
520 /* If this is a global symbol, check the export list. */
521 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
523 register struct string_list *l;
526 /* Unfortunately, a symbol can appear multiple times on the
527 export list, with and without prefixes. */
529 for (l = export_symbols; l != NULL; l = l->next)
531 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
537 zbase = strchr (l->string, '@');
539 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
541 /* We must add a symbol with this prefix. */
542 if (newsymcount >= newsymalloc)
545 newsyms = ((asymbol **)
546 xrealloc ((PTR) newsyms,
548 * sizeof (asymbol *))));
550 newsyms[newsymcount] =
551 (asymbol *) xmalloc (sizeof (asymbol));
552 *newsyms[newsymcount] = *sym;
553 newsyms[newsymcount]->name = l->string;
560 /* The unmodified symbol is actually not exported at
562 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
563 sym->flags |= BSF_LOCAL;
567 /* If it's an undefined symbol, see if it's on the import list.
568 Change the prefix if necessary. */
569 if (bfd_get_section (sym) == &bfd_und_section)
571 register struct string_list *l;
573 for (l = import_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 sym->name = l->string;
592 "%s: warning: symbol %s imported but not in import list\n",
593 program_name, bfd_asymbol_name (sym));
596 /* See if it's one of the special named symbols. */
597 if ((sym->flags & BSF_DEBUGGING) == 0)
601 /* FIXME: If these symbols are not in the .text section, we
602 add the .text section size to the value. This may not be
603 correct for all targets. I'm not sure how this should
604 really be handled. */
605 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
607 val = bfd_asymbol_value (sym);
608 if (bfd_get_section (sym) == data_sec
609 && text_sec != (asection *) NULL)
610 val += bfd_section_size (outbfd, text_sec);
611 if (! bfd_set_start_address (outbfd, val))
612 bfd_fatal ("set start address");
615 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
617 val = bfd_asymbol_value (sym);
618 if (bfd_get_section (sym) == data_sec
619 && text_sec != (asection *) NULL)
620 val += bfd_section_size (outbfd, text_sec);
621 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
624 if (check_procedure != NULL
625 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
627 val = bfd_asymbol_value (sym);
628 if (bfd_get_section (sym) == data_sec
629 && text_sec != (asection *) NULL)
630 val += bfd_section_size (outbfd, text_sec);
631 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
639 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
641 /* FIXME: If any relocs referring to _end use inplace addends,
642 then I think they need to be updated. This is handled by
643 i386_mangle_relocs. Is it needed for any other object
647 if (newsymcount == 0)
651 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
652 * sizeof (asymbol *));
653 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
654 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
655 outsyms[symcount + newsymcount] = NULL;
658 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
661 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
662 program_name, start_procedure);
664 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
665 program_name, exit_procedure);
666 if (check_procedure != NULL
668 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
669 program_name, check_procedure);
671 /* Add additional sections required for the header information. */
672 if (custom_file != NULL)
674 custom_data = fopen (custom_file, "r");
675 if (custom_data == NULL
676 || fstat (fileno (custom_data), &st) < 0)
678 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
684 custom_size = st.st_size;
685 custom_section = bfd_make_section (outbfd, ".nlmcustom");
686 if (custom_section == NULL
687 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
688 || ! bfd_set_section_flags (outbfd, custom_section,
690 bfd_fatal ("custom section");
693 if (help_file != NULL)
695 help_data = fopen (help_file, "r");
696 if (help_data == NULL
697 || fstat (fileno (help_data), &st) < 0)
699 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
705 help_size = st.st_size;
706 help_section = bfd_make_section (outbfd, ".nlmhelp");
707 if (help_section == NULL
708 || ! bfd_set_section_size (outbfd, help_section, help_size)
709 || ! bfd_set_section_flags (outbfd, help_section,
711 bfd_fatal ("help section");
712 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
715 if (message_file != NULL)
717 message_data = fopen (message_file, "r");
718 if (message_data == NULL
719 || fstat (fileno (message_data), &st) < 0)
721 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
727 message_size = st.st_size;
728 message_section = bfd_make_section (outbfd, ".nlmmessages");
729 if (message_section == NULL
730 || ! bfd_set_section_size (outbfd, message_section, message_size)
731 || ! bfd_set_section_flags (outbfd, message_section,
733 bfd_fatal ("message section");
734 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
739 struct string_list *l;
742 for (l = modules; l != NULL; l = l->next)
743 module_size += strlen (l->string) + 1;
744 module_section = bfd_make_section (outbfd, ".nlmmodules");
745 if (module_section == NULL
746 || ! bfd_set_section_size (outbfd, module_section, module_size)
747 || ! bfd_set_section_flags (outbfd, module_section,
749 bfd_fatal ("module section");
751 if (rpc_file != NULL)
753 rpc_data = fopen (rpc_file, "r");
755 || fstat (fileno (rpc_data), &st) < 0)
757 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
763 rpc_size = st.st_size;
764 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
765 if (rpc_section == NULL
766 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
767 || ! bfd_set_section_flags (outbfd, rpc_section,
769 bfd_fatal ("rpc section");
770 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
773 if (sharelib_file != NULL)
775 sharedbfd = bfd_openr (sharelib_file, output_format);
776 if (sharedbfd == NULL
777 || ! bfd_check_format (sharedbfd, bfd_object))
779 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
780 bfd_errmsg (bfd_get_error ()));
781 sharelib_file = NULL;
785 sharedhdr = *nlm_fixed_header (sharedbfd);
786 bfd_close (sharedbfd);
787 shared_data = fopen (sharelib_file, "r");
788 if (shared_data == NULL
789 || (fstat (fileno (shared_data), &st) < 0))
791 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
793 sharelib_file = NULL;
797 /* If we were clever, we could just copy out the
798 sections of the shared library which we actually
799 need. However, we would have to figure out the sizes
800 of the external and public information, and that can
801 not be done without reading through them. */
802 if (sharedhdr.uninitializedDataSize > 0)
804 /* There is no place to record this information. */
806 "%s:%s: warning: shared libraries can not have uninitialized data\n",
807 program_name, sharelib_file);
809 shared_offset = st.st_size;
810 if (shared_offset > sharedhdr.codeImageOffset)
811 shared_offset = sharedhdr.codeImageOffset;
812 if (shared_offset > sharedhdr.dataImageOffset)
813 shared_offset = sharedhdr.dataImageOffset;
814 if (shared_offset > sharedhdr.relocationFixupOffset)
815 shared_offset = sharedhdr.relocationFixupOffset;
816 if (shared_offset > sharedhdr.externalReferencesOffset)
817 shared_offset = sharedhdr.externalReferencesOffset;
818 if (shared_offset > sharedhdr.publicsOffset)
819 shared_offset = sharedhdr.publicsOffset;
820 shared_size = st.st_size - shared_offset;
821 shared_section = bfd_make_section (outbfd, ".nlmshared");
822 if (shared_section == NULL
823 || ! bfd_set_section_size (outbfd, shared_section,
825 || ! bfd_set_section_flags (outbfd, shared_section,
827 bfd_fatal ("shared section");
828 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
833 /* Check whether a version was given. */
834 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
835 fprintf (stderr, "%s: warning: No version number given\n",
838 /* At least for now, always create an extended header, because that
839 is what NLMLINK does. */
840 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
842 /* If the date was not given, force it in. */
843 if (nlm_version_header (outbfd)->month == 0
844 && nlm_version_header (outbfd)->day == 0
845 && nlm_version_header (outbfd)->year == 0)
851 ptm = localtime (&now);
852 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
853 nlm_version_header (outbfd)->day = ptm->tm_mday;
854 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
855 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
857 /* start-sanitize-powerpc-netware */
859 /* Resolve the stubs we build for PowerPC NetWare. */
860 powerpc_resolve_stubs (inbfd, outbfd);
861 /* end-sanitize-powerpc-netware */
863 /* Copy over the sections. */
864 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
866 /* Finish up the header information. */
867 if (custom_file != NULL)
871 data = xmalloc (custom_size);
872 if (fread (data, 1, custom_size, custom_data) != custom_size)
873 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
877 if (! bfd_set_section_contents (outbfd, custom_section, data,
878 (file_ptr) 0, custom_size))
879 bfd_fatal ("custom section");
880 nlm_fixed_header (outbfd)->customDataOffset =
881 custom_section->filepos;
882 nlm_fixed_header (outbfd)->customDataSize = custom_size;
888 /* As a special hack, the backend recognizes a debugInfoOffset
889 of -1 to mean that it should not output any debugging
890 information. This can not be handling by fiddling with the
891 symbol table because exported symbols appear in both the
892 export information and the debugging information. */
893 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
895 if (map_file != NULL)
897 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
899 if (help_file != NULL)
903 data = xmalloc (help_size);
904 if (fread (data, 1, help_size, help_data) != help_size)
905 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
909 if (! bfd_set_section_contents (outbfd, help_section, data,
910 (file_ptr) 0, help_size))
911 bfd_fatal ("help section");
912 nlm_extended_header (outbfd)->helpFileOffset =
913 help_section->filepos;
914 nlm_extended_header (outbfd)->helpFileLength = help_size;
918 if (message_file != NULL)
922 data = xmalloc (message_size);
923 if (fread (data, 1, message_size, message_data) != message_size)
924 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
928 if (! bfd_set_section_contents (outbfd, message_section, data,
929 (file_ptr) 0, message_size))
930 bfd_fatal ("message section");
931 nlm_extended_header (outbfd)->messageFileOffset =
932 message_section->filepos;
933 nlm_extended_header (outbfd)->messageFileLength = message_size;
935 /* FIXME: Are these offsets correct on all platforms? Are
936 they 32 bits on all platforms? What endianness? */
937 nlm_extended_header (outbfd)->languageID =
938 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
939 nlm_extended_header (outbfd)->messageCount =
940 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
948 struct string_list *l;
951 data = xmalloc (module_size);
953 set = (unsigned char *) data;
954 for (l = modules; l != NULL; l = l->next)
956 *set = strlen (l->string);
957 strncpy (set + 1, l->string, *set);
961 if (! bfd_set_section_contents (outbfd, module_section, data,
962 (file_ptr) 0, module_size))
963 bfd_fatal ("module section");
964 nlm_fixed_header (outbfd)->moduleDependencyOffset =
965 module_section->filepos;
966 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
968 if (rpc_file != NULL)
972 data = xmalloc (rpc_size);
973 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
974 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
978 if (! bfd_set_section_contents (outbfd, rpc_section, data,
979 (file_ptr) 0, rpc_size))
980 bfd_fatal ("rpc section");
981 nlm_extended_header (outbfd)->RPCDataOffset =
982 rpc_section->filepos;
983 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
987 if (sharelib_file != NULL)
991 data = xmalloc (shared_size);
992 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
993 || fread (data, 1, shared_size, shared_data) != shared_size)
994 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
998 if (! bfd_set_section_contents (outbfd, shared_section, data,
999 (file_ptr) 0, shared_size))
1000 bfd_fatal ("shared section");
1002 nlm_extended_header (outbfd)->sharedCodeOffset =
1003 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1004 nlm_extended_header (outbfd)->sharedCodeLength =
1005 sharedhdr.codeImageSize;
1006 nlm_extended_header (outbfd)->sharedDataOffset =
1007 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1008 nlm_extended_header (outbfd)->sharedDataLength =
1009 sharedhdr.dataImageSize;
1010 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1011 (sharedhdr.relocationFixupOffset
1013 + shared_section->filepos);
1014 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1015 sharedhdr.numberOfRelocationFixups;
1016 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1017 (sharedhdr.externalReferencesOffset
1019 + shared_section->filepos);
1020 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1021 sharedhdr.numberOfExternalReferences;
1022 nlm_extended_header (outbfd)->sharedPublicsOffset =
1023 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1024 nlm_extended_header (outbfd)->sharedPublicsCount =
1025 sharedhdr.numberOfPublics;
1026 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1027 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1028 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1029 sharedhdr.numberOfDebugRecords;
1030 nlm_extended_header (outbfd)->SharedInitializationOffset =
1031 sharedhdr.codeStartOffset;
1032 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1033 sharedhdr.exitProcedureOffset;
1036 len = strlen (output_file);
1037 if (len > NLM_MODULE_NAME_SIZE - 2)
1038 len = NLM_MODULE_NAME_SIZE - 2;
1039 nlm_fixed_header (outbfd)->moduleName[0] = len;
1041 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1042 NLM_MODULE_NAME_SIZE - 2);
1043 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1044 for (modname = nlm_fixed_header (outbfd)->moduleName;
1047 if (islower (*modname))
1048 *modname = toupper (*modname);
1050 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1051 NLM_OLD_THREAD_NAME_LENGTH);
1053 if (! bfd_close (outbfd))
1054 bfd_fatal (output_file);
1055 if (! bfd_close (inbfd))
1056 bfd_fatal (input_file);
1058 if (unlink_on_exit != NULL)
1059 unlink (unlink_on_exit);
1064 /* Display a help message and exit. */
1069 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1071 show_usage (stdout, 0);
1074 /* Show a usage message and exit. */
1077 show_usage (file, status)
1082 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1083 [--input-target=bfdname] [--output-target=bfdname]\n\
1084 [--header-file=file] [--linker=linker] [--debug]\n\
1085 [--help] [--version]\n\
1086 [in-file [out-file]]\n",
1091 /* Select the output format based on the input architecture, machine,
1092 and endianness. This chooses the appropriate NLM target. */
1095 select_output_format (arch, mach, bigendian)
1096 enum bfd_architecture arch;
1103 return "nlm32-i386";
1104 case bfd_arch_sparc:
1105 return "nlm32-sparc";
1106 case bfd_arch_alpha:
1107 return "nlm32-alpha";
1108 /* start-sanitize-powerpc-netware */
1109 case bfd_arch_powerpc:
1110 return "nlm32-powerpc";
1111 /* end-sanitize-powerpc-netware */
1113 fprintf (stderr, "%s: no default NLM format for %s\n",
1114 program_name, bfd_printable_arch_mach (arch, mach));
1116 /* Avoid warning. */
1122 /* The BFD sections are copied in two passes. This function selects
1123 the output section for each input section, and sets up the section
1127 setup_sections (inbfd, insec, data_ptr)
1132 bfd *outbfd = (bfd *) data_ptr;
1134 const char *outname;
1137 bfd_size_type align;
1140 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1141 file. However, I don't have a good way to describe this section.
1142 We do want to copy the section when using objcopy. */
1143 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1144 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1147 f = bfd_get_section_flags (inbfd, insec);
1149 outname = NLM_CODE_NAME;
1150 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1151 outname = NLM_INITIALIZED_DATA_NAME;
1152 else if (f & SEC_ALLOC)
1153 outname = NLM_UNINITIALIZED_DATA_NAME;
1155 outname = bfd_section_name (inbfd, insec);
1157 outsec = bfd_get_section_by_name (outbfd, outname);
1160 outsec = bfd_make_section (outbfd, outname);
1162 bfd_fatal ("make section");
1165 insec->output_section = outsec;
1167 offset = bfd_section_size (outbfd, outsec);
1168 align = 1 << bfd_section_alignment (inbfd, insec);
1169 add = ((offset + align - 1) &~ (align - 1)) - offset;
1170 insec->output_offset = offset + add;
1172 if (! bfd_set_section_size (outbfd, outsec,
1173 (bfd_section_size (outbfd, outsec)
1174 + bfd_section_size (inbfd, insec)
1176 bfd_fatal ("set section size");
1178 if ((bfd_section_alignment (inbfd, insec)
1179 > bfd_section_alignment (outbfd, outsec))
1180 && ! bfd_set_section_alignment (outbfd, outsec,
1181 bfd_section_alignment (inbfd, insec)))
1182 bfd_fatal ("set section alignment");
1184 if (! bfd_set_section_flags (outbfd, outsec, f))
1185 bfd_fatal ("set section flags");
1187 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1190 /* Copy the section contents. */
1193 copy_sections (inbfd, insec, data_ptr)
1198 bfd *outbfd = (bfd *) data_ptr;
1204 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1205 file. However, I don't have a good way to describe this section.
1206 We do want to copy the section when using objcopy. */
1207 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1208 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1211 outsec = insec->output_section;
1212 assert (outsec != NULL);
1214 size = bfd_get_section_size_before_reloc (insec);
1218 /* FIXME: Why are these necessary? */
1219 insec->_cooked_size = insec->_raw_size;
1220 insec->reloc_done = true;
1222 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1226 contents = xmalloc (size);
1227 if (! bfd_get_section_contents (inbfd, insec, contents,
1228 (file_ptr) 0, size))
1229 bfd_fatal (bfd_get_filename (inbfd));
1232 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1234 bfd_fatal (bfd_get_filename (inbfd));
1235 if (reloc_size != 0)
1240 relocs = (arelent **) xmalloc (reloc_size);
1241 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1242 if (reloc_count < 0)
1243 bfd_fatal (bfd_get_filename (inbfd));
1244 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1247 /* FIXME: refers to internal BFD fields. */
1248 if (outsec->orelocation != (arelent **) NULL)
1250 bfd_size_type total_count;
1253 total_count = reloc_count + outsec->reloc_count;
1254 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1255 memcpy (combined, outsec->orelocation,
1256 outsec->reloc_count * sizeof (arelent));
1257 memcpy (combined + outsec->reloc_count, relocs,
1258 (size_t) (reloc_count * sizeof (arelent)));
1259 free (outsec->orelocation);
1260 reloc_count = total_count;
1264 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1267 if (contents != NULL)
1269 if (! bfd_set_section_contents (outbfd, outsec, contents,
1270 insec->output_offset, size))
1271 bfd_fatal (bfd_get_filename (outbfd));
1276 /* Some, perhaps all, NetWare targets require changing the relocs used
1277 by the input formats. */
1280 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1284 arelent ***relocs_ptr;
1285 long *reloc_count_ptr;
1287 bfd_size_type contents_size;
1289 switch (bfd_get_arch (outbfd))
1292 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1293 contents, contents_size);
1295 case bfd_arch_alpha:
1296 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1297 contents, contents_size);
1299 /* start-sanitize-powerpc-netware */
1300 case bfd_arch_powerpc:
1301 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1302 contents, contents_size);
1304 /* end-sanitize-powerpc-netware */
1306 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1307 contents, contents_size);
1312 /* By default all we need to do for relocs is change the address by
1313 the output_offset. */
1317 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1321 arelent ***relocs_ptr;
1322 long *reloc_count_ptr;
1324 bfd_size_type contents_size;
1326 if (insec->output_offset != 0)
1329 register arelent **relocs;
1332 reloc_count = *reloc_count_ptr;
1333 relocs = *relocs_ptr;
1334 for (i = 0; i < reloc_count; i++, relocs++)
1335 (*relocs)->address += insec->output_offset;
1339 /* NetWare on the i386 supports a restricted set of relocs, which are
1340 different from those used on other i386 targets. This routine
1341 converts the relocs. It is, obviously, very target dependent. At
1342 the moment, the nlm32-i386 backend performs similar translations;
1343 however, it is more reliable and efficient to do them here. */
1345 static reloc_howto_type nlm_i386_pcrel_howto =
1346 HOWTO (1, /* type */
1348 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 true, /* pc_relative */
1352 complain_overflow_signed, /* complain_on_overflow */
1353 0, /* special_function */
1354 "DISP32", /* name */
1355 true, /* partial_inplace */
1356 0xffffffff, /* src_mask */
1357 0xffffffff, /* dst_mask */
1358 true); /* pcrel_offset */
1361 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1365 arelent ***relocs_ptr;
1366 long *reloc_count_ptr;
1368 bfd_size_type contents_size;
1370 long reloc_count, i;
1373 reloc_count = *reloc_count_ptr;
1374 relocs = *relocs_ptr;
1375 for (i = 0; i < reloc_count; i++)
1379 bfd_size_type address;
1383 sym = *rel->sym_ptr_ptr;
1385 /* We're moving the relocs from the input section to the output
1386 section, so we must adjust the address accordingly. */
1387 address = rel->address;
1388 rel->address += insec->output_offset;
1390 /* Note that no serious harm will ensue if we fail to change a
1391 reloc. The backend will fail when writing out the reloc. */
1393 /* Make sure this reloc is within the data we have. We use only
1394 4 byte relocs here, so we insist on having 4 bytes. */
1395 if (address + 4 > contents_size)
1398 /* A PC relative reloc entirely within a single section is
1399 completely unnecessary. This can be generated by ld -r. */
1400 if (sym == insec->symbol
1401 && rel->howto != NULL
1402 && rel->howto->pc_relative
1403 && ! rel->howto->pcrel_offset)
1407 memmove (relocs, relocs + 1,
1408 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1412 /* Get the amount the relocation will add in. */
1413 addend = rel->addend + sym->value;
1415 /* NetWare doesn't support PC relative relocs against defined
1416 symbols, so we have to eliminate them by doing the relocation
1417 now. We can only do this if the reloc is within a single
1419 if (rel->howto != NULL
1420 && rel->howto->pc_relative
1421 && bfd_get_section (sym) == insec->output_section)
1425 if (rel->howto->pcrel_offset)
1428 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1430 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1434 memmove (relocs, relocs + 1,
1435 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1439 /* NetWare doesn't support reloc addends, so we get rid of them
1440 here by simply adding them into the object data. We handle
1441 the symbol value, if any, the same way. */
1443 && rel->howto != NULL
1444 && rel->howto->rightshift == 0
1445 && rel->howto->size == 2
1446 && rel->howto->bitsize == 32
1447 && rel->howto->bitpos == 0
1448 && rel->howto->src_mask == 0xffffffff
1449 && rel->howto->dst_mask == 0xffffffff)
1453 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1455 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1457 /* Adjust the reloc for the changes we just made. */
1459 if (bfd_get_section (sym) != &bfd_und_section)
1460 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1463 /* NetWare uses a reloc with pcrel_offset set. We adjust
1464 pc_relative relocs accordingly. We are going to change the
1465 howto field, so we can only do this if the current one is
1466 compatible. We should check that special_function is NULL
1467 here, but at the moment coff-i386 uses a special_function
1468 which does not affect what we are doing here. */
1469 if (rel->howto != NULL
1470 && rel->howto->pc_relative
1471 && ! rel->howto->pcrel_offset
1472 && rel->howto->rightshift == 0
1473 && rel->howto->size == 2
1474 && rel->howto->bitsize == 32
1475 && rel->howto->bitpos == 0
1476 && rel->howto->src_mask == 0xffffffff
1477 && rel->howto->dst_mask == 0xffffffff)
1481 /* When pcrel_offset is not set, it means that the negative
1482 of the address of the memory location is stored in the
1483 memory location. We must add it back in. */
1484 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1486 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1488 /* We must change to a new howto. */
1489 rel->howto = &nlm_i386_pcrel_howto;
1494 /* On the Alpha the first reloc for every section must be a special
1495 relocs which hold the GP address. Also, the first reloc in the
1496 file must be a special reloc which holds the address of the .lita
1499 static reloc_howto_type nlm32_alpha_nw_howto =
1500 HOWTO (ALPHA_R_NW_RELOC, /* type */
1502 0, /* size (0 = byte, 1 = short, 2 = long) */
1504 false, /* pc_relative */
1506 complain_overflow_dont, /* complain_on_overflow */
1507 0, /* special_function */
1508 "NW_RELOC", /* name */
1509 false, /* partial_inplace */
1512 false); /* pcrel_offset */
1516 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1520 register arelent ***relocs_ptr;
1521 long *reloc_count_ptr;
1523 bfd_size_type contents_size;
1525 long old_reloc_count;
1526 arelent **old_relocs;
1527 register arelent **relocs;
1529 old_reloc_count = *reloc_count_ptr;
1530 old_relocs = *relocs_ptr;
1531 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1532 *relocs_ptr = relocs;
1534 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1537 asection *lita_section;
1539 inbfd = insec->owner;
1540 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1541 if (lita_section != (asection *) NULL)
1543 nlm_alpha_backend_data (outbfd)->lita_address =
1544 bfd_get_section_vma (inbfd, lita_section);
1545 nlm_alpha_backend_data (outbfd)->lita_size =
1546 bfd_section_size (inbfd, lita_section);
1550 /* Avoid outputting this reloc again. */
1551 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1554 *relocs = (arelent *) xmalloc (sizeof (arelent));
1555 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1556 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1557 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1558 (*relocs)->howto = &nlm32_alpha_nw_howto;
1560 ++(*reloc_count_ptr);
1563 /* Get the GP value from bfd. It is in the .reginfo section. */
1564 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1567 asection *reginfo_sec;
1568 struct ecoff_reginfo sreginfo;
1570 inbfd = insec->owner;
1571 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1572 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1573 if (reginfo_sec != (asection *) NULL
1574 && bfd_get_section_contents (inbfd, reginfo_sec,
1575 (PTR) &sreginfo, (file_ptr) 0,
1576 sizeof sreginfo) != false)
1577 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1580 *relocs = (arelent *) xmalloc (sizeof (arelent));
1581 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1582 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1583 (*relocs)->addend = 0;
1584 (*relocs)->howto = &nlm32_alpha_nw_howto;
1586 ++(*reloc_count_ptr);
1588 memcpy ((PTR) relocs, (PTR) old_relocs,
1589 (size_t) old_reloc_count * sizeof (arelent *));
1590 relocs[old_reloc_count] = (arelent *) NULL;
1594 if (insec->output_offset != 0)
1596 register bfd_size_type i;
1598 for (i = 0; i < old_reloc_count; i++, relocs++)
1599 (*relocs)->address += insec->output_offset;
1602 /* start-sanitize-powerpc-netware */
1604 /* We keep a linked list of stubs which we must build. Because BFD
1605 requires us to know the sizes of all sections before we can set the
1606 contents of any, we must figure out which stubs we want to build
1607 before we can actually build any of them. */
1611 /* Next stub in linked list. */
1612 struct powerpc_stub *next;
1614 /* Symbol whose value is the start of the stub. This is a symbol
1615 whose name begins with `.'. */
1618 /* Symbol we are going to create a reloc against. This is a symbol
1619 with the same name as START but without the leading `.'. */
1622 /* The TOC index for this stub. This is the index into the TOC
1623 section at which the reloc is created. */
1624 unsigned int toc_index;
1627 /* The linked list of stubs. */
1629 static struct powerpc_stub *powerpc_stubs;
1631 /* This is what a stub looks like. The first instruction will get
1632 adjusted with the correct TOC index. */
1634 static unsigned long powerpc_stub_insns[] =
1636 0x81820000, /* lwz r12,0(r2) */
1637 0x90410014, /* stw r2,20(r1) */
1638 0x800c0000, /* lwz r0,0(r12) */
1639 0x804c0004, /* lwz r2,r(r12) */
1640 0x7c0903a6, /* mtctr r0 */
1641 0x4e800420, /* bctr */
1642 0, /* Traceback table. */
1647 #define POWERPC_STUB_INSN_COUNT \
1648 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1650 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1652 /* Each stub uses a four byte TOC entry. */
1653 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1655 /* The original size of the .got section. */
1656 static bfd_size_type powerpc_initial_got_size;
1658 /* Look for all undefined symbols beginning with `.', and prepare to
1659 build a stub for each one. */
1662 powerpc_build_stubs (inbfd, symbols_ptr, symcount_ptr)
1664 asymbol ***symbols_ptr;
1669 unsigned int got_base;
1674 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1675 the section to prevent copy_sections from reading from it. */
1676 stub_sec = bfd_make_section (inbfd, ".stubs");
1677 if (stub_sec == (asection *) NULL
1678 || ! bfd_set_section_flags (inbfd, stub_sec,
1683 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1684 bfd_fatal (".stubs");
1686 /* Get the TOC section, which is named .got. */
1687 got_sec = bfd_get_section_by_name (inbfd, ".got");
1688 if (got_sec == (asection *) NULL)
1690 got_sec = bfd_make_section (inbfd, ".got");
1691 if (got_sec == (asection *) NULL
1692 || ! bfd_set_section_flags (inbfd, got_sec,
1697 | SEC_HAS_CONTENTS))
1698 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1702 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1703 got_base = powerpc_initial_got_size;
1704 got_base = (got_base + 3) &~ 3;
1708 symcount = *symcount_ptr;
1709 for (i = 0; i < symcount; i++)
1714 struct powerpc_stub *item;
1716 sym = (*symbols_ptr)[i];
1718 /* We must make a stub for every undefined symbol whose name
1720 if (bfd_asymbol_name (sym)[0] != '.'
1721 || bfd_get_section (sym) != &bfd_und_section)
1724 /* Make a new undefined symbol with the same name but without
1726 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1728 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1729 strcpy (newname, bfd_asymbol_name (sym) + 1);
1730 newsym->name = newname;
1732 /* Define the `.' symbol to be in the stub section. */
1733 sym->section = stub_sec;
1734 sym->value = stubcount * POWERPC_STUB_SIZE;
1735 /* We set the BSF_DYNAMIC flag here so that we can check it when
1736 we are mangling relocs. FIXME: This is a hack. */
1737 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1739 /* Add this stub to the linked list. */
1740 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1742 item->reloc = newsym;
1743 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1745 item->next = powerpc_stubs;
1746 powerpc_stubs = item;
1754 struct powerpc_stub *l;
1756 /* Add the new symbols we just created to the symbol table. */
1757 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1758 ((symcount + stubcount)
1759 * sizeof (asymbol)));
1760 *symcount_ptr += stubcount;
1761 s = &(*symbols_ptr)[symcount];
1762 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1765 /* Set the size of the .stubs section and increase the size of
1766 the .got section. */
1767 if (! bfd_set_section_size (inbfd, stub_sec,
1768 stubcount * POWERPC_STUB_SIZE)
1769 || ! bfd_set_section_size (inbfd, got_sec,
1772 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1773 bfd_fatal ("stub section sizes");
1777 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1778 of the output section, and create new relocs in the TOC. */
1781 powerpc_resolve_stubs (inbfd, outbfd)
1785 bfd_byte buf[POWERPC_STUB_SIZE];
1787 unsigned int stubcount;
1791 struct powerpc_stub *l;
1793 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1796 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1797 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1799 got_sec = bfd_get_section_by_name (inbfd, ".got");
1800 assert (got_sec != (asection *) NULL);
1801 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1804 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1806 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1809 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1813 /* Adjust the first instruction to use the right TOC index. */
1814 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1816 /* Write this stub out. */
1817 if (! bfd_set_section_contents (outbfd,
1818 bfd_get_section (l->start),
1822 bfd_fatal ("writing stub");
1824 /* Create a new reloc for the TOC entry. */
1825 reloc = (arelent *) xmalloc (sizeof (arelent));
1826 reloc->sym_ptr_ptr = &l->reloc;
1827 reloc->address = l->toc_index + got_sec->output_offset;
1829 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1834 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1837 /* Adjust relocation entries for PowerPC NetWare. We do not output
1838 TOC relocations. The object code already contains the offset from
1839 the TOC pointer. When the function is called, the TOC register,
1840 r2, will be set to the correct TOC value, so there is no need for
1841 any further reloc. */
1845 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1849 register arelent ***relocs_ptr;
1850 long *reloc_count_ptr;
1852 bfd_size_type contents_size;
1854 const reloc_howto_type *toc_howto;
1856 register arelent **relocs;
1859 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1860 if (toc_howto == (reloc_howto_type *) NULL)
1863 /* If this is the .got section, clear out all the contents beyond
1864 the initial size. We must do this here because copy_sections is
1865 going to write out whatever we return in the contents field. */
1866 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1867 memset (contents + powerpc_initial_got_size, 0,
1868 (bfd_get_section_size_after_reloc (insec)
1869 - powerpc_initial_got_size));
1871 reloc_count = *reloc_count_ptr;
1872 relocs = *relocs_ptr;
1873 for (i = 0; i < reloc_count; i++)
1880 sym = *rel->sym_ptr_ptr;
1882 /* We must be able to resolve all PC relative relocs at this
1883 point. If we get a branch to an undefined symbol we build a
1884 stub, since NetWare will resolve undefined symbols into a
1885 pointer to a function descriptor. */
1886 if (rel->howto->pc_relative)
1888 /* This check for whether a symbol is in the same section as
1889 the reloc will be wrong if there is a PC relative reloc
1890 between two sections both of which were placed in the
1891 same output section. This should not happen. */
1892 if (bfd_get_section (sym) != insec->output_section)
1893 fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1894 program_name, bfd_asymbol_name (sym));
1899 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1900 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1901 val = ((val &~ rel->howto->dst_mask)
1902 | (((val & rel->howto->src_mask)
1903 + (sym->value - rel->address)
1905 & rel->howto->dst_mask));
1906 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1908 /* If this reloc is against an stubbed symbol and the
1911 then we replace the next instruction with
1913 This reloads the TOC pointer after a stub call. */
1914 if (bfd_asymbol_name (sym)[0] == '.'
1915 && (sym->flags & BSF_DYNAMIC) != 0
1916 && (bfd_get_32 (outbfd,
1917 (bfd_byte *) contents + rel->address + 4)
1918 == 0x4ffffb82)) /* cror 31,31,31 */
1919 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1920 (bfd_byte *) contents + rel->address + 4);
1924 memmove (relocs, relocs + 1,
1925 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1930 /* When considering a TOC reloc, we do not want to include the
1931 symbol value. The symbol will be start of the TOC section
1932 (which is named .got). We do want to include the addend. */
1933 if (rel->howto == toc_howto)
1936 symvalue = sym->value;
1938 /* If this is a relocation against a symbol with a value, or
1939 there is a reloc addend, we need to update the addend in the
1941 if (symvalue + rel->addend != 0)
1945 switch (rel->howto->size)
1948 val = bfd_get_16 (outbfd,
1949 (bfd_byte *) contents + rel->address);
1950 val = ((val &~ rel->howto->dst_mask)
1951 | (((val & rel->howto->src_mask)
1954 & rel->howto->dst_mask));
1955 if ((bfd_signed_vma) val < - 0x8000
1956 || (bfd_signed_vma) val >= 0x8000)
1958 "%s: overflow when adjusting relocation against %s\n",
1959 program_name, bfd_asymbol_name (sym));
1960 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1964 val = bfd_get_32 (outbfd,
1965 (bfd_byte *) contents + rel->address);
1966 val = ((val &~ rel->howto->dst_mask)
1967 | (((val & rel->howto->src_mask)
1970 & rel->howto->dst_mask));
1971 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1978 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1982 /* Now that we have incorporated the addend, remove any TOC
1984 if (rel->howto == toc_howto)
1988 memmove (relocs, relocs + 1,
1989 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1993 rel->address += insec->output_offset;
1996 /* end-sanitize-powerpc-netware */
1998 /* Name of linker. */
2000 #define LD_NAME "ld"
2003 /* Temporary file name base. */
2004 static char *temp_filename;
2006 /* The user has specified several input files. Invoke the linker to
2007 link them all together, and convert and delete the resulting output
2011 link_inputs (inputs, ld)
2012 struct string_list *inputs;
2016 struct string_list *q;
2023 for (q = inputs; q != NULL; q = q->next)
2026 argv = (char **) alloca (c + 5);
2033 /* Find the linker to invoke based on how nlmconv was run. */
2034 p = program_name + strlen (program_name);
2035 while (p != program_name)
2039 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2040 memcpy (ld, program_name, p - program_name);
2041 strcpy (ld + (p - program_name), LD_NAME);
2050 ld = (char *) LD_NAME;
2052 choose_temp_base ();
2054 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2055 sprintf (unlink_on_exit, "%s.O", temp_filename);
2058 argv[1] = (char *) "-r";
2059 argv[2] = (char *) "-o";
2060 argv[3] = unlink_on_exit;
2062 for (q = inputs; q != NULL; q = q->next, i++)
2063 argv[i] = q->string;
2068 for (i = 0; argv[i] != NULL; i++)
2069 fprintf (stderr, " %s", argv[i]);
2070 fprintf (stderr, "\n");
2073 pid = pexecute (ld, argv);
2075 if (waitpid (pid, &status, 0) < 0)
2078 unlink (unlink_on_exit);
2084 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2085 unlink (unlink_on_exit);
2089 return unlink_on_exit;
2092 /* Choose a temporary file name. Stolen from gcc.c. */
2095 choose_temp_base_try (try, base)
2103 else if (try == NULL)
2105 else if (access (try, R_OK | W_OK) != 0)
2115 const char *base = NULL;
2118 base = choose_temp_base_try (getenv ("TMPDIR"), base);
2119 base = choose_temp_base_try (getenv ("TMP"), base);
2120 base = choose_temp_base_try (getenv ("TEMP"), base);
2123 base = choose_temp_base_try (P_tmpdir, base);
2126 base = choose_temp_base_try ("/usr/tmp", base);
2127 base = choose_temp_base_try ("/tmp", base);
2129 /* If all else fails, use the current directory! */
2133 len = strlen (base);
2134 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2135 strcpy (temp_filename, base);
2136 if (len > 0 && temp_filename[len-1] != '/')
2137 temp_filename[len++] = '/';
2138 strcpy (temp_filename + len, "ccXXXXXX");
2140 mktemp (temp_filename);
2141 if (*temp_filename == '\0')
2145 /* Execute a job. Stolen from gcc.c. */
2151 pexecute (program, argv)
2159 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2160 rf = scmd + strlen(program) + 2 + el;
2161 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2162 argfile = fopen (rf, "w");
2164 pfatal_with_name (rf);
2166 for (i=1; argv[i]; i++)
2169 for (cp = argv[i]; *cp; cp++)
2171 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2172 fputc ('\\', argfile);
2173 fputc (*cp, argfile);
2175 fputc ('\n', argfile);
2186 return MIN_FATAL_STATUS << 8;
2192 #else /* not __MSDOS__ */
2195 pexecute (program, argv)
2200 int retries, sleep_interval;
2202 /* Fork a subprocess; wait and retry if it fails. */
2204 for (retries = 0; retries < 4; retries++)
2209 sleep (sleep_interval);
2210 sleep_interval *= 2;
2226 /* Exec the program. */
2227 execvp (program, argv);
2234 /* Return child's process number. */
2239 #endif /* not __MSDOS__ */
2243 pexecute (program, argv)
2247 return spawnvp (1, program, argv);
2249 #endif /* not OS2 */