Add Brazillian Portugese translation.
[binutils.git] / binutils / nlmconv.c
blob7d68dcd2056e9328ef30c8713a8541e6ec60c5fc
1 /* nlmconv.c -- NLM conversion program
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 /* Written by Ian Lance Taylor <ian@cygnus.com>.
23 This program can be used to convert any appropriate object file
24 into a NetWare Loadable Module (an NLM). It will accept a linker
25 specification file which is identical to that accepted by the
26 NetWare linker, NLMLINK. */
28 /* AIX requires this to be the first thing in the file. */
29 #ifndef __GNUC__
30 # ifdef _AIX
31 #pragma alloca
32 #endif
33 #endif
35 #include "bfd.h"
36 #include "libiberty.h"
37 #include "bucomm.h"
38 #include "safe-ctype.h"
40 #include "ansidecl.h"
41 #include <time.h>
42 #include <sys/stat.h>
43 #include <sys/file.h>
44 #include <assert.h>
45 #include "getopt.h"
47 /* Internal BFD NLM header. */
48 #include "libnlm.h"
49 #include "nlmconv.h"
51 #ifdef NLMCONV_ALPHA
52 #include "coff/sym.h"
53 #include "coff/ecoff.h"
54 #endif
56 /* If strerror is just a macro, we want to use the one from libiberty
57 since it will handle undefined values. */
58 #undef strerror
59 extern char *strerror PARAMS ((int));
61 #ifndef localtime
62 extern struct tm *localtime ();
63 #endif
65 #ifndef SEEK_SET
66 #define SEEK_SET 0
67 #endif
69 #ifndef R_OK
70 #define R_OK 4
71 #define W_OK 2
72 #define X_OK 1
73 #endif
75 /* Global variables. */
77 /* The name used to invoke the program. */
78 char *program_name;
80 /* Local variables. */
82 /* Whether to print out debugging information (currently just controls
83 whether it prints the linker command if there is one). */
84 static int debug;
86 /* The symbol table. */
87 static asymbol **symbols;
89 /* A section we create in the output file to hold pointers to where
90 the sections of the input file end up. We will put a pointer to
91 this section in the NLM header. These is an entry for each input
92 section. The format is
93 null terminated section name
94 zeroes to adjust to 4 byte boundary
95 4 byte section data file pointer
96 4 byte section size
97 We don't need a version number. The way we find this information
98 is by finding a stamp in the NLM header information. If we need to
99 change the format of this information, we can simply change the
100 stamp. */
101 static asection *secsec;
103 /* A temporary file name to be unlinked on exit. Actually, for most
104 errors, we leave it around. It's not clear whether that is helpful
105 or not. */
106 static char *unlink_on_exit;
108 /* The list of long options. */
109 static struct option long_options[] =
111 { "debug", no_argument, 0, 'd' },
112 { "header-file", required_argument, 0, 'T' },
113 { "help", no_argument, 0, 'h' },
114 { "input-target", required_argument, 0, 'I' },
115 { "input-format", required_argument, 0, 'I' }, /* Obsolete */
116 { "linker", required_argument, 0, 'l' },
117 { "output-target", required_argument, 0, 'O' },
118 { "output-format", required_argument, 0, 'O' }, /* Obsolete */
119 { "version", no_argument, 0, 'V' },
120 { NULL, no_argument, 0, 0 }
123 /* Local routines. */
125 int main PARAMS ((int, char **));
127 static void show_usage
128 PARAMS ((FILE *, int));
129 static const char *select_output_format
130 PARAMS ((enum bfd_architecture, unsigned long, bfd_boolean));
131 static void setup_sections
132 PARAMS ((bfd *, asection *, PTR));
133 static void copy_sections
134 PARAMS ((bfd *, asection *, PTR));
135 static void mangle_relocs
136 PARAMS ((bfd *, asection *, arelent ***, long *, char *, bfd_size_type));
137 static void default_mangle_relocs
138 PARAMS ((bfd *, asection *, arelent ***, long *, char *, bfd_size_type));
139 static char *link_inputs
140 PARAMS ((struct string_list *, char *));
142 #ifdef NLMCONV_I386
143 static void i386_mangle_relocs
144 PARAMS ((bfd *, asection *, arelent ***, long *, char *, bfd_size_type));
145 #endif
147 #ifdef NLMCONV_ALPHA
148 static void alpha_mangle_relocs
149 PARAMS ((bfd *, asection *, arelent ***, long *, char *, bfd_size_type));
150 #endif
152 #ifdef NLMCONV_POWERPC
153 static void powerpc_build_stubs
154 PARAMS ((bfd *, bfd *, asymbol ***, long *));
155 static void powerpc_resolve_stubs
156 PARAMS ((bfd *, bfd *));
157 static void powerpc_mangle_relocs
158 PARAMS ((bfd *, asection *, arelent ***, long *, char *, bfd_size_type));
159 #endif
161 /* The main routine. */
164 main (argc, argv)
165 int argc;
166 char **argv;
168 int opt;
169 char *input_file = NULL;
170 const char *input_format = NULL;
171 const char *output_format = NULL;
172 const char *header_file = NULL;
173 char *ld_arg = NULL;
174 Nlm_Internal_Fixed_Header fixed_hdr_struct;
175 Nlm_Internal_Variable_Header var_hdr_struct;
176 Nlm_Internal_Version_Header version_hdr_struct;
177 Nlm_Internal_Copyright_Header copyright_hdr_struct;
178 Nlm_Internal_Extended_Header extended_hdr_struct;
179 bfd *inbfd;
180 bfd *outbfd;
181 asymbol **newsyms, **outsyms;
182 long symcount, newsymalloc, newsymcount;
183 long symsize;
184 asection *text_sec, *bss_sec, *data_sec;
185 bfd_vma vma;
186 bfd_size_type align;
187 asymbol *endsym;
188 long i;
189 char inlead, outlead;
190 bfd_boolean gotstart, gotexit, gotcheck;
191 struct stat st;
192 FILE *custom_data = NULL;
193 FILE *help_data = NULL;
194 FILE *message_data = NULL;
195 FILE *rpc_data = NULL;
196 FILE *shared_data = NULL;
197 size_t custom_size = 0;
198 size_t help_size = 0;
199 size_t message_size = 0;
200 size_t module_size = 0;
201 size_t rpc_size = 0;
202 asection *custom_section = NULL;
203 asection *help_section = NULL;
204 asection *message_section = NULL;
205 asection *module_section = NULL;
206 asection *rpc_section = NULL;
207 asection *shared_section = NULL;
208 bfd *sharedbfd;
209 size_t shared_offset = 0;
210 size_t shared_size = 0;
211 Nlm_Internal_Fixed_Header sharedhdr;
212 int len;
213 char *modname;
214 char **matching;
216 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
217 setlocale (LC_MESSAGES, "");
218 #endif
219 #if defined (HAVE_SETLOCALE)
220 setlocale (LC_CTYPE, "");
221 #endif
222 bindtextdomain (PACKAGE, LOCALEDIR);
223 textdomain (PACKAGE);
225 program_name = argv[0];
226 xmalloc_set_program_name (program_name);
228 bfd_init ();
229 set_default_bfd_target ();
231 while ((opt = getopt_long (argc, argv, "dHhI:l:O:T:Vv", long_options,
232 (int *) NULL))
233 != EOF)
235 switch (opt)
237 case 'd':
238 debug = 1;
239 break;
240 case 'H':
241 case 'h':
242 show_usage (stdout, 0);
243 break;
244 case 'I':
245 input_format = optarg;
246 break;
247 case 'l':
248 ld_arg = optarg;
249 break;
250 case 'O':
251 output_format = optarg;
252 break;
253 case 'T':
254 header_file = optarg;
255 break;
256 case 'v':
257 case 'V':
258 print_version ("nlmconv");
259 break;
260 case 0:
261 break;
262 default:
263 show_usage (stderr, 1);
264 break;
268 /* The input and output files may be named on the command line. */
269 output_file = NULL;
270 if (optind < argc)
272 input_file = argv[optind];
273 ++optind;
274 if (optind < argc)
276 output_file = argv[optind];
277 ++optind;
278 if (optind < argc)
279 show_usage (stderr, 1);
280 if (strcmp (input_file, output_file) == 0)
282 fatal (_("input and output files must be different"));
287 /* Initialize the header information to default values. */
288 fixed_hdr = &fixed_hdr_struct;
289 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
290 var_hdr = &var_hdr_struct;
291 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
292 version_hdr = &version_hdr_struct;
293 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
294 copyright_hdr = &copyright_hdr_struct;
295 memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
296 extended_hdr = &extended_hdr_struct;
297 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
298 check_procedure = NULL;
299 custom_file = NULL;
300 debug_info = FALSE;
301 exit_procedure = "_Stop";
302 export_symbols = NULL;
303 map_file = NULL;
304 full_map = FALSE;
305 help_file = NULL;
306 import_symbols = NULL;
307 message_file = NULL;
308 modules = NULL;
309 sharelib_file = NULL;
310 start_procedure = "_Prelude";
311 verbose = FALSE;
312 rpc_file = NULL;
314 parse_errors = 0;
316 /* Parse the header file (if there is one). */
317 if (header_file != NULL)
319 if (! nlmlex_file (header_file)
320 || yyparse () != 0
321 || parse_errors != 0)
322 exit (1);
325 if (input_files != NULL)
327 if (input_file != NULL)
329 fatal (_("input file named both on command line and with INPUT"));
331 if (input_files->next == NULL)
332 input_file = input_files->string;
333 else
334 input_file = link_inputs (input_files, ld_arg);
336 else if (input_file == NULL)
338 non_fatal (_("no input file"));
339 show_usage (stderr, 1);
342 inbfd = bfd_openr (input_file, input_format);
343 if (inbfd == NULL)
344 bfd_fatal (input_file);
346 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
348 bfd_nonfatal (input_file);
349 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
351 list_matching_formats (matching);
352 free (matching);
354 exit (1);
357 if (output_format == NULL)
358 output_format = select_output_format (bfd_get_arch (inbfd),
359 bfd_get_mach (inbfd),
360 bfd_big_endian (inbfd));
362 assert (output_format != NULL);
364 /* Use the output file named on the command line if it exists.
365 Otherwise use the file named in the OUTPUT statement. */
366 if (output_file == NULL)
368 non_fatal (_("no name for output file"));
369 show_usage (stderr, 1);
372 outbfd = bfd_openw (output_file, output_format);
373 if (outbfd == NULL)
374 bfd_fatal (output_file);
375 if (! bfd_set_format (outbfd, bfd_object))
376 bfd_fatal (output_file);
378 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
380 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
381 non_fatal (_("warning: input and output formats are not compatible"));
383 /* Move the values read from the command file into outbfd. */
384 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
385 *nlm_variable_header (outbfd) = var_hdr_struct;
386 *nlm_version_header (outbfd) = version_hdr_struct;
387 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
388 *nlm_extended_header (outbfd) = extended_hdr_struct;
390 /* Start copying the input BFD to the output BFD. */
391 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
392 bfd_fatal (bfd_get_filename (outbfd));
394 symsize = bfd_get_symtab_upper_bound (inbfd);
395 if (symsize < 0)
396 bfd_fatal (input_file);
397 symbols = (asymbol **) xmalloc (symsize);
398 symcount = bfd_canonicalize_symtab (inbfd, symbols);
399 if (symcount < 0)
400 bfd_fatal (input_file);
402 /* Make sure we have a .bss section. */
403 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
404 if (bss_sec == NULL)
406 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
407 if (bss_sec == NULL
408 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
409 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
410 bfd_fatal (_("make .bss section"));
413 /* We store the original section names in the .nlmsections section,
414 so that programs which understand it can resurrect the original
415 sections from the NLM. We will put a pointer to .nlmsections in
416 the NLM header area. */
417 secsec = bfd_make_section (outbfd, ".nlmsections");
418 if (secsec == NULL)
419 bfd_fatal (_("make .nlmsections section"));
420 if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
421 bfd_fatal (_("set .nlmsections flags"));
423 #ifdef NLMCONV_POWERPC
424 /* For PowerPC NetWare we need to build stubs for calls to undefined
425 symbols. Because each stub requires an entry in the TOC section
426 which must be at the same location as other entries in the TOC
427 section, we must do this before determining where the TOC section
428 goes in setup_sections. */
429 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
430 powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
431 #endif
433 /* Set up the sections. */
434 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
436 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
438 /* The .bss section immediately follows the .data section. */
439 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
440 if (data_sec != NULL)
442 bfd_size_type add;
444 vma = bfd_get_section_size_before_reloc (data_sec);
445 align = 1 << bss_sec->alignment_power;
446 add = ((vma + align - 1) &~ (align - 1)) - vma;
447 vma += add;
448 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
449 bfd_fatal (_("set .bss vma"));
450 if (add != 0)
452 bfd_size_type data_size;
454 data_size = bfd_get_section_size_before_reloc (data_sec);
455 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
456 bfd_fatal (_("set .data size"));
460 /* Adjust symbol information. */
461 inlead = bfd_get_symbol_leading_char (inbfd);
462 outlead = bfd_get_symbol_leading_char (outbfd);
463 gotstart = FALSE;
464 gotexit = FALSE;
465 gotcheck = FALSE;
466 newsymalloc = 10;
467 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
468 newsymcount = 0;
469 endsym = NULL;
470 for (i = 0; i < symcount; i++)
472 register asymbol *sym;
474 sym = symbols[i];
476 /* Add or remove a leading underscore. */
477 if (inlead != outlead)
479 if (inlead != '\0')
481 if (bfd_asymbol_name (sym)[0] == inlead)
483 if (outlead == '\0')
484 ++sym->name;
485 else
487 char *new;
489 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
490 new[0] = outlead;
491 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
492 sym->name = new;
496 else
498 char *new;
500 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
501 new[0] = outlead;
502 strcpy (new + 1, bfd_asymbol_name (sym));
503 sym->name = new;
507 /* NLM's have an uninitialized data section, but they do not
508 have a common section in the Unix sense. Move all common
509 symbols into the .bss section, and mark them as exported. */
510 if (bfd_is_com_section (bfd_get_section (sym)))
512 bfd_vma size;
514 sym->section = bss_sec;
515 size = sym->value;
516 sym->value = bss_sec->_raw_size;
517 bss_sec->_raw_size += size;
518 align = 1 << bss_sec->alignment_power;
519 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
520 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
522 else if (bfd_get_section (sym)->output_section != NULL)
524 /* Move the symbol into the output section. */
525 sym->value += bfd_get_section (sym)->output_offset;
526 sym->section = bfd_get_section (sym)->output_section;
527 /* This is no longer a section symbol. */
528 sym->flags &=~ BSF_SECTION_SYM;
531 /* Force _edata and _end to be defined. This would normally be
532 done by the linker, but the manipulation of the common
533 symbols will confuse it. */
534 if ((sym->flags & BSF_DEBUGGING) == 0
535 && bfd_asymbol_name (sym)[0] == '_'
536 && bfd_is_und_section (bfd_get_section (sym)))
538 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
540 sym->section = bss_sec;
541 sym->value = 0;
543 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
545 sym->section = bss_sec;
546 endsym = sym;
549 #ifdef NLMCONV_POWERPC
550 /* For PowerPC NetWare, we define __GOT0. This is the start
551 of the .got section. */
552 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
553 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
555 asection *got_sec;
557 got_sec = bfd_get_section_by_name (inbfd, ".got");
558 assert (got_sec != (asection *) NULL);
559 sym->value = got_sec->output_offset;
560 sym->section = got_sec->output_section;
562 #endif
565 /* If this is a global symbol, check the export list. */
566 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
568 register struct string_list *l;
569 int found_simple;
571 /* Unfortunately, a symbol can appear multiple times on the
572 export list, with and without prefixes. */
573 found_simple = 0;
574 for (l = export_symbols; l != NULL; l = l->next)
576 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
577 found_simple = 1;
578 else
580 char *zbase;
582 zbase = strchr (l->string, '@');
583 if (zbase != NULL
584 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
586 /* We must add a symbol with this prefix. */
587 if (newsymcount >= newsymalloc)
589 newsymalloc += 10;
590 newsyms = ((asymbol **)
591 xrealloc ((PTR) newsyms,
592 (newsymalloc
593 * sizeof (asymbol *))));
595 newsyms[newsymcount] =
596 (asymbol *) xmalloc (sizeof (asymbol));
597 *newsyms[newsymcount] = *sym;
598 newsyms[newsymcount]->name = l->string;
599 ++newsymcount;
603 if (! found_simple)
605 /* The unmodified symbol is actually not exported at
606 all. */
607 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
608 sym->flags |= BSF_LOCAL;
612 /* If it's an undefined symbol, see if it's on the import list.
613 Change the prefix if necessary. */
614 if (bfd_is_und_section (bfd_get_section (sym)))
616 register struct string_list *l;
618 for (l = import_symbols; l != NULL; l = l->next)
620 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
621 break;
622 else
624 char *zbase;
626 zbase = strchr (l->string, '@');
627 if (zbase != NULL
628 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
630 sym->name = l->string;
631 break;
635 if (l == NULL)
636 non_fatal (_("warning: symbol %s imported but not in import list"),
637 bfd_asymbol_name (sym));
640 /* See if it's one of the special named symbols. */
641 if ((sym->flags & BSF_DEBUGGING) == 0)
643 bfd_vma val;
645 /* FIXME: If these symbols are not in the .text section, we
646 add the .text section size to the value. This may not be
647 correct for all targets. I'm not sure how this should
648 really be handled. */
649 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
651 val = bfd_asymbol_value (sym);
652 if (bfd_get_section (sym) == data_sec
653 && text_sec != (asection *) NULL)
654 val += bfd_section_size (outbfd, text_sec);
655 if (! bfd_set_start_address (outbfd, val))
656 bfd_fatal (_("set start address"));
657 gotstart = TRUE;
659 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
661 val = bfd_asymbol_value (sym);
662 if (bfd_get_section (sym) == data_sec
663 && text_sec != (asection *) NULL)
664 val += bfd_section_size (outbfd, text_sec);
665 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
666 gotexit = TRUE;
668 if (check_procedure != NULL
669 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
671 val = bfd_asymbol_value (sym);
672 if (bfd_get_section (sym) == data_sec
673 && text_sec != (asection *) NULL)
674 val += bfd_section_size (outbfd, text_sec);
675 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
676 gotcheck = TRUE;
681 if (endsym != NULL)
683 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
685 /* FIXME: If any relocs referring to _end use inplace addends,
686 then I think they need to be updated. This is handled by
687 i386_mangle_relocs. Is it needed for any other object
688 formats? */
691 if (newsymcount == 0)
692 outsyms = symbols;
693 else
695 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
696 * sizeof (asymbol *));
697 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
698 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
699 outsyms[symcount + newsymcount] = NULL;
702 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
704 if (! gotstart)
705 non_fatal (_("warning: START procedure %s not defined"), start_procedure);
706 if (! gotexit)
707 non_fatal (_("warning: EXIT procedure %s not defined"), exit_procedure);
708 if (check_procedure != NULL && ! gotcheck)
709 non_fatal (_("warning: CHECK procedure %s not defined"), 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,
719 strerror (errno));
720 custom_file = NULL;
722 else
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,
729 SEC_HAS_CONTENTS))
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,
740 strerror (errno));
741 help_file = NULL;
743 else
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,
750 SEC_HAS_CONTENTS))
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,
762 strerror (errno));
763 message_file = NULL;
765 else
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,
772 SEC_HAS_CONTENTS))
773 bfd_fatal (_("message section"));
774 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
777 if (modules != NULL)
779 struct string_list *l;
781 module_size = 0;
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,
788 SEC_HAS_CONTENTS))
789 bfd_fatal (_("module section"));
791 if (rpc_file != NULL)
793 rpc_data = fopen (rpc_file, "r");
794 if (rpc_data == NULL
795 || fstat (fileno (rpc_data), &st) < 0)
797 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
798 strerror (errno));
799 rpc_file = NULL;
801 else
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,
808 SEC_HAS_CONTENTS))
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;
823 else
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,
832 strerror (errno));
833 sharelib_file = NULL;
835 else
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. */
845 non_fatal (_("%s: warning: shared libraries can not have uninitialized data"),
846 sharelib_file);
848 shared_offset = st.st_size;
849 if (shared_offset > (size_t) sharedhdr.codeImageOffset)
850 shared_offset = sharedhdr.codeImageOffset;
851 if (shared_offset > (size_t) sharedhdr.dataImageOffset)
852 shared_offset = sharedhdr.dataImageOffset;
853 if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
854 shared_offset = sharedhdr.relocationFixupOffset;
855 if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
856 shared_offset = sharedhdr.externalReferencesOffset;
857 if (shared_offset > (size_t) sharedhdr.publicsOffset)
858 shared_offset = sharedhdr.publicsOffset;
859 shared_size = st.st_size - shared_offset;
860 shared_section = bfd_make_section (outbfd, ".nlmshared");
861 if (shared_section == NULL
862 || ! bfd_set_section_size (outbfd, shared_section,
863 shared_size)
864 || ! bfd_set_section_flags (outbfd, shared_section,
865 SEC_HAS_CONTENTS))
866 bfd_fatal (_("shared section"));
867 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
872 /* Check whether a version was given. */
873 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
874 non_fatal (_("warning: No version number given"));
876 /* At least for now, always create an extended header, because that
877 is what NLMLINK does. */
878 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
880 strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
882 /* If the date was not given, force it in. */
883 if (nlm_version_header (outbfd)->month == 0
884 && nlm_version_header (outbfd)->day == 0
885 && nlm_version_header (outbfd)->year == 0)
887 time_t now;
888 struct tm *ptm;
890 time (&now);
891 ptm = localtime (&now);
892 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
893 nlm_version_header (outbfd)->day = ptm->tm_mday;
894 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
895 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
898 #ifdef NLMCONV_POWERPC
899 /* Resolve the stubs we build for PowerPC NetWare. */
900 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
901 powerpc_resolve_stubs (inbfd, outbfd);
902 #endif
904 /* Copy over the sections. */
905 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
907 /* Finish up the header information. */
908 if (custom_file != NULL)
910 PTR data;
912 data = xmalloc (custom_size);
913 if (fread (data, 1, custom_size, custom_data) != custom_size)
914 non_fatal (_("%s: read: %s"), custom_file, strerror (errno));
915 else
917 if (! bfd_set_section_contents (outbfd, custom_section, data,
918 (file_ptr) 0, custom_size))
919 bfd_fatal (_("custom section"));
920 nlm_fixed_header (outbfd)->customDataOffset =
921 custom_section->filepos;
922 nlm_fixed_header (outbfd)->customDataSize = custom_size;
924 free (data);
926 if (! debug_info)
928 /* As a special hack, the backend recognizes a debugInfoOffset
929 of -1 to mean that it should not output any debugging
930 information. This can not be handling by fiddling with the
931 symbol table because exported symbols appear in both the
932 export information and the debugging information. */
933 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
935 if (map_file != NULL)
936 non_fatal (_("warning: MAP and FULLMAP are not supported; try ld -M"));
937 if (help_file != NULL)
939 PTR data;
941 data = xmalloc (help_size);
942 if (fread (data, 1, help_size, help_data) != help_size)
943 non_fatal (_("%s: read: %s"), help_file, strerror (errno));
944 else
946 if (! bfd_set_section_contents (outbfd, help_section, data,
947 (file_ptr) 0, help_size))
948 bfd_fatal (_("help section"));
949 nlm_extended_header (outbfd)->helpFileOffset =
950 help_section->filepos;
951 nlm_extended_header (outbfd)->helpFileLength = help_size;
953 free (data);
955 if (message_file != NULL)
957 PTR data;
959 data = xmalloc (message_size);
960 if (fread (data, 1, message_size, message_data) != message_size)
961 non_fatal (_("%s: read: %s"), message_file, strerror (errno));
962 else
964 if (! bfd_set_section_contents (outbfd, message_section, data,
965 (file_ptr) 0, message_size))
966 bfd_fatal (_("message section"));
967 nlm_extended_header (outbfd)->messageFileOffset =
968 message_section->filepos;
969 nlm_extended_header (outbfd)->messageFileLength = message_size;
971 /* FIXME: Are these offsets correct on all platforms? Are
972 they 32 bits on all platforms? What endianness? */
973 nlm_extended_header (outbfd)->languageID =
974 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
975 nlm_extended_header (outbfd)->messageCount =
976 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
978 free (data);
980 if (modules != NULL)
982 PTR data;
983 unsigned char *set;
984 struct string_list *l;
985 bfd_size_type c;
987 data = xmalloc (module_size);
988 c = 0;
989 set = (unsigned char *) data;
990 for (l = modules; l != NULL; l = l->next)
992 *set = strlen (l->string);
993 strncpy (set + 1, l->string, *set);
994 set += *set + 1;
995 ++c;
997 if (! bfd_set_section_contents (outbfd, module_section, data,
998 (file_ptr) 0, module_size))
999 bfd_fatal (_("module section"));
1000 nlm_fixed_header (outbfd)->moduleDependencyOffset =
1001 module_section->filepos;
1002 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
1004 if (rpc_file != NULL)
1006 PTR data;
1008 data = xmalloc (rpc_size);
1009 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
1010 non_fatal (_("%s: read: %s"), rpc_file, strerror (errno));
1011 else
1013 if (! bfd_set_section_contents (outbfd, rpc_section, data,
1014 (file_ptr) 0, rpc_size))
1015 bfd_fatal (_("rpc section"));
1016 nlm_extended_header (outbfd)->RPCDataOffset =
1017 rpc_section->filepos;
1018 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1020 free (data);
1022 if (sharelib_file != NULL)
1024 PTR data;
1026 data = xmalloc (shared_size);
1027 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1028 || fread (data, 1, shared_size, shared_data) != shared_size)
1029 non_fatal (_("%s: read: %s"), sharelib_file, strerror (errno));
1030 else
1032 if (! bfd_set_section_contents (outbfd, shared_section, data,
1033 (file_ptr) 0, shared_size))
1034 bfd_fatal (_("shared section"));
1036 nlm_extended_header (outbfd)->sharedCodeOffset =
1037 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1038 nlm_extended_header (outbfd)->sharedCodeLength =
1039 sharedhdr.codeImageSize;
1040 nlm_extended_header (outbfd)->sharedDataOffset =
1041 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1042 nlm_extended_header (outbfd)->sharedDataLength =
1043 sharedhdr.dataImageSize;
1044 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1045 (sharedhdr.relocationFixupOffset
1046 - shared_offset
1047 + shared_section->filepos);
1048 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1049 sharedhdr.numberOfRelocationFixups;
1050 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1051 (sharedhdr.externalReferencesOffset
1052 - shared_offset
1053 + shared_section->filepos);
1054 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1055 sharedhdr.numberOfExternalReferences;
1056 nlm_extended_header (outbfd)->sharedPublicsOffset =
1057 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1058 nlm_extended_header (outbfd)->sharedPublicsCount =
1059 sharedhdr.numberOfPublics;
1060 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1061 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1062 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1063 sharedhdr.numberOfDebugRecords;
1064 nlm_extended_header (outbfd)->SharedInitializationOffset =
1065 sharedhdr.codeStartOffset;
1066 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1067 sharedhdr.exitProcedureOffset;
1068 free (data);
1070 len = strlen (output_file);
1071 if (len > NLM_MODULE_NAME_SIZE - 2)
1072 len = NLM_MODULE_NAME_SIZE - 2;
1073 nlm_fixed_header (outbfd)->moduleName[0] = len;
1075 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1076 NLM_MODULE_NAME_SIZE - 2);
1077 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1078 for (modname = nlm_fixed_header (outbfd)->moduleName;
1079 *modname != '\0';
1080 modname++)
1081 *modname = TOUPPER (*modname);
1083 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1084 NLM_OLD_THREAD_NAME_LENGTH);
1086 nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1087 nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1089 if (! bfd_close (outbfd))
1090 bfd_fatal (output_file);
1091 if (! bfd_close (inbfd))
1092 bfd_fatal (input_file);
1094 if (unlink_on_exit != NULL)
1095 unlink (unlink_on_exit);
1097 return 0;
1101 /* Show a usage message and exit. */
1103 static void
1104 show_usage (file, status)
1105 FILE *file;
1106 int status;
1108 fprintf (file, _("Usage: %s [option(s)] [in-file [out-file]]\n"), program_name);
1109 fprintf (file, _(" Convert an object file into a NetWare Loadable Module\n"));
1110 fprintf (file, _(" The options are:\n\
1111 -I --input-target=<bfdname> Set the input binary file format\n\
1112 -O --output-target=<bfdname> Set the output binary file format\n\
1113 -T --header-file=<file> Read <file> for NLM header information\n\
1114 -l --linker=<linker> Use <linker> for any linking\n\
1115 -d --debug Display on stderr the linker command line\n\
1116 -h --help Display this information\n\
1117 -v --version Display the program's version\n\
1118 "));
1119 if (status == 0)
1120 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1121 exit (status);
1124 /* Select the output format based on the input architecture, machine,
1125 and endianness. This chooses the appropriate NLM target. */
1127 static const char *
1128 select_output_format (arch, mach, bigendian)
1129 enum bfd_architecture arch;
1130 unsigned long mach;
1131 bfd_boolean bigendian ATTRIBUTE_UNUSED;
1133 switch (arch)
1135 #ifdef NLMCONV_I386
1136 case bfd_arch_i386:
1137 return "nlm32-i386";
1138 #endif
1139 #ifdef NLMCONV_SPARC
1140 case bfd_arch_sparc:
1141 return "nlm32-sparc";
1142 #endif
1143 #ifdef NLMCONV_ALPHA
1144 case bfd_arch_alpha:
1145 return "nlm32-alpha";
1146 #endif
1147 #ifdef NLMCONV_POWERPC
1148 case bfd_arch_powerpc:
1149 return "nlm32-powerpc";
1150 #endif
1151 default:
1152 fatal (_("support not compiled in for %s"),
1153 bfd_printable_arch_mach (arch, mach));
1155 /*NOTREACHED*/
1158 /* The BFD sections are copied in two passes. This function selects
1159 the output section for each input section, and sets up the section
1160 name, size, etc. */
1162 static void
1163 setup_sections (inbfd, insec, data_ptr)
1164 bfd *inbfd ATTRIBUTE_UNUSED;
1165 asection *insec;
1166 PTR data_ptr;
1168 bfd *outbfd = (bfd *) data_ptr;
1169 flagword f;
1170 const char *outname;
1171 asection *outsec;
1172 bfd_vma offset;
1173 bfd_size_type align;
1174 bfd_size_type add;
1175 bfd_size_type secsecsize;
1177 f = bfd_get_section_flags (inbfd, insec);
1178 if (f & SEC_CODE)
1179 outname = NLM_CODE_NAME;
1180 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1181 outname = NLM_INITIALIZED_DATA_NAME;
1182 else if (f & SEC_ALLOC)
1183 outname = NLM_UNINITIALIZED_DATA_NAME;
1184 else
1185 outname = bfd_section_name (inbfd, insec);
1187 outsec = bfd_get_section_by_name (outbfd, outname);
1188 if (outsec == NULL)
1190 outsec = bfd_make_section (outbfd, outname);
1191 if (outsec == NULL)
1192 bfd_fatal (_("make section"));
1195 insec->output_section = outsec;
1197 offset = bfd_section_size (outbfd, outsec);
1198 align = 1 << bfd_section_alignment (inbfd, insec);
1199 add = ((offset + align - 1) &~ (align - 1)) - offset;
1200 insec->output_offset = offset + add;
1202 if (! bfd_set_section_size (outbfd, outsec,
1203 (bfd_section_size (outbfd, outsec)
1204 + bfd_section_size (inbfd, insec)
1205 + add)))
1206 bfd_fatal (_("set section size"));
1208 if ((bfd_section_alignment (inbfd, insec)
1209 > bfd_section_alignment (outbfd, outsec))
1210 && ! bfd_set_section_alignment (outbfd, outsec,
1211 bfd_section_alignment (inbfd, insec)))
1212 bfd_fatal (_("set section alignment"));
1214 if (! bfd_set_section_flags (outbfd, outsec,
1215 f | bfd_get_section_flags (outbfd, outsec)))
1216 bfd_fatal (_("set section flags"));
1218 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1220 /* For each input section we allocate space for an entry in
1221 .nlmsections. */
1222 secsecsize = bfd_section_size (outbfd, secsec);
1223 secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1224 secsecsize = (secsecsize + 3) &~ 3;
1225 secsecsize += 8;
1226 if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1227 bfd_fatal (_("set .nlmsections size"));
1230 /* Copy the section contents. */
1232 static void
1233 copy_sections (inbfd, insec, data_ptr)
1234 bfd *inbfd;
1235 asection *insec;
1236 PTR data_ptr;
1238 static bfd_size_type secsecoff = 0;
1239 bfd *outbfd = (bfd *) data_ptr;
1240 const char *inname;
1241 asection *outsec;
1242 bfd_size_type size;
1243 PTR contents;
1244 long reloc_size;
1245 bfd_byte buf[4];
1246 bfd_size_type add;
1248 inname = bfd_section_name (inbfd, insec);
1250 outsec = insec->output_section;
1251 assert (outsec != NULL);
1253 size = bfd_get_section_size_before_reloc (insec);
1255 /* FIXME: Why are these necessary? */
1256 insec->_cooked_size = insec->_raw_size;
1257 insec->reloc_done = TRUE;
1259 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1260 contents = NULL;
1261 else
1263 contents = xmalloc (size);
1264 if (! bfd_get_section_contents (inbfd, insec, contents,
1265 (file_ptr) 0, size))
1266 bfd_fatal (bfd_get_filename (inbfd));
1269 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1270 if (reloc_size < 0)
1271 bfd_fatal (bfd_get_filename (inbfd));
1272 if (reloc_size != 0)
1274 arelent **relocs;
1275 long reloc_count;
1277 relocs = (arelent **) xmalloc (reloc_size);
1278 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1279 if (reloc_count < 0)
1280 bfd_fatal (bfd_get_filename (inbfd));
1281 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1282 size);
1284 /* FIXME: refers to internal BFD fields. */
1285 if (outsec->orelocation != (arelent **) NULL)
1287 bfd_size_type total_count;
1288 arelent **combined;
1290 total_count = reloc_count + outsec->reloc_count;
1291 combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1292 memcpy (combined, outsec->orelocation,
1293 outsec->reloc_count * sizeof (arelent *));
1294 memcpy (combined + outsec->reloc_count, relocs,
1295 (size_t) (reloc_count * sizeof (arelent *)));
1296 free (outsec->orelocation);
1297 reloc_count = total_count;
1298 relocs = combined;
1301 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1304 if (contents != NULL)
1306 if (! bfd_set_section_contents (outbfd, outsec, contents,
1307 insec->output_offset, size))
1308 bfd_fatal (bfd_get_filename (outbfd));
1309 free (contents);
1312 /* Add this section to .nlmsections. */
1313 if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
1314 strlen (inname) + 1))
1315 bfd_fatal (_("set .nlmsection contents"));
1316 secsecoff += strlen (inname) + 1;
1318 add = ((secsecoff + 3) &~ 3) - secsecoff;
1319 if (add != 0)
1321 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1322 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1323 bfd_fatal (_("set .nlmsection contents"));
1324 secsecoff += add;
1327 if (contents != NULL)
1328 bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1329 else
1330 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1331 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1332 bfd_fatal (_("set .nlmsection contents"));
1333 secsecoff += 4;
1335 bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1336 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1337 bfd_fatal (_("set .nlmsection contents"));
1338 secsecoff += 4;
1341 /* Some, perhaps all, NetWare targets require changing the relocs used
1342 by the input formats. */
1344 static void
1345 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1346 contents_size)
1347 bfd *outbfd;
1348 asection *insec;
1349 arelent ***relocs_ptr;
1350 long *reloc_count_ptr;
1351 char *contents;
1352 bfd_size_type contents_size;
1354 switch (bfd_get_arch (outbfd))
1356 #ifdef NLMCONV_I386
1357 case bfd_arch_i386:
1358 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1359 contents, contents_size);
1360 break;
1361 #endif
1362 #ifdef NLMCONV_ALPHA
1363 case bfd_arch_alpha:
1364 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1365 contents, contents_size);
1366 break;
1367 #endif
1368 #ifdef NLMCONV_POWERPC
1369 case bfd_arch_powerpc:
1370 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1371 contents, contents_size);
1372 break;
1373 #endif
1374 default:
1375 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1376 contents, contents_size);
1377 break;
1381 /* By default all we need to do for relocs is change the address by
1382 the output_offset. */
1384 static void
1385 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1386 contents_size)
1387 bfd *outbfd ATTRIBUTE_UNUSED;
1388 asection *insec;
1389 arelent ***relocs_ptr;
1390 long *reloc_count_ptr;
1391 char *contents ATTRIBUTE_UNUSED;
1392 bfd_size_type contents_size ATTRIBUTE_UNUSED;
1394 if (insec->output_offset != 0)
1396 long reloc_count;
1397 register arelent **relocs;
1398 register long i;
1400 reloc_count = *reloc_count_ptr;
1401 relocs = *relocs_ptr;
1402 for (i = 0; i < reloc_count; i++, relocs++)
1403 (*relocs)->address += insec->output_offset;
1407 #ifdef NLMCONV_I386
1409 /* NetWare on the i386 supports a restricted set of relocs, which are
1410 different from those used on other i386 targets. This routine
1411 converts the relocs. It is, obviously, very target dependent. At
1412 the moment, the nlm32-i386 backend performs similar translations;
1413 however, it is more reliable and efficient to do them here. */
1415 static reloc_howto_type nlm_i386_pcrel_howto =
1416 HOWTO (1, /* type */
1417 0, /* rightshift */
1418 2, /* size (0 = byte, 1 = short, 2 = long) */
1419 32, /* bitsize */
1420 TRUE, /* pc_relative */
1421 0, /* bitpos */
1422 complain_overflow_signed, /* complain_on_overflow */
1423 0, /* special_function */
1424 "DISP32", /* name */
1425 TRUE, /* partial_inplace */
1426 0xffffffff, /* src_mask */
1427 0xffffffff, /* dst_mask */
1428 TRUE); /* pcrel_offset */
1430 static void
1431 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1432 contents_size)
1433 bfd *outbfd;
1434 asection *insec;
1435 arelent ***relocs_ptr;
1436 long *reloc_count_ptr;
1437 char *contents;
1438 bfd_size_type contents_size;
1440 long reloc_count, i;
1441 arelent **relocs;
1443 reloc_count = *reloc_count_ptr;
1444 relocs = *relocs_ptr;
1445 for (i = 0; i < reloc_count; i++)
1447 arelent *rel;
1448 asymbol *sym;
1449 bfd_size_type address;
1450 bfd_vma addend;
1452 rel = *relocs++;
1453 sym = *rel->sym_ptr_ptr;
1455 /* We're moving the relocs from the input section to the output
1456 section, so we must adjust the address accordingly. */
1457 address = rel->address;
1458 rel->address += insec->output_offset;
1460 /* Note that no serious harm will ensue if we fail to change a
1461 reloc. The backend will fail when writing out the reloc. */
1463 /* Make sure this reloc is within the data we have. We use only
1464 4 byte relocs here, so we insist on having 4 bytes. */
1465 if (address + 4 > contents_size)
1466 continue;
1468 /* A PC relative reloc entirely within a single section is
1469 completely unnecessary. This can be generated by ld -r. */
1470 if (sym == insec->symbol
1471 && rel->howto != NULL
1472 && rel->howto->pc_relative
1473 && ! rel->howto->pcrel_offset)
1475 --*reloc_count_ptr;
1476 --relocs;
1477 memmove (relocs, relocs + 1,
1478 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1479 continue;
1482 /* Get the amount the relocation will add in. */
1483 addend = rel->addend + sym->value;
1485 /* NetWare doesn't support PC relative relocs against defined
1486 symbols, so we have to eliminate them by doing the relocation
1487 now. We can only do this if the reloc is within a single
1488 section. */
1489 if (rel->howto != NULL
1490 && rel->howto->pc_relative
1491 && bfd_get_section (sym) == insec->output_section)
1493 bfd_vma val;
1495 if (rel->howto->pcrel_offset)
1496 addend -= address;
1498 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1499 val += addend;
1500 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1502 --*reloc_count_ptr;
1503 --relocs;
1504 memmove (relocs, relocs + 1,
1505 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1506 continue;
1509 /* NetWare doesn't support reloc addends, so we get rid of them
1510 here by simply adding them into the object data. We handle
1511 the symbol value, if any, the same way. */
1512 if (addend != 0
1513 && rel->howto != NULL
1514 && rel->howto->rightshift == 0
1515 && rel->howto->size == 2
1516 && rel->howto->bitsize == 32
1517 && rel->howto->bitpos == 0
1518 && rel->howto->src_mask == 0xffffffff
1519 && rel->howto->dst_mask == 0xffffffff)
1521 bfd_vma val;
1523 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1524 val += addend;
1525 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1527 /* Adjust the reloc for the changes we just made. */
1528 rel->addend = 0;
1529 if (! bfd_is_und_section (bfd_get_section (sym)))
1530 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1533 /* NetWare uses a reloc with pcrel_offset set. We adjust
1534 pc_relative relocs accordingly. We are going to change the
1535 howto field, so we can only do this if the current one is
1536 compatible. We should check that special_function is NULL
1537 here, but at the moment coff-i386 uses a special_function
1538 which does not affect what we are doing here. */
1539 if (rel->howto != NULL
1540 && rel->howto->pc_relative
1541 && ! rel->howto->pcrel_offset
1542 && rel->howto->rightshift == 0
1543 && rel->howto->size == 2
1544 && rel->howto->bitsize == 32
1545 && rel->howto->bitpos == 0
1546 && rel->howto->src_mask == 0xffffffff
1547 && rel->howto->dst_mask == 0xffffffff)
1549 bfd_vma val;
1551 /* When pcrel_offset is not set, it means that the negative
1552 of the address of the memory location is stored in the
1553 memory location. We must add it back in. */
1554 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1555 val += address;
1556 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1558 /* We must change to a new howto. */
1559 rel->howto = &nlm_i386_pcrel_howto;
1564 #endif /* NLMCONV_I386 */
1566 #ifdef NLMCONV_ALPHA
1568 /* On the Alpha the first reloc for every section must be a special
1569 relocs which hold the GP address. Also, the first reloc in the
1570 file must be a special reloc which holds the address of the .lita
1571 section. */
1573 static reloc_howto_type nlm32_alpha_nw_howto =
1574 HOWTO (ALPHA_R_NW_RELOC, /* type */
1575 0, /* rightshift */
1576 0, /* size (0 = byte, 1 = short, 2 = long) */
1577 0, /* bitsize */
1578 FALSE, /* pc_relative */
1579 0, /* bitpos */
1580 complain_overflow_dont, /* complain_on_overflow */
1581 0, /* special_function */
1582 "NW_RELOC", /* name */
1583 FALSE, /* partial_inplace */
1584 0, /* src_mask */
1585 0, /* dst_mask */
1586 FALSE); /* pcrel_offset */
1588 static void
1589 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1590 contents_size)
1591 bfd *outbfd;
1592 asection *insec;
1593 register arelent ***relocs_ptr;
1594 long *reloc_count_ptr;
1595 char *contents ATTRIBUTE_UNUSED;
1596 bfd_size_type contents_size ATTRIBUTE_UNUSED;
1598 long old_reloc_count;
1599 arelent **old_relocs;
1600 register arelent **relocs;
1602 old_reloc_count = *reloc_count_ptr;
1603 old_relocs = *relocs_ptr;
1604 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1605 *relocs_ptr = relocs;
1607 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1609 bfd *inbfd;
1610 asection *lita_section;
1612 inbfd = insec->owner;
1613 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1614 if (lita_section != (asection *) NULL)
1616 nlm_alpha_backend_data (outbfd)->lita_address =
1617 bfd_get_section_vma (inbfd, lita_section);
1618 nlm_alpha_backend_data (outbfd)->lita_size =
1619 bfd_section_size (inbfd, lita_section);
1621 else
1623 /* Avoid outputting this reloc again. */
1624 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1627 *relocs = (arelent *) xmalloc (sizeof (arelent));
1628 (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1629 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1630 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1631 (*relocs)->howto = &nlm32_alpha_nw_howto;
1632 ++relocs;
1633 ++(*reloc_count_ptr);
1636 /* Get the GP value from bfd. */
1637 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1638 nlm_alpha_backend_data (outbfd)->gp =
1639 bfd_ecoff_get_gp_value (insec->owner);
1641 *relocs = (arelent *) xmalloc (sizeof (arelent));
1642 (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1643 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1644 (*relocs)->addend = 0;
1645 (*relocs)->howto = &nlm32_alpha_nw_howto;
1646 ++relocs;
1647 ++(*reloc_count_ptr);
1649 memcpy ((PTR) relocs, (PTR) old_relocs,
1650 (size_t) old_reloc_count * sizeof (arelent *));
1651 relocs[old_reloc_count] = (arelent *) NULL;
1653 free (old_relocs);
1655 if (insec->output_offset != 0)
1657 register bfd_size_type i;
1659 for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
1660 (*relocs)->address += insec->output_offset;
1664 #endif /* NLMCONV_ALPHA */
1666 #ifdef NLMCONV_POWERPC
1668 /* We keep a linked list of stubs which we must build. Because BFD
1669 requires us to know the sizes of all sections before we can set the
1670 contents of any, we must figure out which stubs we want to build
1671 before we can actually build any of them. */
1673 struct powerpc_stub
1675 /* Next stub in linked list. */
1676 struct powerpc_stub *next;
1678 /* Symbol whose value is the start of the stub. This is a symbol
1679 whose name begins with `.'. */
1680 asymbol *start;
1682 /* Symbol we are going to create a reloc against. This is a symbol
1683 with the same name as START but without the leading `.'. */
1684 asymbol *reloc;
1686 /* The TOC index for this stub. This is the index into the TOC
1687 section at which the reloc is created. */
1688 unsigned int toc_index;
1691 /* The linked list of stubs. */
1693 static struct powerpc_stub *powerpc_stubs;
1695 /* This is what a stub looks like. The first instruction will get
1696 adjusted with the correct TOC index. */
1698 static unsigned long powerpc_stub_insns[] =
1700 0x81820000, /* lwz r12,0(r2) */
1701 0x90410014, /* stw r2,20(r1) */
1702 0x800c0000, /* lwz r0,0(r12) */
1703 0x804c0004, /* lwz r2,r(r12) */
1704 0x7c0903a6, /* mtctr r0 */
1705 0x4e800420, /* bctr */
1706 0, /* Traceback table. */
1707 0xc8000,
1711 #define POWERPC_STUB_INSN_COUNT \
1712 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1714 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1716 /* Each stub uses a four byte TOC entry. */
1717 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1719 /* The original size of the .got section. */
1720 static bfd_size_type powerpc_initial_got_size;
1722 /* Look for all undefined symbols beginning with `.', and prepare to
1723 build a stub for each one. */
1725 static void
1726 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1727 bfd *inbfd;
1728 bfd *outbfd ATTRIBUTE_UNUSED;
1729 asymbol ***symbols_ptr;
1730 long *symcount_ptr;
1732 asection *stub_sec;
1733 asection *got_sec;
1734 unsigned int got_base;
1735 long i;
1736 long symcount;
1737 long stubcount;
1739 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1740 the section to prevent copy_sections from reading from it. */
1741 stub_sec = bfd_make_section (inbfd, ".stubs");
1742 if (stub_sec == (asection *) NULL
1743 || ! bfd_set_section_flags (inbfd, stub_sec,
1744 (SEC_CODE
1745 | SEC_RELOC
1746 | SEC_ALLOC
1747 | SEC_LOAD))
1748 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1749 bfd_fatal (".stubs");
1751 /* Get the TOC section, which is named .got. */
1752 got_sec = bfd_get_section_by_name (inbfd, ".got");
1753 if (got_sec == (asection *) NULL)
1755 got_sec = bfd_make_section (inbfd, ".got");
1756 if (got_sec == (asection *) NULL
1757 || ! bfd_set_section_flags (inbfd, got_sec,
1758 (SEC_DATA
1759 | SEC_RELOC
1760 | SEC_ALLOC
1761 | SEC_LOAD
1762 | SEC_HAS_CONTENTS))
1763 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1764 bfd_fatal (".got");
1767 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1768 got_base = powerpc_initial_got_size;
1769 got_base = (got_base + 3) &~ 3;
1771 stubcount = 0;
1773 symcount = *symcount_ptr;
1774 for (i = 0; i < symcount; i++)
1776 asymbol *sym;
1777 asymbol *newsym;
1778 char *newname;
1779 struct powerpc_stub *item;
1781 sym = (*symbols_ptr)[i];
1783 /* We must make a stub for every undefined symbol whose name
1784 starts with '.'. */
1785 if (bfd_asymbol_name (sym)[0] != '.'
1786 || ! bfd_is_und_section (bfd_get_section (sym)))
1787 continue;
1789 /* Make a new undefined symbol with the same name but without
1790 the leading `.'. */
1791 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1792 *newsym = *sym;
1793 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1794 strcpy (newname, bfd_asymbol_name (sym) + 1);
1795 newsym->name = newname;
1797 /* Define the `.' symbol to be in the stub section. */
1798 sym->section = stub_sec;
1799 sym->value = stubcount * POWERPC_STUB_SIZE;
1800 /* We set the BSF_DYNAMIC flag here so that we can check it when
1801 we are mangling relocs. FIXME: This is a hack. */
1802 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1804 /* Add this stub to the linked list. */
1805 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1806 item->start = sym;
1807 item->reloc = newsym;
1808 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1810 item->next = powerpc_stubs;
1811 powerpc_stubs = item;
1813 ++stubcount;
1816 if (stubcount > 0)
1818 asymbol **s;
1819 struct powerpc_stub *l;
1821 /* Add the new symbols we just created to the symbol table. */
1822 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1823 ((symcount + stubcount)
1824 * sizeof (asymbol)));
1825 *symcount_ptr += stubcount;
1826 s = &(*symbols_ptr)[symcount];
1827 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1828 *s++ = l->reloc;
1830 /* Set the size of the .stubs section and increase the size of
1831 the .got section. */
1832 if (! bfd_set_section_size (inbfd, stub_sec,
1833 stubcount * POWERPC_STUB_SIZE)
1834 || ! bfd_set_section_size (inbfd, got_sec,
1835 (got_base
1836 + (stubcount
1837 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1838 bfd_fatal (_("stub section sizes"));
1842 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1843 of the output section, and create new relocs in the TOC. */
1845 static void
1846 powerpc_resolve_stubs (inbfd, outbfd)
1847 bfd *inbfd;
1848 bfd *outbfd;
1850 bfd_byte buf[POWERPC_STUB_SIZE];
1851 unsigned int i;
1852 unsigned int stubcount;
1853 arelent **relocs;
1854 asection *got_sec;
1855 arelent **r;
1856 struct powerpc_stub *l;
1858 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1859 return;
1861 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1862 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1864 got_sec = bfd_get_section_by_name (inbfd, ".got");
1865 assert (got_sec != (asection *) NULL);
1866 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1868 stubcount = 0;
1869 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1870 ++stubcount;
1871 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1873 r = relocs;
1874 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1876 arelent *reloc;
1878 /* Adjust the first instruction to use the right TOC index. */
1879 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1881 /* Write this stub out. */
1882 if (! bfd_set_section_contents (outbfd,
1883 bfd_get_section (l->start),
1884 buf,
1885 l->start->value,
1886 POWERPC_STUB_SIZE))
1887 bfd_fatal (_("writing stub"));
1889 /* Create a new reloc for the TOC entry. */
1890 reloc = (arelent *) xmalloc (sizeof (arelent));
1891 reloc->sym_ptr_ptr = &l->reloc;
1892 reloc->address = l->toc_index + got_sec->output_offset;
1893 reloc->addend = 0;
1894 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1896 *r++ = reloc;
1899 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1902 /* Adjust relocation entries for PowerPC NetWare. We do not output
1903 TOC relocations. The object code already contains the offset from
1904 the TOC pointer. When the function is called, the TOC register,
1905 r2, will be set to the correct TOC value, so there is no need for
1906 any further reloc. */
1908 static void
1909 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1910 contents_size)
1911 bfd *outbfd;
1912 asection *insec;
1913 register arelent ***relocs_ptr;
1914 long *reloc_count_ptr;
1915 char *contents;
1916 bfd_size_type contents_size ATTRIBUTE_UNUSED;
1918 reloc_howto_type *toc_howto;
1919 long reloc_count;
1920 register arelent **relocs;
1921 register long i;
1923 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1924 if (toc_howto == (reloc_howto_type *) NULL)
1925 abort ();
1927 /* If this is the .got section, clear out all the contents beyond
1928 the initial size. We must do this here because copy_sections is
1929 going to write out whatever we return in the contents field. */
1930 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1931 memset (contents + powerpc_initial_got_size, 0,
1932 (size_t) (bfd_get_section_size_after_reloc (insec)
1933 - powerpc_initial_got_size));
1935 reloc_count = *reloc_count_ptr;
1936 relocs = *relocs_ptr;
1937 for (i = 0; i < reloc_count; i++)
1939 arelent *rel;
1940 asymbol *sym;
1941 bfd_vma sym_value;
1943 rel = *relocs++;
1944 sym = *rel->sym_ptr_ptr;
1946 /* Convert any relocs against the .bss section into relocs
1947 against the .data section. */
1948 if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1949 NLM_UNINITIALIZED_DATA_NAME) == 0)
1951 asection *datasec;
1953 datasec = bfd_get_section_by_name (outbfd,
1954 NLM_INITIALIZED_DATA_NAME);
1955 if (datasec != NULL)
1957 rel->addend += (bfd_get_section_vma (outbfd,
1958 bfd_get_section (sym))
1959 + sym->value);
1960 rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1961 sym = *rel->sym_ptr_ptr;
1965 /* We must be able to resolve all PC relative relocs at this
1966 point. If we get a branch to an undefined symbol we build a
1967 stub, since NetWare will resolve undefined symbols into a
1968 pointer to a function descriptor. */
1969 if (rel->howto->pc_relative)
1971 /* This check for whether a symbol is in the same section as
1972 the reloc will be wrong if there is a PC relative reloc
1973 between two sections both of which were placed in the
1974 same output section. This should not happen. */
1975 if (bfd_get_section (sym) != insec->output_section)
1976 non_fatal (_("unresolved PC relative reloc against %s"),
1977 bfd_asymbol_name (sym));
1978 else
1980 bfd_vma val;
1982 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1983 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1984 val = ((val &~ rel->howto->dst_mask)
1985 | (((val & rel->howto->src_mask)
1986 + (sym->value - rel->address)
1987 + rel->addend)
1988 & rel->howto->dst_mask));
1989 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1991 /* If this reloc is against an stubbed symbol and the
1992 next instruction is
1993 cror 31,31,31
1994 then we replace the next instruction with
1995 lwz r2,20(r1)
1996 This reloads the TOC pointer after a stub call. */
1997 if (bfd_asymbol_name (sym)[0] == '.'
1998 && (sym->flags & BSF_DYNAMIC) != 0
1999 && (bfd_get_32 (outbfd,
2000 (bfd_byte *) contents + rel->address + 4)
2001 == 0x4ffffb82)) /* cror 31,31,31 */
2002 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
2003 (bfd_byte *) contents + rel->address + 4);
2005 --*reloc_count_ptr;
2006 --relocs;
2007 memmove (relocs, relocs + 1,
2008 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
2009 continue;
2013 /* When considering a TOC reloc, we do not want to include the
2014 symbol value. The symbol will be start of the TOC section
2015 (which is named .got). We do want to include the addend. */
2016 if (rel->howto == toc_howto)
2017 sym_value = 0;
2018 else
2019 sym_value = sym->value;
2021 /* If this is a relocation against a symbol with a value, or
2022 there is a reloc addend, we need to update the addend in the
2023 object file. */
2024 if (sym_value + rel->addend != 0)
2026 bfd_vma val;
2028 switch (rel->howto->size)
2030 case 1:
2031 val = bfd_get_16 (outbfd,
2032 (bfd_byte *) contents + rel->address);
2033 val = ((val &~ rel->howto->dst_mask)
2034 | (((val & rel->howto->src_mask)
2035 + sym_value
2036 + rel->addend)
2037 & rel->howto->dst_mask));
2038 if ((bfd_signed_vma) val < - 0x8000
2039 || (bfd_signed_vma) val >= 0x8000)
2040 non_fatal (_("overflow when adjusting relocation against %s"),
2041 bfd_asymbol_name (sym));
2042 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2043 break;
2045 case 2:
2046 val = bfd_get_32 (outbfd,
2047 (bfd_byte *) contents + rel->address);
2048 val = ((val &~ rel->howto->dst_mask)
2049 | (((val & rel->howto->src_mask)
2050 + sym_value
2051 + rel->addend)
2052 & rel->howto->dst_mask));
2053 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2054 break;
2056 default:
2057 abort ();
2060 if (! bfd_is_und_section (bfd_get_section (sym)))
2061 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2062 rel->addend = 0;
2065 /* Now that we have incorporated the addend, remove any TOC
2066 relocs. */
2067 if (rel->howto == toc_howto)
2069 --*reloc_count_ptr;
2070 --relocs;
2071 memmove (relocs, relocs + 1,
2072 (size_t) ((reloc_count - i) * sizeof (arelent *)));
2073 continue;
2076 rel->address += insec->output_offset;
2080 #endif /* NLMCONV_POWERPC */
2082 /* Name of linker. */
2083 #ifndef LD_NAME
2084 #define LD_NAME "ld"
2085 #endif
2087 /* The user has specified several input files. Invoke the linker to
2088 link them all together, and convert and delete the resulting output
2089 file. */
2091 static char *
2092 link_inputs (inputs, ld)
2093 struct string_list *inputs;
2094 char *ld;
2096 size_t c;
2097 struct string_list *q;
2098 char **argv;
2099 size_t i;
2100 int pid;
2101 int status;
2102 char *errfmt;
2103 char *errarg;
2105 c = 0;
2106 for (q = inputs; q != NULL; q = q->next)
2107 ++c;
2109 argv = (char **) alloca ((c + 5) * sizeof(char *));
2111 #ifndef __MSDOS__
2112 if (ld == NULL)
2114 char *p;
2116 /* Find the linker to invoke based on how nlmconv was run. */
2117 p = program_name + strlen (program_name);
2118 while (p != program_name)
2120 if (p[-1] == '/')
2122 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2123 memcpy (ld, program_name, p - program_name);
2124 strcpy (ld + (p - program_name), LD_NAME);
2125 break;
2127 --p;
2130 #endif
2132 if (ld == NULL)
2133 ld = (char *) LD_NAME;
2135 unlink_on_exit = make_temp_file (".O");
2137 argv[0] = ld;
2138 argv[1] = (char *) "-Ur";
2139 argv[2] = (char *) "-o";
2140 argv[3] = unlink_on_exit;
2141 i = 4;
2142 for (q = inputs; q != NULL; q = q->next, i++)
2143 argv[i] = q->string;
2144 argv[i] = NULL;
2146 if (debug)
2148 for (i = 0; argv[i] != NULL; i++)
2149 fprintf (stderr, " %s", argv[i]);
2150 fprintf (stderr, "\n");
2153 pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2154 PEXECUTE_SEARCH | PEXECUTE_ONE);
2155 if (pid == -1)
2157 fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2158 fprintf (stderr, errfmt, errarg);
2159 unlink (unlink_on_exit);
2160 exit (1);
2163 if (pwait (pid, &status, 0) < 0)
2165 perror ("pwait");
2166 unlink (unlink_on_exit);
2167 exit (1);
2170 if (status != 0)
2172 non_fatal (_("Execution of %s failed"), ld);
2173 unlink (unlink_on_exit);
2174 exit (1);
2177 return unlink_on_exit;