7fa4c2a635320ff05ef54c72358ebf789d452196
[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 "sysdep.h"
40 #include "bucomm.h"
41 /* Internal BFD NLM header. */
42 #include "libnlm.h"
43 #include "nlmconv.h"
44
45 /* Needed for Alpha support. */
46 #include "coff/sym.h"
47 #include "coff/ecoff.h"
48
49 /* If strerror is just a macro, we want to use the one from libiberty
50 since it will handle undefined values. */
51 #undef strerror
52 extern char *strerror ();
53
54 #ifndef localtime
55 extern struct tm *localtime ();
56 #endif
57
58 #ifndef getenv
59 extern char *getenv ();
60 #endif
61
62 #ifndef SEEK_SET
63 #define SEEK_SET 0
64 #endif
65
66 #ifndef R_OK
67 #define R_OK 4
68 #define W_OK 2
69 #define X_OK 1
70 #endif
71 \f
72 /* Global variables. */
73
74 /* The name used to invoke the program. */
75 char *program_name;
76
77 /* The version number. */
78 extern char *program_version;
79
80 /* Local variables. */
81
82 /* Whether to print out debugging information (currently just controls
83 whether it prints the linker command if there is one). */
84 static int debug;
85
86 /* The symbol table. */
87 static asymbol **symbols;
88
89 /* A temporary file name to be unlinked on exit. Actually, for most
90 errors, we leave it around. It's not clear whether that is helpful
91 or not. */
92 static char *unlink_on_exit;
93
94 /* The list of long options. */
95 static struct option long_options[] =
96 {
97 { "debug", no_argument, 0, 'd' },
98 { "header-file", required_argument, 0, 'T' },
99 { "help", no_argument, 0, 'h' },
100 { "input-format", required_argument, 0, 'I' },
101 { "linker", required_argument, 0, 'l' },
102 { "output-format", required_argument, 0, 'O' },
103 { "version", no_argument, 0, 'V' },
104 { NULL, no_argument, 0, 0 }
105 };
106
107 /* Local routines. */
108
109 static void show_help PARAMS ((void));
110 static void show_usage PARAMS ((FILE *, int));
111 static const char *select_output_format PARAMS ((enum bfd_architecture,
112 unsigned long, boolean));
113 static void setup_sections PARAMS ((bfd *, asection *, PTR));
114 static void copy_sections PARAMS ((bfd *, asection *, PTR));
115 static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
116 bfd_size_type *, char *,
117 bfd_size_type));
118 static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
119 bfd_size_type *, char *,
120 bfd_size_type));
121 static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
122 bfd_size_type *, char *,
123 bfd_size_type));
124 static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
125 bfd_size_type *, char *,
126 bfd_size_type));
127 static char *link_inputs PARAMS ((struct string_list *, char *));
128 static const char *choose_temp_base_try PARAMS ((const char *,
129 const char *));
130 static void choose_temp_base PARAMS ((void));
131 static int pexecute PARAMS ((char *, char *[]));
132 \f
133 /* The main routine. */
134
135 int
136 main (argc, argv)
137 int argc;
138 char **argv;
139 {
140 int opt;
141 char *input_file = NULL;
142 const char *input_format = NULL;
143 const char *output_format = NULL;
144 const char *header_file = NULL;
145 char *ld_arg = NULL;
146 Nlm_Internal_Fixed_Header fixed_hdr_struct;
147 Nlm_Internal_Variable_Header var_hdr_struct;
148 Nlm_Internal_Version_Header version_hdr_struct;
149 Nlm_Internal_Copyright_Header copyright_hdr_struct;
150 Nlm_Internal_Extended_Header extended_hdr_struct;
151 bfd *inbfd;
152 bfd *outbfd;
153 asymbol **newsyms, **outsyms;
154 unsigned int symcount, newsymalloc, newsymcount;
155 asection *bss_sec, *data_sec;
156 bfd_vma vma;
157 bfd_size_type align;
158 asymbol *endsym;
159 unsigned int i;
160 char inlead, outlead;
161 boolean gotstart, gotexit, gotcheck;
162 struct stat st;
163 FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
164 size_t custom_size, help_size, message_size, module_size, rpc_size;
165 asection *custom_section, *help_section, *message_section, *module_section;
166 asection *rpc_section, *shared_section;
167 bfd *sharedbfd;
168 size_t shared_offset, shared_size;
169 Nlm_Internal_Fixed_Header sharedhdr;
170 int len;
171 char *modname;
172
173 program_name = argv[0];
174
175 bfd_init ();
176
177 while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
178 (int *) NULL))
179 != EOF)
180 {
181 switch (opt)
182 {
183 case 'd':
184 debug = 1;
185 break;
186 case 'h':
187 show_help ();
188 /*NOTREACHED*/
189 case 'I':
190 input_format = optarg;
191 break;
192 case 'l':
193 ld_arg = optarg;
194 break;
195 case 'O':
196 output_format = optarg;
197 break;
198 case 'T':
199 header_file = optarg;
200 break;
201 case 'V':
202 printf ("GNU %s version %s\n", program_name, program_version);
203 exit (0);
204 /*NOTREACHED*/
205 case 0:
206 break;
207 default:
208 show_usage (stderr, 1);
209 /*NOTREACHED*/
210 }
211 }
212
213 /* The input and output files may be named on the command line. */
214 output_file = NULL;
215 if (optind < argc)
216 {
217 input_file = argv[optind];
218 ++optind;
219 if (optind < argc)
220 {
221 output_file = argv[optind];
222 ++optind;
223 if (optind < argc)
224 show_usage (stderr, 1);
225 if (strcmp (input_file, output_file) == 0)
226 {
227 fprintf (stderr,
228 "%s: input and output files must be different\n",
229 program_name);
230 exit (1);
231 }
232 }
233 }
234
235 /* Initialize the header information to default values. */
236 fixed_hdr = &fixed_hdr_struct;
237 memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
238 var_hdr = &var_hdr_struct;
239 memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
240 version_hdr = &version_hdr_struct;
241 memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
242 copyright_hdr = &copyright_hdr_struct;
243 memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
244 extended_hdr = &extended_hdr_struct;
245 memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
246 check_procedure = NULL;
247 custom_file = NULL;
248 debug_info = false;
249 exit_procedure = "_Stop";
250 export_symbols = NULL;
251 map_file = NULL;
252 full_map = false;
253 help_file = NULL;
254 import_symbols = NULL;
255 message_file = NULL;
256 modules = NULL;
257 sharelib_file = NULL;
258 start_procedure = "_Prelude";
259 verbose = false;
260 rpc_file = NULL;
261
262 parse_errors = 0;
263
264 /* Parse the header file (if there is one). */
265 if (header_file != NULL)
266 {
267 if (! nlmlex_file (header_file)
268 || yyparse () != 0
269 || parse_errors != 0)
270 exit (1);
271 }
272
273 if (input_files != NULL)
274 {
275 if (input_file != NULL)
276 {
277 fprintf (stderr,
278 "%s: input file named both on command line and with INPUT\n",
279 program_name);
280 exit (1);
281 }
282 if (input_files->next == NULL)
283 input_file = input_files->string;
284 else
285 input_file = link_inputs (input_files, ld_arg);
286 }
287 else if (input_file == NULL)
288 {
289 fprintf (stderr, "%s: no input file\n", program_name);
290 show_usage (stderr, 1);
291 }
292
293 inbfd = bfd_openr (input_file, input_format);
294 if (inbfd == NULL)
295 bfd_fatal (input_file);
296
297 if (! bfd_check_format (inbfd, bfd_object))
298 bfd_fatal (input_file);
299
300 if (output_format == NULL)
301 output_format = select_output_format (bfd_get_arch (inbfd),
302 bfd_get_mach (inbfd),
303 inbfd->xvec->byteorder_big_p);
304
305 assert (output_format != NULL);
306
307 /* Use the output file named on the command line if it exists.
308 Otherwise use the file named in the OUTPUT statement. */
309 if (output_file == NULL)
310 {
311 fprintf (stderr, "%s: no name for output file\n",
312 program_name);
313 show_usage (stderr, 1);
314 }
315
316 outbfd = bfd_openw (output_file, output_format);
317 if (outbfd == NULL)
318 bfd_fatal (output_file);
319 if (! bfd_set_format (outbfd, bfd_object))
320 bfd_fatal (output_file);
321
322 assert (outbfd->xvec->flavour == bfd_target_nlm_flavour);
323
324 if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
325 fprintf (stderr,
326 "%s: warning:input and output formats are not compatible\n",
327 program_name);
328
329 /* Move the values read from the command file into outbfd. */
330 *nlm_fixed_header (outbfd) = fixed_hdr_struct;
331 *nlm_variable_header (outbfd) = var_hdr_struct;
332 *nlm_version_header (outbfd) = version_hdr_struct;
333 *nlm_copyright_header (outbfd) = copyright_hdr_struct;
334 *nlm_extended_header (outbfd) = extended_hdr_struct;
335
336 /* Start copying the input BFD to the output BFD. */
337 if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
338 bfd_fatal (bfd_get_filename (outbfd));
339
340 symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
341 symcount = bfd_canonicalize_symtab (inbfd, symbols);
342
343 /* Make sure we have a .bss section. */
344 bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
345 if (bss_sec == NULL)
346 {
347 bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
348 if (bss_sec == NULL
349 || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
350 || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
351 bfd_fatal ("make .bss section");
352 }
353
354 /* Set up the sections. */
355 bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
356
357 /* The .bss section immediately follows the .data section. */
358 data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
359 if (data_sec != NULL)
360 {
361 bfd_size_type add;
362
363 vma = bfd_get_section_size_before_reloc (data_sec);
364 align = 1 << bss_sec->alignment_power;
365 add = ((vma + align - 1) &~ (align - 1)) - vma;
366 vma += add;
367 if (! bfd_set_section_vma (outbfd, bss_sec, vma))
368 bfd_fatal ("set .bss vma");
369 if (add != 0)
370 {
371 bfd_size_type data_size;
372
373 data_size = bfd_get_section_size_before_reloc (data_sec);
374 if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
375 bfd_fatal ("set .data size");
376 }
377 }
378
379 /* Adjust symbol information. */
380 inlead = bfd_get_symbol_leading_char (inbfd);
381 outlead = bfd_get_symbol_leading_char (outbfd);
382 gotstart = false;
383 gotexit = false;
384 gotcheck = false;
385 newsymalloc = 10;
386 newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
387 newsymcount = 0;
388 endsym = NULL;
389 for (i = 0; i < symcount; i++)
390 {
391 register asymbol *sym;
392
393 sym = symbols[i];
394
395 /* Add or remove a leading underscore. */
396 if (inlead != outlead)
397 {
398 if (inlead != '\0')
399 {
400 if (bfd_asymbol_name (sym)[0] == inlead)
401 {
402 if (outlead == '\0')
403 ++sym->name;
404 else
405 {
406 char *new;
407
408 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
409 new[0] = outlead;
410 strcpy (new + 1, bfd_asymbol_name (sym) + 1);
411 sym->name = new;
412 }
413 }
414 }
415 else
416 {
417 char *new;
418
419 new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
420 new[0] = outlead;
421 strcpy (new + 1, bfd_asymbol_name (sym));
422 sym->name = new;
423 }
424 }
425
426 /* NLM's have an uninitialized data section, but they do not
427 have a common section in the Unix sense. Move all common
428 symbols into the .bss section, and mark them as exported. */
429 if (bfd_is_com_section (bfd_get_section (sym)))
430 {
431 bfd_vma size;
432
433 sym->section = bss_sec;
434 size = sym->value;
435 sym->value = bss_sec->_raw_size;
436 bss_sec->_raw_size += size;
437 align = 1 << bss_sec->alignment_power;
438 bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
439 sym->flags |= BSF_EXPORT | BSF_GLOBAL;
440 }
441 else if (bfd_get_section (sym)->output_section != NULL)
442 {
443 /* Move the symbol into the output section. */
444 sym->value += bfd_get_section (sym)->output_offset;
445 sym->section = bfd_get_section (sym)->output_section;
446 /* This is no longer a section symbol. */
447 sym->flags &=~ BSF_SECTION_SYM;
448 }
449
450 /* Force _edata and _end to be defined. This would normally be
451 done by the linker, but the manipulation of the common
452 symbols will confuse it. */
453 if (bfd_asymbol_name (sym)[0] == '_'
454 && bfd_get_section (sym) == &bfd_und_section)
455 {
456 if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
457 {
458 sym->section = bss_sec;
459 sym->value = 0;
460 }
461 if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
462 {
463 sym->section = bss_sec;
464 endsym = sym;
465 }
466 }
467
468 /* If this is a global symbol, check the export list. */
469 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
470 {
471 register struct string_list *l;
472 int found_simple;
473
474 /* Unfortunately, a symbol can appear multiple times on the
475 export list, with and without prefixes. */
476 found_simple = 0;
477 for (l = export_symbols; l != NULL; l = l->next)
478 {
479 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
480 found_simple = 1;
481 else
482 {
483 char *zbase;
484
485 zbase = strchr (l->string, '@');
486 if (zbase != NULL
487 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
488 {
489 /* We must add a symbol with this prefix. */
490 if (newsymcount >= newsymalloc)
491 {
492 newsymalloc += 10;
493 newsyms = ((asymbol **)
494 xrealloc (newsyms,
495 (newsymalloc
496 * sizeof (asymbol *))));
497 }
498 newsyms[newsymcount] =
499 (asymbol *) xmalloc (sizeof (asymbol));
500 *newsyms[newsymcount] = *sym;
501 newsyms[newsymcount]->name = l->string;
502 ++newsymcount;
503 }
504 }
505 }
506 if (! found_simple)
507 {
508 /* The unmodified symbol is actually not exported at
509 all. */
510 sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
511 sym->flags |= BSF_LOCAL;
512 }
513 }
514
515 /* If it's an undefined symbol, see if it's on the import list.
516 Change the prefix if necessary. */
517 if (bfd_get_section (sym) == &bfd_und_section)
518 {
519 register struct string_list *l;
520
521 for (l = import_symbols; l != NULL; l = l->next)
522 {
523 if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
524 break;
525 else
526 {
527 char *zbase;
528
529 zbase = strchr (l->string, '@');
530 if (zbase != NULL
531 && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
532 {
533 sym->name = l->string;
534 break;
535 }
536 }
537 }
538 if (l == NULL)
539 fprintf (stderr,
540 "%s: warning: symbol %s imported but not in import list\n",
541 program_name, bfd_asymbol_name (sym));
542 }
543
544 /* See if it's one of the special named symbols. */
545 if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
546 {
547 if (! bfd_set_start_address (outbfd, bfd_asymbol_value (sym)))
548 bfd_fatal ("set start address");
549 gotstart = true;
550 }
551 if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
552 {
553 nlm_fixed_header (outbfd)->exitProcedureOffset =
554 bfd_asymbol_value (sym);
555 gotexit = true;
556 }
557 if (check_procedure != NULL
558 && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
559 {
560 nlm_fixed_header (outbfd)->checkUnloadProcedureOffset =
561 bfd_asymbol_value (sym);
562 gotcheck = true;
563 }
564 }
565
566 if (endsym != NULL)
567 endsym->value = bfd_get_section_size_before_reloc (bss_sec);
568
569 if (newsymcount == 0)
570 outsyms = symbols;
571 else
572 {
573 outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
574 * sizeof (asymbol *));
575 memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
576 memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
577 outsyms[symcount + newsymcount] = NULL;
578 }
579
580 bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
581
582 if (! gotstart)
583 fprintf (stderr, "%s: warning: START procedure %s not defined\n",
584 program_name, start_procedure);
585 if (! gotexit)
586 fprintf (stderr, "%s: warning: EXIT procedure %s not defined\n",
587 program_name, exit_procedure);
588 if (check_procedure != NULL
589 && ! gotcheck)
590 fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
591 program_name, check_procedure);
592
593 /* Add additional sections required for the header information. */
594 if (custom_file != NULL)
595 {
596 custom_data = fopen (custom_file, "r");
597 if (custom_data == NULL
598 || fstat (fileno (custom_data), &st) < 0)
599 {
600 fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
601 strerror (errno));
602 custom_file = NULL;
603 }
604 else
605 {
606 custom_size = st.st_size;
607 custom_section = bfd_make_section (outbfd, ".nlmcustom");
608 if (custom_section == NULL
609 || ! bfd_set_section_size (outbfd, custom_section, custom_size)
610 || ! bfd_set_section_flags (outbfd, custom_section,
611 SEC_HAS_CONTENTS))
612 bfd_fatal ("custom section");
613 }
614 }
615 if (help_file != NULL)
616 {
617 help_data = fopen (help_file, "r");
618 if (help_data == NULL
619 || fstat (fileno (help_data), &st) < 0)
620 {
621 fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
622 strerror (errno));
623 help_file = NULL;
624 }
625 else
626 {
627 help_size = st.st_size;
628 help_section = bfd_make_section (outbfd, ".nlmhelp");
629 if (help_section == NULL
630 || ! bfd_set_section_size (outbfd, help_section, help_size)
631 || ! bfd_set_section_flags (outbfd, help_section,
632 SEC_HAS_CONTENTS))
633 bfd_fatal ("help section");
634 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
635 }
636 }
637 if (message_file != NULL)
638 {
639 message_data = fopen (message_file, "r");
640 if (message_data == NULL
641 || fstat (fileno (message_data), &st) < 0)
642 {
643 fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
644 strerror (errno));
645 message_file = NULL;
646 }
647 else
648 {
649 message_size = st.st_size;
650 message_section = bfd_make_section (outbfd, ".nlmmessages");
651 if (message_section == NULL
652 || ! bfd_set_section_size (outbfd, message_section, message_size)
653 || ! bfd_set_section_flags (outbfd, message_section,
654 SEC_HAS_CONTENTS))
655 bfd_fatal ("message section");
656 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
657 }
658 }
659 if (modules != NULL)
660 {
661 struct string_list *l;
662
663 module_size = 0;
664 for (l = modules; l != NULL; l = l->next)
665 module_size += strlen (l->string) + 1;
666 module_section = bfd_make_section (outbfd, ".nlmmodules");
667 if (module_section == NULL
668 || ! bfd_set_section_size (outbfd, module_section, module_size)
669 || ! bfd_set_section_flags (outbfd, module_section,
670 SEC_HAS_CONTENTS))
671 bfd_fatal ("module section");
672 }
673 if (rpc_file != NULL)
674 {
675 rpc_data = fopen (rpc_file, "r");
676 if (rpc_data == NULL
677 || fstat (fileno (rpc_data), &st) < 0)
678 {
679 fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
680 strerror (errno));
681 rpc_file = NULL;
682 }
683 else
684 {
685 rpc_size = st.st_size;
686 rpc_section = bfd_make_section (outbfd, ".nlmrpc");
687 if (rpc_section == NULL
688 || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
689 || ! bfd_set_section_flags (outbfd, rpc_section,
690 SEC_HAS_CONTENTS))
691 bfd_fatal ("rpc section");
692 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
693 }
694 }
695 if (sharelib_file != NULL)
696 {
697 sharedbfd = bfd_openr (sharelib_file, output_format);
698 if (sharedbfd == NULL
699 || ! bfd_check_format (sharedbfd, bfd_object))
700 {
701 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
702 bfd_errmsg (bfd_error));
703 sharelib_file = NULL;
704 }
705 else
706 {
707 sharedhdr = *nlm_fixed_header (sharedbfd);
708 bfd_close (sharedbfd);
709 shared_data = fopen (sharelib_file, "r");
710 if (shared_data == NULL
711 || (fstat (fileno (shared_data), &st) < 0))
712 {
713 fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
714 strerror (errno));
715 sharelib_file = NULL;
716 }
717 else
718 {
719 /* If we were clever, we could just copy out the
720 sections of the shared library which we actually
721 need. However, we would have to figure out the sizes
722 of the external and public information, and that can
723 not be done without reading through them. */
724 shared_offset = st.st_size;
725 if (shared_offset > sharedhdr.codeImageOffset)
726 shared_offset = sharedhdr.codeImageOffset;
727 if (shared_offset > sharedhdr.dataImageOffset)
728 shared_offset = sharedhdr.dataImageOffset;
729 if (shared_offset > sharedhdr.relocationFixupOffset)
730 shared_offset = sharedhdr.relocationFixupOffset;
731 if (shared_offset > sharedhdr.externalReferencesOffset)
732 shared_offset = sharedhdr.externalReferencesOffset;
733 if (shared_offset > sharedhdr.publicsOffset)
734 shared_offset = sharedhdr.publicsOffset;
735 shared_size = st.st_size - shared_offset;
736 shared_section = bfd_make_section (outbfd, ".nlmshared");
737 if (shared_section == NULL
738 || ! bfd_set_section_size (outbfd, shared_section,
739 shared_size)
740 || ! bfd_set_section_flags (outbfd, shared_section,
741 SEC_HAS_CONTENTS))
742 bfd_fatal ("shared section");
743 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
744 }
745 }
746 }
747
748 /* Check whether a version was given. */
749 if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
750 fprintf (stderr, "%s: warning: No version number given\n",
751 program_name);
752
753 /* At least for now, always create an extended header, because that
754 is what NLMLINK does. */
755 strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
756
757 /* If the date was not given, force it in. */
758 if (nlm_version_header (outbfd)->month == 0
759 && nlm_version_header (outbfd)->day == 0
760 && nlm_version_header (outbfd)->year == 0)
761 {
762 time_t now;
763 struct tm *ptm;
764
765 time (&now);
766 ptm = localtime (&now);
767 nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
768 nlm_version_header (outbfd)->day = ptm->tm_mday;
769 nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
770 strncpy (version_hdr->stamp, "VeRsIoN#", 8);
771 }
772
773 /* Copy over the sections. */
774 bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
775
776 /* Finish up the header information. */
777 if (custom_file != NULL)
778 {
779 PTR data;
780
781 data = xmalloc (custom_size);
782 if (fread (data, 1, custom_size, custom_data) != custom_size)
783 fprintf (stderr, "%s:%s: read: %s\n", program_name, custom_file,
784 strerror (errno));
785 else
786 {
787 if (! bfd_set_section_contents (outbfd, custom_section, data,
788 (file_ptr) 0, custom_size))
789 bfd_fatal ("custom section");
790 nlm_fixed_header (outbfd)->customDataOffset =
791 custom_section->filepos;
792 nlm_fixed_header (outbfd)->customDataSize = custom_size;
793 }
794 free (data);
795 }
796 if (! debug_info)
797 {
798 /* As a special hack, the backend recognizes a debugInfoOffset
799 of -1 to mean that it should not output any debugging
800 information. This can not be handling by fiddling with the
801 symbol table because exported symbols appear in both the
802 export information and the debugging information. */
803 nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
804 }
805 if (map_file != NULL)
806 fprintf (stderr,
807 "%s: MAP and FULLMAP are not supported; try ld -M\n",
808 program_name);
809 if (help_file != NULL)
810 {
811 PTR data;
812
813 data = xmalloc (help_size);
814 if (fread (data, 1, help_size, help_data) != help_size)
815 fprintf (stderr, "%s:%s: read: %s\n", program_name, help_file,
816 strerror (errno));
817 else
818 {
819 if (! bfd_set_section_contents (outbfd, help_section, data,
820 (file_ptr) 0, help_size))
821 bfd_fatal ("help section");
822 nlm_extended_header (outbfd)->helpFileOffset =
823 help_section->filepos;
824 nlm_extended_header (outbfd)->helpFileLength = help_size;
825 }
826 free (data);
827 }
828 if (message_file != NULL)
829 {
830 PTR data;
831
832 data = xmalloc (message_size);
833 if (fread (data, 1, message_size, message_data) != message_size)
834 fprintf (stderr, "%s:%s: read: %s\n", program_name, message_file,
835 strerror (errno));
836 else
837 {
838 if (! bfd_set_section_contents (outbfd, message_section, data,
839 (file_ptr) 0, message_size))
840 bfd_fatal ("message section");
841 nlm_extended_header (outbfd)->messageFileOffset =
842 message_section->filepos;
843 nlm_extended_header (outbfd)->messageFileLength = message_size;
844
845 /* FIXME: Are these offsets correct on all platforms? Are
846 they 32 bits on all platforms? What endianness? */
847 nlm_extended_header (outbfd)->languageID =
848 bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
849 nlm_extended_header (outbfd)->messageCount =
850 bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
851 }
852 free (data);
853 }
854 if (modules != NULL)
855 {
856 PTR data;
857 unsigned char *set;
858 struct string_list *l;
859 bfd_size_type c;
860
861 data = xmalloc (module_size);
862 c = 0;
863 set = (unsigned char *) data;
864 for (l = modules; l != NULL; l = l->next)
865 {
866 *set = strlen (l->string);
867 strncpy (set + 1, l->string, *set);
868 set += *set + 1;
869 ++c;
870 }
871 if (! bfd_set_section_contents (outbfd, module_section, data,
872 (file_ptr) 0, module_size))
873 bfd_fatal ("module section");
874 nlm_fixed_header (outbfd)->moduleDependencyOffset =
875 module_section->filepos;
876 nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
877 }
878 if (rpc_file != NULL)
879 {
880 PTR data;
881
882 data = xmalloc (rpc_size);
883 if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
884 fprintf (stderr, "%s:%s: read: %s\n", program_name, rpc_file,
885 strerror (errno));
886 else
887 {
888 if (! bfd_set_section_contents (outbfd, rpc_section, data,
889 (file_ptr) 0, rpc_size))
890 bfd_fatal ("rpc section");
891 nlm_extended_header (outbfd)->RPCDataOffset =
892 rpc_section->filepos;
893 nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
894 }
895 free (data);
896 }
897 if (sharelib_file != NULL)
898 {
899 PTR data;
900
901 data = xmalloc (shared_size);
902 if (fseek (shared_data, shared_offset, SEEK_SET) != 0
903 || fread (data, 1, shared_size, shared_data) != shared_size)
904 fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
905 strerror (errno));
906 else
907 {
908 if (! bfd_set_section_contents (outbfd, shared_section, data,
909 (file_ptr) 0, shared_size))
910 bfd_fatal ("shared section");
911 }
912 nlm_extended_header (outbfd)->sharedCodeOffset =
913 sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
914 nlm_extended_header (outbfd)->sharedCodeLength =
915 sharedhdr.codeImageSize;
916 nlm_extended_header (outbfd)->sharedDataOffset =
917 sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
918 nlm_extended_header (outbfd)->sharedDataLength =
919 sharedhdr.dataImageSize;
920 nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
921 (sharedhdr.relocationFixupOffset
922 - shared_offset
923 + shared_section->filepos);
924 nlm_extended_header (outbfd)->sharedRelocationFixupCount =
925 sharedhdr.numberOfRelocationFixups;
926 nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
927 (sharedhdr.externalReferencesOffset
928 - shared_offset
929 + shared_section->filepos);
930 nlm_extended_header (outbfd)->sharedExternalReferenceCount =
931 sharedhdr.numberOfExternalReferences;
932 nlm_extended_header (outbfd)->sharedPublicsOffset =
933 sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
934 nlm_extended_header (outbfd)->sharedPublicsCount =
935 sharedhdr.numberOfPublics;
936 nlm_extended_header (outbfd)->sharedDebugRecordOffset =
937 sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
938 nlm_extended_header (outbfd)->sharedDebugRecordCount =
939 sharedhdr.numberOfDebugRecords;
940 nlm_extended_header (outbfd)->SharedInitializationOffset =
941 sharedhdr.codeStartOffset;
942 nlm_extended_header (outbfd)->SharedExitProcedureOffset =
943 sharedhdr.exitProcedureOffset;
944 free (data);
945 }
946 len = strlen (output_file);
947 if (len > NLM_MODULE_NAME_SIZE - 2)
948 len = NLM_MODULE_NAME_SIZE - 2;
949 nlm_fixed_header (outbfd)->moduleName[0] = len;
950
951 strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
952 NLM_MODULE_NAME_SIZE - 2);
953 nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
954 for (modname = nlm_fixed_header (outbfd)->moduleName;
955 *modname != '\0';
956 modname++)
957 if (islower (*modname))
958 *modname = toupper (*modname);
959
960 strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
961 NLM_OLD_THREAD_NAME_LENGTH);
962
963 if (! bfd_close (outbfd))
964 bfd_fatal (output_file);
965 if (! bfd_close (inbfd))
966 bfd_fatal (input_file);
967
968 if (unlink_on_exit != NULL)
969 unlink (unlink_on_exit);
970
971 return 0;
972 }
973 \f
974 /* Display a help message and exit. */
975
976 static void
977 show_help ()
978 {
979 printf ("%s: Convert an object file into a NetWare Loadable Module\n",
980 program_name);
981 show_usage (stdout, 0);
982 }
983
984 /* Show a usage message and exit. */
985
986 static void
987 show_usage (file, status)
988 FILE *file;
989 int status;
990 {
991 fprintf (file, "\
992 Usage: %s [-dhV] [-I format] [-O format] [-T header-file] [-l linker]\n\
993 [--input-format=format] [--output-format=format]\n\
994 [--header-file=file] [--linker=linker] [--debug]\n\
995 [--help] [--version]\n\
996 [in-file [out-file]]\n",
997 program_name);
998 exit (status);
999 }
1000 \f
1001 /* Select the output format based on the input architecture, machine,
1002 and endianness. This chooses the appropriate NLM target. */
1003
1004 static const char *
1005 select_output_format (arch, mach, bigendian)
1006 enum bfd_architecture arch;
1007 unsigned long mach;
1008 boolean bigendian;
1009 {
1010 switch (arch)
1011 {
1012 case bfd_arch_i386:
1013 return "nlm32-i386";
1014 case bfd_arch_sparc:
1015 return "nlm32-sparc";
1016 case bfd_arch_alpha:
1017 return "nlm32-alpha";
1018 default:
1019 fprintf (stderr, "%s: no default NLM format for %s\n",
1020 program_name, bfd_printable_arch_mach (arch, mach));
1021 exit (1);
1022 /* Avoid warning. */
1023 return NULL;
1024 }
1025 /*NOTREACHED*/
1026 }
1027 \f
1028 /* The BFD sections are copied in two passes. This function selects
1029 the output section for each input section, and sets up the section
1030 name, size, etc. */
1031
1032 static void
1033 setup_sections (inbfd, insec, data_ptr)
1034 bfd *inbfd;
1035 asection *insec;
1036 PTR data_ptr;
1037 {
1038 bfd *outbfd = (bfd *) data_ptr;
1039 flagword f;
1040 const char *outname;
1041 asection *outsec;
1042
1043 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1044 file. However, I don't have a good way to describe this section.
1045 We do want to copy the section when using objcopy. */
1046 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1047 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1048 return;
1049
1050 f = bfd_get_section_flags (inbfd, insec);
1051 if (f & SEC_CODE)
1052 outname = NLM_CODE_NAME;
1053 else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1054 outname = NLM_INITIALIZED_DATA_NAME;
1055 else if (f & SEC_ALLOC)
1056 outname = NLM_UNINITIALIZED_DATA_NAME;
1057 else
1058 outname = bfd_section_name (inbfd, insec);
1059
1060 outsec = bfd_get_section_by_name (outbfd, outname);
1061 if (outsec == NULL)
1062 {
1063 outsec = bfd_make_section (outbfd, outname);
1064 if (outsec == NULL)
1065 bfd_fatal ("make section");
1066 }
1067
1068 insec->output_section = outsec;
1069 insec->output_offset = bfd_section_size (outbfd, outsec);
1070
1071 if (! bfd_set_section_size (outbfd, outsec,
1072 (bfd_section_size (outbfd, outsec)
1073 + bfd_section_size (inbfd, insec))))
1074 bfd_fatal ("set section size");
1075
1076 if ((bfd_section_alignment (inbfd, insec)
1077 > bfd_section_alignment (outbfd, outsec))
1078 && ! bfd_set_section_alignment (outbfd, outsec,
1079 bfd_section_alignment (inbfd, insec)))
1080 bfd_fatal ("set section alignment");
1081
1082 if (! bfd_set_section_flags (outbfd, outsec, f))
1083 bfd_fatal ("set section flags");
1084
1085 bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1086 }
1087
1088 /* Copy the section contents. */
1089
1090 static void
1091 copy_sections (inbfd, insec, data_ptr)
1092 bfd *inbfd;
1093 asection *insec;
1094 PTR data_ptr;
1095 {
1096 bfd *outbfd = (bfd *) data_ptr;
1097 asection *outsec;
1098 bfd_size_type size;
1099 PTR contents;
1100 bfd_size_type reloc_size;
1101
1102 /* FIXME: We don't want to copy the .reginfo section of an ECOFF
1103 file. However, I don't have a good way to describe this section.
1104 We do want to copy the section when using objcopy. */
1105 if (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour
1106 && strcmp (bfd_section_name (inbfd, insec), ".reginfo") == 0)
1107 return;
1108
1109 outsec = insec->output_section;
1110 assert (outsec != NULL);
1111
1112 size = bfd_get_section_size_before_reloc (insec);
1113 if (size == 0)
1114 return;
1115
1116 /* FIXME: Why are these necessary? */
1117 insec->_cooked_size = insec->_raw_size;
1118 insec->reloc_done = true;
1119
1120 if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1121 contents = NULL;
1122 else
1123 {
1124 contents = xmalloc (size);
1125 if (! bfd_get_section_contents (inbfd, insec, contents,
1126 (file_ptr) 0, size))
1127 bfd_fatal (bfd_get_filename (inbfd));
1128 }
1129
1130 reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1131 if (reloc_size != 0)
1132 {
1133 arelent **relocs;
1134 bfd_size_type reloc_count;
1135
1136 relocs = (arelent **) xmalloc (reloc_size);
1137 reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1138 mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1139 size);
1140
1141 /* FIXME: refers to internal BFD fields. */
1142 if (outsec->orelocation != (arelent **) NULL)
1143 {
1144 bfd_size_type total_count;
1145 arelent **combined;
1146
1147 total_count = reloc_count + outsec->reloc_count;
1148 combined = (arelent **) xmalloc (total_count * sizeof (arelent));
1149 memcpy (combined, outsec->orelocation,
1150 outsec->reloc_count * sizeof (arelent));
1151 memcpy (combined + outsec->reloc_count, relocs,
1152 (size_t) (reloc_count * sizeof (arelent)));
1153 free (outsec->orelocation);
1154 reloc_count = total_count;
1155 relocs = combined;
1156 }
1157
1158 bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1159 }
1160
1161 if (contents != NULL)
1162 {
1163 if (! bfd_set_section_contents (outbfd, outsec, contents,
1164 insec->output_offset, size))
1165 bfd_fatal (bfd_get_filename (outbfd));
1166 free (contents);
1167 }
1168 }
1169
1170 /* Some, perhaps all, NetWare targets require changing the relocs used
1171 by the input formats. */
1172
1173 static void
1174 mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1175 contents_size)
1176 bfd *outbfd;
1177 asection *insec;
1178 arelent ***relocs_ptr;
1179 bfd_size_type *reloc_count_ptr;
1180 char *contents;
1181 bfd_size_type contents_size;
1182 {
1183 switch (bfd_get_arch (outbfd))
1184 {
1185 case bfd_arch_i386:
1186 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1187 contents, contents_size);
1188 break;
1189 case bfd_arch_alpha:
1190 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1191 contents, contents_size);
1192 break;
1193 default:
1194 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1195 contents, contents_size);
1196 break;
1197 }
1198 }
1199
1200 /* By default all we need to do for relocs is change the address by
1201 the output_offset. */
1202
1203 /*ARGSUSED*/
1204 static void
1205 default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1206 contents_size)
1207 bfd *outbfd;
1208 asection *insec;
1209 arelent ***relocs_ptr;
1210 bfd_size_type *reloc_count_ptr;
1211 char *contents;
1212 bfd_size_type contents_size;
1213 {
1214 if (insec->output_offset != 0)
1215 {
1216 bfd_size_type reloc_count;
1217 register arelent **relocs;
1218 register bfd_size_type i;
1219
1220 reloc_count = *reloc_count_ptr;
1221 relocs = *relocs_ptr;
1222 for (i = 0; i < reloc_count; i++, relocs++)
1223 (*relocs)->address += insec->output_offset;
1224 }
1225 }
1226
1227 /* NetWare on the i386 supports a restricted set of relocs, which are
1228 different from those used on other i386 targets. This routine
1229 converts the relocs. It is, obviously, very target dependent. At
1230 the moment, the nlm32-i386 backend performs similar translations;
1231 however, it is more reliable and efficient to do them here. */
1232
1233 static reloc_howto_type nlm_i386_pcrel_howto =
1234 HOWTO (1, /* type */
1235 0, /* rightshift */
1236 2, /* size (0 = byte, 1 = short, 2 = long) */
1237 32, /* bitsize */
1238 true, /* pc_relative */
1239 0, /* bitpos */
1240 complain_overflow_signed, /* complain_on_overflow */
1241 0, /* special_function */
1242 "DISP32", /* name */
1243 true, /* partial_inplace */
1244 0xffffffff, /* src_mask */
1245 0xffffffff, /* dst_mask */
1246 true); /* pcrel_offset */
1247
1248 static void
1249 i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1250 contents_size)
1251 bfd *outbfd;
1252 asection *insec;
1253 arelent ***relocs_ptr;
1254 bfd_size_type *reloc_count_ptr;
1255 char *contents;
1256 bfd_size_type contents_size;
1257 {
1258 bfd_size_type reloc_count, i;
1259 arelent **relocs;
1260
1261 reloc_count = *reloc_count_ptr;
1262 relocs = *relocs_ptr;
1263 for (i = 0; i < reloc_count; i++)
1264 {
1265 arelent *rel;
1266 asymbol *sym;
1267 bfd_size_type address;
1268 bfd_vma addend;
1269
1270 rel = *relocs++;
1271 sym = *rel->sym_ptr_ptr;
1272
1273 /* We're moving the relocs from the input section to the output
1274 section, so we must adjust the address accordingly. */
1275 address = rel->address;
1276 rel->address += insec->output_offset;
1277
1278 /* Note that no serious harm will ensue if we fail to change a
1279 reloc. The backend will fail when writing out the reloc. */
1280
1281 /* Make sure this reloc is within the data we have. We use only
1282 4 byte relocs here, so we insist on having 4 bytes. */
1283 if (address + 4 > contents_size)
1284 continue;
1285
1286 /* A PC relative reloc entirely within a single section is
1287 completely unnecessary. This can be generated by ld -r. */
1288 if (sym == insec->symbol
1289 && rel->howto != NULL
1290 && rel->howto->pc_relative
1291 && ! rel->howto->pcrel_offset)
1292 {
1293 --*reloc_count_ptr;
1294 --relocs;
1295 memmove (relocs, relocs + 1,
1296 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1297 continue;
1298 }
1299
1300 /* Get the amount the relocation will add in. */
1301 addend = rel->addend + sym->value;
1302
1303 /* NetWare doesn't support PC relative relocs against defined
1304 symbols, so we have to eliminate them by doing the relocation
1305 now. We can only do this if the reloc is within a single
1306 section. */
1307 if (rel->howto != NULL
1308 && rel->howto->pc_relative
1309 && bfd_get_section (sym) == insec->output_section)
1310 {
1311 bfd_vma val;
1312
1313 if (rel->howto->pcrel_offset)
1314 addend -= address;
1315
1316 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1317 val += addend;
1318 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1319
1320 --*reloc_count_ptr;
1321 --relocs;
1322 memmove (relocs, relocs + 1,
1323 (size_t) ((reloc_count - i) * sizeof (arelent *)));
1324 continue;
1325 }
1326
1327 /* NetWare doesn't support reloc addends, so we get rid of them
1328 here by simply adding them into the object data. We handle
1329 the symbol value, if any, the same way. */
1330 if (addend != 0
1331 && rel->howto != NULL
1332 && rel->howto->rightshift == 0
1333 && rel->howto->size == 2
1334 && rel->howto->bitsize == 32
1335 && rel->howto->bitpos == 0
1336 && rel->howto->src_mask == 0xffffffff
1337 && rel->howto->dst_mask == 0xffffffff)
1338 {
1339 bfd_vma val;
1340
1341 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1342 val += addend;
1343 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1344
1345 /* Adjust the reloc for the changes we just made. */
1346 rel->addend = 0;
1347 if (bfd_get_section (sym) != &bfd_und_section)
1348 rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1349 }
1350
1351 /* NetWare uses a reloc with pcrel_offset set. We adjust
1352 pc_relative relocs accordingly. We are going to change the
1353 howto field, so we can only do this if the current one is
1354 compatible. We should check that special_function is NULL
1355 here, but at the moment coff-i386 uses a special_function
1356 which does not affect what we are doing here. */
1357 if (rel->howto != NULL
1358 && rel->howto->pc_relative
1359 && ! rel->howto->pcrel_offset
1360 && rel->howto->rightshift == 0
1361 && rel->howto->size == 2
1362 && rel->howto->bitsize == 32
1363 && rel->howto->bitpos == 0
1364 && rel->howto->src_mask == 0xffffffff
1365 && rel->howto->dst_mask == 0xffffffff)
1366 {
1367 bfd_vma val;
1368
1369 /* When pcrel_offset is not set, it means that the negative
1370 of the address of the memory location is stored in the
1371 memory location. We must add it back in. */
1372 val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1373 val += address;
1374 bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1375
1376 /* We must change to a new howto. */
1377 rel->howto = &nlm_i386_pcrel_howto;
1378 }
1379 }
1380 }
1381
1382 /* On the Alpha the first reloc for every section must be a special
1383 relocs which hold the GP address. Also, the first reloc in the
1384 file must be a special reloc which holds the address of the .lita
1385 section. */
1386
1387 static reloc_howto_type nlm32_alpha_nw_howto =
1388 HOWTO (ALPHA_R_NW_RELOC, /* type */
1389 0, /* rightshift */
1390 0, /* size (0 = byte, 1 = short, 2 = long) */
1391 0, /* bitsize */
1392 false, /* pc_relative */
1393 0, /* bitpos */
1394 complain_overflow_dont, /* complain_on_overflow */
1395 0, /* special_function */
1396 "NW_RELOC", /* name */
1397 false, /* partial_inplace */
1398 0, /* src_mask */
1399 0, /* dst_mask */
1400 false); /* pcrel_offset */
1401
1402 /*ARGSUSED*/
1403 static void
1404 alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
1405 contents_size)
1406 bfd *outbfd;
1407 asection *insec;
1408 register arelent ***relocs_ptr;
1409 bfd_size_type *reloc_count_ptr;
1410 char *contents;
1411 bfd_size_type contents_size;
1412 {
1413 bfd_size_type old_reloc_count;
1414 arelent **old_relocs;
1415 register arelent **relocs;
1416
1417 old_reloc_count = *reloc_count_ptr;
1418 old_relocs = *relocs_ptr;
1419 relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1420 *relocs_ptr = relocs;
1421
1422 if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1423 {
1424 bfd *inbfd;
1425 asection *lita_section;
1426
1427 inbfd = insec->owner;
1428 lita_section = bfd_get_section_by_name (inbfd, _LITA);
1429 if (lita_section != (asection *) NULL)
1430 {
1431 nlm_alpha_backend_data (outbfd)->lita_address =
1432 bfd_get_section_vma (inbfd, lita_section);
1433 nlm_alpha_backend_data (outbfd)->lita_size =
1434 bfd_section_size (inbfd, lita_section);
1435 }
1436 else
1437 {
1438 /* Avoid outputting this reloc again. */
1439 nlm_alpha_backend_data (outbfd)->lita_address = 4;
1440 }
1441
1442 *relocs = (arelent *) xmalloc (sizeof (arelent));
1443 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1444 (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1445 (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1446 (*relocs)->howto = &nlm32_alpha_nw_howto;
1447 ++relocs;
1448 ++(*reloc_count_ptr);
1449 }
1450
1451 /* Get the GP value from bfd. It is in the .reginfo section. */
1452 if (nlm_alpha_backend_data (outbfd)->gp == 0)
1453 {
1454 bfd *inbfd;
1455 asection *reginfo_sec;
1456 struct ecoff_reginfo sreginfo;
1457
1458 inbfd = insec->owner;
1459 assert (bfd_get_flavour (inbfd) == bfd_target_ecoff_flavour);
1460 reginfo_sec = bfd_get_section_by_name (inbfd, REGINFO);
1461 if (reginfo_sec != (asection *) NULL
1462 && bfd_get_section_contents (inbfd, reginfo_sec,
1463 (PTR) &sreginfo, (file_ptr) 0,
1464 sizeof sreginfo) != false)
1465 nlm_alpha_backend_data (outbfd)->gp = sreginfo.gp_value;
1466 }
1467
1468 *relocs = (arelent *) xmalloc (sizeof (arelent));
1469 (*relocs)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1470 (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1471 (*relocs)->addend = 0;
1472 (*relocs)->howto = &nlm32_alpha_nw_howto;
1473 ++relocs;
1474 ++(*reloc_count_ptr);
1475
1476 memcpy ((PTR) relocs, (PTR) old_relocs,
1477 (size_t) old_reloc_count * sizeof (arelent *));
1478 relocs[old_reloc_count] = (arelent *) NULL;
1479
1480 free (old_relocs);
1481
1482 if (insec->output_offset != 0)
1483 {
1484 register bfd_size_type i;
1485
1486 for (i = 0; i < old_reloc_count; i++, relocs++)
1487 (*relocs)->address += insec->output_offset;
1488 }
1489 }
1490 \f
1491 /* Name of linker. */
1492 #ifndef LD_NAME
1493 #define LD_NAME "ld"
1494 #endif
1495
1496 /* Temporary file name base. */
1497 static char *temp_filename;
1498
1499 /* The user has specified several input files. Invoke the linker to
1500 link them all together, and convert and delete the resulting output
1501 file. */
1502
1503 static char *
1504 link_inputs (inputs, ld)
1505 struct string_list *inputs;
1506 char *ld;
1507 {
1508 size_t c;
1509 struct string_list *q;
1510 char **argv;
1511 size_t i;
1512 int pid;
1513 int status;
1514
1515 c = 0;
1516 for (q = inputs; q != NULL; q = q->next)
1517 ++c;
1518
1519 argv = (char **) alloca (c + 5);
1520
1521 #ifndef __MSDOS__
1522 if (ld == NULL)
1523 {
1524 char *p;
1525
1526 /* Find the linker to invoke based on how nlmconv was run. */
1527 p = program_name + strlen (program_name);
1528 while (p != program_name)
1529 {
1530 if (p[-1] == '/')
1531 {
1532 ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
1533 memcpy (ld, program_name, p - program_name);
1534 strcpy (ld + (p - program_name), LD_NAME);
1535 break;
1536 }
1537 --p;
1538 }
1539 }
1540 #endif
1541
1542 if (ld == NULL)
1543 ld = (char *) LD_NAME;
1544
1545 choose_temp_base ();
1546
1547 unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
1548 sprintf (unlink_on_exit, "%s.O", temp_filename);
1549
1550 argv[0] = ld;
1551 argv[1] = (char *) "-r";
1552 argv[2] = (char *) "-o";
1553 argv[3] = unlink_on_exit;
1554 i = 4;
1555 for (q = inputs; q != NULL; q = q->next, i++)
1556 argv[i] = q->string;
1557 argv[i] = NULL;
1558
1559 if (debug)
1560 {
1561 for (i = 0; argv[i] != NULL; i++)
1562 fprintf (stderr, " %s", argv[i]);
1563 fprintf (stderr, "\n");
1564 }
1565
1566 pid = pexecute (ld, argv);
1567
1568 if (waitpid (pid, &status, 0) < 0)
1569 {
1570 perror ("waitpid");
1571 unlink (unlink_on_exit);
1572 exit (1);
1573 }
1574
1575 if (status != 0)
1576 {
1577 fprintf (stderr, "%s: Execution of %s failed\n", program_name, ld);
1578 unlink (unlink_on_exit);
1579 exit (1);
1580 }
1581
1582 return unlink_on_exit;
1583 }
1584
1585 /* Choose a temporary file name. Stolen from gcc.c. */
1586
1587 static const char *
1588 choose_temp_base_try (try, base)
1589 const char *try;
1590 const char *base;
1591 {
1592 const char *rv;
1593
1594 if (base)
1595 rv = base;
1596 else if (try == NULL)
1597 rv = NULL;
1598 else if (access (try, R_OK | W_OK) != 0)
1599 rv = NULL;
1600 else
1601 rv = try;
1602 return rv;
1603 }
1604
1605 static void
1606 choose_temp_base ()
1607 {
1608 const char *base = NULL;
1609 int len;
1610
1611 base = choose_temp_base_try (getenv ("TMPDIR"), base);
1612 base = choose_temp_base_try (getenv ("TMP"), base);
1613 base = choose_temp_base_try (getenv ("TEMP"), base);
1614
1615 #ifdef P_tmpdir
1616 base = choose_temp_base_try (P_tmpdir, base);
1617 #endif
1618
1619 base = choose_temp_base_try ("/usr/tmp", base);
1620 base = choose_temp_base_try ("/tmp", base);
1621
1622 /* If all else fails, use the current directory! */
1623 if (base == NULL)
1624 base = "./";
1625
1626 len = strlen (base);
1627 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
1628 strcpy (temp_filename, base);
1629 if (len > 0 && temp_filename[len-1] != '/')
1630 temp_filename[len++] = '/';
1631 strcpy (temp_filename + len, "ccXXXXXX");
1632
1633 mktemp (temp_filename);
1634 if (*temp_filename == '\0')
1635 abort ();
1636 }
1637
1638 /* Execute a job. Stolen from gcc.c. */
1639
1640 #ifndef OS2
1641 #ifdef __MSDOS__
1642
1643 static int
1644 pexecute (program, argv)
1645 char *program;
1646 char *argv[];
1647 {
1648 char *scmd, *rf;
1649 FILE *argfile;
1650 int i;
1651
1652 scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 10);
1653 rf = scmd + strlen(program) + 2 + el;
1654 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
1655 argfile = fopen (rf, "w");
1656 if (argfile == 0)
1657 pfatal_with_name (rf);
1658
1659 for (i=1; argv[i]; i++)
1660 {
1661 char *cp;
1662 for (cp = argv[i]; *cp; cp++)
1663 {
1664 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
1665 fputc ('\\', argfile);
1666 fputc (*cp, argfile);
1667 }
1668 fputc ('\n', argfile);
1669 }
1670 fclose (argfile);
1671
1672 i = system (scmd);
1673
1674 remove (rf);
1675
1676 if (i == -1)
1677 {
1678 perror (program);
1679 return MIN_FATAL_STATUS << 8;
1680 }
1681
1682 return i << 8;
1683 }
1684
1685 #else /* not __MSDOS__ */
1686
1687 static int
1688 pexecute (program, argv)
1689 char *program;
1690 char *argv[];
1691 {
1692 int pid;
1693 int retries, sleep_interval;
1694
1695 /* Fork a subprocess; wait and retry if it fails. */
1696 sleep_interval = 1;
1697 for (retries = 0; retries < 4; retries++)
1698 {
1699 pid = vfork ();
1700 if (pid >= 0)
1701 break;
1702 sleep (sleep_interval);
1703 sleep_interval *= 2;
1704 }
1705
1706 switch (pid)
1707 {
1708 case -1:
1709 #ifdef vfork
1710 perror ("fork");
1711 #else
1712 perror ("vfork");
1713 #endif
1714 exit (1);
1715 /* NOTREACHED */
1716 return 0;
1717
1718 case 0: /* child */
1719 /* Exec the program. */
1720 execvp (program, argv);
1721 perror (program);
1722 exit (1);
1723 /* NOTREACHED */
1724 return 0;
1725
1726 default:
1727 /* Return child's process number. */
1728 return pid;
1729 }
1730 }
1731
1732 #endif /* not __MSDOS__ */
1733 #else /* not OS2 */
1734
1735 static int
1736 pexecute (program, argv)
1737 char *program;
1738 char *argv[];
1739 {
1740 return spawnvp (1, program, argv);
1741 }
1742 #endif /* not OS2 */
This page took 0.065728 seconds and 4 git commands to generate.