start-sanitize-powerpc-netware
[deliverable/binutils-gdb.git] / binutils / nlmconv.c
1 /* nlmconv.c -- NLM conversion program
2 Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU Binutils.
5
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.
10
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.
15
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. */
19
20 /* Written by Ian Lance Taylor <ian@cygnus.com>.
21
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. */
28
29 #include <ansidecl.h>
30 #include <stdio.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/file.h>
36 #include <assert.h>
37 #include <getopt.h>
38 #include "bfd.h"
39 #include "libiberty.h"
40 #include "sysdep.h"
41 #include "bucomm.h"
42 /* Internal BFD NLM header. */
43 #include "libnlm.h"
44 #include "nlmconv.h"
45
46 /* Needed for Alpha support. */
47 #include "coff/sym.h"
48 #include "coff/ecoff.h"
49
50 /* If strerror is just a macro, we want to use the one from libiberty
51 since it will handle undefined values. */
52 #undef strerror
53 extern char *strerror ();
54
55 #ifndef localtime
56 extern struct tm *localtime ();
57 #endif
58
59 #ifndef getenv
60 extern char *getenv ();
61 #endif
62
63 #ifndef SEEK_SET
64 #define SEEK_SET 0
65 #endif
66
67 #ifndef R_OK
68 #define R_OK 4
69 #define W_OK 2
70 #define X_OK 1
71 #endif
72 \f
73 /* Global variables. */
74
75 /* The name used to invoke the program. */
76 char *program_name;
77
78 /* The version number. */
79 extern char *program_version;
80
81 /* Local variables. */
82
83 /* Whether to print out debugging information (currently just controls
84 whether it prints the linker command if there is one). */
85 static int debug;
86
87 /* The symbol table. */
88 static asymbol **symbols;
89
90 /* A temporary file name to be unlinked on exit. Actually, for most
91 errors, we leave it around. It's not clear whether that is helpful
92 or not. */
93 static char *unlink_on_exit;
94
95 /* The list of long options. */
96 static struct option long_options[] =
97 {
98 { "debug", no_argument, 0, 'd' },
99 { "header-file", required_argument, 0, 'T' },
100 { "help", no_argument, 0, 'h' },
101 { "input-target", required_argument, 0, 'I' },
102 { "input-format", required_argument, 0, 'I' }, /* Obsolete */
103 { "linker", required_argument, 0, 'l' },
104 { "output-target", required_argument, 0, 'O' },
105 { "output-format", required_argument, 0, 'O' }, /* Obsolete */
106 { "version", no_argument, 0, 'V' },
107 { NULL, no_argument, 0, 0 }
108 };
109
110 /* Local routines. */
111
112 static void show_help PARAMS ((void));
113 static void show_usage PARAMS ((FILE *, int));
114 static const char *select_output_format PARAMS ((enum bfd_architecture,
115 unsigned long, boolean));
116 static void setup_sections PARAMS ((bfd *, asection *, PTR));
117 static void copy_sections PARAMS ((bfd *, asection *, PTR));
118 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
119 long *, char *,
120 bfd_size_type));
121 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
122 long *, char *,
123 bfd_size_type));
124 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
125 long *, char *,
126 bfd_size_type));
127 /* start-sanitize-powerpc-netware */
128 static void powerpc_build_stubs PARAMS ((bfd *, bfd *, asymbol ***, long *));
129 static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
130 static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
131 long *, char *,
132 bfd_size_type));
133 /* end-sanitize-powerpc-netware */
134 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
135 long *, char *,
136 bfd_size_type));
137 static char *link_inputs PARAMS ((struct string_list *, char *));
138 static const char *choose_temp_base_try PARAMS ((const char *,
139 const char *));
140 static void choose_temp_base PARAMS ((void));
141 static int pexecute PARAMS ((char *, char *[]));
142 \f
143 /* The main routine. */
144
145 int
146 main (argc, argv)
147 int argc;
148 char **argv;
149 {
150 int opt;
151 char *input_file = NULL;
152 const char *input_format = NULL;
153 const char *output_format = NULL;
154 const char *header_file = NULL;
155 char *ld_arg = NULL;
156 Nlm_Internal_Fixed_Header fixed_hdr_struct;
157 Nlm_Internal_Variable_Header var_hdr_struct;
158 Nlm_Internal_Version_Header version_hdr_struct;
159 Nlm_Internal_Copyright_Header copyright_hdr_struct;
160 Nlm_Internal_Extended_Header extended_hdr_struct;
161 bfd *inbfd;
162 bfd *outbfd;
163 asymbol **newsyms, **outsyms;
164 long symcount, newsymalloc, newsymcount;
165 long symsize;
166 asection *text_sec, *bss_sec, *data_sec;
167 bfd_vma vma;
168 bfd_size_type align;
169 asymbol *endsym;
170 long i;
171 char inlead, outlead;
172 boolean gotstart, gotexit, gotcheck;
173 struct stat st;
174 FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
175 size_t custom_size, help_size, message_size, module_size, rpc_size;
176 asection *custom_section, *help_section, *message_section, *module_section;
177 asection *rpc_section, *shared_section;
178 bfd *sharedbfd;
179 size_t shared_offset, shared_size;
180 Nlm_Internal_Fixed_Header sharedhdr;
181 int len;
182 char *modname;
183 char **matching;
184
185 program_name = argv[0];
186 xmalloc_set_program_name (program_name);
187
188 bfd_init ();
189
190 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
191 (int *) NULL))
192 != EOF)
193 {
194 switch (opt)
195 {
196 case 'd':
197 debug = 1;
198 break;
199 case 'h':
200 show_help ();
201 /*NOTREACHED*/
202 case 'I':
203 input_format = optarg;
204 break;
205 case 'l':
206 ld_arg = optarg;
207 break;
208 case 'O':
209 output_format = optarg;
210 break;
211 case 'T':
212 header_file = optarg;
213 break;
214 case 'V':
215 printf ("GNU %s version %s\n", program_name, program_version);
216 exit (0);
217 /*NOTREACHED*/
218 case 0:
219 break;
220 default:
221 show_usage (stderr, 1);
222 /*NOTREACHED*/
223 }
224 }
225
226 /* The input and output files may be named on the command line. */
227 output_file = NULL;
228 if (optind < argc)
229 {
230 input_file = argv[optind];
231 ++optind;
232 if (optind < argc)
233 {
234 output_file = argv[optind];
235 ++optind;
236 if (optind < argc)
237 show_usage (stderr, 1);
238 if (strcmp (input_file, output_file) == 0)
239 {
240 fprintf (stderr,
241 "%s: input and output files must be different\n",
242 program_name);
243 exit (1);
244 }
245 }
246 }
247
248 /* Initialize the header information to default values. */
249 fixed_hdr = &fixed_hdr_struct;
250 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
251 var_hdr = &var_hdr_struct;
252 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
253 version_hdr = &version_hdr_struct;
254 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
255 copyright_hdr = &copyright_hdr_struct;
256 memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
257 extended_hdr = &extended_hdr_struct;
258 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
259 check_procedure = NULL;
260 custom_file = NULL;
261 debug_info = false;
262 exit_procedure = "_Stop";
263 export_symbols = NULL;
264 map_file = NULL;
265 full_map = false;
266 help_file = NULL;
267 import_symbols = NULL;
268 message_file = NULL;
269 modules = NULL;
270 sharelib_file = NULL;
271 start_procedure = "_Prelude";
272 verbose = false;
273 rpc_file = NULL;
274
275 parse_errors = 0;
276
277 /* Parse the header file (if there is one). */
278 if (header_file != NULL)
279 {
280 if (! nlmlex_file (header_file)
281 || yyparse () != 0
282 || parse_errors != 0)
283 exit (1);
284 }
285
286 if (input_files != NULL)
287 {
288 if (input_file != NULL)
289 {
290 fprintf (stderr,
291 "%s: input file named both on command line and with INPUT\n",
292 program_name);
293 exit (1);
294 }
295 if (input_files->next == NULL)
296 input_file = input_files->string;
297 else
298 input_file = link_inputs (input_files, ld_arg);
299 }
300 else if (input_file == NULL)
301 {
302 fprintf (stderr, "%s: no input file\n", program_name);
303 show_usage (stderr, 1);
304 }
305
306 inbfd = bfd_openr (input_file, input_format);
307 if (inbfd == NULL)
308 bfd_fatal (input_file);
309
310 if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
311 {
312 bfd_nonfatal (input_file);
313 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
314 {
315 list_matching_formats (matching);
316 free (matching);
317 }
318 exit (1);
319 }
320
321 if (output_format == NULL)
322 output_format = select_output_format (bfd_get_arch (inbfd),
323 bfd_get_mach (inbfd),
324 inbfd->xvec->byteorder_big_p);
325
326 assert (output_format != NULL);
327
328 /* Use the output file named on the command line if it exists.
329 Otherwise use the file named in the OUTPUT statement. */
330 if (output_file == NULL)
331 {
332 fprintf (stderr, "%s: no name for output file\n",
333 program_name);
334 show_usage (stderr, 1);
335 }
336
337 outbfd = bfd_openw (output_file, output_format);
338 if (outbfd == NULL)
339 bfd_fatal (output_file);
340 if (! bfd_set_format (outbfd, bfd_object))
341 bfd_fatal (output_file);
342
343 assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
344
345 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
346 fprintf (stderr,
347 "%s: warning:input and output formats are not compatible\n",
348 program_name);
349
350 /* Move the values read from the command file into outbfd. */
351 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
352 *nlm_variable_header (outbfd) = var_hdr_struct;
353 *nlm_version_header (outbfd) = version_hdr_struct;
354 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
355 *nlm_extended_header (outbfd) = extended_hdr_struct;
356
357 /* Start copying the input BFD to the output BFD. */
358 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
359 bfd_fatal (bfd_get_filename (outbfd));
360
361 symsize = bfd_get_symtab_upper_bound (inbfd);
362 if (symsize < 0)
363 bfd_fatal (input_file);
364 symbols = (asymbol **) xmalloc (symsize);
365 symcount = bfd_canonicalize_symtab (inbfd, symbols);
366 if (symcount < 0)
367 bfd_fatal (input_file);
368
369 /* Make sure we have a .bss section. */
370 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
371 if (bss_sec == NULL)
372 {
373 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
374 if (bss_sec == NULL
375 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
376 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
377 bfd_fatal ("make .bss section");
378 }
379 /* start-sanitize-powerpc-netware */
380
381 /* For PowerPC NetWare we need to build stubs for calls to undefined
382 symbols. Because each stub requires an entry in the TOC section
383 which must be at the same location as other entries in the TOC
384 section, we must do this before determining where the TOC section
385 goes in setup_sections. */
386 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
387 powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
388 /* end-sanitize-powerpc-netware */
389
390 /* Set up the sections. */
391 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
392
393 text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
394
395 /* The .bss section immediately follows the .data section. */
396 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
397 if (data_sec != NULL)
398 {
399 bfd_size_type add;
400
401 vma = bfd_get_section_size_before_reloc (data_sec);
402 align = 1 << bss_sec->alignment_power;
403 add = ((vma + align - 1) &~ (align - 1)) - vma;
404 vma += add;
405 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
406 bfd_fatal ("set .bss vma");
407 if (add != 0)
408 {
409 bfd_size_type data_size;
410
411 data_size = bfd_get_section_size_before_reloc (data_sec);
412 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
413 bfd_fatal ("set .data size");
414 }
415 }
416
417 /* Adjust symbol information. */
418 inlead = bfd_get_symbol_leading_char (inbfd);
419 outlead = bfd_get_symbol_leading_char (outbfd);
420 gotstart = false;
421 gotexit = false;
422 gotcheck = false;
423 newsymalloc = 10;
424 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
425 newsymcount = 0;
426 endsym = NULL;
427 for (i = 0; i < symcount; i++)
428 {
429 register asymbol *sym;
430
431 sym = symbols[i];
432
433 /* Add or remove a leading underscore. */
434 if (inlead != outlead)
435 {
436 if (inlead != '\0')
437 {
438 if (bfd_asymbol_name (sym)[0] == inlead)
439 {
440 if (outlead == '\0')
441 ++sym->name;
442 else
443 {
444 char *new;
445
446 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
447 new[0] = outlead;
448 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
449 sym->name = new;
450 }
451 }
452 }
453 else
454 {
455 char *new;
456
457 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
458 new[0] = outlead;
459 strcpy (new + 1, bfd_asymbol_name (sym));
460 sym->name = new;
461 }
462 }
463
464 /* NLM's have an uninitialized data section, but they do not
465 have a common section in the Unix sense. Move all common
466 symbols into the .bss section, and mark them as exported. */
467 if (bfd_is_com_section (bfd_get_section (sym)))
468 {
469 bfd_vma size;
470
471 sym->section = bss_sec;
472 size = sym->value;
473 sym->value = bss_sec->_raw_size;
474 bss_sec->_raw_size += size;
475 align = 1 << bss_sec->alignment_power;
476 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
477 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
478 }
479 else if (bfd_get_section (sym)->output_section != NULL)
480 {
481 /* Move the symbol into the output section. */
482 sym->value += bfd_get_section (sym)->output_offset;
483 sym->section = bfd_get_section (sym)->output_section;
484 /* This is no longer a section symbol. */
485 sym->flags &=~ BSF_SECTION_SYM;
486 }
487
488 /* Force _edata and _end to be defined. This would normally be
489 done by the linker, but the manipulation of the common
490 symbols will confuse it. */
491 if ((sym->flags & BSF_DEBUGGING) == 0
492 && bfd_asymbol_name (sym)[0] == '_'
493 && bfd_get_section (sym) == &bfd_und_section)
494 {
495 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
496 {
497 sym->section = bss_sec;
498 sym->value = 0;
499 }
500 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
501 {
502 sym->section = bss_sec;
503 endsym = sym;
504 }
505 /* start-sanitize-powerpc-netware */
506 /* For PowerPC NetWare, we define __GOT0. This is the start
507 of the .got section. */
508 if (bfd_get_arch (inbfd) == bfd_arch_powerpc
509 && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
510 {
511 asection *got_sec;
512
513 got_sec = bfd_get_section_by_name (inbfd, ".got");
514 assert (got_sec != (asection *) NULL);
515 sym->value = got_sec->output_offset;
516 sym->section = got_sec->output_section;
517 }
518 /* end-sanitize-powerpc-netware */
519 }
520
521 /* If this is a global symbol, check the export list. */
522 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
523 {
524 register struct string_list *l;
525 int found_simple;
526
527 /* Unfortunately, a symbol can appear multiple times on the
528 export list, with and without prefixes. */
529 found_simple = 0;
530 for (l = export_symbols; l != NULL; l = l->next)
531 {
532 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
533 found_simple = 1;
534 else
535 {
536 char *zbase;
537
538 zbase = strchr (l->string, '@');
539 if (zbase != NULL
540 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
541 {
542 /* We must add a symbol with this prefix. */
543 if (newsymcount >= newsymalloc)
544 {
545 newsymalloc += 10;
546 newsyms = ((asymbol **)
547 xrealloc ((PTR) newsyms,
548 (newsymalloc
549 * sizeof (asymbol *))));
550 }
551 newsyms[newsymcount] =
552 (asymbol *) xmalloc (sizeof (asymbol));
553 *newsyms[newsymcount] = *sym;
554 newsyms[newsymcount]->name = l->string;
555 ++newsymcount;
556 }
557 }
558 }
559 if (! found_simple)
560 {
561 /* The unmodified symbol is actually not exported at
562 all. */
563 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
564 sym->flags |= BSF_LOCAL;
565 }
566 }
567
568 /* If it's an undefined symbol, see if it's on the import list.
569 Change the prefix if necessary. */
570 if (bfd_get_section (sym) == &bfd_und_section)
571 {
572 register struct string_list *l;
573
574 for (l = import_symbols; l != NULL; l = l->next)
575 {
576 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
577 break;
578 else
579 {
580 char *zbase;
581
582 zbase = strchr (l->string, '@');
583 if (zbase != NULL
584 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
585 {
586 sym->name = l->string;
587 break;
588 }
589 }
590 }
591 if (l == NULL)
592 fprintf (stderr,
593 "%s: warning: symbol %s imported but not in import list\n",
594 program_name, bfd_asymbol_name (sym));
595 }
596
597 /* See if it's one of the special named symbols. */
598 if ((sym->flags & BSF_DEBUGGING) == 0)
599 {
600 bfd_vma val;
601
602 /* FIXME: If these symbols are not in the .text section, we
603 add the .text section size to the value. This may not be
604 correct for all targets. I'm not sure how this should
605 really be handled. */
606 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
607 {
608 val = bfd_asymbol_value (sym);
609 if (bfd_get_section (sym) == data_sec
610 && text_sec != (asection *) NULL)
611 val += bfd_section_size (outbfd, text_sec);
612 if (! bfd_set_start_address (outbfd, val))
613 bfd_fatal ("set start address");
614 gotstart = true;
615 }
616 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
617 {
618 val = bfd_asymbol_value (sym);
619 if (bfd_get_section (sym) == data_sec
620 && text_sec != (asection *) NULL)
621 val += bfd_section_size (outbfd, text_sec);
622 nlm_fixed_header (outbfd)->exitProcedureOffset = val;
623 gotexit = true;
624 }
625 if (check_procedure != NULL
626 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
627 {
628 val = bfd_asymbol_value (sym);
629 if (bfd_get_section (sym) == data_sec
630 && text_sec != (asection *) NULL)
631 val += bfd_section_size (outbfd, text_sec);
632 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
633 gotcheck = true;
634 }
635 }
636 }
637
638 if (endsym != NULL)
639 {
640 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
641
642 /* FIXME: If any relocs referring to _end use inplace addends,
643 then I think they need to be updated. This is handled by
644 i386_mangle_relocs. Is it needed for any other object
645 formats? */
646 }
647
648 if (newsymcount == 0)
649 outsyms = symbols;
650 else
651 {
652 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
653 * sizeof (asymbol *));
654 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
655 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
656 outsyms[symcount + newsymcount] = NULL;
657 }
658
659 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
660
661 if (! gotstart)
662 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
663 program_name, start_procedure);
664 if (! gotexit)
665 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
666 program_name, exit_procedure);
667 if (check_procedure != NULL
668 && ! gotcheck)
669 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
670 program_name, check_procedure);
671
672 /* Add additional sections required for the header information. */
673 if (custom_file != NULL)
674 {
675 custom_data = fopen (custom_file, "r");
676 if (custom_data == NULL
677 || fstat (fileno (custom_data), &st) < 0)
678 {
679 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
680 strerror (errno));
681 custom_file = NULL;
682 }
683 else
684 {
685 custom_size = st.st_size;
686 custom_section = bfd_make_section (outbfd, ".nlmcustom");
687 if (custom_section == NULL
688 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
689 || ! bfd_set_section_flags (outbfd, custom_section,
690 SEC_HAS_CONTENTS))
691 bfd_fatal ("custom section");
692 }
693 }
694 if (help_file != NULL)
695 {
696 help_data = fopen (help_file, "r");
697 if (help_data == NULL
698 || fstat (fileno (help_data), &st) < 0)
699 {
700 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
701 strerror (errno));
702 help_file = NULL;
703 }
704 else
705 {
706 help_size = st.st_size;
707 help_section = bfd_make_section (outbfd, ".nlmhelp");
708 if (help_section == NULL
709 || ! bfd_set_section_size (outbfd, help_section, help_size)
710 || ! bfd_set_section_flags (outbfd, help_section,
711 SEC_HAS_CONTENTS))
712 bfd_fatal ("help section");
713 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
714 }
715 }
716 if (message_file != NULL)
717 {
718 message_data = fopen (message_file, "r");
719 if (message_data == NULL
720 || fstat (fileno (message_data), &st) < 0)
721 {
722 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
723 strerror (errno));
724 message_file = NULL;
725 }
726 else
727 {
728 message_size = st.st_size;
729 message_section = bfd_make_section (outbfd, ".nlmmessages");
730 if (message_section == NULL
731 || ! bfd_set_section_size (outbfd, message_section, message_size)
732 || ! bfd_set_section_flags (outbfd, message_section,
733 SEC_HAS_CONTENTS))
734 bfd_fatal ("message section");
735 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
736 }
737 }
738 if (modules != NULL)
739 {
740 struct string_list *l;
741
742 module_size = 0;
743 for (l = modules; l != NULL; l = l->next)
744 module_size += strlen (l->string) + 1;
745 module_section = bfd_make_section (outbfd, ".nlmmodules");
746 if (module_section == NULL
747 || ! bfd_set_section_size (outbfd, module_section, module_size)
748 || ! bfd_set_section_flags (outbfd, module_section,
749 SEC_HAS_CONTENTS))
750 bfd_fatal ("module section");
751 }
752 if (rpc_file != NULL)
753 {
754 rpc_data = fopen (rpc_file, "r");
755 if (rpc_data == NULL
756 || fstat (fileno (rpc_data), &st) < 0)
757 {
758 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
759 strerror (errno));
760 rpc_file = NULL;
761 }
762 else
763 {
764 rpc_size = st.st_size;
765 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
766 if (rpc_section == NULL
767 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
768 || ! bfd_set_section_flags (outbfd, rpc_section,
769 SEC_HAS_CONTENTS))
770 bfd_fatal ("rpc section");
771 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
772 }
773 }
774 if (sharelib_file != NULL)
775 {
776 sharedbfd = bfd_openr (sharelib_file, output_format);
777 if (sharedbfd == NULL
778 || ! bfd_check_format (sharedbfd, bfd_object))
779 {
780 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
781 bfd_errmsg (bfd_get_error ()));
782 sharelib_file = NULL;
783 }
784 else
785 {
786 sharedhdr = *nlm_fixed_header (sharedbfd);
787 bfd_close (sharedbfd);
788 shared_data = fopen (sharelib_file, "r");
789 if (shared_data == NULL
790 || (fstat (fileno (shared_data), &st) < 0))
791 {
792 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
793 strerror (errno));
794 sharelib_file = NULL;
795 }
796 else
797 {
798 /* If we were clever, we could just copy out the
799 sections of the shared library which we actually
800 need. However, we would have to figure out the sizes
801 of the external and public information, and that can
802 not be done without reading through them. */
803 if (sharedhdr.uninitializedDataSize > 0)
804 {
805 /* There is no place to record this information. */
806 fprintf (stderr,
807 "%s:%s: warning: shared libraries can not have uninitialized data\n",
808 program_name, sharelib_file);
809 }
810 shared_offset = st.st_size;
811 if (shared_offset > sharedhdr.codeImageOffset)
812 shared_offset = sharedhdr.codeImageOffset;
813 if (shared_offset > sharedhdr.dataImageOffset)
814 shared_offset = sharedhdr.dataImageOffset;
815 if (shared_offset > sharedhdr.relocationFixupOffset)
816 shared_offset = sharedhdr.relocationFixupOffset;
817 if (shared_offset > sharedhdr.externalReferencesOffset)
818 shared_offset = sharedhdr.externalReferencesOffset;
819 if (shared_offset > sharedhdr.publicsOffset)
820 shared_offset = sharedhdr.publicsOffset;
821 shared_size = st.st_size - shared_offset;
822 shared_section = bfd_make_section (outbfd, ".nlmshared");
823 if (shared_section == NULL
824 || ! bfd_set_section_size (outbfd, shared_section,
825 shared_size)
826 || ! bfd_set_section_flags (outbfd, shared_section,
827 SEC_HAS_CONTENTS))
828 bfd_fatal ("shared section");
829 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
830 }
831 }
832 }
833
834 /* Check whether a version was given. */
835 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
836 fprintf (stderr, "%s: warning: No version number given\n",
837 program_name);
838
839 /* At least for now, always create an extended header, because that
840 is what NLMLINK does. */
841 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
842
843 /* If the date was not given, force it in. */
844 if (nlm_version_header (outbfd)->month == 0
845 && nlm_version_header (outbfd)->day == 0
846 && nlm_version_header (outbfd)->year == 0)
847 {
848 time_t now;
849 struct tm *ptm;
850
851 time (&now);
852 ptm = localtime (&now);
853 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
854 nlm_version_header (outbfd)->day = ptm->tm_mday;
855 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
856 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
857 }
858 /* start-sanitize-powerpc-netware */
859
860 /* Resolve the stubs we build for PowerPC NetWare. */
861 if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
862 powerpc_resolve_stubs (inbfd, outbfd);
863 /* end-sanitize-powerpc-netware */
864
865 /* Copy over the sections. */
866 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
867
868 /* Finish up the header information. */
869 if (custom_file != NULL)
870 {
871 PTR data;
872
873 data = xmalloc (custom_size);
874 if (fread (data, 1, custom_size, custom_data) != custom_size)
875 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
876 strerror (errno));
877 else
878 {
879 if (! bfd_set_section_contents (outbfd, custom_section, data,
880 (file_ptr) 0, custom_size))
881 bfd_fatal ("custom section");
882 nlm_fixed_header (outbfd)->customDataOffset =
883 custom_section->filepos;
884 nlm_fixed_header (outbfd)->customDataSize = custom_size;
885 }
886 free (data);
887 }
888 if (! debug_info)
889 {
890 /* As a special hack, the backend recognizes a debugInfoOffset
891 of -1 to mean that it should not output any debugging
892 information. This can not be handling by fiddling with the
893 symbol table because exported symbols appear in both the
894 export information and the debugging information. */
895 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
896 }
897 if (map_file != NULL)
898 fprintf (stderr,
899 "%s: warning: MAP and FULLMAP are not supported; try ld -M\n",
900 program_name);
901 if (help_file != NULL)
902 {
903 PTR data;
904
905 data = xmalloc (help_size);
906 if (fread (data, 1, help_size, help_data) != help_size)
907 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
908 strerror (errno));
909 else
910 {
911 if (! bfd_set_section_contents (outbfd, help_section, data,
912 (file_ptr) 0, help_size))
913 bfd_fatal ("help section");
914 nlm_extended_header (outbfd)->helpFileOffset =
915 help_section->filepos;
916 nlm_extended_header (outbfd)->helpFileLength = help_size;
917 }
918 free (data);
919 }
920 if (message_file != NULL)
921 {
922 PTR data;
923
924 data = xmalloc (message_size);
925 if (fread (data, 1, message_size, message_data) != message_size)
926 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
927 strerror (errno));
928 else
929 {
930 if (! bfd_set_section_contents (outbfd, message_section, data,
931 (file_ptr) 0, message_size))
932 bfd_fatal ("message section");
933 nlm_extended_header (outbfd)->messageFileOffset =
934 message_section->filepos;
935 nlm_extended_header (outbfd)->messageFileLength = message_size;
936
937 /* FIXME: Are these offsets correct on all platforms? Are
938 they 32 bits on all platforms? What endianness? */
939 nlm_extended_header (outbfd)->languageID =
940 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
941 nlm_extended_header (outbfd)->messageCount =
942 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
943 }
944 free (data);
945 }
946 if (modules != NULL)
947 {
948 PTR data;
949 unsigned char *set;
950 struct string_list *l;
951 bfd_size_type c;
952
953 data = xmalloc (module_size);
954 c = 0;
955 set = (unsigned char *) data;
956 for (l = modules; l != NULL; l = l->next)
957 {
958 *set = strlen (l->string);
959 strncpy (set + 1, l->string, *set);
960 set += *set + 1;
961 ++c;
962 }
963 if (! bfd_set_section_contents (outbfd, module_section, data,
964 (file_ptr) 0, module_size))
965 bfd_fatal ("module section");
966 nlm_fixed_header (outbfd)->moduleDependencyOffset =
967 module_section->filepos;
968 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
969 }
970 if (rpc_file != NULL)
971 {
972 PTR data;
973
974 data = xmalloc (rpc_size);
975 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
976 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
977 strerror (errno));
978 else
979 {
980 if (! bfd_set_section_contents (outbfd, rpc_section, data,
981 (file_ptr) 0, rpc_size))
982 bfd_fatal ("rpc section");
983 nlm_extended_header (outbfd)->RPCDataOffset =
984 rpc_section->filepos;
985 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
986 }
987 free (data);
988 }
989 if (sharelib_file != NULL)
990 {
991 PTR data;
992
993 data = xmalloc (shared_size);
994 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
995 || fread (data, 1, shared_size, shared_data) != shared_size)
996 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
997 strerror (errno));
998 else
999 {
1000 if (! bfd_set_section_contents (outbfd, shared_section, data,
1001 (file_ptr) 0, shared_size))
1002 bfd_fatal ("shared section");
1003 }
1004 nlm_extended_header (outbfd)->sharedCodeOffset =
1005 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1006 nlm_extended_header (outbfd)->sharedCodeLength =
1007 sharedhdr.codeImageSize;
1008 nlm_extended_header (outbfd)->sharedDataOffset =
1009 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1010 nlm_extended_header (outbfd)->sharedDataLength =
1011 sharedhdr.dataImageSize;
1012 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1013 (sharedhdr.relocationFixupOffset
1014 - shared_offset
1015 + shared_section->filepos);
1016 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1017 sharedhdr.numberOfRelocationFixups;
1018 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1019 (sharedhdr.externalReferencesOffset
1020 - shared_offset
1021 + shared_section->filepos);
1022 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1023 sharedhdr.numberOfExternalReferences;
1024 nlm_extended_header (outbfd)->sharedPublicsOffset =
1025 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1026 nlm_extended_header (outbfd)->sharedPublicsCount =
1027 sharedhdr.numberOfPublics;
1028 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1029 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1030 nlm_extended_header (outbfd)->sharedDebugRecordCount =
1031 sharedhdr.numberOfDebugRecords;
1032 nlm_extended_header (outbfd)->SharedInitializationOffset =
1033 sharedhdr.codeStartOffset;
1034 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1035 sharedhdr.exitProcedureOffset;
1036 free (data);
1037 }
1038 len = strlen (output_file);
1039 if (len > NLM_MODULE_NAME_SIZE - 2)
1040 len = NLM_MODULE_NAME_SIZE - 2;
1041 nlm_fixed_header (outbfd)->moduleName[0] = len;
1042
1043 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
1044 NLM_MODULE_NAME_SIZE - 2);
1045 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
1046 for (modname = nlm_fixed_header (outbfd)->moduleName;
1047 *modname != '\0';
1048 modname++)
1049 if (islower (*modname))
1050 *modname = toupper (*modname);
1051
1052 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1053 NLM_OLD_THREAD_NAME_LENGTH);
1054
1055 if (! bfd_close (outbfd))
1056 bfd_fatal (output_file);
1057 if (! bfd_close (inbfd))
1058 bfd_fatal (input_file);
1059
1060 if (unlink_on_exit != NULL)
1061 unlink (unlink_on_exit);
1062
1063 return 0;
1064 }
1065 \f
1066 /* Display a help message and exit. */
1067
1068 static void
1069 show_help ()
1070 {
1071 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1072 program_name);
1073 show_usage (stdout, 0);
1074 }
1075
1076 /* Show a usage message and exit. */
1077
1078 static void
1079 show_usage (file, status)
1080 FILE *file;
1081 int status;
1082 {
1083 fprintf (file, "\
1084 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1085 [--input-target=bfdname] [--output-target=bfdname]\n\
1086 [--header-file=file] [--linker=linker] [--debug]\n\
1087 [--help] [--version]\n\
1088 [in-file [out-file]]\n",
1089 program_name);
1090 exit (status);
1091 }
1092 \f
1093 /* Select the output format based on the input architecture, machine,
1094 and endianness. This chooses the appropriate NLM target. */
1095
1096 static const char *
1097 select_output_format (arch, mach, bigendian)
1098 enum bfd_architecture arch;
1099 unsigned long mach;
1100 boolean bigendian;
1101 {
1102 switch (arch)
1103 {
1104 case bfd_arch_i386:
1105 return "nlm32-i386";
1106 case bfd_arch_sparc:
1107 return "nlm32-sparc";
1108 case bfd_arch_alpha:
1109 return "nlm32-alpha";
1110 /* start-sanitize-powerpc-netware */
1111 case bfd_arch_powerpc:
1112 return "nlm32-powerpc";
1113 /* end-sanitize-powerpc-netware */
1114 default:
1115 fprintf (stderr, "%s: no default NLM format for %s\n",
1116 program_name, bfd_printable_arch_mach (arch, mach));
1117 exit (1);
1118 /* Avoid warning. */
1119 return NULL;
1120 }
1121 /*NOTREACHED*/
1122 }
1123 \f
1124 /* The BFD sections are copied in two passes. This function selects
1125 the output section for each input section, and sets up the section
1126 name, size, etc. */
1127
1128 static void
1129 setup_sections (inbfd, insec, data_ptr)
1130 bfd *inbfd;
1131 asection *insec;
1132 PTR data_ptr;
1133 {
1134 bfd *outbfd = (bfd *) data_ptr;
1135 flagword f;
1136 const char *outname;
1137 asection *outsec;
1138 bfd_vma offset;
1139 bfd_size_type align;
1140 bfd_size_type add;
1141
1142 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1143 file. However, I don't have a good way to describe this section.
1144 We do want to copy the section when using objcopy. */
1145 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1146 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1147 return;
1148
1149 f = bfd_get_section_flags (inbfd, insec);
1150 if (f & SEC_CODE)
1151 outname = NLM_CODE_NAME;
1152 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1153 outname = NLM_INITIALIZED_DATA_NAME;
1154 else if (f & SEC_ALLOC)
1155 outname = NLM_UNINITIALIZED_DATA_NAME;
1156 else
1157 outname = bfd_section_name (inbfd, insec);
1158
1159 outsec = bfd_get_section_by_name (outbfd, outname);
1160 if (outsec == NULL)
1161 {
1162 outsec = bfd_make_section (outbfd, outname);
1163 if (outsec == NULL)
1164 bfd_fatal ("make section");
1165 }
1166
1167 insec->output_section = outsec;
1168
1169 offset = bfd_section_size (outbfd, outsec);
1170 align = 1 << bfd_section_alignment (inbfd, insec);
1171 add = ((offset + align - 1) &~ (align - 1)) - offset;
1172 insec->output_offset = offset + add;
1173
1174 if (! bfd_set_section_size (outbfd, outsec,
1175 (bfd_section_size (outbfd, outsec)
1176 + bfd_section_size (inbfd, insec)
1177 + add)))
1178 bfd_fatal ("set section size");
1179
1180 if ((bfd_section_alignment (inbfd, insec)
1181 > bfd_section_alignment (outbfd, outsec))
1182 && ! bfd_set_section_alignment (outbfd, outsec,
1183 bfd_section_alignment (inbfd, insec)))
1184 bfd_fatal ("set section alignment");
1185
1186 if (! bfd_set_section_flags (outbfd, outsec, f))
1187 bfd_fatal ("set section flags");
1188
1189 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1190 }
1191
1192 /* Copy the section contents. */
1193
1194 static void
1195 copy_sections (inbfd, insec, data_ptr)
1196 bfd *inbfd;
1197 asection *insec;
1198 PTR data_ptr;
1199 {
1200 bfd *outbfd = (bfd *) data_ptr;
1201 asection *outsec;
1202 bfd_size_type size;
1203 PTR contents;
1204 long reloc_size;
1205
1206 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1207 file. However, I don't have a good way to describe this section.
1208 We do want to copy the section when using objcopy. */
1209 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1210 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1211 return;
1212
1213 outsec = insec->output_section;
1214 assert (outsec != NULL);
1215
1216 size = bfd_get_section_size_before_reloc (insec);
1217 if (size == 0)
1218 return;
1219
1220 /* FIXME: Why are these necessary? */
1221 insec->_cooked_size = insec->_raw_size;
1222 insec->reloc_done = true;
1223
1224 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1225 contents = NULL;
1226 else
1227 {
1228 contents = xmalloc (size);
1229 if (! bfd_get_section_contents (inbfd, insec, contents,
1230 (file_ptr) 0, size))
1231 bfd_fatal (bfd_get_filename (inbfd));
1232 }
1233
1234 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1235 if (reloc_size < 0)
1236 bfd_fatal (bfd_get_filename (inbfd));
1237 if (reloc_size != 0)
1238 {
1239 arelent **relocs;
1240 long reloc_count;
1241
1242 relocs = (arelent **) xmalloc (reloc_size);
1243 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1244 if (reloc_count < 0)
1245 bfd_fatal (bfd_get_filename (inbfd));
1246 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1247 size);
1248
1249 /* FIXME: refers to internal BFD fields. */
1250 if (outsec->orelocation != (arelent **) NULL)
1251 {
1252 bfd_size_type total_count;
1253 arelent **combined;
1254
1255 total_count = reloc_count + outsec->reloc_count;
1256 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1257 memcpy (combined, outsec->orelocation,
1258 outsec->reloc_count * sizeof (arelent));
1259 memcpy (combined + outsec->reloc_count, relocs,
1260 (size_t) (reloc_count * sizeof (arelent)));
1261 free (outsec->orelocation);
1262 reloc_count = total_count;
1263 relocs = combined;
1264 }
1265
1266 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1267 }
1268
1269 if (contents != NULL)
1270 {
1271 if (! bfd_set_section_contents (outbfd, outsec, contents,
1272 insec->output_offset, size))
1273 bfd_fatal (bfd_get_filename (outbfd));
1274 free (contents);
1275 }
1276 }
1277
1278 /* Some, perhaps all, NetWare targets require changing the relocs used
1279 by the input formats. */
1280
1281 static void
1282 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1283 contents_size)
1284 bfd *outbfd;
1285 asection *insec;
1286 arelent ***relocs_ptr;
1287 long *reloc_count_ptr;
1288 char *contents;
1289 bfd_size_type contents_size;
1290 {
1291 switch (bfd_get_arch (outbfd))
1292 {
1293 case bfd_arch_i386:
1294 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1295 contents, contents_size);
1296 break;
1297 case bfd_arch_alpha:
1298 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1299 contents, contents_size);
1300 break;
1301 /* start-sanitize-powerpc-netware */
1302 case bfd_arch_powerpc:
1303 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1304 contents, contents_size);
1305 break;
1306 /* end-sanitize-powerpc-netware */
1307 default:
1308 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1309 contents, contents_size);
1310 break;
1311 }
1312 }
1313
1314 /* By default all we need to do for relocs is change the address by
1315 the output_offset. */
1316
1317 /*ARGSUSED*/
1318 static void
1319 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1320 contents_size)
1321 bfd *outbfd;
1322 asection *insec;
1323 arelent ***relocs_ptr;
1324 long *reloc_count_ptr;
1325 char *contents;
1326 bfd_size_type contents_size;
1327 {
1328 if (insec->output_offset != 0)
1329 {
1330 long reloc_count;
1331 register arelent **relocs;
1332 register long i;
1333
1334 reloc_count = *reloc_count_ptr;
1335 relocs = *relocs_ptr;
1336 for (i = 0; i < reloc_count; i++, relocs++)
1337 (*relocs)->address += insec->output_offset;
1338 }
1339 }
1340
1341 /* NetWare on the i386 supports a restricted set of relocs, which are
1342 different from those used on other i386 targets. This routine
1343 converts the relocs. It is, obviously, very target dependent. At
1344 the moment, the nlm32-i386 backend performs similar translations;
1345 however, it is more reliable and efficient to do them here. */
1346
1347 static reloc_howto_type nlm_i386_pcrel_howto =
1348 HOWTO (1, /* type */
1349 0, /* rightshift */
1350 2, /* size (0 = byte, 1 = short, 2 = long) */
1351 32, /* bitsize */
1352 true, /* pc_relative */
1353 0, /* bitpos */
1354 complain_overflow_signed, /* complain_on_overflow */
1355 0, /* special_function */
1356 "DISP32", /* name */
1357 true, /* partial_inplace */
1358 0xffffffff, /* src_mask */
1359 0xffffffff, /* dst_mask */
1360 true); /* pcrel_offset */
1361
1362 static void
1363 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1364 contents_size)
1365 bfd *outbfd;
1366 asection *insec;
1367 arelent ***relocs_ptr;
1368 long *reloc_count_ptr;
1369 char *contents;
1370 bfd_size_type contents_size;
1371 {
1372 long reloc_count, i;
1373 arelent **relocs;
1374
1375 reloc_count = *reloc_count_ptr;
1376 relocs = *relocs_ptr;
1377 for (i = 0; i < reloc_count; i++)
1378 {
1379 arelent *rel;
1380 asymbol *sym;
1381 bfd_size_type address;
1382 bfd_vma addend;
1383
1384 rel = *relocs++;
1385 sym = *rel->sym_ptr_ptr;
1386
1387 /* We're moving the relocs from the input section to the output
1388 section, so we must adjust the address accordingly. */
1389 address = rel->address;
1390 rel->address += insec->output_offset;
1391
1392 /* Note that no serious harm will ensue if we fail to change a
1393 reloc. The backend will fail when writing out the reloc. */
1394
1395 /* Make sure this reloc is within the data we have. We use only
1396 4 byte relocs here, so we insist on having 4 bytes. */
1397 if (address + 4 > contents_size)
1398 continue;
1399
1400 /* A PC relative reloc entirely within a single section is
1401 completely unnecessary. This can be generated by ld -r. */
1402 if (sym == insec->symbol
1403 && rel->howto != NULL
1404 && rel->howto->pc_relative
1405 && ! rel->howto->pcrel_offset)
1406 {
1407 --*reloc_count_ptr;
1408 --relocs;
1409 memmove (relocs, relocs + 1,
1410 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1411 continue;
1412 }
1413
1414 /* Get the amount the relocation will add in. */
1415 addend = rel->addend + sym->value;
1416
1417 /* NetWare doesn't support PC relative relocs against defined
1418 symbols, so we have to eliminate them by doing the relocation
1419 now. We can only do this if the reloc is within a single
1420 section. */
1421 if (rel->howto != NULL
1422 && rel->howto->pc_relative
1423 && bfd_get_section (sym) == insec->output_section)
1424 {
1425 bfd_vma val;
1426
1427 if (rel->howto->pcrel_offset)
1428 addend -= address;
1429
1430 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1431 val += addend;
1432 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1433
1434 --*reloc_count_ptr;
1435 --relocs;
1436 memmove (relocs, relocs + 1,
1437 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1438 continue;
1439 }
1440
1441 /* NetWare doesn't support reloc addends, so we get rid of them
1442 here by simply adding them into the object data. We handle
1443 the symbol value, if any, the same way. */
1444 if (addend != 0
1445 && rel->howto != NULL
1446 && rel->howto->rightshift == 0
1447 && rel->howto->size == 2
1448 && rel->howto->bitsize == 32
1449 && rel->howto->bitpos == 0
1450 && rel->howto->src_mask == 0xffffffff
1451 && rel->howto->dst_mask == 0xffffffff)
1452 {
1453 bfd_vma val;
1454
1455 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1456 val += addend;
1457 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1458
1459 /* Adjust the reloc for the changes we just made. */
1460 rel->addend = 0;
1461 if (bfd_get_section (sym) != &bfd_und_section)
1462 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1463 }
1464
1465 /* NetWare uses a reloc with pcrel_offset set. We adjust
1466 pc_relative relocs accordingly. We are going to change the
1467 howto field, so we can only do this if the current one is
1468 compatible. We should check that special_function is NULL
1469 here, but at the moment coff-i386 uses a special_function
1470 which does not affect what we are doing here. */
1471 if (rel->howto != NULL
1472 && rel->howto->pc_relative
1473 && ! rel->howto->pcrel_offset
1474 && rel->howto->rightshift == 0
1475 && rel->howto->size == 2
1476 && rel->howto->bitsize == 32
1477 && rel->howto->bitpos == 0
1478 && rel->howto->src_mask == 0xffffffff
1479 && rel->howto->dst_mask == 0xffffffff)
1480 {
1481 bfd_vma val;
1482
1483 /* When pcrel_offset is not set, it means that the negative
1484 of the address of the memory location is stored in the
1485 memory location. We must add it back in. */
1486 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1487 val += address;
1488 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1489
1490 /* We must change to a new howto. */
1491 rel->howto = &nlm_i386_pcrel_howto;
1492 }
1493 }
1494 }
1495
1496 /* On the Alpha the first reloc for every section must be a special
1497 relocs which hold the GP address. Also, the first reloc in the
1498 file must be a special reloc which holds the address of the .lita
1499 section. */
1500
1501 static reloc_howto_type nlm32_alpha_nw_howto =
1502 HOWTO (ALPHA_R_NW_RELOC, /* type */
1503 0, /* rightshift */
1504 0, /* size (0 = byte, 1 = short, 2 = long) */
1505 0, /* bitsize */
1506 false, /* pc_relative */
1507 0, /* bitpos */
1508 complain_overflow_dont, /* complain_on_overflow */
1509 0, /* special_function */
1510 "NW_RELOC", /* name */
1511 false, /* partial_inplace */
1512 0, /* src_mask */
1513 0, /* dst_mask */
1514 false); /* pcrel_offset */
1515
1516 /*ARGSUSED*/
1517 static void
1518 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1519 contents_size)
1520 bfd *outbfd;
1521 asection *insec;
1522 register arelent ***relocs_ptr;
1523 long *reloc_count_ptr;
1524 char *contents;
1525 bfd_size_type contents_size;
1526 {
1527 long old_reloc_count;
1528 arelent **old_relocs;
1529 register arelent **relocs;
1530
1531 old_reloc_count = *reloc_count_ptr;
1532 old_relocs = *relocs_ptr;
1533 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1534 *relocs_ptr = relocs;
1535
1536 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1537 {
1538 bfd *inbfd;
1539 asection *lita_section;
1540
1541 inbfd = insec->owner;
1542 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1543 if (lita_section != (asection *) NULL)
1544 {
1545 nlm_alpha_backend_data (outbfd)->lita_address =
1546 bfd_get_section_vma (inbfd, lita_section);
1547 nlm_alpha_backend_data (outbfd)->lita_size =
1548 bfd_section_size (inbfd, lita_section);
1549 }
1550 else
1551 {
1552 /* Avoid outputting this reloc again. */
1553 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1554 }
1555
1556 *relocs = (arelent *) xmalloc (sizeof (arelent));
1557 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1558 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1559 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1560 (*relocs)->howto = &nlm32_alpha_nw_howto;
1561 ++relocs;
1562 ++(*reloc_count_ptr);
1563 }
1564
1565 /* Get the GP value from bfd. It is in the .reginfo section. */
1566 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1567 {
1568 bfd *inbfd;
1569 asection *reginfo_sec;
1570 struct ecoff_reginfo sreginfo;
1571
1572 inbfd = insec->owner;
1573 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1574 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1575 if (reginfo_sec != (asection *) NULL
1576 && bfd_get_section_contents (inbfd, reginfo_sec,
1577 (PTR) &sreginfo, (file_ptr) 0,
1578 sizeof sreginfo) != false)
1579 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1580 }
1581
1582 *relocs = (arelent *) xmalloc (sizeof (arelent));
1583 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1584 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1585 (*relocs)->addend = 0;
1586 (*relocs)->howto = &nlm32_alpha_nw_howto;
1587 ++relocs;
1588 ++(*reloc_count_ptr);
1589
1590 memcpy ((PTR) relocs, (PTR) old_relocs,
1591 (size_t) old_reloc_count * sizeof (arelent *));
1592 relocs[old_reloc_count] = (arelent *) NULL;
1593
1594 free (old_relocs);
1595
1596 if (insec->output_offset != 0)
1597 {
1598 register bfd_size_type i;
1599
1600 for (i = 0; i < old_reloc_count; i++, relocs++)
1601 (*relocs)->address += insec->output_offset;
1602 }
1603 }
1604 /* start-sanitize-powerpc-netware */
1605
1606 /* We keep a linked list of stubs which we must build. Because BFD
1607 requires us to know the sizes of all sections before we can set the
1608 contents of any, we must figure out which stubs we want to build
1609 before we can actually build any of them. */
1610
1611 struct powerpc_stub
1612 {
1613 /* Next stub in linked list. */
1614 struct powerpc_stub *next;
1615
1616 /* Symbol whose value is the start of the stub. This is a symbol
1617 whose name begins with `.'. */
1618 asymbol *start;
1619
1620 /* Symbol we are going to create a reloc against. This is a symbol
1621 with the same name as START but without the leading `.'. */
1622 asymbol *reloc;
1623
1624 /* The TOC index for this stub. This is the index into the TOC
1625 section at which the reloc is created. */
1626 unsigned int toc_index;
1627 };
1628
1629 /* The linked list of stubs. */
1630
1631 static struct powerpc_stub *powerpc_stubs;
1632
1633 /* This is what a stub looks like. The first instruction will get
1634 adjusted with the correct TOC index. */
1635
1636 static unsigned long powerpc_stub_insns[] =
1637 {
1638 0x81820000, /* lwz r12,0(r2) */
1639 0x90410014, /* stw r2,20(r1) */
1640 0x800c0000, /* lwz r0,0(r12) */
1641 0x804c0004, /* lwz r2,r(r12) */
1642 0x7c0903a6, /* mtctr r0 */
1643 0x4e800420, /* bctr */
1644 0, /* Traceback table. */
1645 0xc8000,
1646 0
1647 };
1648
1649 #define POWERPC_STUB_INSN_COUNT \
1650 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1651
1652 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1653
1654 /* Each stub uses a four byte TOC entry. */
1655 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1656
1657 /* The original size of the .got section. */
1658 static bfd_size_type powerpc_initial_got_size;
1659
1660 /* Look for all undefined symbols beginning with `.', and prepare to
1661 build a stub for each one. */
1662
1663 static void
1664 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1665 bfd *inbfd;
1666 bfd *outbfd;
1667 asymbol ***symbols_ptr;
1668 long *symcount_ptr;
1669 {
1670 asection *stub_sec;
1671 asection *got_sec;
1672 unsigned int got_base;
1673 long i;
1674 long symcount;
1675 long stubcount;
1676
1677 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1678 the section to prevent copy_sections from reading from it. */
1679 stub_sec = bfd_make_section (inbfd, ".stubs");
1680 if (stub_sec == (asection *) NULL
1681 || ! bfd_set_section_flags (inbfd, stub_sec,
1682 (SEC_CODE
1683 | SEC_RELOC
1684 | SEC_ALLOC
1685 | SEC_LOAD))
1686 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1687 bfd_fatal (".stubs");
1688
1689 /* Get the TOC section, which is named .got. */
1690 got_sec = bfd_get_section_by_name (inbfd, ".got");
1691 if (got_sec == (asection *) NULL)
1692 {
1693 got_sec = bfd_make_section (inbfd, ".got");
1694 if (got_sec == (asection *) NULL
1695 || ! bfd_set_section_flags (inbfd, got_sec,
1696 (SEC_DATA
1697 | SEC_RELOC
1698 | SEC_ALLOC
1699 | SEC_LOAD
1700 | SEC_HAS_CONTENTS))
1701 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1702 bfd_fatal (".got");
1703 }
1704
1705 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1706 got_base = powerpc_initial_got_size;
1707 got_base = (got_base + 3) &~ 3;
1708
1709 stubcount = 0;
1710
1711 symcount = *symcount_ptr;
1712 for (i = 0; i < symcount; i++)
1713 {
1714 asymbol *sym;
1715 asymbol *newsym;
1716 char *newname;
1717 struct powerpc_stub *item;
1718
1719 sym = (*symbols_ptr)[i];
1720
1721 /* We must make a stub for every undefined symbol whose name
1722 starts with '.'. */
1723 if (bfd_asymbol_name (sym)[0] != '.'
1724 || bfd_get_section (sym) != &bfd_und_section)
1725 continue;
1726
1727 /* Make a new undefined symbol with the same name but without
1728 the leading `.'. */
1729 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1730 *newsym = *sym;
1731 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1732 strcpy (newname, bfd_asymbol_name (sym) + 1);
1733 newsym->name = newname;
1734
1735 /* Define the `.' symbol to be in the stub section. */
1736 sym->section = stub_sec;
1737 sym->value = stubcount * POWERPC_STUB_SIZE;
1738 /* We set the BSF_DYNAMIC flag here so that we can check it when
1739 we are mangling relocs. FIXME: This is a hack. */
1740 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1741
1742 /* Add this stub to the linked list. */
1743 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1744 item->start = sym;
1745 item->reloc = newsym;
1746 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1747
1748 item->next = powerpc_stubs;
1749 powerpc_stubs = item;
1750
1751 ++stubcount;
1752 }
1753
1754 if (stubcount > 0)
1755 {
1756 asymbol **s;
1757 struct powerpc_stub *l;
1758
1759 /* Add the new symbols we just created to the symbol table. */
1760 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1761 ((symcount + stubcount)
1762 * sizeof (asymbol)));
1763 *symcount_ptr += stubcount;
1764 s = &(*symbols_ptr)[symcount];
1765 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1766 *s++ = l->reloc;
1767
1768 /* Set the size of the .stubs section and increase the size of
1769 the .got section. */
1770 if (! bfd_set_section_size (inbfd, stub_sec,
1771 stubcount * POWERPC_STUB_SIZE)
1772 || ! bfd_set_section_size (inbfd, got_sec,
1773 (got_base
1774 + (stubcount
1775 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1776 bfd_fatal ("stub section sizes");
1777 }
1778
1779 /* PowerPC NetWare requires a custom header. We create it here.
1780 The first word is the header version number, currently 1. The
1781 second word is the timestamp of the input file. */
1782 memcpy (nlm_custom_header (outbfd)->stamp, "CuStHeAd", 8);
1783 nlm_custom_header (outbfd)->dataLength = 8;
1784 nlm_custom_header (outbfd)->data = xmalloc (8);
1785 bfd_h_put_32 (outbfd, (bfd_vma) 1,
1786 (bfd_byte *) nlm_custom_header (outbfd)->data);
1787 {
1788 struct stat s;
1789
1790 if (stat (bfd_get_filename (inbfd), &s) < 0)
1791 s.st_mtime = 0;
1792 bfd_h_put_32 (outbfd, (bfd_vma) s.st_mtime,
1793 (bfd_byte *) nlm_custom_header (outbfd)->data + 4);
1794 }
1795 }
1796
1797 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1798 of the output section, and create new relocs in the TOC. */
1799
1800 static void
1801 powerpc_resolve_stubs (inbfd, outbfd)
1802 bfd *inbfd;
1803 bfd *outbfd;
1804 {
1805 bfd_byte buf[POWERPC_STUB_SIZE];
1806 unsigned int i;
1807 unsigned int stubcount;
1808 arelent **relocs;
1809 asection *got_sec;
1810 arelent **r;
1811 struct powerpc_stub *l;
1812
1813 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1814 return;
1815
1816 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1817 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1818
1819 got_sec = bfd_get_section_by_name (inbfd, ".got");
1820 assert (got_sec != (asection *) NULL);
1821 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1822
1823 stubcount = 0;
1824 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1825 ++stubcount;
1826 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1827
1828 r = relocs;
1829 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1830 {
1831 arelent *reloc;
1832
1833 /* Adjust the first instruction to use the right TOC index. */
1834 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1835
1836 /* Write this stub out. */
1837 if (! bfd_set_section_contents (outbfd,
1838 bfd_get_section (l->start),
1839 buf,
1840 l->start->value,
1841 POWERPC_STUB_SIZE))
1842 bfd_fatal ("writing stub");
1843
1844 /* Create a new reloc for the TOC entry. */
1845 reloc = (arelent *) xmalloc (sizeof (arelent));
1846 reloc->sym_ptr_ptr = &l->reloc;
1847 reloc->address = l->toc_index + got_sec->output_offset;
1848 reloc->addend = 0;
1849 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1850
1851 *r++ = reloc;
1852 }
1853
1854 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1855 }
1856
1857 /* Adjust relocation entries for PowerPC NetWare. We do not output
1858 TOC relocations. The object code already contains the offset from
1859 the TOC pointer. When the function is called, the TOC register,
1860 r2, will be set to the correct TOC value, so there is no need for
1861 any further reloc. */
1862
1863 /*ARGSUSED*/
1864 static void
1865 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1866 contents_size)
1867 bfd *outbfd;
1868 asection *insec;
1869 register arelent ***relocs_ptr;
1870 long *reloc_count_ptr;
1871 char *contents;
1872 bfd_size_type contents_size;
1873 {
1874 const reloc_howto_type *toc_howto;
1875 long reloc_count;
1876 register arelent **relocs;
1877 register long i;
1878
1879 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1880 if (toc_howto == (reloc_howto_type *) NULL)
1881 abort ();
1882
1883 /* If this is the .got section, clear out all the contents beyond
1884 the initial size. We must do this here because copy_sections is
1885 going to write out whatever we return in the contents field. */
1886 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1887 memset (contents + powerpc_initial_got_size, 0,
1888 (bfd_get_section_size_after_reloc (insec)
1889 - powerpc_initial_got_size));
1890
1891 reloc_count = *reloc_count_ptr;
1892 relocs = *relocs_ptr;
1893 for (i = 0; i < reloc_count; i++)
1894 {
1895 arelent *rel;
1896 asymbol *sym;
1897 bfd_vma symvalue;
1898
1899 rel = *relocs++;
1900 sym = *rel->sym_ptr_ptr;
1901
1902 /* We must be able to resolve all PC relative relocs at this
1903 point. If we get a branch to an undefined symbol we build a
1904 stub, since NetWare will resolve undefined symbols into a
1905 pointer to a function descriptor. */
1906 if (rel->howto->pc_relative)
1907 {
1908 /* This check for whether a symbol is in the same section as
1909 the reloc will be wrong if there is a PC relative reloc
1910 between two sections both of which were placed in the
1911 same output section. This should not happen. */
1912 if (bfd_get_section (sym) != insec->output_section)
1913 fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1914 program_name, bfd_asymbol_name (sym));
1915 else
1916 {
1917 bfd_vma val;
1918
1919 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1920 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1921 val = ((val &~ rel->howto->dst_mask)
1922 | (((val & rel->howto->src_mask)
1923 + (sym->value - rel->address)
1924 + rel->addend)
1925 & rel->howto->dst_mask));
1926 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1927
1928 /* If this reloc is against an stubbed symbol and the
1929 next instruction is
1930 cror 31,31,31
1931 then we replace the next instruction with
1932 lwz r2,20(r1)
1933 This reloads the TOC pointer after a stub call. */
1934 if (bfd_asymbol_name (sym)[0] == '.'
1935 && (sym->flags & BSF_DYNAMIC) != 0
1936 && (bfd_get_32 (outbfd,
1937 (bfd_byte *) contents + rel->address + 4)
1938 == 0x4ffffb82)) /* cror 31,31,31 */
1939 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1940 (bfd_byte *) contents + rel->address + 4);
1941
1942 --*reloc_count_ptr;
1943 --relocs;
1944 memmove (relocs, relocs + 1,
1945 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
1946 continue;
1947 }
1948 }
1949
1950 /* When considering a TOC reloc, we do not want to include the
1951 symbol value. The symbol will be start of the TOC section
1952 (which is named .got). We do want to include the addend. */
1953 if (rel->howto == toc_howto)
1954 symvalue = 0;
1955 else
1956 symvalue = sym->value;
1957
1958 /* If this is a relocation against a symbol with a value, or
1959 there is a reloc addend, we need to update the addend in the
1960 object file. */
1961 if (symvalue + rel->addend != 0)
1962 {
1963 bfd_vma val;
1964
1965 switch (rel->howto->size)
1966 {
1967 case 1:
1968 val = bfd_get_16 (outbfd,
1969 (bfd_byte *) contents + rel->address);
1970 val = ((val &~ rel->howto->dst_mask)
1971 | (((val & rel->howto->src_mask)
1972 + symvalue
1973 + rel->addend)
1974 & rel->howto->dst_mask));
1975 if ((bfd_signed_vma) val < - 0x8000
1976 || (bfd_signed_vma) val >= 0x8000)
1977 fprintf (stderr,
1978 "%s: overflow when adjusting relocation against %s\n",
1979 program_name, bfd_asymbol_name (sym));
1980 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1981 break;
1982
1983 case 2:
1984 val = bfd_get_32 (outbfd,
1985 (bfd_byte *) contents + rel->address);
1986 val = ((val &~ rel->howto->dst_mask)
1987 | (((val & rel->howto->src_mask)
1988 + symvalue
1989 + rel->addend)
1990 & rel->howto->dst_mask));
1991 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1992 break;
1993
1994 default:
1995 abort ();
1996 }
1997
1998 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1999 rel->addend = 0;
2000 }
2001
2002 /* Now that we have incorporated the addend, remove any TOC
2003 relocs. */
2004 if (rel->howto == toc_howto)
2005 {
2006 --*reloc_count_ptr;
2007 --relocs;
2008 memmove (relocs, relocs + 1,
2009 (size_t) ((reloc_count - i) * sizeof (arelent *)));
2010 continue;
2011 }
2012
2013 rel->address += insec->output_offset;
2014 }
2015 }
2016 /* end-sanitize-powerpc-netware */
2017 \f
2018 /* Name of linker. */
2019 #ifndef LD_NAME
2020 #define LD_NAME "ld"
2021 #endif
2022
2023 /* Temporary file name base. */
2024 static char *temp_filename;
2025
2026 /* The user has specified several input files. Invoke the linker to
2027 link them all together, and convert and delete the resulting output
2028 file. */
2029
2030 static char *
2031 link_inputs (inputs, ld)
2032 struct string_list *inputs;
2033 char *ld;
2034 {
2035 size_t c;
2036 struct string_list *q;
2037 char **argv;
2038 size_t i;
2039 int pid;
2040 int status;
2041
2042 c = 0;
2043 for (q = inputs; q != NULL; q = q->next)
2044 ++c;
2045
2046 argv = (char **) alloca (c + 5);
2047
2048 #ifndef __MSDOS__
2049 if (ld == NULL)
2050 {
2051 char *p;
2052
2053 /* Find the linker to invoke based on how nlmconv was run. */
2054 p = program_name + strlen (program_name);
2055 while (p != program_name)
2056 {
2057 if (p[-1] == '/')
2058 {
2059 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2060 memcpy (ld, program_name, p - program_name);
2061 strcpy (ld + (p - program_name), LD_NAME);
2062 break;
2063 }
2064 --p;
2065 }
2066 }
2067 #endif
2068
2069 if (ld == NULL)
2070 ld = (char *) LD_NAME;
2071
2072 choose_temp_base ();
2073
2074 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2075 sprintf (unlink_on_exit, "%s.O", temp_filename);
2076
2077 argv[0] = ld;
2078 argv[1] = (char *) "-r";
2079 argv[2] = (char *) "-o";
2080 argv[3] = unlink_on_exit;
2081 i = 4;
2082 for (q = inputs; q != NULL; q = q->next, i++)
2083 argv[i] = q->string;
2084 argv[i] = NULL;
2085
2086 if (debug)
2087 {
2088 for (i = 0; argv[i] != NULL; i++)
2089 fprintf (stderr, " %s", argv[i]);
2090 fprintf (stderr, "\n");
2091 }
2092
2093 pid = pexecute (ld, argv);
2094
2095 if (waitpid (pid, &status, 0) < 0)
2096 {
2097 perror ("waitpid");
2098 unlink (unlink_on_exit);
2099 exit (1);
2100 }
2101
2102 if (status != 0)
2103 {
2104 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2105 unlink (unlink_on_exit);
2106 exit (1);
2107 }
2108
2109 return unlink_on_exit;
2110 }
2111
2112 /* Choose a temporary file name. Stolen from gcc.c. */
2113
2114 static const char *
2115 choose_temp_base_try (try, base)
2116 const char *try;
2117 const char *base;
2118 {
2119 const char *rv;
2120
2121 if (base)
2122 rv = base;
2123 else if (try == NULL)
2124 rv = NULL;
2125 else if (access (try, R_OK | W_OK) != 0)
2126 rv = NULL;
2127 else
2128 rv = try;
2129 return rv;
2130 }
2131
2132 static void
2133 choose_temp_base ()
2134 {
2135 const char *base = NULL;
2136 int len;
2137
2138 base = choose_temp_base_try (getenv ("TMPDIR"), base);
2139 base = choose_temp_base_try (getenv ("TMP"), base);
2140 base = choose_temp_base_try (getenv ("TEMP"), base);
2141
2142 #ifdef P_tmpdir
2143 base = choose_temp_base_try (P_tmpdir, base);
2144 #endif
2145
2146 base = choose_temp_base_try ("/usr/tmp", base);
2147 base = choose_temp_base_try ("/tmp", base);
2148
2149 /* If all else fails, use the current directory! */
2150 if (base == NULL)
2151 base = "./";
2152
2153 len = strlen (base);
2154 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2155 strcpy (temp_filename, base);
2156 if (len > 0 && temp_filename[len-1] != '/')
2157 temp_filename[len++] = '/';
2158 strcpy (temp_filename + len, "ccXXXXXX");
2159
2160 mktemp (temp_filename);
2161 if (*temp_filename == '\0')
2162 abort ();
2163 }
2164
2165 /* Execute a job. Stolen from gcc.c. */
2166
2167 #ifndef OS2
2168 #ifdef __MSDOS__
2169
2170 static int
2171 pexecute (program, argv)
2172 char *program;
2173 char *argv[];
2174 {
2175 char *scmd, *rf;
2176 FILE *argfile;
2177 int i;
2178
2179 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2180 rf = scmd + strlen(program) + 2 + el;
2181 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2182 argfile = fopen (rf, "w");
2183 if (argfile == 0)
2184 pfatal_with_name (rf);
2185
2186 for (i=1; argv[i]; i++)
2187 {
2188 char *cp;
2189 for (cp = argv[i]; *cp; cp++)
2190 {
2191 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2192 fputc ('\\', argfile);
2193 fputc (*cp, argfile);
2194 }
2195 fputc ('\n', argfile);
2196 }
2197 fclose (argfile);
2198
2199 i = system (scmd);
2200
2201 remove (rf);
2202
2203 if (i == -1)
2204 {
2205 perror (program);
2206 return MIN_FATAL_STATUS << 8;
2207 }
2208
2209 return i << 8;
2210 }
2211
2212 #else /* not __MSDOS__ */
2213
2214 static int
2215 pexecute (program, argv)
2216 char *program;
2217 char *argv[];
2218 {
2219 int pid;
2220 int retries, sleep_interval;
2221
2222 /* Fork a subprocess; wait and retry if it fails. */
2223 sleep_interval = 1;
2224 for (retries = 0; retries < 4; retries++)
2225 {
2226 pid = vfork ();
2227 if (pid >= 0)
2228 break;
2229 sleep (sleep_interval);
2230 sleep_interval *= 2;
2231 }
2232
2233 switch (pid)
2234 {
2235 case -1:
2236 #ifdef vfork
2237 perror ("fork");
2238 #else
2239 perror ("vfork");
2240 #endif
2241 exit (1);
2242 /* NOTREACHED */
2243 return 0;
2244
2245 case 0: /* child */
2246 /* Exec the program. */
2247 execvp (program, argv);
2248 perror (program);
2249 exit (1);
2250 /* NOTREACHED */
2251 return 0;
2252
2253 default:
2254 /* Return child's process number. */
2255 return pid;
2256 }
2257 }
2258
2259 #endif /* not __MSDOS__ */
2260 #else /* not OS2 */
2261
2262 static int
2263 pexecute (program, argv)
2264 char *program;
2265 char *argv[];
2266 {
2267 return spawnvp (1, program, argv);
2268 }
2269 #endif /* not OS2 */
This page took 0.091058 seconds and 5 git commands to generate.