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. */
32 #include <sys/types.h>
39 /* Internal BFD NLM header. */
43 /* If strerror is just a macro, we want to use the one from libiberty
44 since it will handle undefined values. */
46 extern char *strerror ();
49 extern struct tm *localtime ();
56 /* Global variables. */
58 /* The name used to invoke the program. */
61 /* The version number. */
62 extern char *program_version;
64 /* Local variables. */
66 /* The symbol table. */
67 static asymbol **symbols;
69 /* The total amount of bss space. */
70 static bfd_size_type total_bss_size;
72 /* The list of long options. */
73 static struct option long_options[] =
75 { "header-info", required_argument, 0, 'T' },
76 { "help", no_argument, 0, 'h' },
77 { "input-format", required_argument, 0, 'I' },
78 { "output-format", required_argument, 0, 'O' },
79 { "version", no_argument, 0, 'V' },
80 { NULL, no_argument, 0, 0 }
85 static void show_help PARAMS ((void));
86 static void show_usage PARAMS ((FILE *, int));
87 static const char *select_output_format PARAMS ((enum bfd_architecture,
89 static void setup_sections PARAMS ((bfd *, asection *, PTR));
90 static void copy_sections PARAMS ((bfd *, asection *, PTR));
91 static void mangle_relocs PARAMS ((bfd *, asection *, arelent **,
92 bfd_size_type *, char *,
94 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent **,
95 bfd_size_type *, char *,
98 /* The main routine. */
106 const char *input_format = NULL;
107 const char *output_format = NULL;
108 const char *header_file = NULL;
111 asymbol **newsyms, **outsyms;
112 unsigned int symcount, newsymalloc, newsymcount;
116 char inlead, outlead;
117 boolean gotstart, gotexit, gotcheck;
119 FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
120 bfd_size_type custom_size, help_size, message_size, module_size, rpc_size;
121 asection *custom_section, *help_section, *message_section, *module_section;
122 asection *rpc_section, *shared_section;
124 bfd_size_type shared_offset, shared_size;
125 Nlm_Internal_Fixed_Header sharedhdr;
128 program_name = argv[0];
132 while ((opt = getopt_long (argc, argv, "hI:O:T:V", long_options, (int *) 0))
141 input_format = optarg;
144 output_format = optarg;
147 header_file = optarg;
150 printf ("GNU %s version %s\n", program_name, program_version);
156 show_usage (stderr, 1);
161 if (optind + 2 != argc)
162 show_usage (stderr, 1);
164 if (strcmp (argv[optind], argv[optind + 1]) == 0)
166 fprintf (stderr, "%s: input and output files must be different\n",
171 inbfd = bfd_openr (argv[optind], input_format);
173 bfd_fatal (argv[optind]);
175 if (! bfd_check_format (inbfd, bfd_object))
176 bfd_fatal (argv[optind]);
178 if (output_format == NULL)
179 output_format = select_output_format (bfd_get_arch (inbfd),
180 bfd_get_mach (inbfd),
181 inbfd->xvec->byteorder_big_p);
183 assert (output_format != NULL);
184 outbfd = bfd_openw (argv[optind + 1], output_format);
186 bfd_fatal (argv[optind + 1]);
187 if (! bfd_set_format (outbfd, bfd_object))
188 bfd_fatal (argv[optind + 1]);
190 assert (outbfd->xvec->flavour == bfd_target_nlm_flavour);
192 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
194 "%s: warning:input and output formats are not compatible\n",
197 /* Initialize the header information to default values. */
198 fixed_hdr = nlm_fixed_header (outbfd);
199 var_hdr = nlm_variable_header (outbfd);
200 version_hdr = nlm_version_header (outbfd);
201 copyright_hdr = nlm_copyright_header (outbfd);
202 extended_hdr = nlm_extended_header (outbfd);
203 check_procedure = NULL;
206 exit_procedure = "_Stop";
207 export_symbols = NULL;
211 import_symbols = NULL;
214 sharelib_file = NULL;
215 start_procedure = "_Prelude";
221 /* Parse the header file (if there is one). */
222 if (header_file != NULL)
224 if (! nlmlex_file (header_file)
226 || parse_errors != 0)
230 /* Start copying the input BFD to the output BFD. */
231 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
232 bfd_fatal (bfd_get_filename (outbfd));
234 symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
235 symcount = bfd_canonicalize_symtab (inbfd, symbols);
237 /* Make sure we have a .bss section. Doing this first is an attempt
238 to ensure that it will be the first bss section. */
239 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
242 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
244 bfd_fatal ("make .bss section");
245 bss_sec->flags = SEC_ALLOC;
246 bss_sec->alignment_power = bfd_log2 (0); /* FIXME */
249 /* Set up the sections. */
250 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
252 /* Adjust symbol information. */
253 inlead = bfd_get_symbol_leading_char (inbfd);
254 outlead = bfd_get_symbol_leading_char (outbfd);
259 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
262 for (i = 0; i < symcount; i++)
264 register asymbol *sym;
268 /* Add or remove a leading underscore. */
269 if (inlead != outlead)
273 if (bfd_asymbol_name (sym)[0] == inlead)
281 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
283 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
292 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
294 strcpy (new + 1, bfd_asymbol_name (sym));
299 /* NLM's have an uninitialized data section, but they do not
300 have a common section in the Unix sense. Move all common
301 symbols into the .bss section, and mark them as exported. */
302 if (bfd_is_com_section (bfd_get_section (sym)))
307 sym->section = bss_sec;
309 sym->value = bss_sec->_raw_size;
310 bss_sec->_raw_size += size;
311 align = 1 << bss_sec->alignment_power;
312 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
313 total_bss_size += bss_sec->_raw_size - sym->value;
314 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
317 /* Force _edata and _end to be defined. This would normally be
318 done by the linker, but the manipulation of the common
319 symbols will confuse it. */
320 if (bfd_asymbol_name (sym)[0] == '_'
321 && bfd_get_section (sym) == &bfd_und_section)
323 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
325 sym->section = bss_sec;
328 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
330 sym->section = bss_sec;
335 /* If this is a global symbol, check the export list. */
336 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
338 register struct string_list *l;
341 /* Unfortunately, a symbol can appear multiple times on the
342 export list, with and without prefixes. */
344 for (l = export_symbols; l != NULL; l = l->next)
346 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
352 zbase = strchr (l->string, '@');
354 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
356 /* We must add a symbol with this prefix. */
357 if (newsymcount >= newsymalloc)
360 newsyms = ((asymbol **)
363 * sizeof (asymbol *))));
365 newsyms[newsymcount] =
366 (asymbol *) xmalloc (sizeof (asymbol));
367 *newsyms[newsymcount] = *sym;
368 newsyms[newsymcount]->name = l->string;
375 /* The unmodified symbol is actually not exported at
377 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
378 sym->flags |= BSF_LOCAL;
382 /* If it's an undefined symbol, see if it's on the import list.
383 Change the prefix if necessary. */
384 if (bfd_get_section (sym) == &bfd_und_section
385 && import_symbols != NULL)
387 register struct string_list *l;
389 for (l = import_symbols; l != NULL; l = l->next)
391 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
397 zbase = strchr (l->string, '@');
399 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
401 sym->name = l->string;
408 "%s: warning: symbol %s imported but not in import list\n",
409 program_name, bfd_asymbol_name (sym));
412 /* See if it's one of the special named symbols. */
413 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
415 if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
416 bfd_fatal ("set start address");
419 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
421 nlm_fixed_header (outbfd)->exitProcedureOffset =
422 bfd_asymbol_value (sym);
425 if (check_procedure != NULL
426 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
428 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
429 bfd_asymbol_value (sym);
435 endsym->value = total_bss_size;
437 if (newsymcount == 0)
441 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
442 * sizeof (asymbol *));
443 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
444 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
445 outsyms[symcount + newsymcount] = NULL;
448 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
451 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
452 program_name, start_procedure);
454 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
455 program_name, exit_procedure);
456 if (check_procedure != NULL
458 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
459 program_name, check_procedure);
461 /* Add additional sections required for the header information. */
462 if (custom_file != NULL)
464 custom_data = fopen (custom_file, "r");
465 if (custom_data == NULL
466 || fstat (fileno (custom_data), &st) < 0)
468 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
474 custom_size = st.st_size;
475 custom_section = bfd_make_section (outbfd, ".nlmcustom");
476 if (custom_section == NULL
477 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
478 || ! bfd_set_section_flags (outbfd, custom_section,
480 bfd_fatal ("custom section");
483 if (help_file != NULL)
485 help_data = fopen (help_file, "r");
486 if (help_data == NULL
487 || fstat (fileno (help_data), &st) < 0)
489 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
495 help_size = st.st_size;
496 help_section = bfd_make_section (outbfd, ".nlmhelp");
497 if (help_section == NULL
498 || ! bfd_set_section_size (outbfd, help_section, help_size)
499 || ! bfd_set_section_flags (outbfd, help_section,
501 bfd_fatal ("help section");
502 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
505 if (message_file != NULL)
507 message_data = fopen (message_file, "r");
508 if (message_data == NULL
509 || fstat (fileno (message_data), &st) < 0)
511 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
517 message_size = st.st_size;
518 message_section = bfd_make_section (outbfd, ".nlmmessages");
519 if (message_section == NULL
520 || ! bfd_set_section_size (outbfd, message_section, message_size)
521 || ! bfd_set_section_flags (outbfd, message_section,
523 bfd_fatal ("message section");
524 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
529 struct string_list *l;
532 for (l = modules; l != NULL; l = l->next)
533 module_size += strlen (l->string) + 1;
534 module_section = bfd_make_section (outbfd, ".nlmmodules");
535 if (module_section == NULL
536 || ! bfd_set_section_size (outbfd, module_section, module_size)
537 || ! bfd_set_section_flags (outbfd, module_section,
539 bfd_fatal ("module section");
541 if (rpc_file != NULL)
543 rpc_data = fopen (rpc_file, "r");
545 || fstat (fileno (rpc_data), &st) < 0)
547 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
553 rpc_size = st.st_size;
554 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
555 if (rpc_section == NULL
556 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
557 || ! bfd_set_section_flags (outbfd, rpc_section,
559 bfd_fatal ("rpc section");
560 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
563 if (sharelib_file != NULL)
565 sharedbfd = bfd_openr (sharelib_file, output_format);
566 if (sharedbfd == NULL
567 || ! bfd_check_format (sharedbfd, bfd_object))
569 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
570 bfd_errmsg (bfd_error));
571 sharelib_file = NULL;
575 sharedhdr = *nlm_fixed_header (sharedbfd);
576 bfd_close (sharedbfd);
577 shared_data = fopen (sharelib_file, "r");
578 if (shared_data == NULL
579 || (fstat (fileno (shared_data), &st) < 0))
581 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
583 sharelib_file = NULL;
587 /* If we were clever, we could just copy out the
588 sections of the shared library which we actually
589 need. However, we would have to figure out the sizes
590 of the external and public information, and that can
591 not be done without reading through them. */
592 shared_offset = st.st_size;
593 if (shared_offset > sharedhdr.codeImageOffset)
594 shared_offset = sharedhdr.codeImageOffset;
595 if (shared_offset > sharedhdr.dataImageOffset)
596 shared_offset = sharedhdr.dataImageOffset;
597 if (shared_offset > sharedhdr.relocationFixupOffset)
598 shared_offset = sharedhdr.relocationFixupOffset;
599 if (shared_offset > sharedhdr.externalReferencesOffset)
600 shared_offset = sharedhdr.externalReferencesOffset;
601 if (shared_offset > sharedhdr.publicsOffset)
602 shared_offset = sharedhdr.publicsOffset;
603 shared_size = st.st_size - shared_offset;
604 shared_section = bfd_make_section (outbfd, ".nlmshared");
605 if (shared_section == NULL
606 || ! bfd_set_section_size (outbfd, shared_section,
608 || ! bfd_set_section_flags (outbfd, shared_section,
610 bfd_fatal ("shared section");
611 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
616 /* Check whether a version was given. */
617 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
618 fprintf (stderr, "%s: warning: No version number given\n",
621 /* At least for now, always create an extended header, because that
622 is what NLMLINK does. */
623 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
625 /* If the date was not given, force it in. */
626 if (nlm_version_header (outbfd)->month == 0
627 && nlm_version_header (outbfd)->day == 0
628 && nlm_version_header (outbfd)->year == 0)
630 unsigned long now; /* FIXME: should be time_t. */
634 ptm = localtime (&now);
635 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
636 nlm_version_header (outbfd)->day = ptm->tm_mday;
637 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
638 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
641 /* Copy over the sections. */
642 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
644 /* Finish up the header information. */
645 if (custom_file != NULL)
649 data = xmalloc (custom_size);
650 if (fread (data, 1, custom_size, custom_data) != custom_size)
651 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
655 if (! bfd_set_section_contents (outbfd, custom_section, data,
656 (file_ptr) 0, custom_size))
657 bfd_fatal ("custom section");
658 nlm_fixed_header (outbfd)->customDataOffset =
659 custom_section->filepos;
660 nlm_fixed_header (outbfd)->customDataSize = custom_size;
666 /* As a special hack, the backend recognizes a debugInfoOffset
667 of -1 to mean that it should not output any debugging
668 information. This can not be handling by fiddling with the
669 symbol table because exported symbols appear in both the
670 export information and the debugging information. */
671 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
673 if (map_file != NULL)
675 "%s: MAP and FULLMAP are not supported; try ld -M\n",
677 if (help_file != NULL)
681 data = xmalloc (help_size);
682 if (fread (data, 1, help_size, help_data) != help_size)
683 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
687 if (! bfd_set_section_contents (outbfd, help_section, data,
688 (file_ptr) 0, help_size))
689 bfd_fatal ("help section");
690 nlm_extended_header (outbfd)->helpFileOffset =
691 help_section->filepos;
692 nlm_extended_header (outbfd)->helpFileLength = help_size;
696 if (message_file != NULL)
700 data = xmalloc (message_size);
701 if (fread (data, 1, message_size, message_data) != message_size)
702 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
706 if (! bfd_set_section_contents (outbfd, message_section, data,
707 (file_ptr) 0, message_size))
708 bfd_fatal ("message section");
709 nlm_extended_header (outbfd)->messageFileOffset =
710 message_section->filepos;
711 nlm_extended_header (outbfd)->messageFileLength = message_size;
713 /* FIXME: Are these offsets correct on all platforms? Are
714 they 32 bits on all platforms? What endianness? */
715 nlm_extended_header (outbfd)->languageID =
716 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
717 nlm_extended_header (outbfd)->messageCount =
718 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
726 struct string_list *l;
729 data = xmalloc (module_size);
732 for (l = modules; l != NULL; l = l->next)
734 *set = strlen (l->string);
735 strncpy (set + 1, l->string, *set);
739 if (! bfd_set_section_contents (outbfd, module_section, data,
740 (file_ptr) 0, module_size))
741 bfd_fatal ("module section");
742 nlm_fixed_header (outbfd)->moduleDependencyOffset =
743 module_section->filepos;
744 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
746 if (rpc_file != NULL)
750 data = xmalloc (rpc_size);
751 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
752 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
756 if (! bfd_set_section_contents (outbfd, rpc_section, data,
757 (file_ptr) 0, rpc_size))
758 bfd_fatal ("rpc section");
759 nlm_extended_header (outbfd)->RPCDataOffset =
760 rpc_section->filepos;
761 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
765 if (sharelib_file != NULL)
769 data = xmalloc (shared_size);
770 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
771 || fread (data, 1, shared_size, shared_data) != shared_size)
772 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
776 if (! bfd_set_section_contents (outbfd, shared_section, data,
777 (file_ptr) 0, shared_size))
778 bfd_fatal ("shared section");
780 nlm_extended_header (outbfd)->sharedCodeOffset =
781 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
782 nlm_extended_header (outbfd)->sharedCodeLength =
783 sharedhdr.codeImageSize;
784 nlm_extended_header (outbfd)->sharedDataOffset =
785 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
786 nlm_extended_header (outbfd)->sharedDataLength =
787 sharedhdr.dataImageSize;
788 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
789 (sharedhdr.relocationFixupOffset
791 + shared_section->filepos);
792 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
793 sharedhdr.numberOfRelocationFixups;
794 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
795 (sharedhdr.externalReferencesOffset
797 + shared_section->filepos);
798 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
799 sharedhdr.numberOfExternalReferences;
800 nlm_extended_header (outbfd)->sharedPublicsOffset =
801 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
802 nlm_extended_header (outbfd)->sharedPublicsCount =
803 sharedhdr.numberOfPublics;
804 nlm_extended_header (outbfd)->SharedInitializationOffset =
805 sharedhdr.codeStartOffset;
806 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
807 sharedhdr.exitProcedureOffset;
810 len = strlen (argv[optind + 1]);
811 if (len > NLM_MODULE_NAME_SIZE - 2)
812 len = NLM_MODULE_NAME_SIZE - 2;
813 nlm_fixed_header (outbfd)->moduleName[0] = len;
814 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, argv[optind + 1],
815 NLM_MODULE_NAME_SIZE - 2);
816 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
817 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
818 NLM_OLD_THREAD_NAME_LENGTH);
820 if (! bfd_close (outbfd))
821 bfd_fatal (argv[optind + 1]);
822 if (! bfd_close (inbfd))
823 bfd_fatal (argv[optind]);
828 /* Display a help message and exit. */
833 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
835 show_usage (stdout, 0);
838 /* Show a usage message and exit. */
841 show_usage (file, status)
846 Usage: %s [-hV] [-I format] [-O format] [-T header-file]\n\
847 [--input-format=format] [--output-format=format]\n\
848 [--header-file=file] [--help] [--version]\n\
854 /* Select the output format based on the input architecture, machine,
855 and endianness. This chooses the appropriate NLM target. */
858 select_output_format (arch, mach, bigendian)
859 enum bfd_architecture arch;
868 fprintf (stderr, "%s: no default NLM format for %s\n",
869 program_name, bfd_printable_arch_mach (arch, mach));
877 /* The BFD sections are copied in two passes. This function sets up
878 the section name, size, etc. */
881 setup_sections (inbfd, insec, data_ptr)
886 bfd *outbfd = (bfd *) data_ptr;
890 outsec = bfd_get_section_by_name (outbfd, bfd_section_name (inbfd, insec));
893 outsec = bfd_make_section (outbfd, bfd_section_name (inbfd, insec));
895 bfd_fatal ("make section");
898 insec->output_section = outsec;
899 insec->output_offset = 0;
901 if (! bfd_set_section_size (outbfd, outsec,
902 bfd_section_size (inbfd, insec)))
903 bfd_fatal ("set section size");
905 if (! bfd_set_section_vma (outbfd, outsec,
906 bfd_section_vma (inbfd, insec)))
907 bfd_fatal ("set section vma");
909 if (! bfd_set_section_alignment (outbfd, outsec,
910 bfd_section_alignment (inbfd, insec)))
911 bfd_fatal ("set section alignment");
913 f = bfd_get_section_flags (inbfd, insec);
914 if (! bfd_set_section_flags (outbfd, outsec, f))
915 bfd_fatal ("set section flags");
917 if ((f & SEC_LOAD) == 0 && (f & SEC_ALLOC) != 0)
918 total_bss_size += bfd_section_size (inbfd, insec);
921 /* Copy the section contents. */
924 copy_sections (inbfd, insec, data_ptr)
929 bfd *outbfd = (bfd *) data_ptr;
933 bfd_size_type reloc_size;
935 outsec = bfd_get_section_by_name (outbfd, bfd_section_name (inbfd, insec));
936 assert (outsec != NULL);
938 size = bfd_get_section_size_before_reloc (insec);
942 /* FIXME: Why are these necessary? */
943 insec->_cooked_size = insec->_raw_size;
944 insec->reloc_done = true;
946 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
950 contents = xmalloc (size);
951 if (! bfd_get_section_contents (inbfd, insec, contents,
953 bfd_fatal (bfd_get_filename (inbfd));
956 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
958 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
962 bfd_size_type reloc_count;
964 relocs = (arelent **) xmalloc (reloc_size);
965 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
966 mangle_relocs (outbfd, insec, relocs, &reloc_count, (char *) contents,
968 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
971 if (contents != NULL)
973 if (! bfd_set_section_contents (outbfd, outsec, contents,
975 bfd_fatal (bfd_get_filename (outbfd));
980 /* Some, perhaps all, NetWare targets require changing the relocs used
981 by the input formats. */
984 mangle_relocs (outbfd, insec, relocs, reloc_count_ptr, contents, contents_size)
988 bfd_size_type *reloc_count_ptr;
990 bfd_size_type contents_size;
992 switch (bfd_get_arch (outbfd))
995 i386_mangle_relocs (outbfd, insec, relocs, reloc_count_ptr, contents,
1003 /* NetWare on the i386 supports a restricted set of relocs, which are
1004 different from those used on other i386 targets. This routine
1005 converts the relocs. It is, obviously, very target dependent. At
1006 the moment, the nlm32-i386 backend performs similar translations;
1007 however, it is more reliable and efficient to do them here. */
1009 static reloc_howto_type nlm_i386_pcrel_howto =
1010 HOWTO (1, /* type */
1012 2, /* size (0 = byte, 1 = short, 2 = long) */
1014 true, /* pc_relative */
1016 complain_overflow_signed, /* complain_on_overflow */
1017 0, /* special_function */
1018 "DISP32", /* name */
1019 true, /* partial_inplace */
1020 0xffffffff, /* src_mask */
1021 0xffffffff, /* dst_mask */
1022 true); /* pcrel_offset */
1025 i386_mangle_relocs (outbfd, insec, relocs, reloc_count_ptr, contents,
1030 bfd_size_type *reloc_count_ptr;
1032 bfd_size_type contents_size;
1034 bfd_size_type reloc_count, i;
1036 reloc_count = *reloc_count_ptr;
1037 for (i = 0; i < reloc_count; i++)
1044 sym = *rel->sym_ptr_ptr;
1046 /* Note that no serious harm will ensue if we fail to change a
1047 reloc. The backend will fail when writing out the reloc. */
1049 /* Make sure this reloc is within the data we have. We use only
1050 4 byte relocs here, so we insist on having 4 bytes. */
1051 if (rel->address + 4 > contents_size)
1054 /* A PC relative reloc entirely within a single section is
1055 completely unnecessary. This can be generated by ld -r. */
1056 if (sym == insec->symbol
1057 && rel->howto != NULL
1058 && rel->howto->pc_relative
1059 && ! rel->howto->pcrel_offset)
1063 memmove (relocs, relocs + 1,
1064 (reloc_count - i) * sizeof (arelent *));
1068 /* NetWare doesn't support reloc addends, so we get rid of them
1069 here by simply adding them into the object data. We handle
1070 the symbol value, if any, the same way. */
1071 addend = rel->addend;
1072 if (! bfd_is_com_section (bfd_get_section (sym)))
1073 addend += sym->value;
1076 && rel->howto != NULL
1077 && rel->howto->rightshift == 0
1078 && rel->howto->size == 2
1079 && rel->howto->bitsize == 32
1080 && rel->howto->bitpos == 0
1081 && rel->howto->src_mask == 0xffffffff
1082 && rel->howto->dst_mask == 0xffffffff)
1086 val = bfd_get_32 (outbfd, contents + rel->address);
1088 bfd_put_32 (outbfd, val, contents + rel->address);
1090 /* Adjust the reloc for the changes we just made. */
1092 if (! bfd_is_com_section (bfd_get_section (sym))
1094 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1097 /* NetWare uses a reloc with pcrel_offset set. We adjust
1098 pc_relative relocs accordingly. We are going to change the
1099 howto field, so we can only do this if the current one is
1100 compatible. We should check that special_function is NULL
1101 here, but at the moment coff-i386 uses a special_function
1102 which does not affect what we are doing here. */
1103 if (rel->howto != NULL
1104 && rel->howto->pc_relative
1105 && ! rel->howto->pcrel_offset
1106 && rel->howto->rightshift == 0
1107 && rel->howto->size == 2
1108 && rel->howto->bitsize == 32
1109 && rel->howto->bitpos == 0
1110 && rel->howto->src_mask == 0xffffffff
1111 && rel->howto->dst_mask == 0xffffffff)
1115 /* When pcrel_offset is not set, it means that the negative
1116 of the address of the memory location is stored in the
1117 memory location. We must add it back in. */
1118 val = bfd_get_32 (outbfd, contents + rel->address);
1119 val += rel->address;
1120 bfd_put_32 (outbfd, val, contents + rel->address);
1122 /* We must change to a new howto. */
1123 rel->howto = &nlm_i386_pcrel_howto;