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