1
/* nlmconv.c -- NLM conversion program
2
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3
2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5
This file is part of GNU Binutils.
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
MA 02110-1301, USA. */
23
/* Written by Ian Lance Taylor <ian@cygnus.com>.
25
This program can be used to convert any appropriate object file
26
into a NetWare Loadable Module (an NLM). It will accept a linker
27
specification file which is identical to that accepted by the
28
NetWare linker, NLMLINK. */
30
/* AIX requires this to be the first thing in the file. */
39
#include "libiberty.h"
40
#include "filenames.h"
41
#include "safe-ctype.h"
50
/* Internal BFD NLM header. */
56
#include "coff/ecoff.h"
61
/* If strerror is just a macro, we want to use the one from libiberty
62
since it will handle undefined values. */
64
extern char *strerror (int);
76
/* Global variables. */
78
/* The name used to invoke the program. */
81
/* Local variables. */
83
/* Whether to print out debugging information (currently just controls
84
whether it prints the linker command if there is one). */
87
/* The symbol table. */
88
static asymbol **symbols;
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
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
102
static asection *secsec;
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
107
static char *unlink_on_exit;
109
/* The list of long options. */
110
static struct option long_options[] =
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 }
124
/* Local routines. */
126
int main (int, char **);
128
static void show_usage (FILE *, int);
129
static const char *select_output_format
130
(enum bfd_architecture, unsigned long, bfd_boolean);
131
static void setup_sections (bfd *, asection *, void *);
132
static void copy_sections (bfd *, asection *, void *);
133
static void mangle_relocs
134
(bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
135
static void default_mangle_relocs
136
(bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
137
static char *link_inputs (struct string_list *, char *, char *);
140
static void i386_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
144
static void alpha_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
147
#ifdef NLMCONV_POWERPC
148
static void powerpc_build_stubs (bfd *, bfd *, asymbol ***, long *);
149
static void powerpc_resolve_stubs (bfd *, bfd *);
150
static void powerpc_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type);
153
/* The main routine. */
156
main (int argc, char **argv)
159
char *input_file = NULL;
160
const char *input_format = NULL;
161
const char *output_format = NULL;
162
const char *header_file = NULL;
164
Nlm_Internal_Fixed_Header fixed_hdr_struct;
165
Nlm_Internal_Variable_Header var_hdr_struct;
166
Nlm_Internal_Version_Header version_hdr_struct;
167
Nlm_Internal_Copyright_Header copyright_hdr_struct;
168
Nlm_Internal_Extended_Header extended_hdr_struct;
171
asymbol **newsyms, **outsyms;
172
long symcount, newsymalloc, newsymcount;
174
asection *text_sec, *bss_sec, *data_sec;
179
char inlead, outlead;
180
bfd_boolean gotstart, gotexit, gotcheck;
182
FILE *custom_data = NULL;
183
FILE *help_data = NULL;
184
FILE *message_data = NULL;
185
FILE *rpc_data = NULL;
186
FILE *shared_data = NULL;
187
size_t custom_size = 0;
188
size_t help_size = 0;
189
size_t message_size = 0;
190
size_t module_size = 0;
192
asection *custom_section = NULL;
193
asection *help_section = NULL;
194
asection *message_section = NULL;
195
asection *module_section = NULL;
196
asection *rpc_section = NULL;
197
asection *shared_section = NULL;
199
size_t shared_offset = 0;
200
size_t shared_size = 0;
201
static Nlm_Internal_Fixed_Header sharedhdr;
206
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
207
setlocale (LC_MESSAGES, "");
209
#if defined (HAVE_SETLOCALE)
210
setlocale (LC_CTYPE, "");
212
bindtextdomain (PACKAGE, LOCALEDIR);
213
textdomain (PACKAGE);
215
program_name = argv[0];
216
xmalloc_set_program_name (program_name);
218
expandargv (&argc, &argv);
221
set_default_bfd_target ();
223
while ((opt = getopt_long (argc, argv, "dHhI:l:O:T:Vv", long_options,
234
show_usage (stdout, 0);
237
input_format = optarg;
243
output_format = optarg;
246
header_file = optarg;
250
print_version ("nlmconv");
255
show_usage (stderr, 1);
260
/* The input and output files may be named on the command line. */
264
input_file = argv[optind];
268
output_file = argv[optind];
271
show_usage (stderr, 1);
272
if (filename_cmp (input_file, output_file) == 0)
274
fatal (_("input and output files must be different"));
279
/* Initialize the header information to default values. */
280
fixed_hdr = &fixed_hdr_struct;
281
memset ((void *) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
282
var_hdr = &var_hdr_struct;
283
memset ((void *) &var_hdr_struct, 0, sizeof var_hdr_struct);
284
version_hdr = &version_hdr_struct;
285
memset ((void *) &version_hdr_struct, 0, sizeof version_hdr_struct);
286
copyright_hdr = ©right_hdr_struct;
287
memset ((void *) ©right_hdr_struct, 0, sizeof copyright_hdr_struct);
288
extended_hdr = &extended_hdr_struct;
289
memset ((void *) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
290
check_procedure = NULL;
293
exit_procedure = "_Stop";
294
export_symbols = NULL;
298
import_symbols = NULL;
301
sharelib_file = NULL;
302
start_procedure = "_Prelude";
308
/* Parse the header file (if there is one). */
309
if (header_file != NULL)
311
if (! nlmlex_file (header_file)
313
|| parse_errors != 0)
317
if (input_files != NULL)
319
if (input_file != NULL)
321
fatal (_("input file named both on command line and with INPUT"));
323
if (input_files->next == NULL)
324
input_file = input_files->string;
326
input_file = link_inputs (input_files, ld_arg, map_file);
328
else if (input_file == NULL)
330
non_fatal (_("no input file"));
331
show_usage (stderr, 1);
334
inbfd = bfd_openr (input_file, input_format);
336
bfd_fatal (input_file);
338
if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
340
bfd_nonfatal (input_file);
341
if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
343
list_matching_formats (matching);
349
if (output_format == NULL)
350
output_format = select_output_format (bfd_get_arch (inbfd),
351
bfd_get_mach (inbfd),
352
bfd_big_endian (inbfd));
354
assert (output_format != NULL);
356
/* Use the output file named on the command line if it exists.
357
Otherwise use the file named in the OUTPUT statement. */
358
if (output_file == NULL)
360
non_fatal (_("no name for output file"));
361
show_usage (stderr, 1);
364
outbfd = bfd_openw (output_file, output_format);
366
bfd_fatal (output_file);
367
if (! bfd_set_format (outbfd, bfd_object))
368
bfd_fatal (output_file);
370
assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
372
/* XXX: Should we accept the unknown bfd format here ? */
373
if (bfd_arch_get_compatible (inbfd, outbfd, TRUE) == NULL)
374
non_fatal (_("warning: input and output formats are not compatible"));
376
/* Move the values read from the command file into outbfd. */
377
*nlm_fixed_header (outbfd) = fixed_hdr_struct;
378
*nlm_variable_header (outbfd) = var_hdr_struct;
379
*nlm_version_header (outbfd) = version_hdr_struct;
380
*nlm_copyright_header (outbfd) = copyright_hdr_struct;
381
*nlm_extended_header (outbfd) = extended_hdr_struct;
383
/* Start copying the input BFD to the output BFD. */
384
if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
385
bfd_fatal (bfd_get_filename (outbfd));
387
symsize = bfd_get_symtab_upper_bound (inbfd);
389
bfd_fatal (input_file);
390
symbols = (asymbol **) xmalloc (symsize);
391
symcount = bfd_canonicalize_symtab (inbfd, symbols);
393
bfd_fatal (input_file);
395
/* Make sure we have a .bss section. */
396
bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
399
bss_sec = bfd_make_section_with_flags (outbfd,
400
NLM_UNINITIALIZED_DATA_NAME,
403
|| ! bfd_set_section_alignment (outbfd, bss_sec, 1))
404
bfd_fatal (_("make .bss section"));
407
/* We store the original section names in the .nlmsections section,
408
so that programs which understand it can resurrect the original
409
sections from the NLM. We will put a pointer to .nlmsections in
410
the NLM header area. */
411
secsec = bfd_make_section_with_flags (outbfd, ".nlmsections",
414
bfd_fatal (_("make .nlmsections section"));
416
#ifdef NLMCONV_POWERPC
417
/* For PowerPC NetWare we need to build stubs for calls to undefined
418
symbols. Because each stub requires an entry in the TOC section
419
which must be at the same location as other entries in the TOC
420
section, we must do this before determining where the TOC section
421
goes in setup_sections. */
422
if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
423
powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
426
/* Set up the sections. */
427
bfd_map_over_sections (inbfd, setup_sections, (void *) outbfd);
429
text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
431
/* The .bss section immediately follows the .data section. */
432
data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
433
if (data_sec != NULL)
437
vma = bfd_get_section_size (data_sec);
438
align = 1 << bss_sec->alignment_power;
439
add = ((vma + align - 1) &~ (align - 1)) - vma;
441
if (! bfd_set_section_vma (outbfd, bss_sec, vma))
442
bfd_fatal (_("set .bss vma"));
445
bfd_size_type data_size;
447
data_size = bfd_get_section_size (data_sec);
448
if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
449
bfd_fatal (_("set .data size"));
453
/* Adjust symbol information. */
454
inlead = bfd_get_symbol_leading_char (inbfd);
455
outlead = bfd_get_symbol_leading_char (outbfd);
460
newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
463
for (i = 0; i < symcount; i++)
469
/* Add or remove a leading underscore. */
470
if (inlead != outlead)
474
if (bfd_asymbol_name (sym)[0] == inlead)
482
new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
483
new_name[0] = outlead;
484
strcpy (new_name + 1, bfd_asymbol_name (sym) + 1);
485
sym->name = new_name;
493
new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
494
new_name[0] = outlead;
495
strcpy (new_name + 1, bfd_asymbol_name (sym));
496
sym->name = new_name;
500
/* NLM's have an uninitialized data section, but they do not
501
have a common section in the Unix sense. Move all common
502
symbols into the .bss section, and mark them as exported. */
503
if (bfd_is_com_section (bfd_get_section (sym)))
505
bfd_vma size = sym->value;
507
sym->section = bss_sec;
508
sym->value = bfd_get_section_size (bss_sec);
510
align = 1 << bss_sec->alignment_power;
511
size = (size + align - 1) & ~(align - 1);
512
bfd_set_section_size (outbfd, bss_sec, size);
513
sym->flags |= BSF_EXPORT | BSF_GLOBAL;
515
else if (bfd_get_section (sym)->output_section != NULL)
517
/* Move the symbol into the output section. */
518
sym->value += bfd_get_section (sym)->output_offset;
519
sym->section = bfd_get_section (sym)->output_section;
520
/* This is no longer a section symbol. */
521
sym->flags &=~ BSF_SECTION_SYM;
524
/* Force _edata and _end to be defined. This would normally be
525
done by the linker, but the manipulation of the common
526
symbols will confuse it. */
527
if ((sym->flags & BSF_DEBUGGING) == 0
528
&& bfd_asymbol_name (sym)[0] == '_'
529
&& bfd_is_und_section (bfd_get_section (sym)))
531
if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
533
sym->section = bss_sec;
536
if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
538
sym->section = bss_sec;
542
#ifdef NLMCONV_POWERPC
543
/* For PowerPC NetWare, we define __GOT0. This is the start
544
of the .got section. */
545
if (bfd_get_arch (inbfd) == bfd_arch_powerpc
546
&& strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
550
got_sec = bfd_get_section_by_name (inbfd, ".got");
551
assert (got_sec != (asection *) NULL);
552
sym->value = got_sec->output_offset;
553
sym->section = got_sec->output_section;
558
/* If this is a global symbol, check the export list. */
559
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
561
struct string_list *l;
564
/* Unfortunately, a symbol can appear multiple times on the
565
export list, with and without prefixes. */
567
for (l = export_symbols; l != NULL; l = l->next)
569
if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
575
zbase = strchr (l->string, '@');
577
&& strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
579
/* We must add a symbol with this prefix. */
580
if (newsymcount >= newsymalloc)
583
newsyms = ((asymbol **)
584
xrealloc ((void *) newsyms,
586
* sizeof (asymbol *))));
588
newsyms[newsymcount] =
589
(asymbol *) xmalloc (sizeof (asymbol));
590
*newsyms[newsymcount] = *sym;
591
newsyms[newsymcount]->name = l->string;
598
/* The unmodified symbol is actually not exported at
600
sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
601
sym->flags |= BSF_LOCAL;
605
/* If it's an undefined symbol, see if it's on the import list.
606
Change the prefix if necessary. */
607
if (bfd_is_und_section (bfd_get_section (sym)))
609
struct string_list *l;
611
for (l = import_symbols; l != NULL; l = l->next)
613
if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
619
zbase = strchr (l->string, '@');
621
&& strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
623
sym->name = l->string;
629
non_fatal (_("warning: symbol %s imported but not in import list"),
630
bfd_asymbol_name (sym));
633
/* See if it's one of the special named symbols. */
634
if ((sym->flags & BSF_DEBUGGING) == 0)
638
/* FIXME: If these symbols are not in the .text section, we
639
add the .text section size to the value. This may not be
640
correct for all targets. I'm not sure how this should
641
really be handled. */
642
if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
644
val = bfd_asymbol_value (sym);
645
if (bfd_get_section (sym) == data_sec
646
&& text_sec != (asection *) NULL)
647
val += bfd_section_size (outbfd, text_sec);
648
if (! bfd_set_start_address (outbfd, val))
649
bfd_fatal (_("set start address"));
652
if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
654
val = bfd_asymbol_value (sym);
655
if (bfd_get_section (sym) == data_sec
656
&& text_sec != (asection *) NULL)
657
val += bfd_section_size (outbfd, text_sec);
658
nlm_fixed_header (outbfd)->exitProcedureOffset = val;
661
if (check_procedure != NULL
662
&& strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
664
val = bfd_asymbol_value (sym);
665
if (bfd_get_section (sym) == data_sec
666
&& text_sec != (asection *) NULL)
667
val += bfd_section_size (outbfd, text_sec);
668
nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
676
endsym->value = bfd_get_section_size (bss_sec);
678
/* FIXME: If any relocs referring to _end use inplace addends,
679
then I think they need to be updated. This is handled by
680
i386_mangle_relocs. Is it needed for any other object
684
if (newsymcount == 0)
688
outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
689
* sizeof (asymbol *));
690
memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
691
memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
692
outsyms[symcount + newsymcount] = NULL;
695
bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
698
non_fatal (_("warning: START procedure %s not defined"), start_procedure);
700
non_fatal (_("warning: EXIT procedure %s not defined"), exit_procedure);
701
if (check_procedure != NULL && ! gotcheck)
702
non_fatal (_("warning: CHECK procedure %s not defined"), check_procedure);
704
/* Add additional sections required for the header information. */
705
if (custom_file != NULL)
707
custom_data = fopen (custom_file, "r");
708
if (custom_data == NULL
709
|| fstat (fileno (custom_data), &st) < 0)
711
fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
717
custom_size = st.st_size;
718
custom_section = bfd_make_section_with_flags (outbfd, ".nlmcustom",
720
if (custom_section == NULL
721
|| ! bfd_set_section_size (outbfd, custom_section, custom_size))
722
bfd_fatal (_("custom section"));
725
if (help_file != NULL)
727
help_data = fopen (help_file, "r");
728
if (help_data == NULL
729
|| fstat (fileno (help_data), &st) < 0)
731
fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
737
help_size = st.st_size;
738
help_section = bfd_make_section_with_flags (outbfd, ".nlmhelp",
740
if (help_section == NULL
741
|| ! bfd_set_section_size (outbfd, help_section, help_size))
742
bfd_fatal (_("help section"));
743
LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
746
if (message_file != NULL)
748
message_data = fopen (message_file, "r");
749
if (message_data == NULL
750
|| fstat (fileno (message_data), &st) < 0)
752
fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
758
message_size = st.st_size;
759
message_section = bfd_make_section_with_flags (outbfd,
762
if (message_section == NULL
763
|| ! bfd_set_section_size (outbfd, message_section, message_size))
764
bfd_fatal (_("message section"));
765
LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
770
struct string_list *l;
773
for (l = modules; l != NULL; l = l->next)
774
module_size += strlen (l->string) + 1;
775
module_section = bfd_make_section_with_flags (outbfd, ".nlmmodules",
777
if (module_section == NULL
778
|| ! bfd_set_section_size (outbfd, module_section, module_size))
779
bfd_fatal (_("module section"));
781
if (rpc_file != NULL)
783
rpc_data = fopen (rpc_file, "r");
785
|| fstat (fileno (rpc_data), &st) < 0)
787
fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
793
rpc_size = st.st_size;
794
rpc_section = bfd_make_section_with_flags (outbfd, ".nlmrpc",
796
if (rpc_section == NULL
797
|| ! bfd_set_section_size (outbfd, rpc_section, rpc_size))
798
bfd_fatal (_("rpc section"));
799
LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
802
if (sharelib_file != NULL)
804
sharedbfd = bfd_openr (sharelib_file, output_format);
805
if (sharedbfd == NULL
806
|| ! bfd_check_format (sharedbfd, bfd_object))
808
fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
809
bfd_errmsg (bfd_get_error ()));
810
sharelib_file = NULL;
814
sharedhdr = *nlm_fixed_header (sharedbfd);
815
bfd_close (sharedbfd);
816
shared_data = fopen (sharelib_file, "r");
817
if (shared_data == NULL
818
|| (fstat (fileno (shared_data), &st) < 0))
820
fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
822
sharelib_file = NULL;
826
/* If we were clever, we could just copy out the
827
sections of the shared library which we actually
828
need. However, we would have to figure out the sizes
829
of the external and public information, and that can
830
not be done without reading through them. */
831
if (sharedhdr.uninitializedDataSize > 0)
833
/* There is no place to record this information. */
834
non_fatal (_("%s: warning: shared libraries can not have uninitialized data"),
837
shared_offset = st.st_size;
838
if (shared_offset > (size_t) sharedhdr.codeImageOffset)
839
shared_offset = sharedhdr.codeImageOffset;
840
if (shared_offset > (size_t) sharedhdr.dataImageOffset)
841
shared_offset = sharedhdr.dataImageOffset;
842
if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
843
shared_offset = sharedhdr.relocationFixupOffset;
844
if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
845
shared_offset = sharedhdr.externalReferencesOffset;
846
if (shared_offset > (size_t) sharedhdr.publicsOffset)
847
shared_offset = sharedhdr.publicsOffset;
848
shared_size = st.st_size - shared_offset;
849
shared_section = bfd_make_section_with_flags (outbfd,
852
if (shared_section == NULL
853
|| ! bfd_set_section_size (outbfd, shared_section,
855
bfd_fatal (_("shared section"));
856
LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
861
/* Check whether a version was given. */
862
if (!CONST_STRNEQ (version_hdr->stamp, "VeRsIoN#"))
863
non_fatal (_("warning: No version number given"));
865
/* At least for now, always create an extended header, because that
866
is what NLMLINK does. */
867
LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
869
LITMEMCPY (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx");
871
/* If the date was not given, force it in. */
872
if (nlm_version_header (outbfd)->month == 0
873
&& nlm_version_header (outbfd)->day == 0
874
&& nlm_version_header (outbfd)->year == 0)
880
ptm = localtime (&now);
881
nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
882
nlm_version_header (outbfd)->day = ptm->tm_mday;
883
nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
884
LITMEMCPY (version_hdr->stamp, "VeRsIoN#");
887
#ifdef NLMCONV_POWERPC
888
/* Resolve the stubs we build for PowerPC NetWare. */
889
if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
890
powerpc_resolve_stubs (inbfd, outbfd);
893
/* Copy over the sections. */
894
bfd_map_over_sections (inbfd, copy_sections, (void *) outbfd);
896
/* Finish up the header information. */
897
if (custom_file != NULL)
901
data = xmalloc (custom_size);
902
if (fread (data, 1, custom_size, custom_data) != custom_size)
903
non_fatal (_("%s: read: %s"), custom_file, strerror (errno));
906
if (! bfd_set_section_contents (outbfd, custom_section, data,
907
(file_ptr) 0, custom_size))
908
bfd_fatal (_("custom section"));
909
nlm_fixed_header (outbfd)->customDataOffset =
910
custom_section->filepos;
911
nlm_fixed_header (outbfd)->customDataSize = custom_size;
917
/* As a special hack, the backend recognizes a debugInfoOffset
918
of -1 to mean that it should not output any debugging
919
information. This can not be handling by fiddling with the
920
symbol table because exported symbols appear in both the
921
export information and the debugging information. */
922
nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
925
non_fatal (_("warning: FULLMAP is not supported; try ld -M"));
926
if (help_file != NULL)
930
data = xmalloc (help_size);
931
if (fread (data, 1, help_size, help_data) != help_size)
932
non_fatal (_("%s: read: %s"), help_file, strerror (errno));
935
if (! bfd_set_section_contents (outbfd, help_section, data,
936
(file_ptr) 0, help_size))
937
bfd_fatal (_("help section"));
938
nlm_extended_header (outbfd)->helpFileOffset =
939
help_section->filepos;
940
nlm_extended_header (outbfd)->helpFileLength = help_size;
944
if (message_file != NULL)
948
data = xmalloc (message_size);
949
if (fread (data, 1, message_size, message_data) != message_size)
950
non_fatal (_("%s: read: %s"), message_file, strerror (errno));
953
if (! bfd_set_section_contents (outbfd, message_section, data,
954
(file_ptr) 0, message_size))
955
bfd_fatal (_("message section"));
956
nlm_extended_header (outbfd)->messageFileOffset =
957
message_section->filepos;
958
nlm_extended_header (outbfd)->messageFileLength = message_size;
960
/* FIXME: Are these offsets correct on all platforms? Are
961
they 32 bits on all platforms? What endianness? */
962
nlm_extended_header (outbfd)->languageID =
963
bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
964
nlm_extended_header (outbfd)->messageCount =
965
bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
973
struct string_list *l;
976
data = xmalloc (module_size);
978
set = (unsigned char *) data;
979
for (l = modules; l != NULL; l = l->next)
981
*set = strlen (l->string);
982
strncpy ((char *) set + 1, l->string, *set);
986
if (! bfd_set_section_contents (outbfd, module_section, data,
987
(file_ptr) 0, module_size))
988
bfd_fatal (_("module section"));
989
nlm_fixed_header (outbfd)->moduleDependencyOffset =
990
module_section->filepos;
991
nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
993
if (rpc_file != NULL)
997
data = xmalloc (rpc_size);
998
if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
999
non_fatal (_("%s: read: %s"), rpc_file, strerror (errno));
1002
if (! bfd_set_section_contents (outbfd, rpc_section, data,
1003
(file_ptr) 0, rpc_size))
1004
bfd_fatal (_("rpc section"));
1005
nlm_extended_header (outbfd)->RPCDataOffset =
1006
rpc_section->filepos;
1007
nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
1011
if (sharelib_file != NULL)
1015
data = xmalloc (shared_size);
1016
if (fseek (shared_data, shared_offset, SEEK_SET) != 0
1017
|| fread (data, 1, shared_size, shared_data) != shared_size)
1018
non_fatal (_("%s: read: %s"), sharelib_file, strerror (errno));
1021
if (! bfd_set_section_contents (outbfd, shared_section, data,
1022
(file_ptr) 0, shared_size))
1023
bfd_fatal (_("shared section"));
1025
nlm_extended_header (outbfd)->sharedCodeOffset =
1026
sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
1027
nlm_extended_header (outbfd)->sharedCodeLength =
1028
sharedhdr.codeImageSize;
1029
nlm_extended_header (outbfd)->sharedDataOffset =
1030
sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
1031
nlm_extended_header (outbfd)->sharedDataLength =
1032
sharedhdr.dataImageSize;
1033
nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
1034
(sharedhdr.relocationFixupOffset
1036
+ shared_section->filepos);
1037
nlm_extended_header (outbfd)->sharedRelocationFixupCount =
1038
sharedhdr.numberOfRelocationFixups;
1039
nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
1040
(sharedhdr.externalReferencesOffset
1042
+ shared_section->filepos);
1043
nlm_extended_header (outbfd)->sharedExternalReferenceCount =
1044
sharedhdr.numberOfExternalReferences;
1045
nlm_extended_header (outbfd)->sharedPublicsOffset =
1046
sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
1047
nlm_extended_header (outbfd)->sharedPublicsCount =
1048
sharedhdr.numberOfPublics;
1049
nlm_extended_header (outbfd)->sharedDebugRecordOffset =
1050
sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
1051
nlm_extended_header (outbfd)->sharedDebugRecordCount =
1052
sharedhdr.numberOfDebugRecords;
1053
nlm_extended_header (outbfd)->SharedInitializationOffset =
1054
sharedhdr.codeStartOffset;
1055
nlm_extended_header (outbfd)->SharedExitProcedureOffset =
1056
sharedhdr.exitProcedureOffset;
1061
const int max_len = NLM_MODULE_NAME_SIZE - 2;
1062
const char * filename = lbasename (output_file);
1064
len = strlen (filename);
1067
nlm_fixed_header (outbfd)->moduleName[0] = len;
1069
strncpy (nlm_fixed_header (outbfd)->moduleName + 1, filename, max_len);
1070
nlm_fixed_header (outbfd)->moduleName[max_len + 1] = '\0';
1072
for (modname = nlm_fixed_header (outbfd)->moduleName;
1075
*modname = TOUPPER (*modname);
1078
strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
1079
NLM_OLD_THREAD_NAME_LENGTH);
1081
nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
1082
nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
1084
if (! bfd_close (outbfd))
1085
bfd_fatal (output_file);
1086
if (! bfd_close (inbfd))
1087
bfd_fatal (input_file);
1089
if (unlink_on_exit != NULL)
1090
unlink (unlink_on_exit);
1096
/* Show a usage message and exit. */
1099
show_usage (FILE *file, int status)
1101
fprintf (file, _("Usage: %s [option(s)] [in-file [out-file]]\n"), program_name);
1102
fprintf (file, _(" Convert an object file into a NetWare Loadable Module\n"));
1103
fprintf (file, _(" The options are:\n\
1104
-I --input-target=<bfdname> Set the input binary file format\n\
1105
-O --output-target=<bfdname> Set the output binary file format\n\
1106
-T --header-file=<file> Read <file> for NLM header information\n\
1107
-l --linker=<linker> Use <linker> for any linking\n\
1108
-d --debug Display on stderr the linker command line\n\
1109
@<file> Read options from <file>.\n\
1110
-h --help Display this information\n\
1111
-v --version Display the program's version\n\
1113
if (REPORT_BUGS_TO[0] && status == 0)
1114
fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
1118
/* Select the output format based on the input architecture, machine,
1119
and endianness. This chooses the appropriate NLM target. */
1122
select_output_format (enum bfd_architecture arch, unsigned long mach,
1123
bfd_boolean bigendian ATTRIBUTE_UNUSED)
1129
return "nlm32-i386";
1131
#ifdef NLMCONV_SPARC
1132
case bfd_arch_sparc:
1133
return "nlm32-sparc";
1135
#ifdef NLMCONV_ALPHA
1136
case bfd_arch_alpha:
1137
return "nlm32-alpha";
1139
#ifdef NLMCONV_POWERPC
1140
case bfd_arch_powerpc:
1141
return "nlm32-powerpc";
1144
fatal (_("support not compiled in for %s"),
1145
bfd_printable_arch_mach (arch, mach));
1150
/* The BFD sections are copied in two passes. This function selects
1151
the output section for each input section, and sets up the section
1155
setup_sections (bfd *inbfd ATTRIBUTE_UNUSED, asection *insec, void *data_ptr)
1157
bfd *outbfd = (bfd *) data_ptr;
1159
const char *outname;
1162
bfd_size_type align;
1164
bfd_size_type secsecsize;
1166
f = bfd_get_section_flags (inbfd, insec);
1168
outname = NLM_CODE_NAME;
1169
else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
1170
outname = NLM_INITIALIZED_DATA_NAME;
1171
else if (f & SEC_ALLOC)
1172
outname = NLM_UNINITIALIZED_DATA_NAME;
1174
outname = bfd_section_name (inbfd, insec);
1176
outsec = bfd_get_section_by_name (outbfd, outname);
1179
outsec = bfd_make_section (outbfd, outname);
1181
bfd_fatal (_("make section"));
1184
insec->output_section = outsec;
1186
offset = bfd_section_size (outbfd, outsec);
1187
align = 1 << bfd_section_alignment (inbfd, insec);
1188
add = ((offset + align - 1) &~ (align - 1)) - offset;
1189
insec->output_offset = offset + add;
1191
if (! bfd_set_section_size (outbfd, outsec,
1192
(bfd_section_size (outbfd, outsec)
1193
+ bfd_section_size (inbfd, insec)
1195
bfd_fatal (_("set section size"));
1197
if ((bfd_section_alignment (inbfd, insec)
1198
> bfd_section_alignment (outbfd, outsec))
1199
&& ! bfd_set_section_alignment (outbfd, outsec,
1200
bfd_section_alignment (inbfd, insec)))
1201
bfd_fatal (_("set section alignment"));
1203
if (! bfd_set_section_flags (outbfd, outsec,
1204
f | bfd_get_section_flags (outbfd, outsec)))
1205
bfd_fatal (_("set section flags"));
1207
bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
1209
/* For each input section we allocate space for an entry in
1211
secsecsize = bfd_section_size (outbfd, secsec);
1212
secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
1213
secsecsize = (secsecsize + 3) &~ 3;
1215
if (! bfd_set_section_size (outbfd, secsec, secsecsize))
1216
bfd_fatal (_("set .nlmsections size"));
1219
/* Copy the section contents. */
1222
copy_sections (bfd *inbfd, asection *insec, void *data_ptr)
1224
static bfd_size_type secsecoff = 0;
1225
bfd *outbfd = (bfd *) data_ptr;
1234
inname = bfd_section_name (inbfd, insec);
1236
outsec = insec->output_section;
1237
assert (outsec != NULL);
1239
size = bfd_get_section_size (insec);
1241
if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
1245
contents = xmalloc (size);
1246
if (! bfd_get_section_contents (inbfd, insec, contents,
1247
(file_ptr) 0, size))
1248
bfd_fatal (bfd_get_filename (inbfd));
1251
reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
1253
bfd_fatal (bfd_get_filename (inbfd));
1254
if (reloc_size != 0)
1259
relocs = (arelent **) xmalloc (reloc_size);
1260
reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
1261
if (reloc_count < 0)
1262
bfd_fatal (bfd_get_filename (inbfd));
1263
mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
1266
/* FIXME: refers to internal BFD fields. */
1267
if (outsec->orelocation != (arelent **) NULL)
1269
bfd_size_type total_count;
1272
total_count = reloc_count + outsec->reloc_count;
1273
combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
1274
memcpy (combined, outsec->orelocation,
1275
outsec->reloc_count * sizeof (arelent *));
1276
memcpy (combined + outsec->reloc_count, relocs,
1277
(size_t) (reloc_count * sizeof (arelent *)));
1278
free (outsec->orelocation);
1279
reloc_count = total_count;
1283
bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
1286
if (contents != NULL)
1288
if (! bfd_set_section_contents (outbfd, outsec, contents,
1289
insec->output_offset, size))
1290
bfd_fatal (bfd_get_filename (outbfd));
1294
/* Add this section to .nlmsections. */
1295
if (! bfd_set_section_contents (outbfd, secsec, (void *) inname, secsecoff,
1296
strlen (inname) + 1))
1297
bfd_fatal (_("set .nlmsection contents"));
1298
secsecoff += strlen (inname) + 1;
1300
add = ((secsecoff + 3) &~ 3) - secsecoff;
1303
bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1304
if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
1305
bfd_fatal (_("set .nlmsection contents"));
1309
if (contents != NULL)
1310
bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
1312
bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
1313
if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1314
bfd_fatal (_("set .nlmsection contents"));
1317
bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
1318
if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
1319
bfd_fatal (_("set .nlmsection contents"));
1323
/* Some, perhaps all, NetWare targets require changing the relocs used
1324
by the input formats. */
1327
mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
1328
long *reloc_count_ptr, char *contents,
1329
bfd_size_type contents_size)
1331
switch (bfd_get_arch (outbfd))
1335
i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1336
contents, contents_size);
1339
#ifdef NLMCONV_ALPHA
1340
case bfd_arch_alpha:
1341
alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1342
contents, contents_size);
1345
#ifdef NLMCONV_POWERPC
1346
case bfd_arch_powerpc:
1347
powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1348
contents, contents_size);
1352
default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
1353
contents, contents_size);
1358
/* By default all we need to do for relocs is change the address by
1359
the output_offset. */
1362
default_mangle_relocs (bfd *outbfd ATTRIBUTE_UNUSED, asection *insec,
1363
arelent ***relocs_ptr, long *reloc_count_ptr,
1364
char *contents ATTRIBUTE_UNUSED,
1365
bfd_size_type contents_size ATTRIBUTE_UNUSED)
1367
if (insec->output_offset != 0)
1373
reloc_count = *reloc_count_ptr;
1374
relocs = *relocs_ptr;
1375
for (i = 0; i < reloc_count; i++, relocs++)
1376
(*relocs)->address += insec->output_offset;
1382
/* NetWare on the i386 supports a restricted set of relocs, which are
1383
different from those used on other i386 targets. This routine
1384
converts the relocs. It is, obviously, very target dependent. At
1385
the moment, the nlm32-i386 backend performs similar translations;
1386
however, it is more reliable and efficient to do them here. */
1388
static reloc_howto_type nlm_i386_pcrel_howto =
1389
HOWTO (1, /* type */
1391
2, /* size (0 = byte, 1 = short, 2 = long) */
1393
TRUE, /* pc_relative */
1395
complain_overflow_signed, /* complain_on_overflow */
1396
0, /* special_function */
1397
"DISP32", /* name */
1398
TRUE, /* partial_inplace */
1399
0xffffffff, /* src_mask */
1400
0xffffffff, /* dst_mask */
1401
TRUE); /* pcrel_offset */
1404
i386_mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
1405
long *reloc_count_ptr, char *contents,
1406
bfd_size_type contents_size)
1408
long reloc_count, i;
1411
reloc_count = *reloc_count_ptr;
1412
relocs = *relocs_ptr;
1413
for (i = 0; i < reloc_count; i++)
1417
bfd_size_type address;
1421
sym = *rel->sym_ptr_ptr;
1423
/* We're moving the relocs from the input section to the output
1424
section, so we must adjust the address accordingly. */
1425
address = rel->address;
1426
rel->address += insec->output_offset;
1428
/* Note that no serious harm will ensue if we fail to change a
1429
reloc. The backend will fail when writing out the reloc. */
1431
/* Make sure this reloc is within the data we have. We use only
1432
4 byte relocs here, so we insist on having 4 bytes. */
1433
if (address + 4 > contents_size)
1436
/* A PC relative reloc entirely within a single section is
1437
completely unnecessary. This can be generated by ld -r. */
1438
if (sym == insec->symbol
1439
&& rel->howto != NULL
1440
&& rel->howto->pc_relative
1441
&& ! rel->howto->pcrel_offset)
1445
memmove (relocs, relocs + 1,
1446
(size_t) ((reloc_count - i) * sizeof (arelent *)));
1450
/* Get the amount the relocation will add in. */
1451
addend = rel->addend + sym->value;
1453
/* NetWare doesn't support PC relative relocs against defined
1454
symbols, so we have to eliminate them by doing the relocation
1455
now. We can only do this if the reloc is within a single
1457
if (rel->howto != NULL
1458
&& rel->howto->pc_relative
1459
&& bfd_get_section (sym) == insec->output_section)
1463
if (rel->howto->pcrel_offset)
1466
val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1468
bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1472
memmove (relocs, relocs + 1,
1473
(size_t) ((reloc_count - i) * sizeof (arelent *)));
1477
/* NetWare doesn't support reloc addends, so we get rid of them
1478
here by simply adding them into the object data. We handle
1479
the symbol value, if any, the same way. */
1481
&& rel->howto != NULL
1482
&& rel->howto->rightshift == 0
1483
&& rel->howto->size == 2
1484
&& rel->howto->bitsize == 32
1485
&& rel->howto->bitpos == 0
1486
&& rel->howto->src_mask == 0xffffffff
1487
&& rel->howto->dst_mask == 0xffffffff)
1491
val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1493
bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1495
/* Adjust the reloc for the changes we just made. */
1497
if (! bfd_is_und_section (bfd_get_section (sym)))
1498
rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
1501
/* NetWare uses a reloc with pcrel_offset set. We adjust
1502
pc_relative relocs accordingly. We are going to change the
1503
howto field, so we can only do this if the current one is
1504
compatible. We should check that special_function is NULL
1505
here, but at the moment coff-i386 uses a special_function
1506
which does not affect what we are doing here. */
1507
if (rel->howto != NULL
1508
&& rel->howto->pc_relative
1509
&& ! rel->howto->pcrel_offset
1510
&& rel->howto->rightshift == 0
1511
&& rel->howto->size == 2
1512
&& rel->howto->bitsize == 32
1513
&& rel->howto->bitpos == 0
1514
&& rel->howto->src_mask == 0xffffffff
1515
&& rel->howto->dst_mask == 0xffffffff)
1519
/* When pcrel_offset is not set, it means that the negative
1520
of the address of the memory location is stored in the
1521
memory location. We must add it back in. */
1522
val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
1524
bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
1526
/* We must change to a new howto. */
1527
rel->howto = &nlm_i386_pcrel_howto;
1532
#endif /* NLMCONV_I386 */
1534
#ifdef NLMCONV_ALPHA
1536
/* On the Alpha the first reloc for every section must be a special
1537
relocs which hold the GP address. Also, the first reloc in the
1538
file must be a special reloc which holds the address of the .lita
1541
static reloc_howto_type nlm32_alpha_nw_howto =
1542
HOWTO (ALPHA_R_NW_RELOC, /* type */
1544
0, /* size (0 = byte, 1 = short, 2 = long) */
1546
FALSE, /* pc_relative */
1548
complain_overflow_dont, /* complain_on_overflow */
1549
0, /* special_function */
1550
"NW_RELOC", /* name */
1551
FALSE, /* partial_inplace */
1554
FALSE); /* pcrel_offset */
1557
alpha_mangle_relocs (bfd *outbfd, asection *insec,
1558
arelent ***relocs_ptr, long *reloc_count_ptr,
1559
char *contents ATTRIBUTE_UNUSED,
1560
bfd_size_type contents_size ATTRIBUTE_UNUSED)
1562
long old_reloc_count;
1563
arelent **old_relocs;
1566
old_reloc_count = *reloc_count_ptr;
1567
old_relocs = *relocs_ptr;
1568
relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
1569
*relocs_ptr = relocs;
1571
if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
1574
asection *lita_section;
1576
inbfd = insec->owner;
1577
lita_section = bfd_get_section_by_name (inbfd, _LITA);
1578
if (lita_section != (asection *) NULL)
1580
nlm_alpha_backend_data (outbfd)->lita_address =
1581
bfd_get_section_vma (inbfd, lita_section);
1582
nlm_alpha_backend_data (outbfd)->lita_size =
1583
bfd_section_size (inbfd, lita_section);
1587
/* Avoid outputting this reloc again. */
1588
nlm_alpha_backend_data (outbfd)->lita_address = 4;
1591
*relocs = (arelent *) xmalloc (sizeof (arelent));
1592
(*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1593
(*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
1594
(*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
1595
(*relocs)->howto = &nlm32_alpha_nw_howto;
1597
++(*reloc_count_ptr);
1600
/* Get the GP value from bfd. */
1601
if (nlm_alpha_backend_data (outbfd)->gp == 0)
1602
nlm_alpha_backend_data (outbfd)->gp =
1603
bfd_ecoff_get_gp_value (insec->owner);
1605
*relocs = (arelent *) xmalloc (sizeof (arelent));
1606
(*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1607
(*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
1608
(*relocs)->addend = 0;
1609
(*relocs)->howto = &nlm32_alpha_nw_howto;
1611
++(*reloc_count_ptr);
1613
memcpy (relocs, old_relocs, (size_t) old_reloc_count * sizeof (arelent *));
1614
relocs[old_reloc_count] = (arelent *) NULL;
1618
if (insec->output_offset != 0)
1622
for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
1623
(*relocs)->address += insec->output_offset;
1627
#endif /* NLMCONV_ALPHA */
1629
#ifdef NLMCONV_POWERPC
1631
/* We keep a linked list of stubs which we must build. Because BFD
1632
requires us to know the sizes of all sections before we can set the
1633
contents of any, we must figure out which stubs we want to build
1634
before we can actually build any of them. */
1638
/* Next stub in linked list. */
1639
struct powerpc_stub *next;
1641
/* Symbol whose value is the start of the stub. This is a symbol
1642
whose name begins with `.'. */
1645
/* Symbol we are going to create a reloc against. This is a symbol
1646
with the same name as START but without the leading `.'. */
1649
/* The TOC index for this stub. This is the index into the TOC
1650
section at which the reloc is created. */
1651
unsigned int toc_index;
1654
/* The linked list of stubs. */
1656
static struct powerpc_stub *powerpc_stubs;
1658
/* This is what a stub looks like. The first instruction will get
1659
adjusted with the correct TOC index. */
1661
static unsigned long powerpc_stub_insns[] =
1663
0x81820000, /* lwz r12,0(r2) */
1664
0x90410014, /* stw r2,20(r1) */
1665
0x800c0000, /* lwz r0,0(r12) */
1666
0x804c0004, /* lwz r2,r(r12) */
1667
0x7c0903a6, /* mtctr r0 */
1668
0x4e800420, /* bctr */
1669
0, /* Traceback table. */
1674
#define POWERPC_STUB_INSN_COUNT \
1675
(sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
1677
#define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
1679
/* Each stub uses a four byte TOC entry. */
1680
#define POWERPC_STUB_TOC_ENTRY_SIZE (4)
1682
/* The original size of the .got section. */
1683
static bfd_size_type powerpc_initial_got_size;
1685
/* Look for all undefined symbols beginning with `.', and prepare to
1686
build a stub for each one. */
1689
powerpc_build_stubs (bfd *inbfd, bfd *outbfd ATTRIBUTE_UNUSED,
1690
asymbol ***symbols_ptr, long *symcount_ptr)
1694
unsigned int got_base;
1699
/* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
1700
the section to prevent copy_sections from reading from it. */
1701
stub_sec = bfd_make_section_with_flags (inbfd, ".stubs",
1706
if (stub_sec == (asection *) NULL
1707
|| ! bfd_set_section_alignment (inbfd, stub_sec, 2))
1708
bfd_fatal (".stubs");
1710
/* Get the TOC section, which is named .got. */
1711
got_sec = bfd_get_section_by_name (inbfd, ".got");
1712
if (got_sec == (asection *) NULL)
1714
got_sec = bfd_make_section_with_flags (inbfd, ".got",
1719
| SEC_HAS_CONTENTS));
1720
if (got_sec == (asection *) NULL
1721
|| ! bfd_set_section_alignment (inbfd, got_sec, 2))
1725
powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
1726
got_base = powerpc_initial_got_size;
1727
got_base = (got_base + 3) &~ 3;
1731
symcount = *symcount_ptr;
1732
for (i = 0; i < symcount; i++)
1737
struct powerpc_stub *item;
1739
sym = (*symbols_ptr)[i];
1741
/* We must make a stub for every undefined symbol whose name
1743
if (bfd_asymbol_name (sym)[0] != '.'
1744
|| ! bfd_is_und_section (bfd_get_section (sym)))
1747
/* Make a new undefined symbol with the same name but without
1749
newsym = xmalloc (sizeof (asymbol));
1751
newname = xmalloc (strlen (bfd_asymbol_name (sym)));
1752
strcpy (newname, bfd_asymbol_name (sym) + 1);
1753
newsym->name = newname;
1755
/* Define the `.' symbol to be in the stub section. */
1756
sym->section = stub_sec;
1757
sym->value = stubcount * POWERPC_STUB_SIZE;
1758
/* We set the BSF_DYNAMIC flag here so that we can check it when
1759
we are mangling relocs. FIXME: This is a hack. */
1760
sym->flags = BSF_LOCAL | BSF_DYNAMIC;
1762
/* Add this stub to the linked list. */
1763
item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
1765
item->reloc = newsym;
1766
item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
1768
item->next = powerpc_stubs;
1769
powerpc_stubs = item;
1777
struct powerpc_stub *l;
1779
/* Add the new symbols we just created to the symbol table. */
1780
*symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
1781
((symcount + stubcount)
1782
* sizeof (asymbol)));
1783
*symcount_ptr += stubcount;
1784
s = &(*symbols_ptr)[symcount];
1785
for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1788
/* Set the size of the .stubs section and increase the size of
1789
the .got section. */
1790
if (! bfd_set_section_size (inbfd, stub_sec,
1791
stubcount * POWERPC_STUB_SIZE)
1792
|| ! bfd_set_section_size (inbfd, got_sec,
1795
* POWERPC_STUB_TOC_ENTRY_SIZE))))
1796
bfd_fatal (_("stub section sizes"));
1800
/* Resolve all the stubs for PowerPC NetWare. We fill in the contents
1801
of the output section, and create new relocs in the TOC. */
1804
powerpc_resolve_stubs (bfd *inbfd, bfd *outbfd)
1806
bfd_byte buf[POWERPC_STUB_SIZE];
1808
unsigned int stubcount;
1812
struct powerpc_stub *l;
1814
if (powerpc_stubs == (struct powerpc_stub *) NULL)
1817
for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
1818
bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
1820
got_sec = bfd_get_section_by_name (inbfd, ".got");
1821
assert (got_sec != (asection *) NULL);
1822
assert (got_sec->output_section->orelocation == (arelent **) NULL);
1825
for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1827
relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
1830
for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
1834
/* Adjust the first instruction to use the right TOC index. */
1835
bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
1837
/* Write this stub out. */
1838
if (! bfd_set_section_contents (outbfd,
1839
bfd_get_section (l->start),
1843
bfd_fatal (_("writing stub"));
1845
/* Create a new reloc for the TOC entry. */
1846
reloc = (arelent *) xmalloc (sizeof (arelent));
1847
reloc->sym_ptr_ptr = &l->reloc;
1848
reloc->address = l->toc_index + got_sec->output_offset;
1850
reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
1855
bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
1858
/* Adjust relocation entries for PowerPC NetWare. We do not output
1859
TOC relocations. The object code already contains the offset from
1860
the TOC pointer. When the function is called, the TOC register,
1861
r2, will be set to the correct TOC value, so there is no need for
1862
any further reloc. */
1865
powerpc_mangle_relocs (bfd *outbfd, asection *insec,
1866
arelent ***relocs_ptr,
1867
long *reloc_count_ptr, char *contents,
1868
bfd_size_type contents_size ATTRIBUTE_UNUSED)
1870
reloc_howto_type *toc_howto;
1875
toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
1876
if (toc_howto == (reloc_howto_type *) NULL)
1879
/* If this is the .got section, clear out all the contents beyond
1880
the initial size. We must do this here because copy_sections is
1881
going to write out whatever we return in the contents field. */
1882
if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
1883
memset (contents + powerpc_initial_got_size, 0,
1884
(size_t) (bfd_get_section_size (insec) - powerpc_initial_got_size));
1886
reloc_count = *reloc_count_ptr;
1887
relocs = *relocs_ptr;
1888
for (i = 0; i < reloc_count; i++)
1895
sym = *rel->sym_ptr_ptr;
1897
/* Convert any relocs against the .bss section into relocs
1898
against the .data section. */
1899
if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
1900
NLM_UNINITIALIZED_DATA_NAME) == 0)
1904
datasec = bfd_get_section_by_name (outbfd,
1905
NLM_INITIALIZED_DATA_NAME);
1906
if (datasec != NULL)
1908
rel->addend += (bfd_get_section_vma (outbfd,
1909
bfd_get_section (sym))
1911
rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
1912
sym = *rel->sym_ptr_ptr;
1916
/* We must be able to resolve all PC relative relocs at this
1917
point. If we get a branch to an undefined symbol we build a
1918
stub, since NetWare will resolve undefined symbols into a
1919
pointer to a function descriptor. */
1920
if (rel->howto->pc_relative)
1922
/* This check for whether a symbol is in the same section as
1923
the reloc will be wrong if there is a PC relative reloc
1924
between two sections both of which were placed in the
1925
same output section. This should not happen. */
1926
if (bfd_get_section (sym) != insec->output_section)
1927
non_fatal (_("unresolved PC relative reloc against %s"),
1928
bfd_asymbol_name (sym));
1933
assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
1934
val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
1935
val = ((val &~ rel->howto->dst_mask)
1936
| (((val & rel->howto->src_mask)
1937
+ (sym->value - rel->address)
1939
& rel->howto->dst_mask));
1940
bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
1942
/* If this reloc is against an stubbed symbol and the
1945
then we replace the next instruction with
1947
This reloads the TOC pointer after a stub call. */
1948
if (bfd_asymbol_name (sym)[0] == '.'
1949
&& (sym->flags & BSF_DYNAMIC) != 0
1950
&& (bfd_get_32 (outbfd,
1951
(bfd_byte *) contents + rel->address + 4)
1952
== 0x4ffffb82)) /* cror 31,31,31 */
1953
bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
1954
(bfd_byte *) contents + rel->address + 4);
1958
memmove (relocs, relocs + 1,
1959
(size_t) ((reloc_count - 1) * sizeof (arelent *)));
1964
/* When considering a TOC reloc, we do not want to include the
1965
symbol value. The symbol will be start of the TOC section
1966
(which is named .got). We do want to include the addend. */
1967
if (rel->howto == toc_howto)
1970
sym_value = sym->value;
1972
/* If this is a relocation against a symbol with a value, or
1973
there is a reloc addend, we need to update the addend in the
1975
if (sym_value + rel->addend != 0)
1979
switch (rel->howto->size)
1982
val = bfd_get_16 (outbfd,
1983
(bfd_byte *) contents + rel->address);
1984
val = ((val &~ rel->howto->dst_mask)
1985
| (((val & rel->howto->src_mask)
1988
& rel->howto->dst_mask));
1989
if ((bfd_signed_vma) val < - 0x8000
1990
|| (bfd_signed_vma) val >= 0x8000)
1991
non_fatal (_("overflow when adjusting relocation against %s"),
1992
bfd_asymbol_name (sym));
1993
bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
1997
val = bfd_get_32 (outbfd,
1998
(bfd_byte *) contents + rel->address);
1999
val = ((val &~ rel->howto->dst_mask)
2000
| (((val & rel->howto->src_mask)
2003
& rel->howto->dst_mask));
2004
bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
2011
if (! bfd_is_und_section (bfd_get_section (sym)))
2012
rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
2016
/* Now that we have incorporated the addend, remove any TOC
2018
if (rel->howto == toc_howto)
2022
memmove (relocs, relocs + 1,
2023
(size_t) ((reloc_count - i) * sizeof (arelent *)));
2027
rel->address += insec->output_offset;
2031
#endif /* NLMCONV_POWERPC */
2033
/* Name of linker. */
2035
#define LD_NAME "ld"
2038
/* The user has specified several input files. Invoke the linker to
2039
link them all together, and convert and delete the resulting output
2043
link_inputs (struct string_list *inputs, char *ld, char * mfile)
2046
struct string_list *q;
2055
for (q = inputs; q != NULL; q = q->next)
2058
argv = (char **) alloca ((c + 7) * sizeof (char *));
2065
/* Find the linker to invoke based on how nlmconv was run. */
2066
p = program_name + strlen (program_name);
2067
while (p != program_name)
2071
ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
2072
memcpy (ld, program_name, p - program_name);
2073
strcpy (ld + (p - program_name), LD_NAME);
2082
ld = (char *) LD_NAME;
2084
unlink_on_exit = make_temp_file (".O");
2087
argv[1] = (char *) "-Ur";
2088
argv[2] = (char *) "-o";
2089
argv[3] = unlink_on_exit;
2090
/* If we have been given the name of a mapfile and that
2091
name is not 'stderr' then pass it on to the linker. */
2094
&& strcmp (mfile, "stderr") == 0)
2096
argv[4] = (char *) "-Map";
2103
for (q = inputs; q != NULL; q = q->next, i++)
2104
argv[i] = q->string;
2109
for (i = 0; argv[i] != NULL; i++)
2110
fprintf (stderr, " %s", argv[i]);
2111
fprintf (stderr, "\n");
2114
pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
2115
PEXECUTE_SEARCH | PEXECUTE_ONE);
2118
fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
2119
fprintf (stderr, errfmt, errarg);
2120
unlink (unlink_on_exit);
2124
if (pwait (pid, &status, 0) < 0)
2127
unlink (unlink_on_exit);
2133
non_fatal (_("Execution of %s failed"), ld);
2134
unlink (unlink_on_exit);
2138
return unlink_on_exit;