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 ***,
119 bfd_size_type *, char *,
121 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
122 bfd_size_type *, char *,
124 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
125 bfd_size_type *, char *,
127 /* start-sanitize-powerpc-netware */
128 static void powerpc_build_stubs PARAMS ((bfd *, asymbol ***, unsigned int *));
129 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
130 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
131 bfd_size_type *, char *,
133 /* end-sanitize-powerpc-netware */
134 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
135 bfd_size_type *, char *,
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 unsigned int symcount, newsymalloc, newsymcount;
165 asection *text_sec, *bss_sec, *data_sec;
170 char inlead, outlead;
171 boolean gotstart, gotexit, gotcheck;
173 FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
174 size_t custom_size, help_size, message_size, module_size, rpc_size;
175 asection *custom_section, *help_section, *message_section, *module_section;
176 asection *rpc_section, *shared_section;
178 size_t shared_offset, shared_size;
179 Nlm_Internal_Fixed_Header sharedhdr;
184 program_name = argv[0];
185 xmalloc_set_program_name (program_name);
189 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
202 input_format = optarg;
208 output_format = optarg;
211 header_file = optarg;
214 printf ("GNU %s version %s\n", program_name, program_version);
220 show_usage (stderr, 1);
225 /* The input and output files may be named on the command line. */
229 input_file = argv[optind];
233 output_file = argv[optind];
236 show_usage (stderr, 1);
237 if (strcmp (input_file, output_file) == 0)
240 "%s: input and output files must be different\n",
247 /* Initialize the header information to default values. */
248 fixed_hdr = &fixed_hdr_struct;
249 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
250 var_hdr = &var_hdr_struct;
251 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
252 version_hdr = &version_hdr_struct;
253 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
254 copyright_hdr = ©right_hdr_struct;
255 memset ((PTR) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
256 extended_hdr = &extended_hdr_struct;
257 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
258 check_procedure = NULL;
261 exit_procedure = "_Stop";
262 export_symbols = NULL;
266 import_symbols = NULL;
269 sharelib_file = NULL;
270 start_procedure = "_Prelude";
276 /* Parse the header file (if there is one). */
277 if (header_file != NULL)
279 if (! nlmlex_file (header_file)
281 || parse_errors != 0)
285 if (input_files != NULL)
287 if (input_file != NULL)
290 "%s: input file named both on command line and with INPUT\n",
294 if (input_files->next == NULL)
295 input_file = input_files->string;
297 input_file = link_inputs (input_files, ld_arg);
299 else if (input_file == NULL)
301 fprintf (stderr, "%s: no input file\n", program_name);
302 show_usage (stderr, 1);
305 inbfd = bfd_openr (input_file, input_format);
307 bfd_fatal (input_file);
309 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
311 bfd_nonfatal (input_file);
312 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
314 list_matching_formats (matching);
320 if (output_format == NULL)
321 output_format = select_output_format (bfd_get_arch (inbfd),
322 bfd_get_mach (inbfd),
323 inbfd->xvec->byteorder_big_p);
325 assert (output_format != NULL);
327 /* Use the output file named on the command line if it exists.
328 Otherwise use the file named in the OUTPUT statement. */
329 if (output_file == NULL)
331 fprintf (stderr, "%s: no name for output file\n",
333 show_usage (stderr, 1);
336 outbfd = bfd_openw (output_file, output_format);
338 bfd_fatal (output_file);
339 if (! bfd_set_format (outbfd, bfd_object))
340 bfd_fatal (output_file);
342 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
344 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
346 "%s: warning:input and output formats are not compatible\n",
349 /* Move the values read from the command file into outbfd. */
350 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
351 *nlm_variable_header (outbfd) = var_hdr_struct;
352 *nlm_version_header (outbfd) = version_hdr_struct;
353 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
354 *nlm_extended_header (outbfd) = extended_hdr_struct;
356 /* Start copying the input BFD to the output BFD. */
357 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
358 bfd_fatal (bfd_get_filename (outbfd));
360 symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
361 symcount = bfd_canonicalize_symtab (inbfd, symbols);
363 /* Make sure we have a .bss section. */
364 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
367 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
369 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
370 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
371 bfd_fatal ("make .bss section");
373 /* start-sanitize-powerpc-netware */
375 /* For PowerPC NetWare we need to build stubs for calls to undefined
376 symbols. Because each stub requires an entry in the TOC section
377 which must be at the same location as other entries in the TOC
378 section, we must do this before determining where the TOC section
379 goes in setup_sections. */
380 powerpc_build_stubs (inbfd, &symbols, &symcount);
381 /* end-sanitize-powerpc-netware */
383 /* Set up the sections. */
384 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
386 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
388 /* The .bss section immediately follows the .data section. */
389 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
390 if (data_sec != NULL)
394 vma = bfd_get_section_size_before_reloc (data_sec);
395 align = 1 << bss_sec->alignment_power;
396 add = ((vma + align - 1) &~ (align - 1)) - vma;
398 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
399 bfd_fatal ("set .bss vma");
402 bfd_size_type data_size;
404 data_size = bfd_get_section_size_before_reloc (data_sec);
405 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
406 bfd_fatal ("set .data size");
410 /* Adjust symbol information. */
411 inlead = bfd_get_symbol_leading_char (inbfd);
412 outlead = bfd_get_symbol_leading_char (outbfd);
417 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
420 for (i = 0; i < symcount; i++)
422 register asymbol *sym;
426 /* Add or remove a leading underscore. */
427 if (inlead != outlead)
431 if (bfd_asymbol_name (sym)[0] == inlead)
439 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
441 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
450 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
452 strcpy (new + 1, bfd_asymbol_name (sym));
457 /* NLM's have an uninitialized data section, but they do not
458 have a common section in the Unix sense. Move all common
459 symbols into the .bss section, and mark them as exported. */
460 if (bfd_is_com_section (bfd_get_section (sym)))
464 sym->section = bss_sec;
466 sym->value = bss_sec->_raw_size;
467 bss_sec->_raw_size += size;
468 align = 1 << bss_sec->alignment_power;
469 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
470 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
472 else if (bfd_get_section (sym)->output_section != NULL)
474 /* Move the symbol into the output section. */
475 sym->value += bfd_get_section (sym)->output_offset;
476 sym->section = bfd_get_section (sym)->output_section;
477 /* This is no longer a section symbol. */
478 sym->flags &=~ BSF_SECTION_SYM;
481 /* Force _edata and _end to be defined. This would normally be
482 done by the linker, but the manipulation of the common
483 symbols will confuse it. */
484 if ((sym->flags & BSF_DEBUGGING) == 0
485 && bfd_asymbol_name (sym)[0] == '_'
486 && bfd_get_section (sym) == &bfd_und_section)
488 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
490 sym->section = bss_sec;
493 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
495 sym->section = bss_sec;
498 /* start-sanitize-powerpc-netware */
499 /* For PowerPC NetWare, we define __GOT0. This is the start
500 of the .got section. */
501 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
502 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
506 got_sec = bfd_get_section_by_name (inbfd, ".got");
507 assert (got_sec != (asection *) NULL);
508 sym->value = got_sec->output_offset;
509 sym->section = got_sec->output_section;
511 /* end-sanitize-powerpc-netware */
514 /* If this is a global symbol, check the export list. */
515 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
517 register struct string_list *l;
520 /* Unfortunately, a symbol can appear multiple times on the
521 export list, with and without prefixes. */
523 for (l = export_symbols; l != NULL; l = l->next)
525 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
531 zbase = strchr (l->string, '@');
533 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
535 /* We must add a symbol with this prefix. */
536 if (newsymcount >= newsymalloc)
539 newsyms = ((asymbol **)
540 xrealloc ((PTR) newsyms,
542 * sizeof (asymbol *))));
544 newsyms[newsymcount] =
545 (asymbol *) xmalloc (sizeof (asymbol));
546 *newsyms[newsymcount] = *sym;
547 newsyms[newsymcount]->name = l->string;
554 /* The unmodified symbol is actually not exported at
556 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
557 sym->flags |= BSF_LOCAL;
561 /* If it's an undefined symbol, see if it's on the import list.
562 Change the prefix if necessary. */
563 if (bfd_get_section (sym) == &bfd_und_section)
565 register struct string_list *l;
567 for (l = import_symbols; l != NULL; l = l->next)
569 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
575 zbase = strchr (l->string, '@');
577 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
579 sym->name = l->string;
586 "%s: warning: symbol %s imported but not in import list\n",
587 program_name, bfd_asymbol_name (sym));
590 /* See if it's one of the special named symbols. */
591 if ((sym->flags & BSF_DEBUGGING) == 0)
595 /* FIXME: If these symbols are not in the .text section, we
596 add the .text section size to the value. This may not be
597 correct for all targets. I'm not sure how this should
598 really be handled. */
599 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
601 val = bfd_asymbol_value (sym);
602 if (bfd_get_section (sym) == data_sec
603 && text_sec != (asection *) NULL)
604 val += bfd_section_size (outbfd, text_sec);
605 if (! bfd_set_start_address (outbfd, val))
606 bfd_fatal ("set start address");
609 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
611 val = bfd_asymbol_value (sym);
612 if (bfd_get_section (sym) == data_sec
613 && text_sec != (asection *) NULL)
614 val += bfd_section_size (outbfd, text_sec);
615 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
618 if (check_procedure != NULL
619 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
621 val = bfd_asymbol_value (sym);
622 if (bfd_get_section (sym) == data_sec
623 && text_sec != (asection *) NULL)
624 val += bfd_section_size (outbfd, text_sec);
625 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
633 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
635 /* FIXME: If any relocs referring to _end use inplace addends,
636 then I think they need to be updated. This is handled by
637 i386_mangle_relocs. Is it needed for any other object
641 if (newsymcount == 0)
645 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
646 * sizeof (asymbol *));
647 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
648 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
649 outsyms[symcount + newsymcount] = NULL;
652 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
655 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
656 program_name, start_procedure);
658 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
659 program_name, exit_procedure);
660 if (check_procedure != NULL
662 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
663 program_name, check_procedure);
665 /* Add additional sections required for the header information. */
666 if (custom_file != NULL)
668 custom_data = fopen (custom_file, "r");
669 if (custom_data == NULL
670 || fstat (fileno (custom_data), &st) < 0)
672 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
678 custom_size = st.st_size;
679 custom_section = bfd_make_section (outbfd, ".nlmcustom");
680 if (custom_section == NULL
681 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
682 || ! bfd_set_section_flags (outbfd, custom_section,
684 bfd_fatal ("custom section");
687 if (help_file != NULL)
689 help_data = fopen (help_file, "r");
690 if (help_data == NULL
691 || fstat (fileno (help_data), &st) < 0)
693 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
699 help_size = st.st_size;
700 help_section = bfd_make_section (outbfd, ".nlmhelp");
701 if (help_section == NULL
702 || ! bfd_set_section_size (outbfd, help_section, help_size)
703 || ! bfd_set_section_flags (outbfd, help_section,
705 bfd_fatal ("help section");
706 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
709 if (message_file != NULL)
711 message_data = fopen (message_file, "r");
712 if (message_data == NULL
713 || fstat (fileno (message_data), &st) < 0)
715 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
721 message_size = st.st_size;
722 message_section = bfd_make_section (outbfd, ".nlmmessages");
723 if (message_section == NULL
724 || ! bfd_set_section_size (outbfd, message_section, message_size)
725 || ! bfd_set_section_flags (outbfd, message_section,
727 bfd_fatal ("message section");
728 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
733 struct string_list *l;
736 for (l = modules; l != NULL; l = l->next)
737 module_size += strlen (l->string) + 1;
738 module_section = bfd_make_section (outbfd, ".nlmmodules");
739 if (module_section == NULL
740 || ! bfd_set_section_size (outbfd, module_section, module_size)
741 || ! bfd_set_section_flags (outbfd, module_section,
743 bfd_fatal ("module section");
745 if (rpc_file != NULL)
747 rpc_data = fopen (rpc_file, "r");
749 || fstat (fileno (rpc_data), &st) < 0)
751 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
757 rpc_size = st.st_size;
758 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
759 if (rpc_section == NULL
760 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
761 || ! bfd_set_section_flags (outbfd, rpc_section,
763 bfd_fatal ("rpc section");
764 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
767 if (sharelib_file != NULL)
769 sharedbfd = bfd_openr (sharelib_file, output_format);
770 if (sharedbfd == NULL
771 || ! bfd_check_format (sharedbfd, bfd_object))
773 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
774 bfd_errmsg (bfd_get_error ()));
775 sharelib_file = NULL;
779 sharedhdr = *nlm_fixed_header (sharedbfd);
780 bfd_close (sharedbfd);
781 shared_data = fopen (sharelib_file, "r");
782 if (shared_data == NULL
783 || (fstat (fileno (shared_data), &st) < 0))
785 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
787 sharelib_file = NULL;
791 /* If we were clever, we could just copy out the
792 sections of the shared library which we actually
793 need. However, we would have to figure out the sizes
794 of the external and public information, and that can
795 not be done without reading through them. */
796 if (sharedhdr.uninitializedDataSize > 0)
798 /* There is no place to record this information. */
800 "%s:%s: warning: shared libraries can not have uninitialized data\n",
801 program_name, sharelib_file);
803 shared_offset = st.st_size;
804 if (shared_offset > sharedhdr.codeImageOffset)
805 shared_offset = sharedhdr.codeImageOffset;
806 if (shared_offset > sharedhdr.dataImageOffset)
807 shared_offset = sharedhdr.dataImageOffset;
808 if (shared_offset > sharedhdr.relocationFixupOffset)
809 shared_offset = sharedhdr.relocationFixupOffset;
810 if (shared_offset > sharedhdr.externalReferencesOffset)
811 shared_offset = sharedhdr.externalReferencesOffset;
812 if (shared_offset > sharedhdr.publicsOffset)
813 shared_offset = sharedhdr.publicsOffset;
814 shared_size = st.st_size - shared_offset;
815 shared_section = bfd_make_section (outbfd, ".nlmshared");
816 if (shared_section == NULL
817 || ! bfd_set_section_size (outbfd, shared_section,
819 || ! bfd_set_section_flags (outbfd, shared_section,
821 bfd_fatal ("shared section");
822 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
827 /* Check whether a version was given. */
828 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
829 fprintf (stderr, "%s: warning: No version number given\n",
832 /* At least for now, always create an extended header, because that
833 is what NLMLINK does. */
834 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
836 /* If the date was not given, force it in. */
837 if (nlm_version_header (outbfd)->month == 0
838 && nlm_version_header (outbfd)->day == 0
839 && nlm_version_header (outbfd)->year == 0)
845 ptm = localtime (&now);
846 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
847 nlm_version_header (outbfd)->day = ptm->tm_mday;
848 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
849 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
851 /* start-sanitize-powerpc-netware */
853 /* Resolve the stubs we build for PowerPC NetWare. */
854 powerpc_resolve_stubs (inbfd, outbfd);
855 /* end-sanitize-powerpc-netware */
857 /* Copy over the sections. */
858 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
860 /* Finish up the header information. */
861 if (custom_file != NULL)
865 data = xmalloc (custom_size);
866 if (fread (data, 1, custom_size, custom_data) != custom_size)
867 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
871 if (! bfd_set_section_contents (outbfd, custom_section, data,
872 (file_ptr) 0, custom_size))
873 bfd_fatal ("custom section");
874 nlm_fixed_header (outbfd)->customDataOffset =
875 custom_section->filepos;
876 nlm_fixed_header (outbfd)->customDataSize = custom_size;
882 /* As a special hack, the backend recognizes a debugInfoOffset
883 of -1 to mean that it should not output any debugging
884 information. This can not be handling by fiddling with the
885 symbol table because exported symbols appear in both the
886 export information and the debugging information. */
887 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
889 if (map_file != NULL)
891 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
893 if (help_file != NULL)
897 data = xmalloc (help_size);
898 if (fread (data, 1, help_size, help_data) != help_size)
899 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
903 if (! bfd_set_section_contents (outbfd, help_section, data,
904 (file_ptr) 0, help_size))
905 bfd_fatal ("help section");
906 nlm_extended_header (outbfd)->helpFileOffset =
907 help_section->filepos;
908 nlm_extended_header (outbfd)->helpFileLength = help_size;
912 if (message_file != NULL)
916 data = xmalloc (message_size);
917 if (fread (data, 1, message_size, message_data) != message_size)
918 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
922 if (! bfd_set_section_contents (outbfd, message_section, data,
923 (file_ptr) 0, message_size))
924 bfd_fatal ("message section");
925 nlm_extended_header (outbfd)->messageFileOffset =
926 message_section->filepos;
927 nlm_extended_header (outbfd)->messageFileLength = message_size;
929 /* FIXME: Are these offsets correct on all platforms? Are
930 they 32 bits on all platforms? What endianness? */
931 nlm_extended_header (outbfd)->languageID =
932 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
933 nlm_extended_header (outbfd)->messageCount =
934 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
942 struct string_list *l;
945 data = xmalloc (module_size);
947 set = (unsigned char *) data;
948 for (l = modules; l != NULL; l = l->next)
950 *set = strlen (l->string);
951 strncpy (set + 1, l->string, *set);
955 if (! bfd_set_section_contents (outbfd, module_section, data,
956 (file_ptr) 0, module_size))
957 bfd_fatal ("module section");
958 nlm_fixed_header (outbfd)->moduleDependencyOffset =
959 module_section->filepos;
960 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
962 if (rpc_file != NULL)
966 data = xmalloc (rpc_size);
967 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
968 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
972 if (! bfd_set_section_contents (outbfd, rpc_section, data,
973 (file_ptr) 0, rpc_size))
974 bfd_fatal ("rpc section");
975 nlm_extended_header (outbfd)->RPCDataOffset =
976 rpc_section->filepos;
977 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
981 if (sharelib_file != NULL)
985 data = xmalloc (shared_size);
986 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
987 || fread (data, 1, shared_size, shared_data) != shared_size)
988 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
992 if (! bfd_set_section_contents (outbfd, shared_section, data,
993 (file_ptr) 0, shared_size))
994 bfd_fatal ("shared section");
996 nlm_extended_header (outbfd)->sharedCodeOffset =
997 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
998 nlm_extended_header (outbfd)->sharedCodeLength =
999 sharedhdr.codeImageSize;
1000 nlm_extended_header (outbfd)->sharedDataOffset =
1001 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1002 nlm_extended_header (outbfd)->sharedDataLength =
1003 sharedhdr.dataImageSize;
1004 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1005 (sharedhdr.relocationFixupOffset
1007 + shared_section->filepos);
1008 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1009 sharedhdr.numberOfRelocationFixups;
1010 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1011 (sharedhdr.externalReferencesOffset
1013 + shared_section->filepos);
1014 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1015 sharedhdr.numberOfExternalReferences;
1016 nlm_extended_header (outbfd)->sharedPublicsOffset =
1017 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1018 nlm_extended_header (outbfd)->sharedPublicsCount =
1019 sharedhdr.numberOfPublics;
1020 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1021 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1022 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1023 sharedhdr.numberOfDebugRecords;
1024 nlm_extended_header (outbfd)->SharedInitializationOffset =
1025 sharedhdr.codeStartOffset;
1026 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1027 sharedhdr.exitProcedureOffset;
1030 len = strlen (output_file);
1031 if (len > NLM_MODULE_NAME_SIZE - 2)
1032 len = NLM_MODULE_NAME_SIZE - 2;
1033 nlm_fixed_header (outbfd)->moduleName[0] = len;
1035 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1036 NLM_MODULE_NAME_SIZE - 2);
1037 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1038 for (modname = nlm_fixed_header (outbfd)->moduleName;
1041 if (islower (*modname))
1042 *modname = toupper (*modname);
1044 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1045 NLM_OLD_THREAD_NAME_LENGTH);
1047 if (! bfd_close (outbfd))
1048 bfd_fatal (output_file);
1049 if (! bfd_close (inbfd))
1050 bfd_fatal (input_file);
1052 if (unlink_on_exit != NULL)
1053 unlink (unlink_on_exit);
1058 /* Display a help message and exit. */
1063 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1065 show_usage (stdout, 0);
1068 /* Show a usage message and exit. */
1071 show_usage (file, status)
1076 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1077 [--input-target=bfdname] [--output-target=bfdname]\n\
1078 [--header-file=file] [--linker=linker] [--debug]\n\
1079 [--help] [--version]\n\
1080 [in-file [out-file]]\n",
1085 /* Select the output format based on the input architecture, machine,
1086 and endianness. This chooses the appropriate NLM target. */
1089 select_output_format (arch, mach, bigendian)
1090 enum bfd_architecture arch;
1097 return "nlm32-i386";
1098 case bfd_arch_sparc:
1099 return "nlm32-sparc";
1100 case bfd_arch_alpha:
1101 return "nlm32-alpha";
1102 /* start-sanitize-powerpc-netware */
1103 case bfd_arch_powerpc:
1104 return "nlm32-powerpc";
1105 /* end-sanitize-powerpc-netware */
1107 fprintf (stderr, "%s: no default NLM format for %s\n",
1108 program_name, bfd_printable_arch_mach (arch, mach));
1110 /* Avoid warning. */
1116 /* The BFD sections are copied in two passes. This function selects
1117 the output section for each input section, and sets up the section
1121 setup_sections (inbfd, insec, data_ptr)
1126 bfd *outbfd = (bfd *) data_ptr;
1128 const char *outname;
1131 bfd_size_type align;
1134 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1135 file. However, I don't have a good way to describe this section.
1136 We do want to copy the section when using objcopy. */
1137 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1138 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1141 f = bfd_get_section_flags (inbfd, insec);
1143 outname = NLM_CODE_NAME;
1144 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1145 outname = NLM_INITIALIZED_DATA_NAME;
1146 else if (f & SEC_ALLOC)
1147 outname = NLM_UNINITIALIZED_DATA_NAME;
1149 outname = bfd_section_name (inbfd, insec);
1151 outsec = bfd_get_section_by_name (outbfd, outname);
1154 outsec = bfd_make_section (outbfd, outname);
1156 bfd_fatal ("make section");
1159 insec->output_section = outsec;
1161 offset = bfd_section_size (outbfd, outsec);
1162 align = 1 << bfd_section_alignment (inbfd, insec);
1163 add = ((offset + align - 1) &~ (align - 1)) - offset;
1164 insec->output_offset = offset + add;
1166 if (! bfd_set_section_size (outbfd, outsec,
1167 (bfd_section_size (outbfd, outsec)
1168 + bfd_section_size (inbfd, insec)
1170 bfd_fatal ("set section size");
1172 if ((bfd_section_alignment (inbfd, insec)
1173 > bfd_section_alignment (outbfd, outsec))
1174 && ! bfd_set_section_alignment (outbfd, outsec,
1175 bfd_section_alignment (inbfd, insec)))
1176 bfd_fatal ("set section alignment");
1178 if (! bfd_set_section_flags (outbfd, outsec, f))
1179 bfd_fatal ("set section flags");
1181 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1184 /* Copy the section contents. */
1187 copy_sections (inbfd, insec, data_ptr)
1192 bfd *outbfd = (bfd *) data_ptr;
1196 bfd_size_type reloc_size;
1198 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1199 file. However, I don't have a good way to describe this section.
1200 We do want to copy the section when using objcopy. */
1201 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1202 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1205 outsec = insec->output_section;
1206 assert (outsec != NULL);
1208 size = bfd_get_section_size_before_reloc (insec);
1212 /* FIXME: Why are these necessary? */
1213 insec->_cooked_size = insec->_raw_size;
1214 insec->reloc_done = true;
1216 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1220 contents = xmalloc (size);
1221 if (! bfd_get_section_contents (inbfd, insec, contents,
1222 (file_ptr) 0, size))
1223 bfd_fatal (bfd_get_filename (inbfd));
1226 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1227 if (reloc_size != 0)
1230 bfd_size_type reloc_count;
1232 relocs = (arelent **) xmalloc (reloc_size);
1233 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1234 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1237 /* FIXME: refers to internal BFD fields. */
1238 if (outsec->orelocation != (arelent **) NULL)
1240 bfd_size_type total_count;
1243 total_count = reloc_count + outsec->reloc_count;
1244 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1245 memcpy (combined, outsec->orelocation,
1246 outsec->reloc_count * sizeof (arelent));
1247 memcpy (combined + outsec->reloc_count, relocs,
1248 (size_t) (reloc_count * sizeof (arelent)));
1249 free (outsec->orelocation);
1250 reloc_count = total_count;
1254 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1257 if (contents != NULL)
1259 if (! bfd_set_section_contents (outbfd, outsec, contents,
1260 insec->output_offset, size))
1261 bfd_fatal (bfd_get_filename (outbfd));
1266 /* Some, perhaps all, NetWare targets require changing the relocs used
1267 by the input formats. */
1270 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1274 arelent ***relocs_ptr;
1275 bfd_size_type *reloc_count_ptr;
1277 bfd_size_type contents_size;
1279 switch (bfd_get_arch (outbfd))
1282 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1283 contents, contents_size);
1285 case bfd_arch_alpha:
1286 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1287 contents, contents_size);
1289 /* start-sanitize-powerpc-netware */
1290 case bfd_arch_powerpc:
1291 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1292 contents, contents_size);
1294 /* end-sanitize-powerpc-netware */
1296 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1297 contents, contents_size);
1302 /* By default all we need to do for relocs is change the address by
1303 the output_offset. */
1307 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1311 arelent ***relocs_ptr;
1312 bfd_size_type *reloc_count_ptr;
1314 bfd_size_type contents_size;
1316 if (insec->output_offset != 0)
1318 bfd_size_type reloc_count;
1319 register arelent **relocs;
1320 register bfd_size_type i;
1322 reloc_count = *reloc_count_ptr;
1323 relocs = *relocs_ptr;
1324 for (i = 0; i < reloc_count; i++, relocs++)
1325 (*relocs)->address += insec->output_offset;
1329 /* NetWare on the i386 supports a restricted set of relocs, which are
1330 different from those used on other i386 targets. This routine
1331 converts the relocs. It is, obviously, very target dependent. At
1332 the moment, the nlm32-i386 backend performs similar translations;
1333 however, it is more reliable and efficient to do them here. */
1335 static reloc_howto_type nlm_i386_pcrel_howto =
1336 HOWTO (1, /* type */
1338 2, /* size (0 = byte, 1 = short, 2 = long) */
1340 true, /* pc_relative */
1342 complain_overflow_signed, /* complain_on_overflow */
1343 0, /* special_function */
1344 "DISP32", /* name */
1345 true, /* partial_inplace */
1346 0xffffffff, /* src_mask */
1347 0xffffffff, /* dst_mask */
1348 true); /* pcrel_offset */
1351 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1355 arelent ***relocs_ptr;
1356 bfd_size_type *reloc_count_ptr;
1358 bfd_size_type contents_size;
1360 bfd_size_type reloc_count, i;
1363 reloc_count = *reloc_count_ptr;
1364 relocs = *relocs_ptr;
1365 for (i = 0; i < reloc_count; i++)
1369 bfd_size_type address;
1373 sym = *rel->sym_ptr_ptr;
1375 /* We're moving the relocs from the input section to the output
1376 section, so we must adjust the address accordingly. */
1377 address = rel->address;
1378 rel->address += insec->output_offset;
1380 /* Note that no serious harm will ensue if we fail to change a
1381 reloc. The backend will fail when writing out the reloc. */
1383 /* Make sure this reloc is within the data we have. We use only
1384 4 byte relocs here, so we insist on having 4 bytes. */
1385 if (address + 4 > contents_size)
1388 /* A PC relative reloc entirely within a single section is
1389 completely unnecessary. This can be generated by ld -r. */
1390 if (sym == insec->symbol
1391 && rel->howto != NULL
1392 && rel->howto->pc_relative
1393 && ! rel->howto->pcrel_offset)
1397 memmove (relocs, relocs + 1,
1398 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1402 /* Get the amount the relocation will add in. */
1403 addend = rel->addend + sym->value;
1405 /* NetWare doesn't support PC relative relocs against defined
1406 symbols, so we have to eliminate them by doing the relocation
1407 now. We can only do this if the reloc is within a single
1409 if (rel->howto != NULL
1410 && rel->howto->pc_relative
1411 && bfd_get_section (sym) == insec->output_section)
1415 if (rel->howto->pcrel_offset)
1418 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1420 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1424 memmove (relocs, relocs + 1,
1425 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1429 /* NetWare doesn't support reloc addends, so we get rid of them
1430 here by simply adding them into the object data. We handle
1431 the symbol value, if any, the same way. */
1433 && rel->howto != NULL
1434 && rel->howto->rightshift == 0
1435 && rel->howto->size == 2
1436 && rel->howto->bitsize == 32
1437 && rel->howto->bitpos == 0
1438 && rel->howto->src_mask == 0xffffffff
1439 && rel->howto->dst_mask == 0xffffffff)
1443 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1445 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1447 /* Adjust the reloc for the changes we just made. */
1449 if (bfd_get_section (sym) != &bfd_und_section)
1450 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1453 /* NetWare uses a reloc with pcrel_offset set. We adjust
1454 pc_relative relocs accordingly. We are going to change the
1455 howto field, so we can only do this if the current one is
1456 compatible. We should check that special_function is NULL
1457 here, but at the moment coff-i386 uses a special_function
1458 which does not affect what we are doing here. */
1459 if (rel->howto != NULL
1460 && rel->howto->pc_relative
1461 && ! rel->howto->pcrel_offset
1462 && rel->howto->rightshift == 0
1463 && rel->howto->size == 2
1464 && rel->howto->bitsize == 32
1465 && rel->howto->bitpos == 0
1466 && rel->howto->src_mask == 0xffffffff
1467 && rel->howto->dst_mask == 0xffffffff)
1471 /* When pcrel_offset is not set, it means that the negative
1472 of the address of the memory location is stored in the
1473 memory location. We must add it back in. */
1474 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1476 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1478 /* We must change to a new howto. */
1479 rel->howto = &nlm_i386_pcrel_howto;
1484 /* On the Alpha the first reloc for every section must be a special
1485 relocs which hold the GP address. Also, the first reloc in the
1486 file must be a special reloc which holds the address of the .lita
1489 static reloc_howto_type nlm32_alpha_nw_howto =
1490 HOWTO (ALPHA_R_NW_RELOC, /* type */
1492 0, /* size (0 = byte, 1 = short, 2 = long) */
1494 false, /* pc_relative */
1496 complain_overflow_dont, /* complain_on_overflow */
1497 0, /* special_function */
1498 "NW_RELOC", /* name */
1499 false, /* partial_inplace */
1502 false); /* pcrel_offset */
1506 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1510 register arelent ***relocs_ptr;
1511 bfd_size_type *reloc_count_ptr;
1513 bfd_size_type contents_size;
1515 bfd_size_type old_reloc_count;
1516 arelent **old_relocs;
1517 register arelent **relocs;
1519 old_reloc_count = *reloc_count_ptr;
1520 old_relocs = *relocs_ptr;
1521 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1522 *relocs_ptr = relocs;
1524 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1527 asection *lita_section;
1529 inbfd = insec->owner;
1530 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1531 if (lita_section != (asection *) NULL)
1533 nlm_alpha_backend_data (outbfd)->lita_address =
1534 bfd_get_section_vma (inbfd, lita_section);
1535 nlm_alpha_backend_data (outbfd)->lita_size =
1536 bfd_section_size (inbfd, lita_section);
1540 /* Avoid outputting this reloc again. */
1541 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1544 *relocs = (arelent *) xmalloc (sizeof (arelent));
1545 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1546 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1547 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1548 (*relocs)->howto = &nlm32_alpha_nw_howto;
1550 ++(*reloc_count_ptr);
1553 /* Get the GP value from bfd. It is in the .reginfo section. */
1554 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1557 asection *reginfo_sec;
1558 struct ecoff_reginfo sreginfo;
1560 inbfd = insec->owner;
1561 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1562 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1563 if (reginfo_sec != (asection *) NULL
1564 && bfd_get_section_contents (inbfd, reginfo_sec,
1565 (PTR) &sreginfo, (file_ptr) 0,
1566 sizeof sreginfo) != false)
1567 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1570 *relocs = (arelent *) xmalloc (sizeof (arelent));
1571 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1572 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1573 (*relocs)->addend = 0;
1574 (*relocs)->howto = &nlm32_alpha_nw_howto;
1576 ++(*reloc_count_ptr);
1578 memcpy ((PTR) relocs, (PTR) old_relocs,
1579 (size_t) old_reloc_count * sizeof (arelent *));
1580 relocs[old_reloc_count] = (arelent *) NULL;
1584 if (insec->output_offset != 0)
1586 register bfd_size_type i;
1588 for (i = 0; i < old_reloc_count; i++, relocs++)
1589 (*relocs)->address += insec->output_offset;
1592 /* start-sanitize-powerpc-netware */
1594 /* We keep a linked list of stubs which we must build. Because BFD
1595 requires us to know the sizes of all sections before we can set the
1596 contents of any, we must figure out which stubs we want to build
1597 before we can actually build any of them. */
1601 /* Next stub in linked list. */
1602 struct powerpc_stub *next;
1604 /* Symbol whose value is the start of the stub. This is a symbol
1605 whose name begins with `.'. */
1608 /* Symbol we are going to create a reloc against. This is a symbol
1609 with the same name as START but without the leading `.'. */
1612 /* The TOC index for this stub. This is the index into the TOC
1613 section at which the reloc is created. */
1614 unsigned int toc_index;
1617 /* The linked list of stubs. */
1619 static struct powerpc_stub *powerpc_stubs;
1621 /* This is what a stub looks like. The first instruction will get
1622 adjusted with the correct TOC index. */
1624 static unsigned long powerpc_stub_insns[] =
1626 0x81820000, /* lwz r12,0(r2) */
1627 0x90410014, /* stw r2,20(r1) */
1628 0x800c0000, /* lwz r0,0(r12) */
1629 0x804c0004, /* lwz r2,r(r12) */
1630 0x7c0903a6, /* mtctr r0 */
1631 0x4e800420, /* bctr */
1632 0, /* Traceback table. */
1637 #define POWERPC_STUB_INSN_COUNT \
1638 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1640 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1642 /* Each stub uses a four byte TOC entry. */
1643 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1645 /* The original size of the .got section. */
1646 static bfd_size_type powerpc_initial_got_size;
1648 /* Look for all undefined symbols beginning with `.', and prepare to
1649 build a stub for each one. */
1652 powerpc_build_stubs (inbfd, symbols_ptr, symcount_ptr)
1654 asymbol ***symbols_ptr;
1655 unsigned int *symcount_ptr;
1659 unsigned int got_base;
1661 unsigned int symcount;
1662 unsigned int stubcount;
1664 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1665 the section to prevent copy_sections from reading from it. */
1666 stub_sec = bfd_make_section (inbfd, ".stubs");
1667 if (stub_sec == (asection *) NULL
1668 || ! bfd_set_section_flags (inbfd, stub_sec,
1673 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1674 bfd_fatal (".stubs");
1676 /* Get the TOC section, which is named .got. */
1677 got_sec = bfd_get_section_by_name (inbfd, ".got");
1678 if (got_sec == (asection *) NULL)
1680 got_sec = bfd_make_section (inbfd, ".got");
1681 if (got_sec == (asection *) NULL
1682 || ! bfd_set_section_flags (inbfd, got_sec,
1687 | SEC_HAS_CONTENTS))
1688 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1692 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1693 got_base = powerpc_initial_got_size;
1694 got_base = (got_base + 3) &~ 3;
1698 symcount = *symcount_ptr;
1699 for (i = 0; i < symcount; i++)
1704 struct powerpc_stub *item;
1706 sym = (*symbols_ptr)[i];
1708 /* We must make a stub for every undefined symbol whose name
1710 if (bfd_asymbol_name (sym)[0] != '.'
1711 || bfd_get_section (sym) != &bfd_und_section)
1714 /* Make a new undefined symbol with the same name but without
1716 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1718 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1719 strcpy (newname, bfd_asymbol_name (sym) + 1);
1720 newsym->name = newname;
1722 /* Define the `.' symbol to be in the stub section. */
1723 sym->section = stub_sec;
1724 sym->value = stubcount * POWERPC_STUB_SIZE;
1725 sym->flags = BSF_LOCAL;
1727 /* Add this stub to the linked list. */
1728 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1730 item->reloc = newsym;
1731 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1733 item->next = powerpc_stubs;
1734 powerpc_stubs = item;
1742 struct powerpc_stub *l;
1744 /* Add the new symbols we just created to the symbol table. */
1745 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1746 ((symcount + stubcount)
1747 * sizeof (asymbol)));
1748 *symcount_ptr += stubcount;
1749 s = &(*symbols_ptr)[symcount];
1750 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1753 /* Set the size of the .stubs section and increase the size of
1754 the .got section. */
1755 if (! bfd_set_section_size (inbfd, stub_sec,
1756 stubcount * POWERPC_STUB_SIZE)
1757 || ! bfd_set_section_size (inbfd, got_sec,
1760 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1761 bfd_fatal ("stub section sizes");
1765 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1766 of the output section, and create new relocs in the TOC. */
1769 powerpc_resolve_stubs (inbfd, outbfd)
1773 bfd_byte buf[POWERPC_STUB_SIZE];
1775 unsigned int stubcount;
1779 struct powerpc_stub *l;
1781 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1784 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1785 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1787 got_sec = bfd_get_section_by_name (inbfd, ".got");
1788 assert (got_sec != (asection *) NULL);
1789 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1792 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1794 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1797 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1801 /* Adjust the first instruction to use the right TOC index. */
1802 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1804 /* Write this stub out. */
1805 if (! bfd_set_section_contents (outbfd,
1806 bfd_get_section (l->start),
1810 bfd_fatal ("writing stub");
1812 /* Create a new reloc for the TOC entry. */
1813 reloc = (arelent *) xmalloc (sizeof (arelent));
1814 reloc->sym_ptr_ptr = &l->reloc;
1815 reloc->address = l->toc_index + got_sec->output_offset;
1817 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1822 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1825 /* Adjust relocation entries for PowerPC NetWare. We do not output
1826 TOC relocations. The object code already contains the offset from
1827 the TOC pointer. When the function is called, the TOC register,
1828 r2, will be set to the correct TOC value, so there is no need for
1829 any further reloc. */
1833 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1837 register arelent ***relocs_ptr;
1838 bfd_size_type *reloc_count_ptr;
1840 bfd_size_type contents_size;
1842 const reloc_howto_type *toc_howto;
1843 bfd_size_type reloc_count;
1844 register arelent **relocs;
1845 register bfd_size_type i;
1847 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1848 if (toc_howto == (reloc_howto_type *) NULL)
1851 /* If this is the .got section, clear out all the contents beyond
1852 the initial size. We must do this here because copy_sections is
1853 going to write out whatever we return in the contents field. */
1854 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1855 memset (contents + powerpc_initial_got_size, 0,
1856 (bfd_get_section_size_after_reloc (insec)
1857 - powerpc_initial_got_size));
1859 reloc_count = *reloc_count_ptr;
1860 relocs = *relocs_ptr;
1861 for (i = 0; i < reloc_count; i++)
1868 sym = *rel->sym_ptr_ptr;
1870 /* We must be able to resolve all PC relative relocs at this
1871 point. If we get a branch to an undefined symbol we build a
1872 stub, since NetWare will resolve undefined symbols into a
1873 pointer to a function descriptor. */
1874 if (rel->howto->pc_relative)
1876 /* This check for whether a symbol is in the same section as
1877 the reloc will be wrong if there is a PC relative reloc
1878 between two sections both of which were placed in the
1879 same output section. This should not happen. */
1880 if (bfd_get_section (sym) != insec->output_section)
1881 fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1882 program_name, bfd_asymbol_name (sym));
1887 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1888 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1889 val = ((val &~ rel->howto->dst_mask)
1890 | (((val & rel->howto->src_mask)
1891 + (sym->value - rel->address)
1893 & rel->howto->dst_mask));
1894 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1896 /* If this reloc is against a symbol whose name begins
1897 with a `.', and the next instruction is
1899 then we replace the next instruction with
1901 This reloads the TOC pointer after a call. */
1902 if (bfd_asymbol_name (sym)[0] == '.'
1903 && (bfd_get_32 (outbfd,
1904 (bfd_byte *) contents + rel->address + 4)
1905 == 0x4ffffb82)) /* cror 31,31,31 */
1906 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1907 (bfd_byte *) contents + rel->address + 4);
1911 memmove (relocs, relocs + 1,
1912 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1917 /* When considering a TOC reloc, we do not want to include the
1918 symbol value. The symbol will be start of the TOC section
1919 (which is named .got). We do want to include the addend. */
1920 if (rel->howto == toc_howto)
1923 symvalue = sym->value;
1925 /* If this is a relocation against a symbol with a value, or
1926 there is a reloc addend, we need to update the addend in the
1928 if (symvalue + rel->addend != 0)
1932 switch (rel->howto->size)
1935 val = bfd_get_16 (outbfd,
1936 (bfd_byte *) contents + rel->address);
1937 val = ((val &~ rel->howto->dst_mask)
1938 | (((val & rel->howto->src_mask)
1941 & rel->howto->dst_mask));
1942 if ((bfd_signed_vma) val < - 0x8000
1943 || (bfd_signed_vma) val >= 0x8000)
1945 "%s: overflow when adjusting relocation against %s\n",
1946 program_name, bfd_asymbol_name (sym));
1947 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1951 val = bfd_get_32 (outbfd,
1952 (bfd_byte *) contents + rel->address);
1953 val = ((val &~ rel->howto->dst_mask)
1954 | (((val & rel->howto->src_mask)
1957 & rel->howto->dst_mask));
1958 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1965 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1969 /* Now that we have incorporated the addend, remove any TOC
1971 if (rel->howto == toc_howto)
1975 memmove (relocs, relocs + 1,
1976 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1980 rel->address += insec->output_offset;
1983 /* end-sanitize-powerpc-netware */
1985 /* Name of linker. */
1987 #define LD_NAME "ld"
1990 /* Temporary file name base. */
1991 static char *temp_filename;
1993 /* The user has specified several input files. Invoke the linker to
1994 link them all together, and convert and delete the resulting output
1998 link_inputs (inputs, ld)
1999 struct string_list *inputs;
2003 struct string_list *q;
2010 for (q = inputs; q != NULL; q = q->next)
2013 argv = (char **) alloca (c + 5);
2020 /* Find the linker to invoke based on how nlmconv was run. */
2021 p = program_name + strlen (program_name);
2022 while (p != program_name)
2026 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2027 memcpy (ld, program_name, p - program_name);
2028 strcpy (ld + (p - program_name), LD_NAME);
2037 ld = (char *) LD_NAME;
2039 choose_temp_base ();
2041 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2042 sprintf (unlink_on_exit, "%s.O", temp_filename);
2045 argv[1] = (char *) "-r";
2046 argv[2] = (char *) "-o";
2047 argv[3] = unlink_on_exit;
2049 for (q = inputs; q != NULL; q = q->next, i++)
2050 argv[i] = q->string;
2055 for (i = 0; argv[i] != NULL; i++)
2056 fprintf (stderr, " %s", argv[i]);
2057 fprintf (stderr, "\n");
2060 pid = pexecute (ld, argv);
2062 if (waitpid (pid, &status, 0) < 0)
2065 unlink (unlink_on_exit);
2071 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2072 unlink (unlink_on_exit);
2076 return unlink_on_exit;
2079 /* Choose a temporary file name. Stolen from gcc.c. */
2082 choose_temp_base_try (try, base)
2090 else if (try == NULL)
2092 else if (access (try, R_OK | W_OK) != 0)
2102 const char *base = NULL;
2105 base = choose_temp_base_try (getenv ("TMPDIR"), base);
2106 base = choose_temp_base_try (getenv ("TMP"), base);
2107 base = choose_temp_base_try (getenv ("TEMP"), base);
2110 base = choose_temp_base_try (P_tmpdir, base);
2113 base = choose_temp_base_try ("/usr/tmp", base);
2114 base = choose_temp_base_try ("/tmp", base);
2116 /* If all else fails, use the current directory! */
2120 len = strlen (base);
2121 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2122 strcpy (temp_filename, base);
2123 if (len > 0 && temp_filename[len-1] != '/')
2124 temp_filename[len++] = '/';
2125 strcpy (temp_filename + len, "ccXXXXXX");
2127 mktemp (temp_filename);
2128 if (*temp_filename == '\0')
2132 /* Execute a job. Stolen from gcc.c. */
2138 pexecute (program, argv)
2146 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2147 rf = scmd + strlen(program) + 2 + el;
2148 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2149 argfile = fopen (rf, "w");
2151 pfatal_with_name (rf);
2153 for (i=1; argv[i]; i++)
2156 for (cp = argv[i]; *cp; cp++)
2158 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2159 fputc ('\\', argfile);
2160 fputc (*cp, argfile);
2162 fputc ('\n', argfile);
2173 return MIN_FATAL_STATUS << 8;
2179 #else /* not __MSDOS__ */
2182 pexecute (program, argv)
2187 int retries, sleep_interval;
2189 /* Fork a subprocess; wait and retry if it fails. */
2191 for (retries = 0; retries < 4; retries++)
2196 sleep (sleep_interval);
2197 sleep_interval *= 2;
2213 /* Exec the program. */
2214 execvp (program, argv);
2221 /* Return child's process number. */
2226 #endif /* not __MSDOS__ */
2230 pexecute (program, argv)
2234 return spawnvp (1, program, argv);
2236 #endif /* not OS2 */