1 /* nlmconv.c -- NLM conversion program
2 Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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. */
27 /* AIX requires this to be the first thing in the file. */
35 #include "libiberty.h"
46 /* Internal BFD NLM header. */
52 #include "coff/ecoff.h"
55 /* If strerror is just a macro, we want to use the one from libiberty
56 since it will handle undefined values. */
58 extern char *strerror ();
61 extern struct tm *localtime ();
74 /* Global variables. */
76 /* The name used to invoke the program. */
79 /* Local variables. */
81 /* Whether to print out debugging information (currently just controls
82 whether it prints the linker command if there is one). */
85 /* The symbol table. */
86 static asymbol **symbols;
88 /* A section we create in the output file to hold pointers to where
89 the sections of the input file end up. We will put a pointer to
90 this section in the NLM header. These is an entry for each input
91 section. The format is
92 null terminated section name
93 zeroes to adjust to 4 byte boundary
94 4 byte section data file pointer
96 We don't need a version number. The way we find this information
97 is by finding a stamp in the NLM header information. If we need to
98 change the format of this information, we can simply change the
100 static asection *secsec;
102 /* A temporary file name to be unlinked on exit. Actually, for most
103 errors, we leave it around. It's not clear whether that is helpful
105 static char *unlink_on_exit;
107 /* The list of long options. */
108 static struct option long_options[] =
110 { "debug", no_argument, 0, 'd' },
111 { "header-file", required_argument, 0, 'T' },
112 { "help", no_argument, 0, 'h' },
113 { "input-target", required_argument, 0, 'I' },
114 { "input-format", required_argument, 0, 'I' }, /* Obsolete */
115 { "linker", required_argument, 0, 'l' },
116 { "output-target", required_argument, 0, 'O' },
117 { "output-format", required_argument, 0, 'O' }, /* Obsolete */
118 { "version", no_argument, 0, 'V' },
119 { NULL, no_argument, 0, 0 }
122 /* Local routines. */
124 static void show_help PARAMS ((void));
125 static void show_usage PARAMS ((FILE *, int));
126 static const char *select_output_format PARAMS ((enum bfd_architecture,
127 unsigned long, boolean));
128 static void setup_sections PARAMS ((bfd *, asection *, PTR));
129 static void copy_sections PARAMS ((bfd *, asection *, PTR));
130 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
133 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
136 static char *link_inputs PARAMS ((struct string_list *, char *));
139 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
145 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
150 #ifdef NLMCONV_POWERPC
151 static void powerpc_build_stubs PARAMS ((bfd *, bfd *, asymbol ***, long *));
152 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
153 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
158 /* The main routine. */
166 char *input_file = NULL;
167 const char *input_format = NULL;
168 const char *output_format = NULL;
169 const char *header_file = NULL;
171 Nlm_Internal_Fixed_Header fixed_hdr_struct;
172 Nlm_Internal_Variable_Header var_hdr_struct;
173 Nlm_Internal_Version_Header version_hdr_struct;
174 Nlm_Internal_Copyright_Header copyright_hdr_struct;
175 Nlm_Internal_Extended_Header extended_hdr_struct;
178 asymbol **newsyms, **outsyms;
179 long symcount, newsymalloc, newsymcount;
181 asection *text_sec, *bss_sec, *data_sec;
186 char inlead, outlead;
187 boolean gotstart, gotexit, gotcheck;
189 FILE *custom_data = NULL;
190 FILE *help_data = NULL;
191 FILE *message_data = NULL;
192 FILE *rpc_data = NULL;
193 FILE *shared_data = NULL;
194 size_t custom_size = 0;
195 size_t help_size = 0;
196 size_t message_size = 0;
197 size_t module_size = 0;
199 asection *custom_section = NULL;
200 asection *help_section = NULL;
201 asection *message_section = NULL;
202 asection *module_section = NULL;
203 asection *rpc_section = NULL;
204 asection *shared_section = NULL;
206 size_t shared_offset = 0;
207 size_t shared_size = 0;
208 Nlm_Internal_Fixed_Header sharedhdr;
213 program_name = argv[0];
214 xmalloc_set_program_name (program_name);
217 set_default_bfd_target ();
219 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
232 input_format = optarg;
238 output_format = optarg;
241 header_file = optarg;
244 print_version ("nlmconv");
249 show_usage (stderr, 1);
254 /* The input and output files may be named on the command line. */
258 input_file = argv[optind];
262 output_file = argv[optind];
265 show_usage (stderr, 1);
266 if (strcmp (input_file, output_file) == 0)
269 _("%s: input and output files must be different\n"),
276 /* Initialize the header information to default values. */
277 fixed_hdr = &fixed_hdr_struct;
278 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
279 var_hdr = &var_hdr_struct;
280 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
281 version_hdr = &version_hdr_struct;
282 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
283 copyright_hdr = ©right_hdr_struct;
284 memset ((PTR) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
285 extended_hdr = &extended_hdr_struct;
286 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
287 check_procedure = NULL;
290 exit_procedure = "_Stop";
291 export_symbols = NULL;
295 import_symbols = NULL;
298 sharelib_file = NULL;
299 start_procedure = "_Prelude";
305 /* Parse the header file (if there is one). */
306 if (header_file != NULL)
308 if (! nlmlex_file (header_file)
310 || parse_errors != 0)
314 if (input_files != NULL)
316 if (input_file != NULL)
319 _("%s: input file named both on command line and with INPUT\n"),
323 if (input_files->next == NULL)
324 input_file = input_files->string;
326 input_file = link_inputs (input_files, ld_arg);
328 else if (input_file == NULL)
330 fprintf (stderr, _("%s: no input file\n"), program_name);
331 show_usage (stderr, 1);
334 inbfd = bfd_openr (input_file, input_format);
336 bfd_fatal (input_file);
338 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
340 bfd_nonfatal (input_file);
341 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
343 list_matching_formats (matching);
349 if (output_format == NULL)
350 output_format = select_output_format (bfd_get_arch (inbfd),
351 bfd_get_mach (inbfd),
352 bfd_big_endian (inbfd));
354 assert (output_format != NULL);
356 /* Use the output file named on the command line if it exists.
357 Otherwise use the file named in the OUTPUT statement. */
358 if (output_file == NULL)
360 fprintf (stderr, _("%s: no name for output file\n"),
362 show_usage (stderr, 1);
365 outbfd = bfd_openw (output_file, output_format);
367 bfd_fatal (output_file);
368 if (! bfd_set_format (outbfd, bfd_object))
369 bfd_fatal (output_file);
371 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
373 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
375 _("%s: warning:input and output formats are not compatible\n"),
378 /* Move the values read from the command file into outbfd. */
379 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
380 *nlm_variable_header (outbfd) = var_hdr_struct;
381 *nlm_version_header (outbfd) = version_hdr_struct;
382 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
383 *nlm_extended_header (outbfd) = extended_hdr_struct;
385 /* Start copying the input BFD to the output BFD. */
386 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
387 bfd_fatal (bfd_get_filename (outbfd));
389 symsize = bfd_get_symtab_upper_bound (inbfd);
391 bfd_fatal (input_file);
392 symbols = (asymbol **) xmalloc (symsize);
393 symcount = bfd_canonicalize_symtab (inbfd, symbols);
395 bfd_fatal (input_file);
397 /* Make sure we have a .bss section. */
398 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
401 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
403 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
404 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
405 bfd_fatal (_("make .bss section"));
408 /* We store the original section names in the .nlmsections section,
409 so that programs which understand it can resurrect the original
410 sections from the NLM. We will put a pointer to .nlmsections in
411 the NLM header area. */
412 secsec = bfd_make_section (outbfd, ".nlmsections");
414 bfd_fatal (_("make .nlmsections section"));
415 if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
416 bfd_fatal (_("set .nlmsections flags"));
418 #ifdef NLMCONV_POWERPC
419 /* For PowerPC NetWare we need to build stubs for calls to undefined
420 symbols. Because each stub requires an entry in the TOC section
421 which must be at the same location as other entries in the TOC
422 section, we must do this before determining where the TOC section
423 goes in setup_sections. */
424 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
425 powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
428 /* Set up the sections. */
429 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
431 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
433 /* The .bss section immediately follows the .data section. */
434 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
435 if (data_sec != NULL)
439 vma = bfd_get_section_size_before_reloc (data_sec);
440 align = 1 << bss_sec->alignment_power;
441 add = ((vma + align - 1) &~ (align - 1)) - vma;
443 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
444 bfd_fatal (_("set .bss vma"));
447 bfd_size_type data_size;
449 data_size = bfd_get_section_size_before_reloc (data_sec);
450 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
451 bfd_fatal (_("set .data size"));
455 /* Adjust symbol information. */
456 inlead = bfd_get_symbol_leading_char (inbfd);
457 outlead = bfd_get_symbol_leading_char (outbfd);
462 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
465 for (i = 0; i < symcount; i++)
467 register asymbol *sym;
471 /* Add or remove a leading underscore. */
472 if (inlead != outlead)
476 if (bfd_asymbol_name (sym)[0] == inlead)
484 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
486 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
495 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
497 strcpy (new + 1, bfd_asymbol_name (sym));
502 /* NLM's have an uninitialized data section, but they do not
503 have a common section in the Unix sense. Move all common
504 symbols into the .bss section, and mark them as exported. */
505 if (bfd_is_com_section (bfd_get_section (sym)))
509 sym->section = bss_sec;
511 sym->value = bss_sec->_raw_size;
512 bss_sec->_raw_size += size;
513 align = 1 << bss_sec->alignment_power;
514 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
515 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
517 else if (bfd_get_section (sym)->output_section != NULL)
519 /* Move the symbol into the output section. */
520 sym->value += bfd_get_section (sym)->output_offset;
521 sym->section = bfd_get_section (sym)->output_section;
522 /* This is no longer a section symbol. */
523 sym->flags &=~ BSF_SECTION_SYM;
526 /* Force _edata and _end to be defined. This would normally be
527 done by the linker, but the manipulation of the common
528 symbols will confuse it. */
529 if ((sym->flags & BSF_DEBUGGING) == 0
530 && bfd_asymbol_name (sym)[0] == '_'
531 && bfd_is_und_section (bfd_get_section (sym)))
533 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
535 sym->section = bss_sec;
538 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
540 sym->section = bss_sec;
544 #ifdef NLMCONV_POWERPC
545 /* For PowerPC NetWare, we define __GOT0. This is the start
546 of the .got section. */
547 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
548 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
552 got_sec = bfd_get_section_by_name (inbfd, ".got");
553 assert (got_sec != (asection *) NULL);
554 sym->value = got_sec->output_offset;
555 sym->section = got_sec->output_section;
560 /* If this is a global symbol, check the export list. */
561 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
563 register struct string_list *l;
566 /* Unfortunately, a symbol can appear multiple times on the
567 export list, with and without prefixes. */
569 for (l = export_symbols; l != NULL; l = l->next)
571 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
577 zbase = strchr (l->string, '@');
579 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
581 /* We must add a symbol with this prefix. */
582 if (newsymcount >= newsymalloc)
585 newsyms = ((asymbol **)
586 xrealloc ((PTR) newsyms,
588 * sizeof (asymbol *))));
590 newsyms[newsymcount] =
591 (asymbol *) xmalloc (sizeof (asymbol));
592 *newsyms[newsymcount] = *sym;
593 newsyms[newsymcount]->name = l->string;
600 /* The unmodified symbol is actually not exported at
602 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
603 sym->flags |= BSF_LOCAL;
607 /* If it's an undefined symbol, see if it's on the import list.
608 Change the prefix if necessary. */
609 if (bfd_is_und_section (bfd_get_section (sym)))
611 register struct string_list *l;
613 for (l = import_symbols; l != NULL; l = l->next)
615 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
621 zbase = strchr (l->string, '@');
623 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
625 sym->name = l->string;
632 _("%s: warning: symbol %s imported but not in import list\n"),
633 program_name, bfd_asymbol_name (sym));
636 /* See if it's one of the special named symbols. */
637 if ((sym->flags & BSF_DEBUGGING) == 0)
641 /* FIXME: If these symbols are not in the .text section, we
642 add the .text section size to the value. This may not be
643 correct for all targets. I'm not sure how this should
644 really be handled. */
645 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
647 val = bfd_asymbol_value (sym);
648 if (bfd_get_section (sym) == data_sec
649 && text_sec != (asection *) NULL)
650 val += bfd_section_size (outbfd, text_sec);
651 if (! bfd_set_start_address (outbfd, val))
652 bfd_fatal (_("set start address"));
655 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
657 val = bfd_asymbol_value (sym);
658 if (bfd_get_section (sym) == data_sec
659 && text_sec != (asection *) NULL)
660 val += bfd_section_size (outbfd, text_sec);
661 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
664 if (check_procedure != NULL
665 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
667 val = bfd_asymbol_value (sym);
668 if (bfd_get_section (sym) == data_sec
669 && text_sec != (asection *) NULL)
670 val += bfd_section_size (outbfd, text_sec);
671 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
679 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
681 /* FIXME: If any relocs referring to _end use inplace addends,
682 then I think they need to be updated. This is handled by
683 i386_mangle_relocs. Is it needed for any other object
687 if (newsymcount == 0)
691 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
692 * sizeof (asymbol *));
693 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
694 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
695 outsyms[symcount + newsymcount] = NULL;
698 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
701 fprintf (stderr, _("%s: warning: START procedure %s not defined\n"),
702 program_name, start_procedure);
704 fprintf (stderr, _("%s: warning: EXIT procedure %s not defined\n"),
705 program_name, exit_procedure);
706 if (check_procedure != NULL
708 fprintf (stderr, _("%s: warning: CHECK procedure %s not defined\n"),
709 program_name, check_procedure);
711 /* Add additional sections required for the header information. */
712 if (custom_file != NULL)
714 custom_data = fopen (custom_file, "r");
715 if (custom_data == NULL
716 || fstat (fileno (custom_data), &st) < 0)
718 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
724 custom_size = st.st_size;
725 custom_section = bfd_make_section (outbfd, ".nlmcustom");
726 if (custom_section == NULL
727 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
728 || ! bfd_set_section_flags (outbfd, custom_section,
730 bfd_fatal (_("custom section"));
733 if (help_file != NULL)
735 help_data = fopen (help_file, "r");
736 if (help_data == NULL
737 || fstat (fileno (help_data), &st) < 0)
739 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
745 help_size = st.st_size;
746 help_section = bfd_make_section (outbfd, ".nlmhelp");
747 if (help_section == NULL
748 || ! bfd_set_section_size (outbfd, help_section, help_size)
749 || ! bfd_set_section_flags (outbfd, help_section,
751 bfd_fatal (_("help section"));
752 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
755 if (message_file != NULL)
757 message_data = fopen (message_file, "r");
758 if (message_data == NULL
759 || fstat (fileno (message_data), &st) < 0)
761 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
767 message_size = st.st_size;
768 message_section = bfd_make_section (outbfd, ".nlmmessages");
769 if (message_section == NULL
770 || ! bfd_set_section_size (outbfd, message_section, message_size)
771 || ! bfd_set_section_flags (outbfd, message_section,
773 bfd_fatal (_("message section"));
774 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
779 struct string_list *l;
782 for (l = modules; l != NULL; l = l->next)
783 module_size += strlen (l->string) + 1;
784 module_section = bfd_make_section (outbfd, ".nlmmodules");
785 if (module_section == NULL
786 || ! bfd_set_section_size (outbfd, module_section, module_size)
787 || ! bfd_set_section_flags (outbfd, module_section,
789 bfd_fatal (_("module section"));
791 if (rpc_file != NULL)
793 rpc_data = fopen (rpc_file, "r");
795 || fstat (fileno (rpc_data), &st) < 0)
797 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
803 rpc_size = st.st_size;
804 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
805 if (rpc_section == NULL
806 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
807 || ! bfd_set_section_flags (outbfd, rpc_section,
809 bfd_fatal (_("rpc section"));
810 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
813 if (sharelib_file != NULL)
815 sharedbfd = bfd_openr (sharelib_file, output_format);
816 if (sharedbfd == NULL
817 || ! bfd_check_format (sharedbfd, bfd_object))
819 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
820 bfd_errmsg (bfd_get_error ()));
821 sharelib_file = NULL;
825 sharedhdr = *nlm_fixed_header (sharedbfd);
826 bfd_close (sharedbfd);
827 shared_data = fopen (sharelib_file, "r");
828 if (shared_data == NULL
829 || (fstat (fileno (shared_data), &st) < 0))
831 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
833 sharelib_file = NULL;
837 /* If we were clever, we could just copy out the
838 sections of the shared library which we actually
839 need. However, we would have to figure out the sizes
840 of the external and public information, and that can
841 not be done without reading through them. */
842 if (sharedhdr.uninitializedDataSize > 0)
844 /* There is no place to record this information. */
846 _("%s:%s: warning: shared libraries can not have uninitialized data\n"),
847 program_name, sharelib_file);
849 shared_offset = st.st_size;
850 if (shared_offset > (size_t) sharedhdr.codeImageOffset)
851 shared_offset = sharedhdr.codeImageOffset;
852 if (shared_offset > (size_t) sharedhdr.dataImageOffset)
853 shared_offset = sharedhdr.dataImageOffset;
854 if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
855 shared_offset = sharedhdr.relocationFixupOffset;
856 if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
857 shared_offset = sharedhdr.externalReferencesOffset;
858 if (shared_offset > (size_t) sharedhdr.publicsOffset)
859 shared_offset = sharedhdr.publicsOffset;
860 shared_size = st.st_size - shared_offset;
861 shared_section = bfd_make_section (outbfd, ".nlmshared");
862 if (shared_section == NULL
863 || ! bfd_set_section_size (outbfd, shared_section,
865 || ! bfd_set_section_flags (outbfd, shared_section,
867 bfd_fatal (_("shared section"));
868 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
873 /* Check whether a version was given. */
874 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
875 fprintf (stderr, _("%s: warning: No version number given\n"),
878 /* At least for now, always create an extended header, because that
879 is what NLMLINK does. */
880 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
882 strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
884 /* If the date was not given, force it in. */
885 if (nlm_version_header (outbfd)->month == 0
886 && nlm_version_header (outbfd)->day == 0
887 && nlm_version_header (outbfd)->year == 0)
893 ptm = localtime (&now);
894 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
895 nlm_version_header (outbfd)->day = ptm->tm_mday;
896 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
897 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
900 #ifdef NLMCONV_POWERPC
901 /* Resolve the stubs we build for PowerPC NetWare. */
902 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
903 powerpc_resolve_stubs (inbfd, outbfd);
906 /* Copy over the sections. */
907 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
909 /* Finish up the header information. */
910 if (custom_file != NULL)
914 data = xmalloc (custom_size);
915 if (fread (data, 1, custom_size, custom_data) != custom_size)
916 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, custom_file,
920 if (! bfd_set_section_contents (outbfd, custom_section, data,
921 (file_ptr) 0, custom_size))
922 bfd_fatal (_("custom section"));
923 nlm_fixed_header (outbfd)->customDataOffset =
924 custom_section->filepos;
925 nlm_fixed_header (outbfd)->customDataSize = custom_size;
931 /* As a special hack, the backend recognizes a debugInfoOffset
932 of -1 to mean that it should not output any debugging
933 information. This can not be handling by fiddling with the
934 symbol table because exported symbols appear in both the
935 export information and the debugging information. */
936 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
938 if (map_file != NULL)
940 _("%s: warning: MAP and FULLMAP are not supported; try ld -M\n"),
942 if (help_file != NULL)
946 data = xmalloc (help_size);
947 if (fread (data, 1, help_size, help_data) != help_size)
948 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, help_file,
952 if (! bfd_set_section_contents (outbfd, help_section, data,
953 (file_ptr) 0, help_size))
954 bfd_fatal (_("help section"));
955 nlm_extended_header (outbfd)->helpFileOffset =
956 help_section->filepos;
957 nlm_extended_header (outbfd)->helpFileLength = help_size;
961 if (message_file != NULL)
965 data = xmalloc (message_size);
966 if (fread (data, 1, message_size, message_data) != message_size)
967 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, message_file,
971 if (! bfd_set_section_contents (outbfd, message_section, data,
972 (file_ptr) 0, message_size))
973 bfd_fatal (_("message section"));
974 nlm_extended_header (outbfd)->messageFileOffset =
975 message_section->filepos;
976 nlm_extended_header (outbfd)->messageFileLength = message_size;
978 /* FIXME: Are these offsets correct on all platforms? Are
979 they 32 bits on all platforms? What endianness? */
980 nlm_extended_header (outbfd)->languageID =
981 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
982 nlm_extended_header (outbfd)->messageCount =
983 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
991 struct string_list *l;
994 data = xmalloc (module_size);
996 set = (unsigned char *) data;
997 for (l = modules; l != NULL; l = l->next)
999 *set = strlen (l->string);
1000 strncpy (set + 1, l->string, *set);
1004 if (! bfd_set_section_contents (outbfd, module_section, data,
1005 (file_ptr) 0, module_size))
1006 bfd_fatal (_("module section"));
1007 nlm_fixed_header (outbfd)->moduleDependencyOffset =
1008 module_section->filepos;
1009 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
1011 if (rpc_file != NULL)
1015 data = xmalloc (rpc_size);
1016 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
1017 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, rpc_file,
1021 if (! bfd_set_section_contents (outbfd, rpc_section, data,
1022 (file_ptr) 0, rpc_size))
1023 bfd_fatal (_("rpc section"));
1024 nlm_extended_header (outbfd)->RPCDataOffset =
1025 rpc_section->filepos;
1026 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1030 if (sharelib_file != NULL)
1034 data = xmalloc (shared_size);
1035 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1036 || fread (data, 1, shared_size, shared_data) != shared_size)
1037 fprintf (stderr, _("%s:%s: read: %s\n"), program_name, sharelib_file,
1041 if (! bfd_set_section_contents (outbfd, shared_section, data,
1042 (file_ptr) 0, shared_size))
1043 bfd_fatal (_("shared section"));
1045 nlm_extended_header (outbfd)->sharedCodeOffset =
1046 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1047 nlm_extended_header (outbfd)->sharedCodeLength =
1048 sharedhdr.codeImageSize;
1049 nlm_extended_header (outbfd)->sharedDataOffset =
1050 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1051 nlm_extended_header (outbfd)->sharedDataLength =
1052 sharedhdr.dataImageSize;
1053 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1054 (sharedhdr.relocationFixupOffset
1056 + shared_section->filepos);
1057 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1058 sharedhdr.numberOfRelocationFixups;
1059 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1060 (sharedhdr.externalReferencesOffset
1062 + shared_section->filepos);
1063 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1064 sharedhdr.numberOfExternalReferences;
1065 nlm_extended_header (outbfd)->sharedPublicsOffset =
1066 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1067 nlm_extended_header (outbfd)->sharedPublicsCount =
1068 sharedhdr.numberOfPublics;
1069 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1070 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1071 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1072 sharedhdr.numberOfDebugRecords;
1073 nlm_extended_header (outbfd)->SharedInitializationOffset =
1074 sharedhdr.codeStartOffset;
1075 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1076 sharedhdr.exitProcedureOffset;
1079 len = strlen (output_file);
1080 if (len > NLM_MODULE_NAME_SIZE - 2)
1081 len = NLM_MODULE_NAME_SIZE - 2;
1082 nlm_fixed_header (outbfd)->moduleName[0] = len;
1084 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1085 NLM_MODULE_NAME_SIZE - 2);
1086 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1087 for (modname = nlm_fixed_header (outbfd)->moduleName;
1090 if (islower ((unsigned char) *modname))
1091 *modname = toupper (*modname);
1093 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1094 NLM_OLD_THREAD_NAME_LENGTH);
1096 nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1097 nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1099 if (! bfd_close (outbfd))
1100 bfd_fatal (output_file);
1101 if (! bfd_close (inbfd))
1102 bfd_fatal (input_file);
1104 if (unlink_on_exit != NULL)
1105 unlink (unlink_on_exit);
1110 /* Display a help message and exit. */
1115 printf (_("%s: Convert an object file into a NetWare Loadable Module\n"),
1117 show_usage (stdout, 0);
1120 /* Show a usage message and exit. */
1123 show_usage (file, status)
1128 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1129 [--input-target=bfdname] [--output-target=bfdname]\n\
1130 [--header-file=file] [--linker=linker] [--debug]\n\
1131 [--help] [--version]\n\
1132 [in-file [out-file]]\n"),
1135 fprintf (file, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1139 /* Select the output format based on the input architecture, machine,
1140 and endianness. This chooses the appropriate NLM target. */
1143 select_output_format (arch, mach, bigendian)
1144 enum bfd_architecture arch;
1152 return "nlm32-i386";
1154 #ifdef NLMCONV_SPARC
1155 case bfd_arch_sparc:
1156 return "nlm32-sparc";
1158 #ifdef NLMCONV_ALPHA
1159 case bfd_arch_alpha:
1160 return "nlm32-alpha";
1162 #ifdef NLMCONV_POWERPC
1163 case bfd_arch_powerpc:
1164 return "nlm32-powerpc";
1167 fprintf (stderr, _("%s: support not compiled in for %s\n"),
1168 program_name, bfd_printable_arch_mach (arch, mach));
1170 /* Avoid warning. */
1176 /* The BFD sections are copied in two passes. This function selects
1177 the output section for each input section, and sets up the section
1181 setup_sections (inbfd, insec, data_ptr)
1186 bfd *outbfd = (bfd *) data_ptr;
1188 const char *outname;
1191 bfd_size_type align;
1193 bfd_size_type secsecsize;
1195 f = bfd_get_section_flags (inbfd, insec);
1197 outname = NLM_CODE_NAME;
1198 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1199 outname = NLM_INITIALIZED_DATA_NAME;
1200 else if (f & SEC_ALLOC)
1201 outname = NLM_UNINITIALIZED_DATA_NAME;
1203 outname = bfd_section_name (inbfd, insec);
1205 outsec = bfd_get_section_by_name (outbfd, outname);
1208 outsec = bfd_make_section (outbfd, outname);
1210 bfd_fatal (_("make section"));
1213 insec->output_section = outsec;
1215 offset = bfd_section_size (outbfd, outsec);
1216 align = 1 << bfd_section_alignment (inbfd, insec);
1217 add = ((offset + align - 1) &~ (align - 1)) - offset;
1218 insec->output_offset = offset + add;
1220 if (! bfd_set_section_size (outbfd, outsec,
1221 (bfd_section_size (outbfd, outsec)
1222 + bfd_section_size (inbfd, insec)
1224 bfd_fatal (_("set section size"));
1226 if ((bfd_section_alignment (inbfd, insec)
1227 > bfd_section_alignment (outbfd, outsec))
1228 && ! bfd_set_section_alignment (outbfd, outsec,
1229 bfd_section_alignment (inbfd, insec)))
1230 bfd_fatal (_("set section alignment"));
1232 if (! bfd_set_section_flags (outbfd, outsec,
1233 f | bfd_get_section_flags (outbfd, outsec)))
1234 bfd_fatal (_("set section flags"));
1236 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1238 /* For each input section we allocate space for an entry in
1240 secsecsize = bfd_section_size (outbfd, secsec);
1241 secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1242 secsecsize = (secsecsize + 3) &~ 3;
1244 if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1245 bfd_fatal (_("set .nlmsections size"));
1248 /* Copy the section contents. */
1251 copy_sections (inbfd, insec, data_ptr)
1256 static bfd_size_type secsecoff = 0;
1257 bfd *outbfd = (bfd *) data_ptr;
1266 inname = bfd_section_name (inbfd, insec);
1268 outsec = insec->output_section;
1269 assert (outsec != NULL);
1271 size = bfd_get_section_size_before_reloc (insec);
1273 /* FIXME: Why are these necessary? */
1274 insec->_cooked_size = insec->_raw_size;
1275 insec->reloc_done = true;
1277 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1281 contents = xmalloc (size);
1282 if (! bfd_get_section_contents (inbfd, insec, contents,
1283 (file_ptr) 0, size))
1284 bfd_fatal (bfd_get_filename (inbfd));
1287 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1289 bfd_fatal (bfd_get_filename (inbfd));
1290 if (reloc_size != 0)
1295 relocs = (arelent **) xmalloc (reloc_size);
1296 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1297 if (reloc_count < 0)
1298 bfd_fatal (bfd_get_filename (inbfd));
1299 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1302 /* FIXME: refers to internal BFD fields. */
1303 if (outsec->orelocation != (arelent **) NULL)
1305 bfd_size_type total_count;
1308 total_count = reloc_count + outsec->reloc_count;
1309 combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1310 memcpy (combined, outsec->orelocation,
1311 outsec->reloc_count * sizeof (arelent *));
1312 memcpy (combined + outsec->reloc_count, relocs,
1313 (size_t) (reloc_count * sizeof (arelent *)));
1314 free (outsec->orelocation);
1315 reloc_count = total_count;
1319 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1322 if (contents != NULL)
1324 if (! bfd_set_section_contents (outbfd, outsec, contents,
1325 insec->output_offset, size))
1326 bfd_fatal (bfd_get_filename (outbfd));
1330 /* Add this section to .nlmsections. */
1331 if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
1332 strlen (inname) + 1))
1333 bfd_fatal (_("set .nlmsection contents"));
1334 secsecoff += strlen (inname) + 1;
1336 add = ((secsecoff + 3) &~ 3) - secsecoff;
1339 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1340 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1341 bfd_fatal (_("set .nlmsection contents"));
1345 if (contents != NULL)
1346 bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1348 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1349 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1350 bfd_fatal (_("set .nlmsection contents"));
1353 bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1354 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1355 bfd_fatal (_("set .nlmsection contents"));
1359 /* Some, perhaps all, NetWare targets require changing the relocs used
1360 by the input formats. */
1363 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 switch (bfd_get_arch (outbfd))
1376 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1377 contents, contents_size);
1380 #ifdef NLMCONV_ALPHA
1381 case bfd_arch_alpha:
1382 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1383 contents, contents_size);
1386 #ifdef NLMCONV_POWERPC
1387 case bfd_arch_powerpc:
1388 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1389 contents, contents_size);
1393 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1394 contents, contents_size);
1399 /* By default all we need to do for relocs is change the address by
1400 the output_offset. */
1404 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1408 arelent ***relocs_ptr;
1409 long *reloc_count_ptr;
1411 bfd_size_type contents_size;
1413 if (insec->output_offset != 0)
1416 register arelent **relocs;
1419 reloc_count = *reloc_count_ptr;
1420 relocs = *relocs_ptr;
1421 for (i = 0; i < reloc_count; i++, relocs++)
1422 (*relocs)->address += insec->output_offset;
1428 /* NetWare on the i386 supports a restricted set of relocs, which are
1429 different from those used on other i386 targets. This routine
1430 converts the relocs. It is, obviously, very target dependent. At
1431 the moment, the nlm32-i386 backend performs similar translations;
1432 however, it is more reliable and efficient to do them here. */
1434 static reloc_howto_type nlm_i386_pcrel_howto =
1435 HOWTO (1, /* type */
1437 2, /* size (0 = byte, 1 = short, 2 = long) */
1439 true, /* pc_relative */
1441 complain_overflow_signed, /* complain_on_overflow */
1442 0, /* special_function */
1443 "DISP32", /* name */
1444 true, /* partial_inplace */
1445 0xffffffff, /* src_mask */
1446 0xffffffff, /* dst_mask */
1447 true); /* pcrel_offset */
1450 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1454 arelent ***relocs_ptr;
1455 long *reloc_count_ptr;
1457 bfd_size_type contents_size;
1459 long reloc_count, i;
1462 reloc_count = *reloc_count_ptr;
1463 relocs = *relocs_ptr;
1464 for (i = 0; i < reloc_count; i++)
1468 bfd_size_type address;
1472 sym = *rel->sym_ptr_ptr;
1474 /* We're moving the relocs from the input section to the output
1475 section, so we must adjust the address accordingly. */
1476 address = rel->address;
1477 rel->address += insec->output_offset;
1479 /* Note that no serious harm will ensue if we fail to change a
1480 reloc. The backend will fail when writing out the reloc. */
1482 /* Make sure this reloc is within the data we have. We use only
1483 4 byte relocs here, so we insist on having 4 bytes. */
1484 if (address + 4 > contents_size)
1487 /* A PC relative reloc entirely within a single section is
1488 completely unnecessary. This can be generated by ld -r. */
1489 if (sym == insec->symbol
1490 && rel->howto != NULL
1491 && rel->howto->pc_relative
1492 && ! rel->howto->pcrel_offset)
1496 memmove (relocs, relocs + 1,
1497 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1501 /* Get the amount the relocation will add in. */
1502 addend = rel->addend + sym->value;
1504 /* NetWare doesn't support PC relative relocs against defined
1505 symbols, so we have to eliminate them by doing the relocation
1506 now. We can only do this if the reloc is within a single
1508 if (rel->howto != NULL
1509 && rel->howto->pc_relative
1510 && bfd_get_section (sym) == insec->output_section)
1514 if (rel->howto->pcrel_offset)
1517 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1519 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1523 memmove (relocs, relocs + 1,
1524 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1528 /* NetWare doesn't support reloc addends, so we get rid of them
1529 here by simply adding them into the object data. We handle
1530 the symbol value, if any, the same way. */
1532 && rel->howto != NULL
1533 && rel->howto->rightshift == 0
1534 && rel->howto->size == 2
1535 && rel->howto->bitsize == 32
1536 && rel->howto->bitpos == 0
1537 && rel->howto->src_mask == 0xffffffff
1538 && rel->howto->dst_mask == 0xffffffff)
1542 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1544 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1546 /* Adjust the reloc for the changes we just made. */
1548 if (! bfd_is_und_section (bfd_get_section (sym)))
1549 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1552 /* NetWare uses a reloc with pcrel_offset set. We adjust
1553 pc_relative relocs accordingly. We are going to change the
1554 howto field, so we can only do this if the current one is
1555 compatible. We should check that special_function is NULL
1556 here, but at the moment coff-i386 uses a special_function
1557 which does not affect what we are doing here. */
1558 if (rel->howto != NULL
1559 && rel->howto->pc_relative
1560 && ! rel->howto->pcrel_offset
1561 && rel->howto->rightshift == 0
1562 && rel->howto->size == 2
1563 && rel->howto->bitsize == 32
1564 && rel->howto->bitpos == 0
1565 && rel->howto->src_mask == 0xffffffff
1566 && rel->howto->dst_mask == 0xffffffff)
1570 /* When pcrel_offset is not set, it means that the negative
1571 of the address of the memory location is stored in the
1572 memory location. We must add it back in. */
1573 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1575 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1577 /* We must change to a new howto. */
1578 rel->howto = &nlm_i386_pcrel_howto;
1583 #endif /* NLMCONV_I386 */
1585 #ifdef NLMCONV_ALPHA
1587 /* On the Alpha the first reloc for every section must be a special
1588 relocs which hold the GP address. Also, the first reloc in the
1589 file must be a special reloc which holds the address of the .lita
1592 static reloc_howto_type nlm32_alpha_nw_howto =
1593 HOWTO (ALPHA_R_NW_RELOC, /* type */
1595 0, /* size (0 = byte, 1 = short, 2 = long) */
1597 false, /* pc_relative */
1599 complain_overflow_dont, /* complain_on_overflow */
1600 0, /* special_function */
1601 "NW_RELOC", /* name */
1602 false, /* partial_inplace */
1605 false); /* pcrel_offset */
1609 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1613 register arelent ***relocs_ptr;
1614 long *reloc_count_ptr;
1616 bfd_size_type contents_size;
1618 long old_reloc_count;
1619 arelent **old_relocs;
1620 register arelent **relocs;
1622 old_reloc_count = *reloc_count_ptr;
1623 old_relocs = *relocs_ptr;
1624 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1625 *relocs_ptr = relocs;
1627 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1630 asection *lita_section;
1632 inbfd = insec->owner;
1633 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1634 if (lita_section != (asection *) NULL)
1636 nlm_alpha_backend_data (outbfd)->lita_address =
1637 bfd_get_section_vma (inbfd, lita_section);
1638 nlm_alpha_backend_data (outbfd)->lita_size =
1639 bfd_section_size (inbfd, lita_section);
1643 /* Avoid outputting this reloc again. */
1644 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1647 *relocs = (arelent *) xmalloc (sizeof (arelent));
1648 (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1649 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1650 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1651 (*relocs)->howto = &nlm32_alpha_nw_howto;
1653 ++(*reloc_count_ptr);
1656 /* Get the GP value from bfd. */
1657 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1658 nlm_alpha_backend_data (outbfd)->gp =
1659 bfd_ecoff_get_gp_value (insec->owner);
1661 *relocs = (arelent *) xmalloc (sizeof (arelent));
1662 (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1663 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1664 (*relocs)->addend = 0;
1665 (*relocs)->howto = &nlm32_alpha_nw_howto;
1667 ++(*reloc_count_ptr);
1669 memcpy ((PTR) relocs, (PTR) old_relocs,
1670 (size_t) old_reloc_count * sizeof (arelent *));
1671 relocs[old_reloc_count] = (arelent *) NULL;
1675 if (insec->output_offset != 0)
1677 register bfd_size_type i;
1679 for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
1680 (*relocs)->address += insec->output_offset;
1684 #endif /* NLMCONV_ALPHA */
1686 #ifdef NLMCONV_POWERPC
1688 /* We keep a linked list of stubs which we must build. Because BFD
1689 requires us to know the sizes of all sections before we can set the
1690 contents of any, we must figure out which stubs we want to build
1691 before we can actually build any of them. */
1695 /* Next stub in linked list. */
1696 struct powerpc_stub *next;
1698 /* Symbol whose value is the start of the stub. This is a symbol
1699 whose name begins with `.'. */
1702 /* Symbol we are going to create a reloc against. This is a symbol
1703 with the same name as START but without the leading `.'. */
1706 /* The TOC index for this stub. This is the index into the TOC
1707 section at which the reloc is created. */
1708 unsigned int toc_index;
1711 /* The linked list of stubs. */
1713 static struct powerpc_stub *powerpc_stubs;
1715 /* This is what a stub looks like. The first instruction will get
1716 adjusted with the correct TOC index. */
1718 static unsigned long powerpc_stub_insns[] =
1720 0x81820000, /* lwz r12,0(r2) */
1721 0x90410014, /* stw r2,20(r1) */
1722 0x800c0000, /* lwz r0,0(r12) */
1723 0x804c0004, /* lwz r2,r(r12) */
1724 0x7c0903a6, /* mtctr r0 */
1725 0x4e800420, /* bctr */
1726 0, /* Traceback table. */
1731 #define POWERPC_STUB_INSN_COUNT \
1732 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1734 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1736 /* Each stub uses a four byte TOC entry. */
1737 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1739 /* The original size of the .got section. */
1740 static bfd_size_type powerpc_initial_got_size;
1742 /* Look for all undefined symbols beginning with `.', and prepare to
1743 build a stub for each one. */
1746 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1749 asymbol ***symbols_ptr;
1754 unsigned int got_base;
1759 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1760 the section to prevent copy_sections from reading from it. */
1761 stub_sec = bfd_make_section (inbfd, ".stubs");
1762 if (stub_sec == (asection *) NULL
1763 || ! bfd_set_section_flags (inbfd, stub_sec,
1768 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1769 bfd_fatal (".stubs");
1771 /* Get the TOC section, which is named .got. */
1772 got_sec = bfd_get_section_by_name (inbfd, ".got");
1773 if (got_sec == (asection *) NULL)
1775 got_sec = bfd_make_section (inbfd, ".got");
1776 if (got_sec == (asection *) NULL
1777 || ! bfd_set_section_flags (inbfd, got_sec,
1782 | SEC_HAS_CONTENTS))
1783 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1787 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1788 got_base = powerpc_initial_got_size;
1789 got_base = (got_base + 3) &~ 3;
1793 symcount = *symcount_ptr;
1794 for (i = 0; i < symcount; i++)
1799 struct powerpc_stub *item;
1801 sym = (*symbols_ptr)[i];
1803 /* We must make a stub for every undefined symbol whose name
1805 if (bfd_asymbol_name (sym)[0] != '.'
1806 || ! bfd_is_und_section (bfd_get_section (sym)))
1809 /* Make a new undefined symbol with the same name but without
1811 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1813 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1814 strcpy (newname, bfd_asymbol_name (sym) + 1);
1815 newsym->name = newname;
1817 /* Define the `.' symbol to be in the stub section. */
1818 sym->section = stub_sec;
1819 sym->value = stubcount * POWERPC_STUB_SIZE;
1820 /* We set the BSF_DYNAMIC flag here so that we can check it when
1821 we are mangling relocs. FIXME: This is a hack. */
1822 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1824 /* Add this stub to the linked list. */
1825 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1827 item->reloc = newsym;
1828 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1830 item->next = powerpc_stubs;
1831 powerpc_stubs = item;
1839 struct powerpc_stub *l;
1841 /* Add the new symbols we just created to the symbol table. */
1842 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1843 ((symcount + stubcount)
1844 * sizeof (asymbol)));
1845 *symcount_ptr += stubcount;
1846 s = &(*symbols_ptr)[symcount];
1847 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1850 /* Set the size of the .stubs section and increase the size of
1851 the .got section. */
1852 if (! bfd_set_section_size (inbfd, stub_sec,
1853 stubcount * POWERPC_STUB_SIZE)
1854 || ! bfd_set_section_size (inbfd, got_sec,
1857 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1858 bfd_fatal (_("stub section sizes"));
1862 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1863 of the output section, and create new relocs in the TOC. */
1866 powerpc_resolve_stubs (inbfd, outbfd)
1870 bfd_byte buf[POWERPC_STUB_SIZE];
1872 unsigned int stubcount;
1876 struct powerpc_stub *l;
1878 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1881 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1882 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1884 got_sec = bfd_get_section_by_name (inbfd, ".got");
1885 assert (got_sec != (asection *) NULL);
1886 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1889 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1891 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1894 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1898 /* Adjust the first instruction to use the right TOC index. */
1899 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1901 /* Write this stub out. */
1902 if (! bfd_set_section_contents (outbfd,
1903 bfd_get_section (l->start),
1907 bfd_fatal (_("writing stub"));
1909 /* Create a new reloc for the TOC entry. */
1910 reloc = (arelent *) xmalloc (sizeof (arelent));
1911 reloc->sym_ptr_ptr = &l->reloc;
1912 reloc->address = l->toc_index + got_sec->output_offset;
1914 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1919 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1922 /* Adjust relocation entries for PowerPC NetWare. We do not output
1923 TOC relocations. The object code already contains the offset from
1924 the TOC pointer. When the function is called, the TOC register,
1925 r2, will be set to the correct TOC value, so there is no need for
1926 any further reloc. */
1930 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1934 register arelent ***relocs_ptr;
1935 long *reloc_count_ptr;
1937 bfd_size_type contents_size;
1939 reloc_howto_type *toc_howto;
1941 register arelent **relocs;
1944 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1945 if (toc_howto == (reloc_howto_type *) NULL)
1948 /* If this is the .got section, clear out all the contents beyond
1949 the initial size. We must do this here because copy_sections is
1950 going to write out whatever we return in the contents field. */
1951 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1952 memset (contents + powerpc_initial_got_size, 0,
1953 (size_t) (bfd_get_section_size_after_reloc (insec)
1954 - powerpc_initial_got_size));
1956 reloc_count = *reloc_count_ptr;
1957 relocs = *relocs_ptr;
1958 for (i = 0; i < reloc_count; i++)
1965 sym = *rel->sym_ptr_ptr;
1967 /* Convert any relocs against the .bss section into relocs
1968 against the .data section. */
1969 if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1970 NLM_UNINITIALIZED_DATA_NAME) == 0)
1974 datasec = bfd_get_section_by_name (outbfd,
1975 NLM_INITIALIZED_DATA_NAME);
1976 if (datasec != NULL)
1978 rel->addend += (bfd_get_section_vma (outbfd,
1979 bfd_get_section (sym))
1981 rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1982 sym = *rel->sym_ptr_ptr;
1986 /* We must be able to resolve all PC relative relocs at this
1987 point. If we get a branch to an undefined symbol we build a
1988 stub, since NetWare will resolve undefined symbols into a
1989 pointer to a function descriptor. */
1990 if (rel->howto->pc_relative)
1992 /* This check for whether a symbol is in the same section as
1993 the reloc will be wrong if there is a PC relative reloc
1994 between two sections both of which were placed in the
1995 same output section. This should not happen. */
1996 if (bfd_get_section (sym) != insec->output_section)
1997 fprintf (stderr, _("%s: unresolved PC relative reloc against %s\n"),
1998 program_name, bfd_asymbol_name (sym));
2003 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
2004 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
2005 val = ((val &~ rel->howto->dst_mask)
2006 | (((val & rel->howto->src_mask)
2007 + (sym->value - rel->address)
2009 & rel->howto->dst_mask));
2010 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2012 /* If this reloc is against an stubbed symbol and the
2015 then we replace the next instruction with
2017 This reloads the TOC pointer after a stub call. */
2018 if (bfd_asymbol_name (sym)[0] == '.'
2019 && (sym->flags & BSF_DYNAMIC) != 0
2020 && (bfd_get_32 (outbfd,
2021 (bfd_byte *) contents + rel->address + 4)
2022 == 0x4ffffb82)) /* cror 31,31,31 */
2023 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
2024 (bfd_byte *) contents + rel->address + 4);
2028 memmove (relocs, relocs + 1,
2029 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
2034 /* When considering a TOC reloc, we do not want to include the
2035 symbol value. The symbol will be start of the TOC section
2036 (which is named .got). We do want to include the addend. */
2037 if (rel->howto == toc_howto)
2040 sym_value = sym->value;
2042 /* If this is a relocation against a symbol with a value, or
2043 there is a reloc addend, we need to update the addend in the
2045 if (sym_value + rel->addend != 0)
2049 switch (rel->howto->size)
2052 val = bfd_get_16 (outbfd,
2053 (bfd_byte *) contents + rel->address);
2054 val = ((val &~ rel->howto->dst_mask)
2055 | (((val & rel->howto->src_mask)
2058 & rel->howto->dst_mask));
2059 if ((bfd_signed_vma) val < - 0x8000
2060 || (bfd_signed_vma) val >= 0x8000)
2062 _("%s: overflow when adjusting relocation against %s\n"),
2063 program_name, bfd_asymbol_name (sym));
2064 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2068 val = bfd_get_32 (outbfd,
2069 (bfd_byte *) contents + rel->address);
2070 val = ((val &~ rel->howto->dst_mask)
2071 | (((val & rel->howto->src_mask)
2074 & rel->howto->dst_mask));
2075 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2082 if (! bfd_is_und_section (bfd_get_section (sym)))
2083 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2087 /* Now that we have incorporated the addend, remove any TOC
2089 if (rel->howto == toc_howto)
2093 memmove (relocs, relocs + 1,
2094 (size_t) ((reloc_count - i) * sizeof (arelent *)));
2098 rel->address += insec->output_offset;
2102 #endif /* NLMCONV_POWERPC */
2104 /* Name of linker. */
2106 #define LD_NAME "ld"
2109 /* Temporary file name base. */
2110 static char *temp_filename;
2112 /* The user has specified several input files. Invoke the linker to
2113 link them all together, and convert and delete the resulting output
2117 link_inputs (inputs, ld)
2118 struct string_list *inputs;
2122 struct string_list *q;
2131 for (q = inputs; q != NULL; q = q->next)
2134 argv = (char **) alloca ((c + 5) * sizeof(char *));
2141 /* Find the linker to invoke based on how nlmconv was run. */
2142 p = program_name + strlen (program_name);
2143 while (p != program_name)
2147 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2148 memcpy (ld, program_name, p - program_name);
2149 strcpy (ld + (p - program_name), LD_NAME);
2158 ld = (char *) LD_NAME;
2160 temp_filename = choose_temp_base ();
2162 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2163 sprintf (unlink_on_exit, "%s.O", temp_filename);
2166 argv[1] = (char *) "-Ur";
2167 argv[2] = (char *) "-o";
2168 argv[3] = unlink_on_exit;
2170 for (q = inputs; q != NULL; q = q->next, i++)
2171 argv[i] = q->string;
2176 for (i = 0; argv[i] != NULL; i++)
2177 fprintf (stderr, " %s", argv[i]);
2178 fprintf (stderr, "\n");
2181 pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2182 PEXECUTE_SEARCH | PEXECUTE_ONE);
2185 fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2186 fprintf (stderr, errfmt, errarg);
2187 unlink (unlink_on_exit);
2191 if (pwait (pid, &status, 0) < 0)
2194 unlink (unlink_on_exit);
2200 fprintf (stderr, _("%s: Execution of %s failed\n"), program_name, ld);
2201 unlink (unlink_on_exit);
2205 return unlink_on_exit;