* nlmconv.c (main): Use CyGnUsEx rather than CyGnUsSeCs for
[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_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
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_ext_header (outbfd)->offset = secsec->filepos;
1082 nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1083
1084 if (! bfd_close (outbfd))
1085 bfd_fatal (output_file);
1086 if (! bfd_close (inbfd))
1087 bfd_fatal (input_file);
1088
1089 if (unlink_on_exit != NULL)
1090 unlink (unlink_on_exit);
1091
1092 return 0;
1093 }
1094 \f
1095 /* Display a help message and exit. */
1096
1097 static void
1098 show_help ()
1099 {
1100 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
1101 program_name);
1102 show_usage (stdout, 0);
1103 }
1104
1105 /* Show a usage message and exit. */
1106
1107 static void
1108 show_usage (file, status)
1109 FILE *file;
1110 int status;
1111 {
1112 fprintf (file, "\
1113 Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
1114 [--input-target=bfdname] [--output-target=bfdname]\n\
1115 [--header-file=file] [--linker=linker] [--debug]\n\
1116 [--help] [--version]\n\
1117 [in-file [out-file]]\n",
1118 program_name);
1119 exit (status);
1120 }
1121 \f
1122 /* Select the output format based on the input architecture, machine,
1123 and endianness. This chooses the appropriate NLM target. */
1124
1125 static const char *
1126 select_output_format (arch, mach, bigendian)
1127 enum bfd_architecture arch;
1128 unsigned long mach;
1129 boolean bigendian;
1130 {
1131 switch (arch)
1132 {
1133 case bfd_arch_i386:
1134 return "nlm32-i386";
1135 case bfd_arch_sparc:
1136 return "nlm32-sparc";
1137 case bfd_arch_alpha:
1138 return "nlm32-alpha";
1139 /* start-sanitize-powerpc-netware */
1140 case bfd_arch_powerpc:
1141 return "nlm32-powerpc";
1142 /* end-sanitize-powerpc-netware */
1143 default:
1144 fprintf (stderr, "%s: no default NLM format for %s\n",
1145 program_name, bfd_printable_arch_mach (arch, mach));
1146 exit (1);
1147 /* Avoid warning. */
1148 return NULL;
1149 }
1150 /*NOTREACHED*/
1151 }
1152 \f
1153 /* The BFD sections are copied in two passes. This function selects
1154 the output section for each input section, and sets up the section
1155 name, size, etc. */
1156
1157 static void
1158 setup_sections (inbfd, insec, data_ptr)
1159 bfd *inbfd;
1160 asection *insec;
1161 PTR data_ptr;
1162 {
1163 bfd *outbfd = (bfd *) data_ptr;
1164 flagword f;
1165 const char *outname;
1166 asection *outsec;
1167 bfd_vma offset;
1168 bfd_size_type align;
1169 bfd_size_type add;
1170 bfd_size_type secsecsize;
1171
1172 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1173 file. However, I don't have a good way to describe this section.
1174 We do want to copy the section when using objcopy. */
1175 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1176 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1177 return;
1178
1179 f = bfd_get_section_flags (inbfd, insec);
1180 if (f & SEC_CODE)
1181 outname = NLM_CODE_NAME;
1182 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1183 outname = NLM_INITIALIZED_DATA_NAME;
1184 else if (f & SEC_ALLOC)
1185 outname = NLM_UNINITIALIZED_DATA_NAME;
1186 else
1187 outname = bfd_section_name (inbfd, insec);
1188
1189 outsec = bfd_get_section_by_name (outbfd, outname);
1190 if (outsec == NULL)
1191 {
1192 outsec = bfd_make_section (outbfd, outname);
1193 if (outsec == NULL)
1194 bfd_fatal ("make section");
1195 }
1196
1197 insec->output_section = outsec;
1198
1199 offset = bfd_section_size (outbfd, outsec);
1200 align = 1 << bfd_section_alignment (inbfd, insec);
1201 add = ((offset + align - 1) &~ (align - 1)) - offset;
1202 insec->output_offset = offset + add;
1203
1204 if (! bfd_set_section_size (outbfd, outsec,
1205 (bfd_section_size (outbfd, outsec)
1206 + bfd_section_size (inbfd, insec)
1207 + add)))
1208 bfd_fatal ("set section size");
1209
1210 if ((bfd_section_alignment (inbfd, insec)
1211 > bfd_section_alignment (outbfd, outsec))
1212 && ! bfd_set_section_alignment (outbfd, outsec,
1213 bfd_section_alignment (inbfd, insec)))
1214 bfd_fatal ("set section alignment");
1215
1216 if (! bfd_set_section_flags (outbfd, outsec, f))
1217 bfd_fatal ("set section flags");
1218
1219 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1220
1221 /* For each input section we allocate space for an entry in
1222 .nlmsections. */
1223 secsecsize = bfd_section_size (outbfd, secsec);
1224 secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1225 secsecsize = (secsecsize + 3) &~ 3;
1226 secsecsize += 8;
1227 if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1228 bfd_fatal ("set .nlmsections size");
1229 }
1230
1231 /* Copy the section contents. */
1232
1233 static void
1234 copy_sections (inbfd, insec, data_ptr)
1235 bfd *inbfd;
1236 asection *insec;
1237 PTR data_ptr;
1238 {
1239 static bfd_size_type secsecoff = 0;
1240 bfd *outbfd = (bfd *) data_ptr;
1241 const char *inname;
1242 asection *outsec;
1243 bfd_size_type size;
1244 PTR contents;
1245 long reloc_size;
1246 bfd_byte buf[4];
1247 bfd_size_type add;
1248
1249 inname = bfd_section_name (inbfd, insec);
1250
1251 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1252 file. However, I don't have a good way to describe this section.
1253 We do want to copy the section when using objcopy. */
1254 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1255 && strcmp (inname, ".reginfo") == 0)
1256 return;
1257
1258 outsec = insec->output_section;
1259 assert (outsec != NULL);
1260
1261 size = bfd_get_section_size_before_reloc (insec);
1262
1263 /* FIXME: Why are these necessary? */
1264 insec->_cooked_size = insec->_raw_size;
1265 insec->reloc_done = true;
1266
1267 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1268 contents = NULL;
1269 else
1270 {
1271 contents = xmalloc (size);
1272 if (! bfd_get_section_contents (inbfd, insec, contents,
1273 (file_ptr) 0, size))
1274 bfd_fatal (bfd_get_filename (inbfd));
1275 }
1276
1277 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1278 if (reloc_size < 0)
1279 bfd_fatal (bfd_get_filename (inbfd));
1280 if (reloc_size != 0)
1281 {
1282 arelent **relocs;
1283 long reloc_count;
1284
1285 relocs = (arelent **) xmalloc (reloc_size);
1286 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1287 if (reloc_count < 0)
1288 bfd_fatal (bfd_get_filename (inbfd));
1289 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1290 size);
1291
1292 /* FIXME: refers to internal BFD fields. */
1293 if (outsec->orelocation != (arelent **) NULL)
1294 {
1295 bfd_size_type total_count;
1296 arelent **combined;
1297
1298 total_count = reloc_count + outsec->reloc_count;
1299 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1300 memcpy (combined, outsec->orelocation,
1301 outsec->reloc_count * sizeof (arelent));
1302 memcpy (combined + outsec->reloc_count, relocs,
1303 (size_t) (reloc_count * sizeof (arelent)));
1304 free (outsec->orelocation);
1305 reloc_count = total_count;
1306 relocs = combined;
1307 }
1308
1309 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1310 }
1311
1312 if (contents != NULL)
1313 {
1314 if (! bfd_set_section_contents (outbfd, outsec, contents,
1315 insec->output_offset, size))
1316 bfd_fatal (bfd_get_filename (outbfd));
1317 free (contents);
1318 }
1319
1320 /* Add this section to .nlmsections. */
1321 if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
1322 strlen (inname) + 1))
1323 bfd_fatal ("set .nlmsection contents");
1324 secsecoff += strlen (inname) + 1;
1325
1326 add = ((secsecoff + 3) &~ 3) - secsecoff;
1327 if (add != 0)
1328 {
1329 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1330 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1331 bfd_fatal ("set .nlmsection contents");
1332 secsecoff += add;
1333 }
1334
1335 if (contents != NULL)
1336 bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1337 else
1338 bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1339 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1340 bfd_fatal ("set .nlmsection contents");
1341 secsecoff += 4;
1342
1343 bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1344 if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1345 bfd_fatal ("set .nlmsection contents");
1346 secsecoff += 4;
1347 }
1348
1349 /* Some, perhaps all, NetWare targets require changing the relocs used
1350 by the input formats. */
1351
1352 static void
1353 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1354 contents_size)
1355 bfd *outbfd;
1356 asection *insec;
1357 arelent ***relocs_ptr;
1358 long *reloc_count_ptr;
1359 char *contents;
1360 bfd_size_type contents_size;
1361 {
1362 switch (bfd_get_arch (outbfd))
1363 {
1364 case bfd_arch_i386:
1365 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1366 contents, contents_size);
1367 break;
1368 case bfd_arch_alpha:
1369 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1370 contents, contents_size);
1371 break;
1372 /* start-sanitize-powerpc-netware */
1373 case bfd_arch_powerpc:
1374 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1375 contents, contents_size);
1376 break;
1377 /* end-sanitize-powerpc-netware */
1378 default:
1379 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1380 contents, contents_size);
1381 break;
1382 }
1383 }
1384
1385 /* By default all we need to do for relocs is change the address by
1386 the output_offset. */
1387
1388 /*ARGSUSED*/
1389 static void
1390 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1391 contents_size)
1392 bfd *outbfd;
1393 asection *insec;
1394 arelent ***relocs_ptr;
1395 long *reloc_count_ptr;
1396 char *contents;
1397 bfd_size_type contents_size;
1398 {
1399 if (insec->output_offset != 0)
1400 {
1401 long reloc_count;
1402 register arelent **relocs;
1403 register long i;
1404
1405 reloc_count = *reloc_count_ptr;
1406 relocs = *relocs_ptr;
1407 for (i = 0; i < reloc_count; i++, relocs++)
1408 (*relocs)->address += insec->output_offset;
1409 }
1410 }
1411
1412 /* NetWare on the i386 supports a restricted set of relocs, which are
1413 different from those used on other i386 targets. This routine
1414 converts the relocs. It is, obviously, very target dependent. At
1415 the moment, the nlm32-i386 backend performs similar translations;
1416 however, it is more reliable and efficient to do them here. */
1417
1418 static reloc_howto_type nlm_i386_pcrel_howto =
1419 HOWTO (1, /* type */
1420 0, /* rightshift */
1421 2, /* size (0 = byte, 1 = short, 2 = long) */
1422 32, /* bitsize */
1423 true, /* pc_relative */
1424 0, /* bitpos */
1425 complain_overflow_signed, /* complain_on_overflow */
1426 0, /* special_function */
1427 "DISP32", /* name */
1428 true, /* partial_inplace */
1429 0xffffffff, /* src_mask */
1430 0xffffffff, /* dst_mask */
1431 true); /* pcrel_offset */
1432
1433 static void
1434 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1435 contents_size)
1436 bfd *outbfd;
1437 asection *insec;
1438 arelent ***relocs_ptr;
1439 long *reloc_count_ptr;
1440 char *contents;
1441 bfd_size_type contents_size;
1442 {
1443 long reloc_count, i;
1444 arelent **relocs;
1445
1446 reloc_count = *reloc_count_ptr;
1447 relocs = *relocs_ptr;
1448 for (i = 0; i < reloc_count; i++)
1449 {
1450 arelent *rel;
1451 asymbol *sym;
1452 bfd_size_type address;
1453 bfd_vma addend;
1454
1455 rel = *relocs++;
1456 sym = *rel->sym_ptr_ptr;
1457
1458 /* We're moving the relocs from the input section to the output
1459 section, so we must adjust the address accordingly. */
1460 address = rel->address;
1461 rel->address += insec->output_offset;
1462
1463 /* Note that no serious harm will ensue if we fail to change a
1464 reloc. The backend will fail when writing out the reloc. */
1465
1466 /* Make sure this reloc is within the data we have. We use only
1467 4 byte relocs here, so we insist on having 4 bytes. */
1468 if (address + 4 > contents_size)
1469 continue;
1470
1471 /* A PC relative reloc entirely within a single section is
1472 completely unnecessary. This can be generated by ld -r. */
1473 if (sym == insec->symbol
1474 && rel->howto != NULL
1475 && rel->howto->pc_relative
1476 && ! rel->howto->pcrel_offset)
1477 {
1478 --*reloc_count_ptr;
1479 --relocs;
1480 memmove (relocs, relocs + 1,
1481 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1482 continue;
1483 }
1484
1485 /* Get the amount the relocation will add in. */
1486 addend = rel->addend + sym->value;
1487
1488 /* NetWare doesn't support PC relative relocs against defined
1489 symbols, so we have to eliminate them by doing the relocation
1490 now. We can only do this if the reloc is within a single
1491 section. */
1492 if (rel->howto != NULL
1493 && rel->howto->pc_relative
1494 && bfd_get_section (sym) == insec->output_section)
1495 {
1496 bfd_vma val;
1497
1498 if (rel->howto->pcrel_offset)
1499 addend -= address;
1500
1501 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1502 val += addend;
1503 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1504
1505 --*reloc_count_ptr;
1506 --relocs;
1507 memmove (relocs, relocs + 1,
1508 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1509 continue;
1510 }
1511
1512 /* NetWare doesn't support reloc addends, so we get rid of them
1513 here by simply adding them into the object data. We handle
1514 the symbol value, if any, the same way. */
1515 if (addend != 0
1516 && rel->howto != NULL
1517 && rel->howto->rightshift == 0
1518 && rel->howto->size == 2
1519 && rel->howto->bitsize == 32
1520 && rel->howto->bitpos == 0
1521 && rel->howto->src_mask == 0xffffffff
1522 && rel->howto->dst_mask == 0xffffffff)
1523 {
1524 bfd_vma val;
1525
1526 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1527 val += addend;
1528 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1529
1530 /* Adjust the reloc for the changes we just made. */
1531 rel->addend = 0;
1532 if (bfd_get_section (sym) != &bfd_und_section)
1533 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1534 }
1535
1536 /* NetWare uses a reloc with pcrel_offset set. We adjust
1537 pc_relative relocs accordingly. We are going to change the
1538 howto field, so we can only do this if the current one is
1539 compatible. We should check that special_function is NULL
1540 here, but at the moment coff-i386 uses a special_function
1541 which does not affect what we are doing here. */
1542 if (rel->howto != NULL
1543 && rel->howto->pc_relative
1544 && ! rel->howto->pcrel_offset
1545 && rel->howto->rightshift == 0
1546 && rel->howto->size == 2
1547 && rel->howto->bitsize == 32
1548 && rel->howto->bitpos == 0
1549 && rel->howto->src_mask == 0xffffffff
1550 && rel->howto->dst_mask == 0xffffffff)
1551 {
1552 bfd_vma val;
1553
1554 /* When pcrel_offset is not set, it means that the negative
1555 of the address of the memory location is stored in the
1556 memory location. We must add it back in. */
1557 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1558 val += address;
1559 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1560
1561 /* We must change to a new howto. */
1562 rel->howto = &nlm_i386_pcrel_howto;
1563 }
1564 }
1565 }
1566
1567 /* On the Alpha the first reloc for every section must be a special
1568 relocs which hold the GP address. Also, the first reloc in the
1569 file must be a special reloc which holds the address of the .lita
1570 section. */
1571
1572 static reloc_howto_type nlm32_alpha_nw_howto =
1573 HOWTO (ALPHA_R_NW_RELOC, /* type */
1574 0, /* rightshift */
1575 0, /* size (0 = byte, 1 = short, 2 = long) */
1576 0, /* bitsize */
1577 false, /* pc_relative */
1578 0, /* bitpos */
1579 complain_overflow_dont, /* complain_on_overflow */
1580 0, /* special_function */
1581 "NW_RELOC", /* name */
1582 false, /* partial_inplace */
1583 0, /* src_mask */
1584 0, /* dst_mask */
1585 false); /* pcrel_offset */
1586
1587 /*ARGSUSED*/
1588 static void
1589 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1590 contents_size)
1591 bfd *outbfd;
1592 asection *insec;
1593 register arelent ***relocs_ptr;
1594 long *reloc_count_ptr;
1595 char *contents;
1596 bfd_size_type contents_size;
1597 {
1598 long old_reloc_count;
1599 arelent **old_relocs;
1600 register arelent **relocs;
1601
1602 old_reloc_count = *reloc_count_ptr;
1603 old_relocs = *relocs_ptr;
1604 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1605 *relocs_ptr = relocs;
1606
1607 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1608 {
1609 bfd *inbfd;
1610 asection *lita_section;
1611
1612 inbfd = insec->owner;
1613 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1614 if (lita_section != (asection *) NULL)
1615 {
1616 nlm_alpha_backend_data (outbfd)->lita_address =
1617 bfd_get_section_vma (inbfd, lita_section);
1618 nlm_alpha_backend_data (outbfd)->lita_size =
1619 bfd_section_size (inbfd, lita_section);
1620 }
1621 else
1622 {
1623 /* Avoid outputting this reloc again. */
1624 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1625 }
1626
1627 *relocs = (arelent *) xmalloc (sizeof (arelent));
1628 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1629 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1630 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1631 (*relocs)->howto = &nlm32_alpha_nw_howto;
1632 ++relocs;
1633 ++(*reloc_count_ptr);
1634 }
1635
1636 /* Get the GP value from bfd. It is in the .reginfo section. */
1637 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1638 {
1639 bfd *inbfd;
1640 asection *reginfo_sec;
1641 struct ecoff_reginfo sreginfo;
1642
1643 inbfd = insec->owner;
1644 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1645 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1646 if (reginfo_sec != (asection *) NULL
1647 && bfd_get_section_contents (inbfd, reginfo_sec,
1648 (PTR) &sreginfo, (file_ptr) 0,
1649 sizeof sreginfo) != false)
1650 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1651 }
1652
1653 *relocs = (arelent *) xmalloc (sizeof (arelent));
1654 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1655 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1656 (*relocs)->addend = 0;
1657 (*relocs)->howto = &nlm32_alpha_nw_howto;
1658 ++relocs;
1659 ++(*reloc_count_ptr);
1660
1661 memcpy ((PTR) relocs, (PTR) old_relocs,
1662 (size_t) old_reloc_count * sizeof (arelent *));
1663 relocs[old_reloc_count] = (arelent *) NULL;
1664
1665 free (old_relocs);
1666
1667 if (insec->output_offset != 0)
1668 {
1669 register bfd_size_type i;
1670
1671 for (i = 0; i < old_reloc_count; i++, relocs++)
1672 (*relocs)->address += insec->output_offset;
1673 }
1674 }
1675 /* start-sanitize-powerpc-netware */
1676
1677 /* We keep a linked list of stubs which we must build. Because BFD
1678 requires us to know the sizes of all sections before we can set the
1679 contents of any, we must figure out which stubs we want to build
1680 before we can actually build any of them. */
1681
1682 struct powerpc_stub
1683 {
1684 /* Next stub in linked list. */
1685 struct powerpc_stub *next;
1686
1687 /* Symbol whose value is the start of the stub. This is a symbol
1688 whose name begins with `.'. */
1689 asymbol *start;
1690
1691 /* Symbol we are going to create a reloc against. This is a symbol
1692 with the same name as START but without the leading `.'. */
1693 asymbol *reloc;
1694
1695 /* The TOC index for this stub. This is the index into the TOC
1696 section at which the reloc is created. */
1697 unsigned int toc_index;
1698 };
1699
1700 /* The linked list of stubs. */
1701
1702 static struct powerpc_stub *powerpc_stubs;
1703
1704 /* This is what a stub looks like. The first instruction will get
1705 adjusted with the correct TOC index. */
1706
1707 static unsigned long powerpc_stub_insns[] =
1708 {
1709 0x81820000, /* lwz r12,0(r2) */
1710 0x90410014, /* stw r2,20(r1) */
1711 0x800c0000, /* lwz r0,0(r12) */
1712 0x804c0004, /* lwz r2,r(r12) */
1713 0x7c0903a6, /* mtctr r0 */
1714 0x4e800420, /* bctr */
1715 0, /* Traceback table. */
1716 0xc8000,
1717 0
1718 };
1719
1720 #define POWERPC_STUB_INSN_COUNT \
1721 (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1722
1723 #define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1724
1725 /* Each stub uses a four byte TOC entry. */
1726 #define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1727
1728 /* The original size of the .got section. */
1729 static bfd_size_type powerpc_initial_got_size;
1730
1731 /* Look for all undefined symbols beginning with `.', and prepare to
1732 build a stub for each one. */
1733
1734 static void
1735 powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
1736 bfd *inbfd;
1737 bfd *outbfd;
1738 asymbol ***symbols_ptr;
1739 long *symcount_ptr;
1740 {
1741 asection *stub_sec;
1742 asection *got_sec;
1743 unsigned int got_base;
1744 long i;
1745 long symcount;
1746 long stubcount;
1747
1748 /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1749 the section to prevent copy_sections from reading from it. */
1750 stub_sec = bfd_make_section (inbfd, ".stubs");
1751 if (stub_sec == (asection *) NULL
1752 || ! bfd_set_section_flags (inbfd, stub_sec,
1753 (SEC_CODE
1754 | SEC_RELOC
1755 | SEC_ALLOC
1756 | SEC_LOAD))
1757 || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1758 bfd_fatal (".stubs");
1759
1760 /* Get the TOC section, which is named .got. */
1761 got_sec = bfd_get_section_by_name (inbfd, ".got");
1762 if (got_sec == (asection *) NULL)
1763 {
1764 got_sec = bfd_make_section (inbfd, ".got");
1765 if (got_sec == (asection *) NULL
1766 || ! bfd_set_section_flags (inbfd, got_sec,
1767 (SEC_DATA
1768 | SEC_RELOC
1769 | SEC_ALLOC
1770 | SEC_LOAD
1771 | SEC_HAS_CONTENTS))
1772 || ! bfd_set_section_alignment (inbfd, got_sec, 2))
1773 bfd_fatal (".got");
1774 }
1775
1776 powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1777 got_base = powerpc_initial_got_size;
1778 got_base = (got_base + 3) &~ 3;
1779
1780 stubcount = 0;
1781
1782 symcount = *symcount_ptr;
1783 for (i = 0; i < symcount; i++)
1784 {
1785 asymbol *sym;
1786 asymbol *newsym;
1787 char *newname;
1788 struct powerpc_stub *item;
1789
1790 sym = (*symbols_ptr)[i];
1791
1792 /* We must make a stub for every undefined symbol whose name
1793 starts with '.'. */
1794 if (bfd_asymbol_name (sym)[0] != '.'
1795 || bfd_get_section (sym) != &bfd_und_section)
1796 continue;
1797
1798 /* Make a new undefined symbol with the same name but without
1799 the leading `.'. */
1800 newsym = (asymbol *) xmalloc (sizeof (asymbol));
1801 *newsym = *sym;
1802 newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
1803 strcpy (newname, bfd_asymbol_name (sym) + 1);
1804 newsym->name = newname;
1805
1806 /* Define the `.' symbol to be in the stub section. */
1807 sym->section = stub_sec;
1808 sym->value = stubcount * POWERPC_STUB_SIZE;
1809 /* We set the BSF_DYNAMIC flag here so that we can check it when
1810 we are mangling relocs. FIXME: This is a hack. */
1811 sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1812
1813 /* Add this stub to the linked list. */
1814 item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1815 item->start = sym;
1816 item->reloc = newsym;
1817 item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1818
1819 item->next = powerpc_stubs;
1820 powerpc_stubs = item;
1821
1822 ++stubcount;
1823 }
1824
1825 if (stubcount > 0)
1826 {
1827 asymbol **s;
1828 struct powerpc_stub *l;
1829
1830 /* Add the new symbols we just created to the symbol table. */
1831 *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1832 ((symcount + stubcount)
1833 * sizeof (asymbol)));
1834 *symcount_ptr += stubcount;
1835 s = &(*symbols_ptr)[symcount];
1836 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1837 *s++ = l->reloc;
1838
1839 /* Set the size of the .stubs section and increase the size of
1840 the .got section. */
1841 if (! bfd_set_section_size (inbfd, stub_sec,
1842 stubcount * POWERPC_STUB_SIZE)
1843 || ! bfd_set_section_size (inbfd, got_sec,
1844 (got_base
1845 + (stubcount
1846 * POWERPC_STUB_TOC_ENTRY_SIZE))))
1847 bfd_fatal ("stub section sizes");
1848 }
1849
1850 /* PowerPC NetWare requires a custom header. We create it here.
1851 The first word is the header version number, currently 1. The
1852 second word is the timestamp of the input file. */
1853 memcpy (nlm_custom_header (outbfd)->stamp, "CuStHeAd", 8);
1854 nlm_custom_header (outbfd)->dataLength = 8;
1855 nlm_custom_header (outbfd)->data = xmalloc (8);
1856 bfd_h_put_32 (outbfd, (bfd_vma) 1,
1857 (bfd_byte *) nlm_custom_header (outbfd)->data);
1858 {
1859 struct stat s;
1860
1861 if (stat (bfd_get_filename (inbfd), &s) < 0)
1862 s.st_mtime = 0;
1863 bfd_h_put_32 (outbfd, (bfd_vma) s.st_mtime,
1864 (bfd_byte *) nlm_custom_header (outbfd)->data + 4);
1865 }
1866 }
1867
1868 /* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1869 of the output section, and create new relocs in the TOC. */
1870
1871 static void
1872 powerpc_resolve_stubs (inbfd, outbfd)
1873 bfd *inbfd;
1874 bfd *outbfd;
1875 {
1876 bfd_byte buf[POWERPC_STUB_SIZE];
1877 unsigned int i;
1878 unsigned int stubcount;
1879 arelent **relocs;
1880 asection *got_sec;
1881 arelent **r;
1882 struct powerpc_stub *l;
1883
1884 if (powerpc_stubs == (struct powerpc_stub *) NULL)
1885 return;
1886
1887 for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1888 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1889
1890 got_sec = bfd_get_section_by_name (inbfd, ".got");
1891 assert (got_sec != (asection *) NULL);
1892 assert (got_sec->output_section->orelocation == (arelent **) NULL);
1893
1894 stubcount = 0;
1895 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1896 ++stubcount;
1897 relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1898
1899 r = relocs;
1900 for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1901 {
1902 arelent *reloc;
1903
1904 /* Adjust the first instruction to use the right TOC index. */
1905 bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1906
1907 /* Write this stub out. */
1908 if (! bfd_set_section_contents (outbfd,
1909 bfd_get_section (l->start),
1910 buf,
1911 l->start->value,
1912 POWERPC_STUB_SIZE))
1913 bfd_fatal ("writing stub");
1914
1915 /* Create a new reloc for the TOC entry. */
1916 reloc = (arelent *) xmalloc (sizeof (arelent));
1917 reloc->sym_ptr_ptr = &l->reloc;
1918 reloc->address = l->toc_index + got_sec->output_offset;
1919 reloc->addend = 0;
1920 reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1921
1922 *r++ = reloc;
1923 }
1924
1925 bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1926 }
1927
1928 /* Adjust relocation entries for PowerPC NetWare. We do not output
1929 TOC relocations. The object code already contains the offset from
1930 the TOC pointer. When the function is called, the TOC register,
1931 r2, will be set to the correct TOC value, so there is no need for
1932 any further reloc. */
1933
1934 /*ARGSUSED*/
1935 static void
1936 powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1937 contents_size)
1938 bfd *outbfd;
1939 asection *insec;
1940 register arelent ***relocs_ptr;
1941 long *reloc_count_ptr;
1942 char *contents;
1943 bfd_size_type contents_size;
1944 {
1945 const reloc_howto_type *toc_howto;
1946 long reloc_count;
1947 register arelent **relocs;
1948 register long i;
1949
1950 toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1951 if (toc_howto == (reloc_howto_type *) NULL)
1952 abort ();
1953
1954 /* If this is the .got section, clear out all the contents beyond
1955 the initial size. We must do this here because copy_sections is
1956 going to write out whatever we return in the contents field. */
1957 if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1958 memset (contents + powerpc_initial_got_size, 0,
1959 (bfd_get_section_size_after_reloc (insec)
1960 - powerpc_initial_got_size));
1961
1962 reloc_count = *reloc_count_ptr;
1963 relocs = *relocs_ptr;
1964 for (i = 0; i < reloc_count; i++)
1965 {
1966 arelent *rel;
1967 asymbol *sym;
1968 bfd_vma symvalue;
1969
1970 rel = *relocs++;
1971 sym = *rel->sym_ptr_ptr;
1972
1973 /* We must be able to resolve all PC relative relocs at this
1974 point. If we get a branch to an undefined symbol we build a
1975 stub, since NetWare will resolve undefined symbols into a
1976 pointer to a function descriptor. */
1977 if (rel->howto->pc_relative)
1978 {
1979 /* This check for whether a symbol is in the same section as
1980 the reloc will be wrong if there is a PC relative reloc
1981 between two sections both of which were placed in the
1982 same output section. This should not happen. */
1983 if (bfd_get_section (sym) != insec->output_section)
1984 fprintf (stderr, "%s: unresolved PC relative reloc against %s\n",
1985 program_name, bfd_asymbol_name (sym));
1986 else
1987 {
1988 bfd_vma val;
1989
1990 assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1991 val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1992 val = ((val &~ rel->howto->dst_mask)
1993 | (((val & rel->howto->src_mask)
1994 + (sym->value - rel->address)
1995 + rel->addend)
1996 & rel->howto->dst_mask));
1997 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1998
1999 /* If this reloc is against an stubbed symbol and the
2000 next instruction is
2001 cror 31,31,31
2002 then we replace the next instruction with
2003 lwz r2,20(r1)
2004 This reloads the TOC pointer after a stub call. */
2005 if (bfd_asymbol_name (sym)[0] == '.'
2006 && (sym->flags & BSF_DYNAMIC) != 0
2007 && (bfd_get_32 (outbfd,
2008 (bfd_byte *) contents + rel->address + 4)
2009 == 0x4ffffb82)) /* cror 31,31,31 */
2010 bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
2011 (bfd_byte *) contents + rel->address + 4);
2012
2013 --*reloc_count_ptr;
2014 --relocs;
2015 memmove (relocs, relocs + 1,
2016 (size_t) ((reloc_count - 1) * sizeof (arelent *)));
2017 continue;
2018 }
2019 }
2020
2021 /* When considering a TOC reloc, we do not want to include the
2022 symbol value. The symbol will be start of the TOC section
2023 (which is named .got). We do want to include the addend. */
2024 if (rel->howto == toc_howto)
2025 symvalue = 0;
2026 else
2027 symvalue = sym->value;
2028
2029 /* If this is a relocation against a symbol with a value, or
2030 there is a reloc addend, we need to update the addend in the
2031 object file. */
2032 if (symvalue + rel->addend != 0)
2033 {
2034 bfd_vma val;
2035
2036 switch (rel->howto->size)
2037 {
2038 case 1:
2039 val = bfd_get_16 (outbfd,
2040 (bfd_byte *) contents + rel->address);
2041 val = ((val &~ rel->howto->dst_mask)
2042 | (((val & rel->howto->src_mask)
2043 + symvalue
2044 + rel->addend)
2045 & rel->howto->dst_mask));
2046 if ((bfd_signed_vma) val < - 0x8000
2047 || (bfd_signed_vma) val >= 0x8000)
2048 fprintf (stderr,
2049 "%s: overflow when adjusting relocation against %s\n",
2050 program_name, bfd_asymbol_name (sym));
2051 bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
2052 break;
2053
2054 case 2:
2055 val = bfd_get_32 (outbfd,
2056 (bfd_byte *) contents + rel->address);
2057 val = ((val &~ rel->howto->dst_mask)
2058 | (((val & rel->howto->src_mask)
2059 + symvalue
2060 + rel->addend)
2061 & rel->howto->dst_mask));
2062 bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2063 break;
2064
2065 default:
2066 abort ();
2067 }
2068
2069 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2070 rel->addend = 0;
2071 }
2072
2073 /* Now that we have incorporated the addend, remove any TOC
2074 relocs. */
2075 if (rel->howto == toc_howto)
2076 {
2077 --*reloc_count_ptr;
2078 --relocs;
2079 memmove (relocs, relocs + 1,
2080 (size_t) ((reloc_count - i) * sizeof (arelent *)));
2081 continue;
2082 }
2083
2084 rel->address += insec->output_offset;
2085 }
2086 }
2087 /* end-sanitize-powerpc-netware */
2088 \f
2089 /* Name of linker. */
2090 #ifndef LD_NAME
2091 #define LD_NAME "ld"
2092 #endif
2093
2094 /* Temporary file name base. */
2095 static char *temp_filename;
2096
2097 /* The user has specified several input files. Invoke the linker to
2098 link them all together, and convert and delete the resulting output
2099 file. */
2100
2101 static char *
2102 link_inputs (inputs, ld)
2103 struct string_list *inputs;
2104 char *ld;
2105 {
2106 size_t c;
2107 struct string_list *q;
2108 char **argv;
2109 size_t i;
2110 int pid;
2111 int status;
2112
2113 c = 0;
2114 for (q = inputs; q != NULL; q = q->next)
2115 ++c;
2116
2117 argv = (char **) alloca (c + 5);
2118
2119 #ifndef __MSDOS__
2120 if (ld == NULL)
2121 {
2122 char *p;
2123
2124 /* Find the linker to invoke based on how nlmconv was run. */
2125 p = program_name + strlen (program_name);
2126 while (p != program_name)
2127 {
2128 if (p[-1] == '/')
2129 {
2130 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2131 memcpy (ld, program_name, p - program_name);
2132 strcpy (ld + (p - program_name), LD_NAME);
2133 break;
2134 }
2135 --p;
2136 }
2137 }
2138 #endif
2139
2140 if (ld == NULL)
2141 ld = (char *) LD_NAME;
2142
2143 choose_temp_base ();
2144
2145 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
2146 sprintf (unlink_on_exit, "%s.O", temp_filename);
2147
2148 argv[0] = ld;
2149 argv[1] = (char *) "-r";
2150 argv[2] = (char *) "-o";
2151 argv[3] = unlink_on_exit;
2152 i = 4;
2153 for (q = inputs; q != NULL; q = q->next, i++)
2154 argv[i] = q->string;
2155 argv[i] = NULL;
2156
2157 if (debug)
2158 {
2159 for (i = 0; argv[i] != NULL; i++)
2160 fprintf (stderr, " %s", argv[i]);
2161 fprintf (stderr, "\n");
2162 }
2163
2164 pid = pexecute (ld, argv);
2165
2166 if (waitpid (pid, &status, 0) < 0)
2167 {
2168 perror ("waitpid");
2169 unlink (unlink_on_exit);
2170 exit (1);
2171 }
2172
2173 if (status != 0)
2174 {
2175 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
2176 unlink (unlink_on_exit);
2177 exit (1);
2178 }
2179
2180 return unlink_on_exit;
2181 }
2182
2183 /* Choose a temporary file name. Stolen from gcc.c. */
2184
2185 static const char *
2186 choose_temp_base_try (try, base)
2187 const char *try;
2188 const char *base;
2189 {
2190 const char *rv;
2191
2192 if (base)
2193 rv = base;
2194 else if (try == NULL)
2195 rv = NULL;
2196 else if (access (try, R_OK | W_OK) != 0)
2197 rv = NULL;
2198 else
2199 rv = try;
2200 return rv;
2201 }
2202
2203 static void
2204 choose_temp_base ()
2205 {
2206 const char *base = NULL;
2207 int len;
2208
2209 base = choose_temp_base_try (getenv ("TMPDIR"), base);
2210 base = choose_temp_base_try (getenv ("TMP"), base);
2211 base = choose_temp_base_try (getenv ("TEMP"), base);
2212
2213 #ifdef P_tmpdir
2214 base = choose_temp_base_try (P_tmpdir, base);
2215 #endif
2216
2217 base = choose_temp_base_try ("/usr/tmp", base);
2218 base = choose_temp_base_try ("/tmp", base);
2219
2220 /* If all else fails, use the current directory! */
2221 if (base == NULL)
2222 base = "./";
2223
2224 len = strlen (base);
2225 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
2226 strcpy (temp_filename, base);
2227 if (len > 0 && temp_filename[len-1] != '/')
2228 temp_filename[len++] = '/';
2229 strcpy (temp_filename + len, "ccXXXXXX");
2230
2231 mktemp (temp_filename);
2232 if (*temp_filename == '\0')
2233 abort ();
2234 }
2235
2236 /* Execute a job. Stolen from gcc.c. */
2237
2238 #ifndef OS2
2239 #ifdef __MSDOS__
2240
2241 static int
2242 pexecute (program, argv)
2243 char *program;
2244 char *argv[];
2245 {
2246 char *scmd, *rf;
2247 FILE *argfile;
2248 int i;
2249
2250 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
2251 rf = scmd + strlen(program) + 2 + el;
2252 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
2253 argfile = fopen (rf, "w");
2254 if (argfile == 0)
2255 pfatal_with_name (rf);
2256
2257 for (i=1; argv[i]; i++)
2258 {
2259 char *cp;
2260 for (cp = argv[i]; *cp; cp++)
2261 {
2262 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2263 fputc ('\\', argfile);
2264 fputc (*cp, argfile);
2265 }
2266 fputc ('\n', argfile);
2267 }
2268 fclose (argfile);
2269
2270 i = system (scmd);
2271
2272 remove (rf);
2273
2274 if (i == -1)
2275 {
2276 perror (program);
2277 return MIN_FATAL_STATUS << 8;
2278 }
2279
2280 return i << 8;
2281 }
2282
2283 #else /* not __MSDOS__ */
2284
2285 static int
2286 pexecute (program, argv)
2287 char *program;
2288 char *argv[];
2289 {
2290 int pid;
2291 int retries, sleep_interval;
2292
2293 /* Fork a subprocess; wait and retry if it fails. */
2294 sleep_interval = 1;
2295 for (retries = 0; retries < 4; retries++)
2296 {
2297 pid = vfork ();
2298 if (pid >= 0)
2299 break;
2300 sleep (sleep_interval);
2301 sleep_interval *= 2;
2302 }
2303
2304 switch (pid)
2305 {
2306 case -1:
2307 #ifdef vfork
2308 perror ("fork");
2309 #else
2310 perror ("vfork");
2311 #endif
2312 exit (1);
2313 /* NOTREACHED */
2314 return 0;
2315
2316 case 0: /* child */
2317 /* Exec the program. */
2318 execvp (program, argv);
2319 perror (program);
2320 exit (1);
2321 /* NOTREACHED */
2322 return 0;
2323
2324 default:
2325 /* Return child's process number. */
2326 return pid;
2327 }
2328 }
2329
2330 #endif /* not __MSDOS__ */
2331 #else /* not OS2 */
2332
2333 static int
2334 pexecute (program, argv)
2335 char *program;
2336 char *argv[];
2337 {
2338 return spawnvp (1, program, argv);
2339 }
2340 #endif /* not OS2 */