1 /* nlmconv.c -- NLM conversion program
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Written by Ian Lance Taylor <ian@cygnus.com>.
22 This program can be used to convert any appropriate object file
23 into a NetWare Loadable Module (an NLM). It will accept a linker
24 specification file which is identical to that accepted by the
25 NetWare linker, NLMLINK, except that the INPUT command, normally
26 used to give a list of object files to link together, is not used.
27 This program will convert only a single object file. */
33 #include <sys/types.h>
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 *, 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 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
387 powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
388 /* end-sanitize-powerpc-netware */
390 /* Set up the sections. */
391 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
393 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
395 /* The .bss section immediately follows the .data section. */
396 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
397 if (data_sec != NULL)
401 vma = bfd_get_section_size_before_reloc (data_sec);
402 align = 1 << bss_sec->alignment_power;
403 add = ((vma + align - 1) &~ (align - 1)) - vma;
405 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
406 bfd_fatal ("set .bss vma");
409 bfd_size_type data_size;
411 data_size = bfd_get_section_size_before_reloc (data_sec);
412 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
413 bfd_fatal ("set .data size");
417 /* Adjust symbol information. */
418 inlead = bfd_get_symbol_leading_char (inbfd);
419 outlead = bfd_get_symbol_leading_char (outbfd);
424 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
427 for (i = 0; i < symcount; i++)
429 register asymbol *sym;
433 /* Add or remove a leading underscore. */
434 if (inlead != outlead)
438 if (bfd_asymbol_name (sym)[0] == inlead)
446 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
448 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
457 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
459 strcpy (new + 1, bfd_asymbol_name (sym));
464 /* NLM's have an uninitialized data section, but they do not
465 have a common section in the Unix sense. Move all common
466 symbols into the .bss section, and mark them as exported. */
467 if (bfd_is_com_section (bfd_get_section (sym)))
471 sym->section = bss_sec;
473 sym->value = bss_sec->_raw_size;
474 bss_sec->_raw_size += size;
475 align = 1 << bss_sec->alignment_power;
476 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
477 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
479 else if (bfd_get_section (sym)->output_section != NULL)
481 /* Move the symbol into the output section. */
482 sym->value += bfd_get_section (sym)->output_offset;
483 sym->section = bfd_get_section (sym)->output_section;
484 /* This is no longer a section symbol. */
485 sym->flags &=~ BSF_SECTION_SYM;
488 /* Force _edata and _end to be defined. This would normally be
489 done by the linker, but the manipulation of the common
490 symbols will confuse it. */
491 if ((sym->flags & BSF_DEBUGGING) == 0
492 && bfd_asymbol_name (sym)[0] == '_'
493 && bfd_get_section (sym) == &bfd_und_section)
495 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
497 sym->section = bss_sec;
500 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
502 sym->section = bss_sec;
505 /* start-sanitize-powerpc-netware */
506 /* For PowerPC NetWare, we define __GOT0. This is the start
507 of the .got section. */
508 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
509 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
513 got_sec = bfd_get_section_by_name (inbfd, ".got");
514 assert (got_sec != (asection *) NULL);
515 sym->value = got_sec->output_offset;
516 sym->section = got_sec->output_section;
518 /* end-sanitize-powerpc-netware */
521 /* If this is a global symbol, check the export list. */
522 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
524 register struct string_list *l;
527 /* Unfortunately, a symbol can appear multiple times on the
528 export list, with and without prefixes. */
530 for (l = export_symbols; l != NULL; l = l->next)
532 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
538 zbase = strchr (l->string, '@');
540 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
542 /* We must add a symbol with this prefix. */
543 if (newsymcount >= newsymalloc)
546 newsyms = ((asymbol **)
547 xrealloc ((PTR) newsyms,
549 * sizeof (asymbol *))));
551 newsyms[newsymcount] =
552 (asymbol *) xmalloc (sizeof (asymbol));
553 *newsyms[newsymcount] = *sym;
554 newsyms[newsymcount]->name = l->string;
561 /* The unmodified symbol is actually not exported at
563 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
564 sym->flags |= BSF_LOCAL;
568 /* If it's an undefined symbol, see if it's on the import list.
569 Change the prefix if necessary. */
570 if (bfd_get_section (sym) == &bfd_und_section)
572 register struct string_list *l;
574 for (l = import_symbols; l != NULL; l = l->next)
576 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
582 zbase = strchr (l->string, '@');
584 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
586 sym->name = l->string;
593 "%s: warning: symbol %s imported but not in import list\n",
594 program_name, bfd_asymbol_name (sym));
597 /* See if it's one of the special named symbols. */
598 if ((sym->flags & BSF_DEBUGGING) == 0)
602 /* FIXME: If these symbols are not in the .text section, we
603 add the .text section size to the value. This may not be
604 correct for all targets. I'm not sure how this should
605 really be handled. */
606 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
608 val = bfd_asymbol_value (sym);
609 if (bfd_get_section (sym) == data_sec
610 && text_sec != (asection *) NULL)
611 val += bfd_section_size (outbfd, text_sec);
612 if (! bfd_set_start_address (outbfd, val))
613 bfd_fatal ("set start address");
616 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
618 val = bfd_asymbol_value (sym);
619 if (bfd_get_section (sym) == data_sec
620 && text_sec != (asection *) NULL)
621 val += bfd_section_size (outbfd, text_sec);
622 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
625 if (check_procedure != NULL
626 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
628 val = bfd_asymbol_value (sym);
629 if (bfd_get_section (sym) == data_sec
630 && text_sec != (asection *) NULL)
631 val += bfd_section_size (outbfd, text_sec);
632 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
640 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
642 /* FIXME: If any relocs referring to _end use inplace addends,
643 then I think they need to be updated. This is handled by
644 i386_mangle_relocs. Is it needed for any other object
648 if (newsymcount == 0)
652 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
653 * sizeof (asymbol *));
654 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
655 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
656 outsyms[symcount + newsymcount] = NULL;
659 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
662 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
663 program_name, start_procedure);
665 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
666 program_name, exit_procedure);
667 if (check_procedure != NULL
669 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
670 program_name, check_procedure);
672 /* Add additional sections required for the header information. */
673 if (custom_file != NULL)
675 custom_data = fopen (custom_file, "r");
676 if (custom_data == NULL
677 || fstat (fileno (custom_data), &st) < 0)
679 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
685 custom_size = st.st_size;
686 custom_section = bfd_make_section (outbfd, ".nlmcustom");
687 if (custom_section == NULL
688 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
689 || ! bfd_set_section_flags (outbfd, custom_section,
691 bfd_fatal ("custom section");
694 if (help_file != NULL)
696 help_data = fopen (help_file, "r");
697 if (help_data == NULL
698 || fstat (fileno (help_data), &st) < 0)
700 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
706 help_size = st.st_size;
707 help_section = bfd_make_section (outbfd, ".nlmhelp");
708 if (help_section == NULL
709 || ! bfd_set_section_size (outbfd, help_section, help_size)
710 || ! bfd_set_section_flags (outbfd, help_section,
712 bfd_fatal ("help section");
713 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
716 if (message_file != NULL)
718 message_data = fopen (message_file, "r");
719 if (message_data == NULL
720 || fstat (fileno (message_data), &st) < 0)
722 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
728 message_size = st.st_size;
729 message_section = bfd_make_section (outbfd, ".nlmmessages");
730 if (message_section == NULL
731 || ! bfd_set_section_size (outbfd, message_section, message_size)
732 || ! bfd_set_section_flags (outbfd, message_section,
734 bfd_fatal ("message section");
735 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
740 struct string_list *l;
743 for (l = modules; l != NULL; l = l->next)
744 module_size += strlen (l->string) + 1;
745 module_section = bfd_make_section (outbfd, ".nlmmodules");
746 if (module_section == NULL
747 || ! bfd_set_section_size (outbfd, module_section, module_size)
748 || ! bfd_set_section_flags (outbfd, module_section,
750 bfd_fatal ("module section");
752 if (rpc_file != NULL)
754 rpc_data = fopen (rpc_file, "r");
756 || fstat (fileno (rpc_data), &st) < 0)
758 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
764 rpc_size = st.st_size;
765 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
766 if (rpc_section == NULL
767 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
768 || ! bfd_set_section_flags (outbfd, rpc_section,
770 bfd_fatal ("rpc section");
771 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
774 if (sharelib_file != NULL)
776 sharedbfd = bfd_openr (sharelib_file, output_format);
777 if (sharedbfd == NULL
778 || ! bfd_check_format (sharedbfd, bfd_object))
780 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
781 bfd_errmsg (bfd_get_error ()));
782 sharelib_file = NULL;
786 sharedhdr = *nlm_fixed_header (sharedbfd);
787 bfd_close (sharedbfd);
788 shared_data = fopen (sharelib_file, "r");
789 if (shared_data == NULL
790 || (fstat (fileno (shared_data), &st) < 0))
792 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
794 sharelib_file = NULL;
798 /* If we were clever, we could just copy out the
799 sections of the shared library which we actually
800 need. However, we would have to figure out the sizes
801 of the external and public information, and that can
802 not be done without reading through them. */
803 if (sharedhdr.uninitializedDataSize > 0)
805 /* There is no place to record this information. */
807 "%s:%s: warning: shared libraries can not have uninitialized data\n",
808 program_name, sharelib_file);
810 shared_offset = st.st_size;
811 if (shared_offset > sharedhdr.codeImageOffset)
812 shared_offset = sharedhdr.codeImageOffset;
813 if (shared_offset > sharedhdr.dataImageOffset)
814 shared_offset = sharedhdr.dataImageOffset;
815 if (shared_offset > sharedhdr.relocationFixupOffset)
816 shared_offset = sharedhdr.relocationFixupOffset;
817 if (shared_offset > sharedhdr.externalReferencesOffset)
818 shared_offset = sharedhdr.externalReferencesOffset;
819 if (shared_offset > sharedhdr.publicsOffset)
820 shared_offset = sharedhdr.publicsOffset;
821 shared_size = st.st_size - shared_offset;
822 shared_section = bfd_make_section (outbfd, ".nlmshared");
823 if (shared_section == NULL
824 || ! bfd_set_section_size (outbfd, shared_section,
826 || ! bfd_set_section_flags (outbfd, shared_section,
828 bfd_fatal ("shared section");
829 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
834 /* Check whether a version was given. */
835 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
836 fprintf (stderr, "%s: warning: No version number given\n",
839 /* At least for now, always create an extended header, because that
840 is what NLMLINK does. */
841 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
843 /* If the date was not given, force it in. */
844 if (nlm_version_header (outbfd)->month == 0
845 && nlm_version_header (outbfd)->day == 0
846 && nlm_version_header (outbfd)->year == 0)
852 ptm = localtime (&now);
853 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
854 nlm_version_header (outbfd)->day = ptm->tm_mday;
855 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
856 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
858 /* start-sanitize-powerpc-netware */
860 /* Resolve the stubs we build for PowerPC NetWare. */
861 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
862 powerpc_resolve_stubs (inbfd, outbfd);
863 /* end-sanitize-powerpc-netware */
865 /* Copy over the sections. */
866 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
868 /* Finish up the header information. */
869 if (custom_file != NULL)
873 data = xmalloc (custom_size);
874 if (fread (data, 1, custom_size, custom_data) != custom_size)
875 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
879 if (! bfd_set_section_contents (outbfd, custom_section, data,
880 (file_ptr) 0, custom_size))
881 bfd_fatal ("custom section");
882 nlm_fixed_header (outbfd)->customDataOffset =
883 custom_section->filepos;
884 nlm_fixed_header (outbfd)->customDataSize = custom_size;
890 /* As a special hack, the backend recognizes a debugInfoOffset
891 of -1 to mean that it should not output any debugging
892 information. This can not be handling by fiddling with the
893 symbol table because exported symbols appear in both the
894 export information and the debugging information. */
895 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
897 if (map_file != NULL)
899 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
901 if (help_file != NULL)
905 data = xmalloc (help_size);
906 if (fread (data, 1, help_size, help_data) != help_size)
907 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
911 if (! bfd_set_section_contents (outbfd, help_section, data,
912 (file_ptr) 0, help_size))
913 bfd_fatal ("help section");
914 nlm_extended_header (outbfd)->helpFileOffset =
915 help_section->filepos;
916 nlm_extended_header (outbfd)->helpFileLength = help_size;
920 if (message_file != NULL)
924 data = xmalloc (message_size);
925 if (fread (data, 1, message_size, message_data) != message_size)
926 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
930 if (! bfd_set_section_contents (outbfd, message_section, data,
931 (file_ptr) 0, message_size))
932 bfd_fatal ("message section");
933 nlm_extended_header (outbfd)->messageFileOffset =
934 message_section->filepos;
935 nlm_extended_header (outbfd)->messageFileLength = message_size;
937 /* FIXME: Are these offsets correct on all platforms? Are
938 they 32 bits on all platforms? What endianness? */
939 nlm_extended_header (outbfd)->languageID =
940 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
941 nlm_extended_header (outbfd)->messageCount =
942 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
950 struct string_list *l;
953 data = xmalloc (module_size);
955 set = (unsigned char *) data;
956 for (l = modules; l != NULL; l = l->next)
958 *set = strlen (l->string);
959 strncpy (set + 1, l->string, *set);
963 if (! bfd_set_section_contents (outbfd, module_section, data,
964 (file_ptr) 0, module_size))
965 bfd_fatal ("module section");
966 nlm_fixed_header (outbfd)->moduleDependencyOffset =
967 module_section->filepos;
968 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
970 if (rpc_file != NULL)
974 data = xmalloc (rpc_size);
975 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
976 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
980 if (! bfd_set_section_contents (outbfd, rpc_section, data,
981 (file_ptr) 0, rpc_size))
982 bfd_fatal ("rpc section");
983 nlm_extended_header (outbfd)->RPCDataOffset =
984 rpc_section->filepos;
985 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
989 if (sharelib_file != NULL)
993 data = xmalloc (shared_size);
994 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
995 || fread (data, 1, shared_size, shared_data) != shared_size)
996 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
1000 if (! bfd_set_section_contents (outbfd, shared_section, data,
1001 (file_ptr) 0, shared_size))
1002 bfd_fatal ("shared section");
1004 nlm_extended_header (outbfd)->sharedCodeOffset =
1005 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1006 nlm_extended_header (outbfd)->sharedCodeLength =
1007 sharedhdr.codeImageSize;
1008 nlm_extended_header (outbfd)->sharedDataOffset =
1009 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1010 nlm_extended_header (outbfd)->sharedDataLength =
1011 sharedhdr.dataImageSize;
1012 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1013 (sharedhdr.relocationFixupOffset
1015 + shared_section->filepos);
1016 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1017 sharedhdr.numberOfRelocationFixups;
1018 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1019 (sharedhdr.externalReferencesOffset
1021 + shared_section->filepos);
1022 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1023 sharedhdr.numberOfExternalReferences;
1024 nlm_extended_header (outbfd)->sharedPublicsOffset =
1025 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1026 nlm_extended_header (outbfd)->sharedPublicsCount =
1027 sharedhdr.numberOfPublics;
1028 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1029 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1030 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1031 sharedhdr.numberOfDebugRecords;
1032 nlm_extended_header (outbfd)->SharedInitializationOffset =
1033 sharedhdr.codeStartOffset;
1034 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1035 sharedhdr.exitProcedureOffset;
1038 len = strlen (output_file);
1039 if (len > NLM_MODULE_NAME_SIZE - 2)
1040 len = NLM_MODULE_NAME_SIZE - 2;
1041 nlm_fixed_header (outbfd)->moduleName[0] = len;
1043 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1044 NLM_MODULE_NAME_SIZE - 2);
1045 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1046 for (modname = nlm_fixed_header (outbfd)->moduleName;
1049 if (islower (*modname))
1050 *modname = toupper (*modname);
1052 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1053 NLM_OLD_THREAD_NAME_LENGTH);
1055 if (! bfd_close (outbfd))
1056 bfd_fatal (output_file);
1057 if (! bfd_close (inbfd))
1058 bfd_fatal (input_file);
1060 if (unlink_on_exit != NULL)
1061 unlink (unlink_on_exit);
1066 /* Display a help message and exit. */
1071 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1073 show_usage (stdout, 0);
1076 /* Show a usage message and exit. */
1079 show_usage (file, status)
1084 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1085 [--input-target=bfdname] [--output-target=bfdname]\n\
1086 [--header-file=file] [--linker=linker] [--debug]\n\
1087 [--help] [--version]\n\
1088 [in-file [out-file]]\n",
1093 /* Select the output format based on the input architecture, machine,
1094 and endianness. This chooses the appropriate NLM target. */
1097 select_output_format (arch, mach, bigendian)
1098 enum bfd_architecture arch;
1105 return "nlm32-i386";
1106 case bfd_arch_sparc:
1107 return "nlm32-sparc";
1108 case bfd_arch_alpha:
1109 return "nlm32-alpha";
1110 /* start-sanitize-powerpc-netware */
1111 case bfd_arch_powerpc:
1112 return "nlm32-powerpc";
1113 /* end-sanitize-powerpc-netware */
1115 fprintf (stderr, "%s: no default NLM format for %s\n",
1116 program_name, bfd_printable_arch_mach (arch, mach));
1118 /* Avoid warning. */
1124 /* The BFD sections are copied in two passes. This function selects
1125 the output section for each input section, and sets up the section
1129 setup_sections (inbfd, insec, data_ptr)
1134 bfd *outbfd = (bfd *) data_ptr;
1136 const char *outname;
1139 bfd_size_type align;
1142 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1143 file. However, I don't have a good way to describe this section.
1144 We do want to copy the section when using objcopy. */
1145 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1146 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1149 f = bfd_get_section_flags (inbfd, insec);
1151 outname = NLM_CODE_NAME;
1152 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1153 outname = NLM_INITIALIZED_DATA_NAME;
1154 else if (f & SEC_ALLOC)
1155 outname = NLM_UNINITIALIZED_DATA_NAME;
1157 outname = bfd_section_name (inbfd, insec);
1159 outsec = bfd_get_section_by_name (outbfd, outname);
1162 outsec = bfd_make_section (outbfd, outname);
1164 bfd_fatal ("make section");
1167 insec->output_section = outsec;
1169 offset = bfd_section_size (outbfd, outsec);
1170 align = 1 << bfd_section_alignment (inbfd, insec);
1171 add = ((offset + align - 1) &~ (align - 1)) - offset;
1172 insec->output_offset = offset + add;
1174 if (! bfd_set_section_size (outbfd, outsec,
1175 (bfd_section_size (outbfd, outsec)
1176 + bfd_section_size (inbfd, insec)
1178 bfd_fatal ("set section size");
1180 if ((bfd_section_alignment (inbfd, insec)
1181 > bfd_section_alignment (outbfd, outsec))
1182 && ! bfd_set_section_alignment (outbfd, outsec,
1183 bfd_section_alignment (inbfd, insec)))
1184 bfd_fatal ("set section alignment");
1186 if (! bfd_set_section_flags (outbfd, outsec, f))
1187 bfd_fatal ("set section flags");
1189 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1192 /* Copy the section contents. */
1195 copy_sections (inbfd, insec, data_ptr)
1200 bfd *outbfd = (bfd *) data_ptr;
1206 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1207 file. However, I don't have a good way to describe this section.
1208 We do want to copy the section when using objcopy. */
1209 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1210 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1213 outsec = insec->output_section;
1214 assert (outsec != NULL);
1216 size = bfd_get_section_size_before_reloc (insec);
1220 /* FIXME: Why are these necessary? */
1221 insec->_cooked_size = insec->_raw_size;
1222 insec->reloc_done = true;
1224 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1228 contents = xmalloc (size);
1229 if (! bfd_get_section_contents (inbfd, insec, contents,
1230 (file_ptr) 0, size))
1231 bfd_fatal (bfd_get_filename (inbfd));
1234 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1236 bfd_fatal (bfd_get_filename (inbfd));
1237 if (reloc_size != 0)
1242 relocs = (arelent **) xmalloc (reloc_size);
1243 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1244 if (reloc_count < 0)
1245 bfd_fatal (bfd_get_filename (inbfd));
1246 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1249 /* FIXME: refers to internal BFD fields. */
1250 if (outsec->orelocation != (arelent **) NULL)
1252 bfd_size_type total_count;
1255 total_count = reloc_count + outsec->reloc_count;
1256 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1257 memcpy (combined, outsec->orelocation,
1258 outsec->reloc_count * sizeof (arelent));
1259 memcpy (combined + outsec->reloc_count, relocs,
1260 (size_t) (reloc_count * sizeof (arelent)));
1261 free (outsec->orelocation);
1262 reloc_count = total_count;
1266 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1269 if (contents != NULL)
1271 if (! bfd_set_section_contents (outbfd, outsec, contents,
1272 insec->output_offset, size))
1273 bfd_fatal (bfd_get_filename (outbfd));
1278 /* Some, perhaps all, NetWare targets require changing the relocs used
1279 by the input formats. */
1282 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1286 arelent ***relocs_ptr;
1287 long *reloc_count_ptr;
1289 bfd_size_type contents_size;
1291 switch (bfd_get_arch (outbfd))
1294 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1295 contents, contents_size);
1297 case bfd_arch_alpha:
1298 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1299 contents, contents_size);
1301 /* start-sanitize-powerpc-netware */
1302 case bfd_arch_powerpc:
1303 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1304 contents, contents_size);
1306 /* end-sanitize-powerpc-netware */
1308 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1309 contents, contents_size);
1314 /* By default all we need to do for relocs is change the address by
1315 the output_offset. */
1319 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1323 arelent ***relocs_ptr;
1324 long *reloc_count_ptr;
1326 bfd_size_type contents_size;
1328 if (insec->output_offset != 0)
1331 register arelent **relocs;
1334 reloc_count = *reloc_count_ptr;
1335 relocs = *relocs_ptr;
1336 for (i = 0; i < reloc_count; i++, relocs++)
1337 (*relocs)->address += insec->output_offset;
1341 /* NetWare on the i386 supports a restricted set of relocs, which are
1342 different from those used on other i386 targets. This routine
1343 converts the relocs. It is, obviously, very target dependent. At
1344 the moment, the nlm32-i386 backend performs similar translations;
1345 however, it is more reliable and efficient to do them here. */
1347 static reloc_howto_type nlm_i386_pcrel_howto =
1348 HOWTO (1, /* type */
1350 2, /* size (0 = byte, 1 = short, 2 = long) */
1352 true, /* pc_relative */
1354 complain_overflow_signed, /* complain_on_overflow */
1355 0, /* special_function */
1356 "DISP32", /* name */
1357 true, /* partial_inplace */
1358 0xffffffff, /* src_mask */
1359 0xffffffff, /* dst_mask */
1360 true); /* pcrel_offset */
1363 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1367 arelent ***relocs_ptr;
1368 long *reloc_count_ptr;
1370 bfd_size_type contents_size;
1372 long reloc_count, i;
1375 reloc_count = *reloc_count_ptr;
1376 relocs = *relocs_ptr;
1377 for (i = 0; i < reloc_count; i++)
1381 bfd_size_type address;
1385 sym = *rel->sym_ptr_ptr;
1387 /* We're moving the relocs from the input section to the output
1388 section, so we must adjust the address accordingly. */
1389 address = rel->address;
1390 rel->address += insec->output_offset;
1392 /* Note that no serious harm will ensue if we fail to change a
1393 reloc. The backend will fail when writing out the reloc. */
1395 /* Make sure this reloc is within the data we have. We use only
1396 4 byte relocs here, so we insist on having 4 bytes. */
1397 if (address + 4 > contents_size)
1400 /* A PC relative reloc entirely within a single section is
1401 completely unnecessary. This can be generated by ld -r. */
1402 if (sym == insec->symbol
1403 && rel->howto != NULL
1404 && rel->howto->pc_relative
1405 && ! rel->howto->pcrel_offset)
1409 memmove (relocs, relocs + 1,
1410 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1414 /* Get the amount the relocation will add in. */
1415 addend = rel->addend + sym->value;
1417 /* NetWare doesn't support PC relative relocs against defined
1418 symbols, so we have to eliminate them by doing the relocation
1419 now. We can only do this if the reloc is within a single
1421 if (rel->howto != NULL
1422 && rel->howto->pc_relative
1423 && bfd_get_section (sym) == insec->output_section)
1427 if (rel->howto->pcrel_offset)
1430 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1432 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1436 memmove (relocs, relocs + 1,
1437 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1441 /* NetWare doesn't support reloc addends, so we get rid of them
1442 here by simply adding them into the object data. We handle
1443 the symbol value, if any, the same way. */
1445 && rel->howto != NULL
1446 && rel->howto->rightshift == 0
1447 && rel->howto->size == 2
1448 && rel->howto->bitsize == 32
1449 && rel->howto->bitpos == 0
1450 && rel->howto->src_mask == 0xffffffff
1451 && rel->howto->dst_mask == 0xffffffff)
1455 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1457 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1459 /* Adjust the reloc for the changes we just made. */
1461 if (bfd_get_section (sym) != &bfd_und_section)
1462 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1465 /* NetWare uses a reloc with pcrel_offset set. We adjust
1466 pc_relative relocs accordingly. We are going to change the
1467 howto field, so we can only do this if the current one is
1468 compatible. We should check that special_function is NULL
1469 here, but at the moment coff-i386 uses a special_function
1470 which does not affect what we are doing here. */
1471 if (rel->howto != NULL
1472 && rel->howto->pc_relative
1473 && ! rel->howto->pcrel_offset
1474 && rel->howto->rightshift == 0
1475 && rel->howto->size == 2
1476 && rel->howto->bitsize == 32
1477 && rel->howto->bitpos == 0
1478 && rel->howto->src_mask == 0xffffffff
1479 && rel->howto->dst_mask == 0xffffffff)
1483 /* When pcrel_offset is not set, it means that the negative
1484 of the address of the memory location is stored in the
1485 memory location. We must add it back in. */
1486 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1488 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1490 /* We must change to a new howto. */
1491 rel->howto = &nlm_i386_pcrel_howto;
1496 /* On the Alpha the first reloc for every section must be a special
1497 relocs which hold the GP address. Also, the first reloc in the
1498 file must be a special reloc which holds the address of the .lita
1501 static reloc_howto_type nlm32_alpha_nw_howto =
1502 HOWTO (ALPHA_R_NW_RELOC, /* type */
1504 0, /* size (0 = byte, 1 = short, 2 = long) */
1506 false, /* pc_relative */
1508 complain_overflow_dont, /* complain_on_overflow */
1509 0, /* special_function */
1510 "NW_RELOC", /* name */
1511 false, /* partial_inplace */
1514 false); /* pcrel_offset */
1518 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1522 register arelent ***relocs_ptr;
1523 long *reloc_count_ptr;
1525 bfd_size_type contents_size;
1527 long old_reloc_count;
1528 arelent **old_relocs;
1529 register arelent **relocs;
1531 old_reloc_count = *reloc_count_ptr;
1532 old_relocs = *relocs_ptr;
1533 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1534 *relocs_ptr = relocs;
1536 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1539 asection *lita_section;
1541 inbfd = insec->owner;
1542 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1543 if (lita_section != (asection *) NULL)
1545 nlm_alpha_backend_data (outbfd)->lita_address =
1546 bfd_get_section_vma (inbfd, lita_section);
1547 nlm_alpha_backend_data (outbfd)->lita_size =
1548 bfd_section_size (inbfd, lita_section);
1552 /* Avoid outputting this reloc again. */
1553 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1556 *relocs = (arelent *) xmalloc (sizeof (arelent));
1557 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1558 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1559 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1560 (*relocs)->howto = &nlm32_alpha_nw_howto;
1562 ++(*reloc_count_ptr);
1565 /* Get the GP value from bfd. It is in the .reginfo section. */
1566 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1569 asection *reginfo_sec;
1570 struct ecoff_reginfo sreginfo;
1572 inbfd = insec->owner;
1573 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1574 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1575 if (reginfo_sec != (asection *) NULL
1576 && bfd_get_section_contents (inbfd, reginfo_sec,
1577 (PTR) &sreginfo, (file_ptr) 0,
1578 sizeof sreginfo) != false)
1579 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1582 *relocs = (arelent *) xmalloc (sizeof (arelent));
1583 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1584 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1585 (*relocs)->addend = 0;
1586 (*relocs)->howto = &nlm32_alpha_nw_howto;
1588 ++(*reloc_count_ptr);
1590 memcpy ((PTR) relocs, (PTR) old_relocs,
1591 (size_t) old_reloc_count * sizeof (arelent *));
1592 relocs[old_reloc_count] = (arelent *) NULL;
1596 if (insec->output_offset != 0)
1598 register bfd_size_type i;
1600 for (i = 0; i < old_reloc_count; i++, relocs++)
1601 (*relocs)->address += insec->output_offset;
1604 /* start-sanitize-powerpc-netware */
1606 /* We keep a linked list of stubs which we must build. Because BFD
1607 requires us to know the sizes of all sections before we can set the
1608 contents of any, we must figure out which stubs we want to build
1609 before we can actually build any of them. */
1613 /* Next stub in linked list. */
1614 struct powerpc_stub *next;
1616 /* Symbol whose value is the start of the stub. This is a symbol
1617 whose name begins with `.'. */
1620 /* Symbol we are going to create a reloc against. This is a symbol
1621 with the same name as START but without the leading `.'. */
1624 /* The TOC index for this stub. This is the index into the TOC
1625 section at which the reloc is created. */
1626 unsigned int toc_index;
1629 /* The linked list of stubs. */
1631 static struct powerpc_stub *powerpc_stubs;
1633 /* This is what a stub looks like. The first instruction will get
1634 adjusted with the correct TOC index. */
1636 static unsigned long powerpc_stub_insns[] =
1638 0x81820000, /* lwz r12,0(r2) */
1639 0x90410014, /* stw r2,20(r1) */
1640 0x800c0000, /* lwz r0,0(r12) */
1641 0x804c0004, /* lwz r2,r(r12) */
1642 0x7c0903a6, /* mtctr r0 */
1643 0x4e800420, /* bctr */
1644 0, /* Traceback table. */
1649 #define POWERPC_STUB_INSN_COUNT \
1650 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1652 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1654 /* Each stub uses a four byte TOC entry. */
1655 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1657 /* The original size of the .got section. */
1658 static bfd_size_type powerpc_initial_got_size;
1660 /* Look for all undefined symbols beginning with `.', and prepare to
1661 build a stub for each one. */
1664 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1667 asymbol ***symbols_ptr;
1672 unsigned int got_base;
1677 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1678 the section to prevent copy_sections from reading from it. */
1679 stub_sec = bfd_make_section (inbfd, ".stubs");
1680 if (stub_sec == (asection *) NULL
1681 || ! bfd_set_section_flags (inbfd, stub_sec,
1686 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1687 bfd_fatal (".stubs");
1689 /* Get the TOC section, which is named .got. */
1690 got_sec = bfd_get_section_by_name (inbfd, ".got");
1691 if (got_sec == (asection *) NULL)
1693 got_sec = bfd_make_section (inbfd, ".got");
1694 if (got_sec == (asection *) NULL
1695 || ! bfd_set_section_flags (inbfd, got_sec,
1700 | SEC_HAS_CONTENTS))
1701 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1705 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1706 got_base = powerpc_initial_got_size;
1707 got_base = (got_base + 3) &~ 3;
1711 symcount = *symcount_ptr;
1712 for (i = 0; i < symcount; i++)
1717 struct powerpc_stub *item;
1719 sym = (*symbols_ptr)[i];
1721 /* We must make a stub for every undefined symbol whose name
1723 if (bfd_asymbol_name (sym)[0] != '.'
1724 || bfd_get_section (sym) != &bfd_und_section)
1727 /* Make a new undefined symbol with the same name but without
1729 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1731 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1732 strcpy (newname, bfd_asymbol_name (sym) + 1);
1733 newsym->name = newname;
1735 /* Define the `.' symbol to be in the stub section. */
1736 sym->section = stub_sec;
1737 sym->value = stubcount * POWERPC_STUB_SIZE;
1738 /* We set the BSF_DYNAMIC flag here so that we can check it when
1739 we are mangling relocs. FIXME: This is a hack. */
1740 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1742 /* Add this stub to the linked list. */
1743 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1745 item->reloc = newsym;
1746 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1748 item->next = powerpc_stubs;
1749 powerpc_stubs = item;
1757 struct powerpc_stub *l;
1759 /* Add the new symbols we just created to the symbol table. */
1760 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1761 ((symcount + stubcount)
1762 * sizeof (asymbol)));
1763 *symcount_ptr += stubcount;
1764 s = &(*symbols_ptr)[symcount];
1765 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1768 /* Set the size of the .stubs section and increase the size of
1769 the .got section. */
1770 if (! bfd_set_section_size (inbfd, stub_sec,
1771 stubcount * POWERPC_STUB_SIZE)
1772 || ! bfd_set_section_size (inbfd, got_sec,
1775 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1776 bfd_fatal ("stub section sizes");
1779 /* PowerPC NetWare requires a custom header. We create it here.
1780 The first word is the header version number, currently 1. The
1781 second word is the timestamp of the input file. */
1782 memcpy (nlm_custom_header (outbfd)->stamp, "CuStHeAd", 8);
1783 nlm_custom_header (outbfd)->dataLength = 8;
1784 nlm_custom_header (outbfd)->data = xmalloc (8);
1785 bfd_h_put_32 (outbfd, (bfd_vma) 1,
1786 (bfd_byte *) nlm_custom_header (outbfd)->data);
1790 if (stat (bfd_get_filename (inbfd), &s) < 0)
1792 bfd_h_put_32 (outbfd, (bfd_vma) s.st_mtime,
1793 (bfd_byte *) nlm_custom_header (outbfd)->data + 4);
1797 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1798 of the output section, and create new relocs in the TOC. */
1801 powerpc_resolve_stubs (inbfd, outbfd)
1805 bfd_byte buf[POWERPC_STUB_SIZE];
1807 unsigned int stubcount;
1811 struct powerpc_stub *l;
1813 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1816 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1817 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1819 got_sec = bfd_get_section_by_name (inbfd, ".got");
1820 assert (got_sec != (asection *) NULL);
1821 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1824 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1826 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1829 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1833 /* Adjust the first instruction to use the right TOC index. */
1834 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1836 /* Write this stub out. */
1837 if (! bfd_set_section_contents (outbfd,
1838 bfd_get_section (l->start),
1842 bfd_fatal ("writing stub");
1844 /* Create a new reloc for the TOC entry. */
1845 reloc = (arelent *) xmalloc (sizeof (arelent));
1846 reloc->sym_ptr_ptr = &l->reloc;
1847 reloc->address = l->toc_index + got_sec->output_offset;
1849 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1854 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1857 /* Adjust relocation entries for PowerPC NetWare. We do not output
1858 TOC relocations. The object code already contains the offset from
1859 the TOC pointer. When the function is called, the TOC register,
1860 r2, will be set to the correct TOC value, so there is no need for
1861 any further reloc. */
1865 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1869 register arelent ***relocs_ptr;
1870 long *reloc_count_ptr;
1872 bfd_size_type contents_size;
1874 const reloc_howto_type *toc_howto;
1876 register arelent **relocs;
1879 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1880 if (toc_howto == (reloc_howto_type *) NULL)
1883 /* If this is the .got section, clear out all the contents beyond
1884 the initial size. We must do this here because copy_sections is
1885 going to write out whatever we return in the contents field. */
1886 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1887 memset (contents + powerpc_initial_got_size, 0,
1888 (bfd_get_section_size_after_reloc (insec)
1889 - powerpc_initial_got_size));
1891 reloc_count = *reloc_count_ptr;
1892 relocs = *relocs_ptr;
1893 for (i = 0; i < reloc_count; i++)
1900 sym = *rel->sym_ptr_ptr;
1902 /* We must be able to resolve all PC relative relocs at this
1903 point. If we get a branch to an undefined symbol we build a
1904 stub, since NetWare will resolve undefined symbols into a
1905 pointer to a function descriptor. */
1906 if (rel->howto->pc_relative)
1908 /* This check for whether a symbol is in the same section as
1909 the reloc will be wrong if there is a PC relative reloc
1910 between two sections both of which were placed in the
1911 same output section. This should not happen. */
1912 if (bfd_get_section (sym) != insec->output_section)
1913 fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1914 program_name, bfd_asymbol_name (sym));
1919 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1920 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1921 val = ((val &~ rel->howto->dst_mask)
1922 | (((val & rel->howto->src_mask)
1923 + (sym->value - rel->address)
1925 & rel->howto->dst_mask));
1926 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1928 /* If this reloc is against an stubbed symbol and the
1931 then we replace the next instruction with
1933 This reloads the TOC pointer after a stub call. */
1934 if (bfd_asymbol_name (sym)[0] == '.'
1935 && (sym->flags & BSF_DYNAMIC) != 0
1936 && (bfd_get_32 (outbfd,
1937 (bfd_byte *) contents + rel->address + 4)
1938 == 0x4ffffb82)) /* cror 31,31,31 */
1939 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1940 (bfd_byte *) contents + rel->address + 4);
1944 memmove (relocs, relocs + 1,
1945 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1950 /* When considering a TOC reloc, we do not want to include the
1951 symbol value. The symbol will be start of the TOC section
1952 (which is named .got). We do want to include the addend. */
1953 if (rel->howto == toc_howto)
1956 symvalue = sym->value;
1958 /* If this is a relocation against a symbol with a value, or
1959 there is a reloc addend, we need to update the addend in the
1961 if (symvalue + rel->addend != 0)
1965 switch (rel->howto->size)
1968 val = bfd_get_16 (outbfd,
1969 (bfd_byte *) contents + rel->address);
1970 val = ((val &~ rel->howto->dst_mask)
1971 | (((val & rel->howto->src_mask)
1974 & rel->howto->dst_mask));
1975 if ((bfd_signed_vma) val < - 0x8000
1976 || (bfd_signed_vma) val >= 0x8000)
1978 "%s: overflow when adjusting relocation against %s\n",
1979 program_name, bfd_asymbol_name (sym));
1980 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1984 val = bfd_get_32 (outbfd,
1985 (bfd_byte *) contents + rel->address);
1986 val = ((val &~ rel->howto->dst_mask)
1987 | (((val & rel->howto->src_mask)
1990 & rel->howto->dst_mask));
1991 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1998 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2002 /* Now that we have incorporated the addend, remove any TOC
2004 if (rel->howto == toc_howto)
2008 memmove (relocs, relocs + 1,
2009 (size_t) ((reloc_count - i) * sizeof (arelent *)));
2013 rel->address += insec->output_offset;
2016 /* end-sanitize-powerpc-netware */
2018 /* Name of linker. */
2020 #define LD_NAME "ld"
2023 /* Temporary file name base. */
2024 static char *temp_filename;
2026 /* The user has specified several input files. Invoke the linker to
2027 link them all together, and convert and delete the resulting output
2031 link_inputs (inputs, ld)
2032 struct string_list *inputs;
2036 struct string_list *q;
2043 for (q = inputs; q != NULL; q = q->next)
2046 argv = (char **) alloca (c + 5);
2053 /* Find the linker to invoke based on how nlmconv was run. */
2054 p = program_name + strlen (program_name);
2055 while (p != program_name)
2059 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2060 memcpy (ld, program_name, p - program_name);
2061 strcpy (ld + (p - program_name), LD_NAME);
2070 ld = (char *) LD_NAME;
2072 choose_temp_base ();
2074 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2075 sprintf (unlink_on_exit, "%s.O", temp_filename);
2078 argv[1] = (char *) "-r";
2079 argv[2] = (char *) "-o";
2080 argv[3] = unlink_on_exit;
2082 for (q = inputs; q != NULL; q = q->next, i++)
2083 argv[i] = q->string;
2088 for (i = 0; argv[i] != NULL; i++)
2089 fprintf (stderr, " %s", argv[i]);
2090 fprintf (stderr, "\n");
2093 pid = pexecute (ld, argv);
2095 if (waitpid (pid, &status, 0) < 0)
2098 unlink (unlink_on_exit);
2104 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2105 unlink (unlink_on_exit);
2109 return unlink_on_exit;
2112 /* Choose a temporary file name. Stolen from gcc.c. */
2115 choose_temp_base_try (try, base)
2123 else if (try == NULL)
2125 else if (access (try, R_OK | W_OK) != 0)
2135 const char *base = NULL;
2138 base = choose_temp_base_try (getenv ("TMPDIR"), base);
2139 base = choose_temp_base_try (getenv ("TMP"), base);
2140 base = choose_temp_base_try (getenv ("TEMP"), base);
2143 base = choose_temp_base_try (P_tmpdir, base);
2146 base = choose_temp_base_try ("/usr/tmp", base);
2147 base = choose_temp_base_try ("/tmp", base);
2149 /* If all else fails, use the current directory! */
2153 len = strlen (base);
2154 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2155 strcpy (temp_filename, base);
2156 if (len > 0 && temp_filename[len-1] != '/')
2157 temp_filename[len++] = '/';
2158 strcpy (temp_filename + len, "ccXXXXXX");
2160 mktemp (temp_filename);
2161 if (*temp_filename == '\0')
2165 /* Execute a job. Stolen from gcc.c. */
2171 pexecute (program, argv)
2179 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2180 rf = scmd + strlen(program) + 2 + el;
2181 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2182 argfile = fopen (rf, "w");
2184 pfatal_with_name (rf);
2186 for (i=1; argv[i]; i++)
2189 for (cp = argv[i]; *cp; cp++)
2191 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2192 fputc ('\\', argfile);
2193 fputc (*cp, argfile);
2195 fputc ('\n', argfile);
2206 return MIN_FATAL_STATUS << 8;
2212 #else /* not __MSDOS__ */
2215 pexecute (program, argv)
2220 int retries, sleep_interval;
2222 /* Fork a subprocess; wait and retry if it fails. */
2224 for (retries = 0; retries < 4; retries++)
2229 sleep (sleep_interval);
2230 sleep_interval *= 2;
2246 /* Exec the program. */
2247 execvp (program, argv);
2254 /* Return child's process number. */
2259 #endif /* not __MSDOS__ */
2263 pexecute (program, argv)
2267 return spawnvp (1, program, argv);
2269 #endif /* not OS2 */