1
/* NLM (NetWare Loadable Module) executable support for BFD.
2
Copyright 1993, 1994, 1995, 1998, 2000, 2001, 2002
3
Free Software Foundation, Inc.
5
Written by Fred Fish @ Cygnus Support, using ELF support as the
8
This file is part of BFD, the Binary File Descriptor library.
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 2 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29
/* The functions in this file do not use the names they appear to use.
30
This file is actually compiled multiple times, once for each size
31
of NLM target we are using. At each size we use a different name,
32
constructed by the macro nlmNAME. For example, the function which
33
is named nlm_symbol_type below is actually named nlm32_symbol_type
34
in the final executable. */
36
#define Nlm_External_Fixed_Header NlmNAME(External_Fixed_Header)
37
#define Nlm_External_Version_Header NlmNAME(External_Version_Header)
38
#define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header)
39
#define Nlm_External_Extended_Header NlmNAME(External_Extended_Header)
40
#define Nlm_External_Custom_Header NlmNAME(External_Custom_Header)
41
#define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header)
43
#define nlm_symbol_type nlmNAME(symbol_type)
44
#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
45
#define nlm_get_symtab nlmNAME(get_symtab)
46
#define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
47
#define nlm_print_symbol nlmNAME(print_symbol)
48
#define nlm_get_symbol_info nlmNAME(get_symbol_info)
49
#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
50
#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
51
#define nlm_object_p nlmNAME(object_p)
52
#define nlm_set_section_contents nlmNAME(set_section_contents)
53
#define nlm_write_object_contents nlmNAME(write_object_contents)
55
#define nlm_swap_fixed_header_in(abfd,src,dst) \
56
(nlm_swap_fixed_header_in_func(abfd)) (abfd,src,dst)
57
#define nlm_swap_fixed_header_out(abfd,src,dst) \
58
(nlm_swap_fixed_header_out_func(abfd)) (abfd,src,dst)
60
/* Forward declarations of static functions */
62
static boolean add_bfd_section
63
PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
64
static boolean nlm_swap_variable_header_in
66
static boolean nlm_swap_variable_header_out
68
static boolean find_nonzero
69
PARAMS ((PTR, size_t));
70
static boolean nlm_swap_auxiliary_headers_in
72
static boolean nlm_swap_auxiliary_headers_out
74
static boolean nlm_slurp_symbol_table
76
static boolean nlm_slurp_reloc_fixups
78
static boolean nlm_compute_section_file_positions
80
static int nlm_external_reloc_compare
81
PARAMS ((const void *, const void *));
83
/* Should perhaps use put_offset, put_word, etc. For now, the two versions
84
can be handled by explicitly specifying 32 bits or "the long type". */
86
#define put_word H_PUT_64
87
#define get_word H_GET_64
90
#define put_word H_PUT_32
91
#define get_word H_GET_32
98
struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
99
boolean (*backend_object_p) PARAMS ((bfd *));
101
Nlm_Internal_Fixed_Header *i_fxdhdrp;
102
struct nlm_obj_tdata *new_tdata = NULL;
103
const char *signature;
104
enum bfd_architecture arch;
107
/* Some NLM formats have a prefix before the standard NLM fixed
109
backend_object_p = nlm_backend_object_p_func (abfd);
110
if (backend_object_p)
112
if (!(*backend_object_p) (abfd))
113
goto got_wrong_format_error;
116
/* Read in the fixed length portion of the NLM header in external format. */
118
amt = nlm_fixed_header_size (abfd);
119
x_fxdhdr = (PTR) bfd_malloc (amt);
120
if (x_fxdhdr == NULL)
123
if (bfd_bread ((PTR) x_fxdhdr, amt, abfd) != amt)
125
if (bfd_get_error () != bfd_error_system_call)
126
goto got_wrong_format_error;
131
/* Allocate an instance of the nlm_obj_tdata structure and hook it up to
132
the tdata pointer in the bfd. */
134
amt = sizeof (struct nlm_obj_tdata);
135
new_tdata = (struct nlm_obj_tdata *) bfd_zalloc (abfd, amt);
136
if (new_tdata == NULL)
139
nlm_tdata (abfd) = new_tdata;
141
i_fxdhdrp = nlm_fixed_header (abfd);
142
nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
146
/* Check to see if we have an NLM file for this backend by matching
147
the NLM signature. */
149
signature = nlm_signature (abfd);
150
if (signature != NULL
151
&& *signature != '\0'
152
&& strncmp ((char *) i_fxdhdrp->signature, signature,
153
NLM_SIGNATURE_SIZE) != 0)
154
goto got_wrong_format_error;
156
/* There's no supported way to discover the endianess of an NLM, so test for
157
a sane version number after doing byte swapping appropriate for this
158
XVEC. (Hack alert!) */
160
if (i_fxdhdrp->version > 0xFFFF)
161
goto got_wrong_format_error;
163
/* There's no supported way to check for 32 bit versus 64 bit addresses,
164
so ignore this distinction for now. (FIXME) */
166
/* Swap in the rest of the required header. */
167
if (!nlm_swap_variable_header_in (abfd))
169
if (bfd_get_error () != bfd_error_system_call)
170
goto got_wrong_format_error;
175
/* Add the sections supplied by all NLM's, and then read in the
176
auxiliary headers. Reading the auxiliary headers may create
177
additional sections described in the cygnus_ext header.
178
From this point on we assume that we have an NLM, and do not
179
treat errors as indicating the wrong format. */
181
if (!add_bfd_section (abfd, NLM_CODE_NAME,
182
i_fxdhdrp->codeImageOffset,
183
i_fxdhdrp->codeImageSize,
184
(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
186
|| !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
187
i_fxdhdrp->dataImageOffset,
188
i_fxdhdrp->dataImageSize,
189
(SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
191
|| !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
193
i_fxdhdrp->uninitializedDataSize,
197
if (!nlm_swap_auxiliary_headers_in (abfd))
200
if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
201
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
202
abfd->flags |= HAS_RELOC;
203
if (nlm_fixed_header (abfd)->numberOfPublics != 0
204
|| nlm_fixed_header (abfd)->numberOfDebugRecords != 0
205
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
206
abfd->flags |= HAS_SYMS;
208
arch = nlm_architecture (abfd);
209
if (arch != bfd_arch_unknown)
210
bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
212
abfd->flags |= EXEC_P;
213
bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
217
got_wrong_format_error:
218
bfd_set_error (bfd_error_wrong_format);
220
nlm_tdata (abfd) = preserved_tdata;
221
if (new_tdata != NULL)
222
bfd_release (abfd, new_tdata);
223
if (x_fxdhdr != NULL)
228
/* Add a section to the bfd. */
231
add_bfd_section (abfd, name, offset, size, flags)
240
newsect = bfd_make_section (abfd, name);
245
newsect->vma = 0; /* NLM's are relocatable. */
246
newsect->_raw_size = size;
247
newsect->filepos = offset;
248
newsect->flags = flags;
249
newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */
253
/* Read and swap in the variable length header. All the fields must
254
exist in the NLM, and must exist in the order they are read here. */
257
nlm_swap_variable_header_in (abfd)
260
unsigned char temp[NLM_TARGET_LONG_SIZE];
263
/* Read the description length and text members. */
265
amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
266
if (bfd_bread ((PTR) &nlm_variable_header (abfd)->descriptionLength,
269
amt = nlm_variable_header (abfd)->descriptionLength + 1;
270
if (bfd_bread ((PTR) nlm_variable_header (abfd)->descriptionText,
274
/* Read and convert the stackSize field. */
277
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
279
nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
281
/* Read and convert the reserved field. */
284
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
286
nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
288
/* Read the oldThreadName field. This field is a fixed length string. */
290
amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
291
if (bfd_bread ((PTR) nlm_variable_header (abfd)->oldThreadName,
295
/* Read the screen name length and text members. */
297
amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
298
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->screenNameLength,
301
amt = nlm_variable_header (abfd)->screenNameLength + 1;
302
if (bfd_bread ((PTR) nlm_variable_header (abfd)->screenName,
306
/* Read the thread name length and text members. */
308
amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
309
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->threadNameLength,
312
amt = nlm_variable_header (abfd)->threadNameLength + 1;
313
if (bfd_bread ((PTR) nlm_variable_header (abfd)->threadName,
319
/* Swap and write out the variable length header. All the fields must
320
exist in the NLM, and must exist in this order. */
323
nlm_swap_variable_header_out (abfd)
326
unsigned char temp[NLM_TARGET_LONG_SIZE];
329
/* Write the description length and text members. */
331
amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
332
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->descriptionLength, amt,
335
amt = nlm_variable_header (abfd)->descriptionLength + 1;
336
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->descriptionText, amt,
340
/* Convert and write the stackSize field. */
342
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
345
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
348
/* Convert and write the reserved field. */
350
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
353
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
356
/* Write the oldThreadName field. This field is a fixed length string. */
358
amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
359
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->oldThreadName, amt,
363
/* Write the screen name length and text members. */
365
amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
366
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->screenNameLength, amt,
369
amt = nlm_variable_header (abfd)->screenNameLength + 1;
370
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->screenName, amt,
374
/* Write the thread name length and text members. */
376
amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
377
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->threadNameLength, amt,
380
amt = nlm_variable_header (abfd)->threadNameLength + 1;
381
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->threadName, amt,
387
/* Read and swap in the contents of all the auxiliary headers. Because of
388
the braindead design, we have to do strcmps on strings of indeterminate
389
length to figure out what each auxiliary header is. Even worse, we have
390
no way of knowing how many auxiliary headers there are or where the end
391
of the auxiliary headers are, except by finding something that doesn't
392
look like a known auxiliary header. This means that the first new type
393
of auxiliary header added will break all existing tools that don't
397
nlm_swap_auxiliary_headers_in (abfd)
406
position = bfd_tell (abfd);
407
amt = sizeof (tempstr);
408
if (bfd_bread ((PTR) tempstr, amt, abfd) != amt)
410
if (bfd_seek (abfd, position, SEEK_SET) != 0)
412
if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
414
Nlm_External_Version_Header thdr;
417
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
419
memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
420
sizeof (thdr.stamp));
421
nlm_version_header (abfd)->majorVersion =
422
get_word (abfd, (bfd_byte *) thdr.majorVersion);
423
nlm_version_header (abfd)->minorVersion =
424
get_word (abfd, (bfd_byte *) thdr.minorVersion);
425
nlm_version_header (abfd)->revision =
426
get_word (abfd, (bfd_byte *) thdr.revision);
427
nlm_version_header (abfd)->year =
428
get_word (abfd, (bfd_byte *) thdr.year);
429
nlm_version_header (abfd)->month =
430
get_word (abfd, (bfd_byte *) thdr.month);
431
nlm_version_header (abfd)->day =
432
get_word (abfd, (bfd_byte *) thdr.day);
434
else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
436
Nlm_External_Extended_Header thdr;
439
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
441
memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
442
sizeof (thdr.stamp));
443
nlm_extended_header (abfd)->languageID =
444
get_word (abfd, (bfd_byte *) thdr.languageID);
445
nlm_extended_header (abfd)->messageFileOffset =
446
get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
447
nlm_extended_header (abfd)->messageFileLength =
448
get_word (abfd, (bfd_byte *) thdr.messageFileLength);
449
nlm_extended_header (abfd)->messageCount =
450
get_word (abfd, (bfd_byte *) thdr.messageCount);
451
nlm_extended_header (abfd)->helpFileOffset =
452
get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
453
nlm_extended_header (abfd)->helpFileLength =
454
get_word (abfd, (bfd_byte *) thdr.helpFileLength);
455
nlm_extended_header (abfd)->RPCDataOffset =
456
get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
457
nlm_extended_header (abfd)->RPCDataLength =
458
get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
459
nlm_extended_header (abfd)->sharedCodeOffset =
460
get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
461
nlm_extended_header (abfd)->sharedCodeLength =
462
get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
463
nlm_extended_header (abfd)->sharedDataOffset =
464
get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
465
nlm_extended_header (abfd)->sharedDataLength =
466
get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
467
nlm_extended_header (abfd)->sharedRelocationFixupOffset =
468
get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
469
nlm_extended_header (abfd)->sharedRelocationFixupCount =
470
get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
471
nlm_extended_header (abfd)->sharedExternalReferenceOffset =
472
get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
473
nlm_extended_header (abfd)->sharedExternalReferenceCount =
474
get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
475
nlm_extended_header (abfd)->sharedPublicsOffset =
476
get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
477
nlm_extended_header (abfd)->sharedPublicsCount =
478
get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
479
nlm_extended_header (abfd)->sharedDebugRecordOffset =
480
get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
481
nlm_extended_header (abfd)->sharedDebugRecordCount =
482
get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
483
nlm_extended_header (abfd)->SharedInitializationOffset =
484
get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
485
nlm_extended_header (abfd)->SharedExitProcedureOffset =
486
get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
487
nlm_extended_header (abfd)->productID =
488
get_word (abfd, (bfd_byte *) thdr.productID);
489
nlm_extended_header (abfd)->reserved0 =
490
get_word (abfd, (bfd_byte *) thdr.reserved0);
491
nlm_extended_header (abfd)->reserved1 =
492
get_word (abfd, (bfd_byte *) thdr.reserved1);
493
nlm_extended_header (abfd)->reserved2 =
494
get_word (abfd, (bfd_byte *) thdr.reserved2);
495
nlm_extended_header (abfd)->reserved3 =
496
get_word (abfd, (bfd_byte *) thdr.reserved3);
497
nlm_extended_header (abfd)->reserved4 =
498
get_word (abfd, (bfd_byte *) thdr.reserved4);
499
nlm_extended_header (abfd)->reserved5 =
500
get_word (abfd, (bfd_byte *) thdr.reserved5);
502
else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
504
amt = sizeof (nlm_copyright_header (abfd)->stamp);
505
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->stamp,
508
if (bfd_bread ((PTR) &(nlm_copyright_header (abfd)
509
->copyrightMessageLength),
510
(bfd_size_type) 1, abfd) != 1)
512
/* The copyright message is a variable length string. */
513
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
514
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
518
else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
520
Nlm_External_Custom_Header thdr;
521
bfd_size_type hdrLength;
523
bfd_size_type dataLength;
527
/* Read the stamp ("CuStHeAd"). */
528
amt = sizeof (thdr.stamp);
529
if (bfd_bread ((PTR) thdr.stamp, amt, abfd) != amt)
531
/* Read the length of this custom header. */
532
amt = sizeof (thdr.length);
533
if (bfd_bread ((PTR) thdr.length, amt, abfd) != amt)
535
hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
536
/* Read further fields if we have them. */
537
if (hdrLength < NLM_TARGET_LONG_SIZE)
541
amt = sizeof (thdr.dataOffset);
542
if (bfd_bread ((PTR) thdr.dataOffset, amt, abfd) != amt)
544
dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
546
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
550
amt = sizeof (thdr.dataLength);
551
if (bfd_bread ((PTR) thdr.dataLength, amt, abfd) != amt)
553
dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
555
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
556
memset (dataStamp, 0, sizeof (dataStamp));
559
amt = sizeof (dataStamp);
560
if (bfd_bread ((PTR) dataStamp, amt, abfd) != amt)
564
/* Read the rest of the header, if any. */
565
if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
572
hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
573
hdr = bfd_alloc (abfd, hdrLength);
576
if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
580
/* If we have found a Cygnus header, process it. Otherwise,
581
just save the associated data without trying to interpret
583
if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
589
BFD_ASSERT (hdrLength == 0 && hdr == NULL);
591
pos = bfd_tell (abfd);
592
if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
594
contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
595
if (contents == NULL)
597
if (bfd_bread (contents, dataLength, abfd) != dataLength)
599
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
602
memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
603
nlm_cygnus_ext_header (abfd)->offset = dataOffset;
604
nlm_cygnus_ext_header (abfd)->length = dataLength;
606
/* This data this header points to provides a list of
607
the sections which were in the original object file
608
which was converted to become an NLM. We locate
609
those sections and add them to the BFD. Note that
610
this is likely to create a second .text, .data and
611
.bss section; retrieving the sections by name will
612
get the actual NLM sections, which is what we want to
613
happen. The sections from the original file, which
614
may be subsets of the NLM section, can only be found
615
using bfd_map_over_sections. */
617
pend = p + dataLength;
626
/* The format of this information is
627
null terminated section name
628
zeroes to adjust to 4 byte boundary
629
4 byte section data file pointer
634
l = strlen (name) + 1;
635
l = (l + 3) &~ (size_t) 3;
637
filepos = H_GET_32 (abfd, p);
639
size = H_GET_32 (abfd, p);
642
newsec = bfd_make_section_anyway (abfd, name);
643
if (newsec == (asection *) NULL)
645
newsec->_raw_size = size;
648
newsec->filepos = filepos;
649
newsec->flags |= SEC_HAS_CONTENTS;
655
memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
656
sizeof (thdr.stamp));
657
nlm_custom_header (abfd)->hdrLength = hdrLength;
658
nlm_custom_header (abfd)->dataOffset = dataOffset;
659
nlm_custom_header (abfd)->dataLength = dataLength;
660
memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
662
nlm_custom_header (abfd)->hdr = hdr;
673
/* Return whether there is a non-zero byte in a memory block. */
676
find_nonzero (buf, size)
680
char *p = (char *) buf;
688
/* Swap out the contents of the auxiliary headers. We create those
689
auxiliary headers which have been set non-zero. We do not require
690
the caller to set up the stamp fields. */
693
nlm_swap_auxiliary_headers_out (abfd)
698
/* Write out the version header if there is one. */
699
if (find_nonzero ((PTR) nlm_version_header (abfd),
700
sizeof (Nlm_Internal_Version_Header)))
702
Nlm_External_Version_Header thdr;
704
memcpy (thdr.stamp, "VeRsIoN#", 8);
705
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
706
(bfd_byte *) thdr.majorVersion);
707
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
708
(bfd_byte *) thdr.minorVersion);
709
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
710
(bfd_byte *) thdr.revision);
711
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
712
(bfd_byte *) thdr.year);
713
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
714
(bfd_byte *) thdr.month);
715
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
716
(bfd_byte *) thdr.day);
717
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
722
/* Write out the extended header if there is one. */
723
if (find_nonzero ((PTR) nlm_extended_header (abfd),
724
sizeof (Nlm_Internal_Extended_Header)))
726
Nlm_External_Extended_Header thdr;
728
memcpy (thdr.stamp, "MeSsAgEs", 8);
730
(bfd_vma) nlm_extended_header (abfd)->languageID,
731
(bfd_byte *) thdr.languageID);
733
(bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
734
(bfd_byte *) thdr.messageFileOffset);
736
(bfd_vma) nlm_extended_header (abfd)->messageFileLength,
737
(bfd_byte *) thdr.messageFileLength);
739
(bfd_vma) nlm_extended_header (abfd)->messageCount,
740
(bfd_byte *) thdr.messageCount);
742
(bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
743
(bfd_byte *) thdr.helpFileOffset);
745
(bfd_vma) nlm_extended_header (abfd)->helpFileLength,
746
(bfd_byte *) thdr.helpFileLength);
748
(bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
749
(bfd_byte *) thdr.RPCDataOffset);
751
(bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
752
(bfd_byte *) thdr.RPCDataLength);
754
(bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
755
(bfd_byte *) thdr.sharedCodeOffset);
757
(bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
758
(bfd_byte *) thdr.sharedCodeLength);
760
(bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
761
(bfd_byte *) thdr.sharedDataOffset);
763
(bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
764
(bfd_byte *) thdr.sharedDataLength);
766
(bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
767
(bfd_byte *) thdr.sharedRelocationFixupOffset);
769
(bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
770
(bfd_byte *) thdr.sharedRelocationFixupCount);
772
(bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
773
(bfd_byte *) thdr.sharedExternalReferenceOffset);
775
(bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
776
(bfd_byte *) thdr.sharedExternalReferenceCount);
778
(bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
779
(bfd_byte *) thdr.sharedPublicsOffset);
781
(bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
782
(bfd_byte *) thdr.sharedPublicsCount);
784
(bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
785
(bfd_byte *) thdr.sharedDebugRecordOffset);
787
(bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
788
(bfd_byte *) thdr.sharedDebugRecordCount);
790
(bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
791
(bfd_byte *) thdr.sharedInitializationOffset);
793
(bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
794
(bfd_byte *) thdr.SharedExitProcedureOffset);
796
(bfd_vma) nlm_extended_header (abfd)->productID,
797
(bfd_byte *) thdr.productID);
799
(bfd_vma) nlm_extended_header (abfd)->reserved0,
800
(bfd_byte *) thdr.reserved0);
802
(bfd_vma) nlm_extended_header (abfd)->reserved1,
803
(bfd_byte *) thdr.reserved1);
805
(bfd_vma) nlm_extended_header (abfd)->reserved2,
806
(bfd_byte *) thdr.reserved2);
808
(bfd_vma) nlm_extended_header (abfd)->reserved3,
809
(bfd_byte *) thdr.reserved3);
811
(bfd_vma) nlm_extended_header (abfd)->reserved4,
812
(bfd_byte *) thdr.reserved4);
814
(bfd_vma) nlm_extended_header (abfd)->reserved5,
815
(bfd_byte *) thdr.reserved5);
816
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
821
/* Write out the copyright header if there is one. */
822
if (find_nonzero ((PTR) nlm_copyright_header (abfd),
823
sizeof (Nlm_Internal_Copyright_Header)))
825
Nlm_External_Copyright_Header thdr;
827
memcpy (thdr.stamp, "CoPyRiGhT=", 10);
828
amt = sizeof (thdr.stamp);
829
if (bfd_bwrite ((PTR) thdr.stamp, amt, abfd) != amt)
831
thdr.copyrightMessageLength[0] =
832
nlm_copyright_header (abfd)->copyrightMessageLength;
834
if (bfd_bwrite ((PTR) thdr.copyrightMessageLength, amt, abfd) != amt)
836
/* The copyright message is a variable length string. */
837
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
838
if (bfd_bwrite ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
843
/* Write out the custom header if there is one. */
844
if (find_nonzero ((PTR) nlm_custom_header (abfd),
845
sizeof (Nlm_Internal_Custom_Header)))
847
Nlm_External_Custom_Header thdr;
849
bfd_size_type hdrLength;
851
ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
852
sizeof (nlm_custom_header (abfd)->dataStamp));
853
memcpy (thdr.stamp, "CuStHeAd", 8);
854
hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
855
+ nlm_custom_header (abfd)->hdrLength);
856
put_word (abfd, hdrLength, thdr.length);
857
put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
859
put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
863
BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
864
amt = sizeof (thdr) - sizeof (thdr.dataStamp);
865
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
870
memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
871
sizeof (thdr.dataStamp));
873
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
875
amt = nlm_custom_header (abfd)->hdrLength;
876
if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
881
/* Write out the Cygnus debugging header if there is one. */
882
if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
883
sizeof (Nlm_Internal_Cygnus_Ext_Header)))
885
Nlm_External_Custom_Header thdr;
887
memcpy (thdr.stamp, "CuStHeAd", 8);
888
put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
889
(bfd_byte *) thdr.length);
890
put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
891
(bfd_byte *) thdr.dataOffset);
892
put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
893
(bfd_byte *) thdr.dataLength);
894
memcpy (thdr.dataStamp, "CyGnUsEx", 8);
896
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
903
/* We read the NLM's public symbols and use it to generate a bfd symbol
904
table (hey, it's better than nothing) on a one-for-one basis. Thus
905
use the number of public symbols as the number of bfd symbols we will
906
have once we actually get around to reading them in.
908
Return the number of bytes required to hold the symtab vector, based on
909
the count plus 1, since we will NULL terminate the vector allocated based
913
nlm_get_symtab_upper_bound (abfd)
916
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
918
long symtab_size = 0;
920
i_fxdhdrp = nlm_fixed_header (abfd);
921
symcount = (i_fxdhdrp->numberOfPublics
922
+ i_fxdhdrp->numberOfDebugRecords
923
+ i_fxdhdrp->numberOfExternalReferences);
924
symtab_size = (symcount + 1) * (sizeof (asymbol));
925
return (symtab_size);
928
/* Note that bfd_get_symcount is guaranteed to be zero if slurping the
929
symbol table fails. */
932
nlm_get_symtab (abfd, alocation)
936
nlm_symbol_type *symbase;
937
bfd_size_type counter = 0;
939
if (! nlm_slurp_symbol_table (abfd))
941
symbase = nlm_get_symbols (abfd);
942
while (counter < bfd_get_symcount (abfd))
944
*alocation++ = &symbase->symbol;
948
*alocation = (asymbol *) NULL;
949
return bfd_get_symcount (abfd);
952
/* Make an NLM symbol. There is nothing special to do here. */
955
nlm_make_empty_symbol (abfd)
958
bfd_size_type amt = sizeof (nlm_symbol_type);
959
nlm_symbol_type *new = (nlm_symbol_type *) bfd_zalloc (abfd, amt);
962
new->symbol.the_bfd = abfd;
966
/* Get symbol information. */
969
nlm_get_symbol_info (ignore_abfd, symbol, ret)
970
bfd *ignore_abfd ATTRIBUTE_UNUSED;
974
bfd_symbol_info (symbol, ret);
977
/* Print symbol information. */
980
nlm_print_symbol (abfd, afile, symbol, how)
984
bfd_print_symbol_type how;
986
FILE *file = (FILE *) afile;
990
case bfd_print_symbol_name:
991
case bfd_print_symbol_more:
993
fprintf (file, "%s", symbol->name);
995
case bfd_print_symbol_all:
996
bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
997
fprintf (file, " %-5s", symbol->section->name);
999
fprintf (file, " %s", symbol->name);
1004
/* Slurp in nlm symbol table.
1006
In the external (in-file) form, NLM export records are variable length,
1007
with the following form:
1009
1 byte length of the symbol name (N)
1010
N bytes the symbol name
1011
4 bytes the symbol offset from start of it's section
1013
We also read in the debugging symbols and import records. Import
1014
records are treated as undefined symbols. As we read the import
1015
records we also read in the associated reloc information, which is
1016
attached to the symbol.
1018
The bfd symbols are copied to SYMPTRS.
1020
When we return, the bfd symcount is either zero or contains the correct
1025
nlm_slurp_symbol_table (abfd)
1028
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
1029
bfd_size_type totsymcount; /* Number of NLM symbols */
1030
bfd_size_type symcount; /* Counter of NLM symbols */
1031
nlm_symbol_type *sym; /* Pointer to current bfd symbol */
1032
unsigned char symlength; /* Symbol length read into here */
1033
unsigned char symtype; /* Type of debugging symbol */
1034
bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
1035
boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
1036
boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
1039
if (nlm_get_symbols (abfd) != NULL)
1042
/* Read each raw NLM symbol, using the information to create a canonical bfd
1045
Note that we allocate the initial bfd canonical symbol buffer based on a
1046
one-to-one mapping of the NLM symbols to canonical symbols. We actually
1047
use all the NLM symbols, so there will be no space left over at the end.
1048
When we have all the symbols, we build the caller's pointer vector. */
1051
i_fxdhdrp = nlm_fixed_header (abfd);
1052
totsymcount = (i_fxdhdrp->numberOfPublics
1053
+ i_fxdhdrp->numberOfDebugRecords
1054
+ i_fxdhdrp->numberOfExternalReferences);
1055
if (totsymcount == 0)
1060
if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
1063
amt = totsymcount * sizeof (nlm_symbol_type);
1064
sym = ((nlm_symbol_type *) bfd_zalloc (abfd, amt));
1067
nlm_set_symbols (abfd, sym);
1069
/* We use the bfd's symcount directly as the control count, so that early
1070
termination of the loop leaves the symcount correct for the symbols that
1073
set_public_section_func = nlm_set_public_section_func (abfd);
1074
symcount = i_fxdhdrp->numberOfPublics;
1075
while (abfd->symcount < symcount)
1077
amt = sizeof (symlength);
1078
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
1081
sym->symbol.the_bfd = abfd;
1082
sym->symbol.name = bfd_alloc (abfd, amt + 1);
1083
if (!sym->symbol.name)
1085
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
1087
/* Cast away const. */
1088
((char *) (sym->symbol.name))[symlength] = '\0';
1089
amt = sizeof (temp);
1090
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
1092
sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1093
sym->symbol.value = get_word (abfd, temp);
1094
if (set_public_section_func)
1096
/* Most backends can use the code below, but unfortunately
1097
some use a different scheme. */
1098
if (! (*set_public_section_func) (abfd, sym))
1103
if (sym->symbol.value & NLM_HIBIT)
1105
sym->symbol.value &= ~NLM_HIBIT;
1106
sym->symbol.flags |= BSF_FUNCTION;
1107
sym->symbol.section =
1108
bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1112
sym->symbol.section =
1113
bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1121
/* Read the debugging records. */
1123
if (i_fxdhdrp->numberOfDebugRecords > 0)
1125
if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
1128
symcount += i_fxdhdrp->numberOfDebugRecords;
1129
while (abfd->symcount < symcount)
1131
amt = sizeof (symtype);
1132
if (bfd_bread ((PTR) &symtype, amt, abfd) != amt)
1134
amt = sizeof (temp);
1135
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
1137
amt = sizeof (symlength);
1138
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
1141
sym->symbol.the_bfd = abfd;
1142
sym->symbol.name = bfd_alloc (abfd, amt + 1);
1143
if (!sym->symbol.name)
1145
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
1147
/* Cast away const. */
1148
((char *) (sym->symbol.name))[symlength] = '\0';
1149
sym->symbol.flags = BSF_LOCAL;
1150
sym->symbol.value = get_word (abfd, temp);
1153
sym->symbol.section =
1154
bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1156
else if (symtype == 1)
1158
sym->symbol.flags |= BSF_FUNCTION;
1159
sym->symbol.section =
1160
bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1164
sym->symbol.section = bfd_abs_section_ptr;
1172
/* Read in the import records. We can only do this if we know how
1173
to read relocs for this target. */
1175
read_import_func = nlm_read_import_func (abfd);
1176
if (read_import_func != NULL)
1178
if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
1181
symcount += i_fxdhdrp->numberOfExternalReferences;
1182
while (abfd->symcount < symcount)
1184
if (! (*read_import_func) (abfd, sym))
1194
/* Get the relocs for an NLM file. There are two types of relocs.
1195
Imports are relocs against symbols defined in other NLM files. We
1196
treat these as relocs against global symbols. Relocation fixups
1197
are internal relocs.
1199
The actual format used to store the relocs is machine specific. */
1201
/* Read in the relocation fixup information. This is stored in
1202
nlm_relocation_fixups, an array of arelent structures, and
1203
nlm_relocation_fixup_secs, an array of section pointers. The
1204
section pointers are needed because the relocs are not sorted by
1208
nlm_slurp_reloc_fixups (abfd)
1211
boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1213
bfd_size_type count, amt;
1217
if (nlm_relocation_fixups (abfd) != NULL)
1219
read_func = nlm_read_reloc_func (abfd);
1220
if (read_func == NULL)
1223
if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1227
count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1228
amt = count * sizeof (arelent);
1229
rels = (arelent *) bfd_alloc (abfd, amt);
1230
amt = count * sizeof (asection *);
1231
secs = (asection **) bfd_alloc (abfd, amt);
1232
if ((rels == NULL || secs == NULL) && count != 0)
1234
nlm_relocation_fixups (abfd) = rels;
1235
nlm_relocation_fixup_secs (abfd) = secs;
1237
/* We have to read piece by piece, because we don't know how large
1238
the machine specific reloc information is. */
1239
while (count-- != 0)
1241
if (! (*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels))
1243
nlm_relocation_fixups (abfd) = NULL;
1244
nlm_relocation_fixup_secs (abfd) = NULL;
1254
/* Get the number of relocs. This really just returns an upper bound,
1255
since it does not attempt to distinguish them based on the section.
1256
That will be handled when they are actually read. */
1259
nlm_get_reloc_upper_bound (abfd, sec)
1263
nlm_symbol_type *syms;
1264
bfd_size_type count;
1267
/* If we don't know how to read relocs, just return 0. */
1268
if (nlm_read_reloc_func (abfd) == NULL)
1270
/* Make sure we have either the code or the data section. */
1271
if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1274
syms = nlm_get_symbols (abfd);
1277
if (! nlm_slurp_symbol_table (abfd))
1279
syms = nlm_get_symbols (abfd);
1282
ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1284
count = bfd_get_symcount (abfd);
1285
while (count-- != 0)
1291
return (ret + 1) * sizeof (arelent *);
1294
/* Get the relocs themselves. */
1297
nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1305
bfd_size_type count, i;
1308
/* Get the relocation fixups. */
1309
rels = nlm_relocation_fixups (abfd);
1312
if (! nlm_slurp_reloc_fixups (abfd))
1314
rels = nlm_relocation_fixups (abfd);
1316
secs = nlm_relocation_fixup_secs (abfd);
1319
count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1320
for (i = 0; i < count; i++, rels++, secs++)
1329
/* Get the import symbols. */
1330
count = bfd_get_symcount (abfd);
1331
for (i = 0; i < count; i++, symbols++)
1336
if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1338
nlm_symbol_type *nlm_sym;
1341
nlm_sym = (nlm_symbol_type *) sym;
1342
for (j = 0; j < nlm_sym->rcnt; j++)
1344
if (nlm_sym->relocs[j].section == sec)
1346
*relptr = &nlm_sym->relocs[j].reloc;
1347
(*relptr)->sym_ptr_ptr = symbols;
1360
/* Compute the section file positions for an NLM file. All variable
1361
length data in the file headers must be set before this function is
1362
called. If the variable length data is changed later, the
1363
resulting object file will be incorrect. Unfortunately, there is
1364
no way to check this.
1366
This routine also sets the Size and Offset fields in the fixed
1369
It also looks over the symbols and moves any common symbols into
1370
the .bss section; NLM has no way to represent a common symbol.
1371
This approach means that either the symbols must already have been
1372
set at this point, or there must be no common symbols. We need to
1373
move the symbols at this point so that mangle_relocs can see the
1377
nlm_compute_section_file_positions (abfd)
1382
bfd_vma text, data, bss;
1383
bfd_vma text_low, data_low;
1384
unsigned int text_align, data_align, other_align;
1385
file_ptr text_ptr, data_ptr, other_ptr;
1387
asymbol **sym_ptr_ptr;
1389
if (abfd->output_has_begun)
1392
/* Make sure we have a section to hold uninitialized data. */
1393
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1394
if (bss_sec == NULL)
1396
if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1397
(file_ptr) 0, (bfd_size_type) 0,
1400
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1403
abfd->output_has_begun = true;
1405
/* The fixed header. */
1406
sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1408
/* The variable header. */
1409
sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1410
+ nlm_variable_header (abfd)->descriptionLength + 1
1411
+ NLM_TARGET_LONG_SIZE /* stackSize */
1412
+ NLM_TARGET_LONG_SIZE /* reserved */
1413
+ sizeof (nlm_variable_header (abfd)->oldThreadName)
1414
+ sizeof (nlm_variable_header (abfd)->screenNameLength)
1415
+ nlm_variable_header (abfd)->screenNameLength + 1
1416
+ sizeof (nlm_variable_header (abfd)->threadNameLength)
1417
+ nlm_variable_header (abfd)->threadNameLength + 1);
1419
/* The auxiliary headers. */
1420
if (find_nonzero ((PTR) nlm_version_header (abfd),
1421
sizeof (Nlm_Internal_Version_Header)))
1422
sofar += sizeof (Nlm_External_Version_Header);
1423
if (find_nonzero ((PTR) nlm_extended_header (abfd),
1424
sizeof (Nlm_Internal_Extended_Header)))
1425
sofar += sizeof (Nlm_External_Extended_Header);
1426
if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1427
sizeof (Nlm_Internal_Copyright_Header)))
1428
sofar += (sizeof (Nlm_External_Copyright_Header)
1429
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1430
if (find_nonzero ((PTR) nlm_custom_header (abfd),
1431
sizeof (Nlm_Internal_Custom_Header)))
1432
sofar += (sizeof (Nlm_External_Custom_Header)
1433
+ nlm_custom_header (abfd)->hdrLength);
1434
if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
1435
sizeof (Nlm_Internal_Cygnus_Ext_Header)))
1436
sofar += sizeof (Nlm_External_Custom_Header);
1438
/* Compute the section file positions in two passes. First get the
1439
sizes of the text and data sections, and then set the file
1440
positions. This code aligns the sections in the file using the
1441
same alignment restrictions that apply to the sections in memory;
1442
this may not be necessary. */
1444
text_low = (bfd_vma) - 1;
1447
data_low = (bfd_vma) - 1;
1451
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1455
sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1457
f = bfd_get_section_flags (abfd, sec);
1460
text += sec->_raw_size;
1461
if (bfd_get_section_vma (abfd, sec) < text_low)
1462
text_low = bfd_get_section_vma (abfd, sec);
1463
if (sec->alignment_power > text_align)
1464
text_align = sec->alignment_power;
1466
else if (f & SEC_DATA)
1468
data += sec->_raw_size;
1469
if (bfd_get_section_vma (abfd, sec) < data_low)
1470
data_low = bfd_get_section_vma (abfd, sec);
1471
if (sec->alignment_power > data_align)
1472
data_align = sec->alignment_power;
1474
else if (f & SEC_HAS_CONTENTS)
1476
if (sec->alignment_power > other_align)
1477
other_align = sec->alignment_power;
1479
else if (f & SEC_ALLOC)
1480
bss += sec->_raw_size;
1483
nlm_set_text_low (abfd, text_low);
1484
nlm_set_data_low (abfd, data_low);
1486
if (nlm_no_uninitialized_data (abfd))
1488
/* This NetWare format does not use uninitialized data. We must
1489
increase the size of the data section. We will never wind up
1490
writing those file locations, so they will remain zero. */
1495
text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1496
data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1497
other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1499
/* Fill in some fields in the header for which we now have the
1501
nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1502
nlm_fixed_header (abfd)->codeImageSize = text;
1503
nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1504
nlm_fixed_header (abfd)->dataImageSize = data;
1505
nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1507
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1511
f = bfd_get_section_flags (abfd, sec);
1515
sec->filepos = text_ptr;
1516
text_ptr += sec->_raw_size;
1518
else if (f & SEC_DATA)
1520
sec->filepos = data_ptr;
1521
data_ptr += sec->_raw_size;
1523
else if (f & SEC_HAS_CONTENTS)
1525
sec->filepos = other_ptr;
1526
other_ptr += sec->_raw_size;
1530
nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1532
/* Move all common symbols into the .bss section. */
1534
sym_ptr_ptr = bfd_get_outsymbols (abfd);
1535
if (sym_ptr_ptr != NULL)
1540
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1542
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1549
if (!bfd_is_com_section (bfd_get_section (sym)))
1552
/* Put the common symbol in the .bss section, and increase
1553
the size of the .bss section by the size of the common
1554
symbol (which is the old value of the symbol). */
1555
sym->section = bss_sec;
1557
sym->value = bss_sec->_raw_size + add;
1559
add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1563
if (nlm_no_uninitialized_data (abfd))
1565
/* We could handle this case, but so far it hasn't been
1569
nlm_fixed_header (abfd)->uninitializedDataSize += add;
1570
bss_sec->_raw_size += add;
1577
/* Set the contents of a section. To do this we need to know where
1578
the section is going to be located in the output file. That means
1579
that the sizes of all the sections must be set, and all the
1580
variable size header information must be known. */
1583
nlm_set_section_contents (abfd, section, location, offset, count)
1588
bfd_size_type count;
1590
if (! abfd->output_has_begun
1591
&& ! nlm_compute_section_file_positions (abfd))
1597
/* i386 NetWare has a very restricted set of relocs. In order for
1598
objcopy to work, the NLM i386 backend needs a chance to rework
1599
the section contents so that its set of relocs will work. If all
1600
the relocs are already acceptable, this will not do anything. */
1601
if (section->reloc_count != 0)
1603
boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1604
bfd_vma, bfd_size_type));
1606
mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1607
if (mangle_relocs_func != NULL)
1609
if (!(*mangle_relocs_func) (abfd, section, location,
1610
(bfd_vma) offset, count))
1615
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1616
|| bfd_bwrite (location, count, abfd) != count)
1622
/* We need to sort a list of relocs associated with sections when we
1623
write out the external relocs. */
1626
nlm_external_reloc_compare (p1, p2)
1630
const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1631
const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1634
cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1635
(*r2->rel->sym_ptr_ptr)->name);
1639
/* We sort by address within symbol to make the sort more stable and
1640
increase the chances that different hosts will generate bit for
1641
bit equivalent results. */
1642
return (int) (r1->rel->address - r2->rel->address);
1645
/* Write out an NLM file. We write out the information in this order:
1651
other sections (custom data, messages, help, shared NLM, RPC,
1652
module dependencies)
1654
external references (imports)
1655
public symbols (exports)
1657
This is similar to the order used by the NetWare tools; the
1658
difference is that NetWare puts the sections other than code, data
1659
and custom data at the end of the NLM. It is convenient for us to
1660
know where the sections are going to be before worrying about the
1661
size of the other information.
1663
By the time this function is called, all the section data should
1664
have been output using set_section_contents. Note that custom
1665
data, the message file, the help file, the shared NLM file, the RPC
1666
data, and the module dependencies are all considered to be
1667
sections; the caller is responsible for filling in the offset and
1668
length fields in the NLM headers. The relocation fixups and
1669
imports are both obtained from the list of relocs attached to each
1670
section. The exports and debugging records are obtained from the
1671
list of outsymbols. */
1674
nlm_write_object_contents (abfd)
1678
boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1679
bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1680
struct reloc_and_sec *external_relocs;
1681
asymbol **sym_ptr_ptr;
1683
boolean (*write_prefix_func) PARAMS ((bfd *));
1684
unsigned char *fixed_header = NULL;
1688
fixed_header = ((unsigned char *)
1689
bfd_malloc (nlm_fixed_header_size (abfd)));
1690
if (fixed_header == NULL)
1693
if (! abfd->output_has_begun
1694
&& ! nlm_compute_section_file_positions (abfd))
1697
/* Write out the variable length headers. */
1698
pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1699
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
1701
if (! nlm_swap_variable_header_out (abfd)
1702
|| ! nlm_swap_auxiliary_headers_out (abfd))
1704
bfd_set_error (bfd_error_system_call);
1708
/* A weak check on whether the section file positions were
1710
if (bfd_tell (abfd) > (ufile_ptr) nlm_fixed_header (abfd)->codeImageOffset)
1712
bfd_set_error (bfd_error_invalid_operation);
1716
/* Advance to the relocs. */
1717
if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1721
/* The format of the relocation entries is dependent upon the
1722
particular target. We use an external routine to write the reloc
1724
write_import_func = nlm_write_import_func (abfd);
1726
/* Write out the internal relocation fixups. While we're looping
1727
over the relocs, we also count the external relocs, which is
1728
needed when they are written out below. */
1729
internal_reloc_count = 0;
1730
external_reloc_count = 0;
1731
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1733
arelent **rel_ptr_ptr, **rel_end;
1735
if (sec->reloc_count == 0)
1738
/* We can only represent relocs within a code or data
1739
section. We ignore them for a debugging section. */
1740
if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1743
/* We need to know how to write out imports */
1744
if (write_import_func == NULL)
1746
bfd_set_error (bfd_error_invalid_operation);
1750
rel_ptr_ptr = sec->orelocation;
1751
rel_end = rel_ptr_ptr + sec->reloc_count;
1752
for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1758
sym = *rel->sym_ptr_ptr;
1760
if (! bfd_is_und_section (bfd_get_section (sym)))
1762
++internal_reloc_count;
1763
if (! (*write_import_func) (abfd, sec, rel))
1767
++external_reloc_count;
1770
nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1772
/* Write out the imports (relocs against external symbols). These
1773
are output as a symbol name followed by all the relocs for that
1774
symbol, so we must first gather together all the relocs against
1775
external symbols and sort them. */
1776
amt = external_reloc_count * sizeof (struct reloc_and_sec);
1777
external_relocs = (struct reloc_and_sec *) bfd_alloc (abfd, amt);
1778
if (external_relocs == (struct reloc_and_sec *) NULL)
1781
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1783
arelent **rel_ptr_ptr, **rel_end;
1785
if (sec->reloc_count == 0)
1788
rel_ptr_ptr = sec->orelocation;
1789
rel_end = rel_ptr_ptr + sec->reloc_count;
1790
for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1796
sym = *rel->sym_ptr_ptr;
1798
if (! bfd_is_und_section (bfd_get_section (sym)))
1801
external_relocs[i].rel = rel;
1802
external_relocs[i].sec = sec;
1807
BFD_ASSERT (i == external_reloc_count);
1809
/* Sort the external relocs by name. */
1810
qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1811
sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1813
/* Write out the external relocs. */
1814
nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1817
while (i < external_reloc_count)
1821
bfd_size_type j, cnt;
1825
rel = external_relocs[i].rel;
1826
sym = *rel->sym_ptr_ptr;
1830
(j < external_reloc_count
1831
&& *external_relocs[j].rel->sym_ptr_ptr == sym);
1835
if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1836
&external_relocs[i]))
1842
nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1844
/* Write out the public symbols (exports). */
1845
sym_ptr_ptr = bfd_get_outsymbols (abfd);
1846
if (sym_ptr_ptr != (asymbol **) NULL)
1848
bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1849
boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1853
nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1854
get_public_offset_func = nlm_get_public_offset_func (abfd);
1855
write_export_func = nlm_write_export_func (abfd);
1857
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1858
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1863
bfd_byte temp[NLM_TARGET_LONG_SIZE];
1867
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1868
|| bfd_is_und_section (bfd_get_section (sym)))
1873
if (get_public_offset_func)
1875
/* Most backends can use the code below, but
1876
unfortunately some use a different scheme. */
1877
offset = (*get_public_offset_func) (abfd, sym);
1881
offset = bfd_asymbol_value (sym);
1883
if (sec->flags & SEC_CODE)
1885
offset -= nlm_get_text_low (abfd);
1886
offset |= NLM_HIBIT;
1888
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1890
/* SEC_ALLOC is for the .bss section. */
1891
offset -= nlm_get_data_low (abfd);
1895
/* We can't handle an exported symbol that is not in
1896
the code or data segment. */
1897
bfd_set_error (bfd_error_invalid_operation);
1902
if (write_export_func)
1904
if (! (*write_export_func) (abfd, sym, offset))
1909
len = strlen (sym->name);
1910
if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1911
!= sizeof (bfd_byte))
1912
|| bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1915
put_word (abfd, offset, temp);
1916
if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1921
nlm_fixed_header (abfd)->numberOfPublics = c;
1923
/* Write out the debugging records. The NLM conversion program
1924
wants to be able to inhibit this, so as a special hack if
1925
debugInfoOffset is set to -1 we don't write any debugging
1926
information. This can not be handled by fiddling with the
1927
symbol table, because exported symbols appear in both the
1928
exported symbol list and the debugging information. */
1929
if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1931
nlm_fixed_header (abfd)->debugInfoOffset = 0;
1932
nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1936
nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1938
sym_ptr_ptr = bfd_get_outsymbols (abfd);
1939
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1940
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1945
bfd_byte temp[NLM_TARGET_LONG_SIZE];
1949
/* The NLM notion of a debugging symbol is actually what
1950
BFD calls a local or global symbol. What BFD calls a
1951
debugging symbol NLM does not understand at all. */
1952
if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1953
|| (sym->flags & BSF_DEBUGGING) != 0
1954
|| bfd_is_und_section (bfd_get_section (sym)))
1959
offset = bfd_asymbol_value (sym);
1961
if (sec->flags & SEC_CODE)
1963
offset -= nlm_get_text_low (abfd);
1966
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1968
/* SEC_ALLOC is for the .bss section. */
1969
offset -= nlm_get_data_low (abfd);
1975
/* The type is 0 for data, 1 for code, 2 for absolute. */
1976
if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
1977
!= sizeof (bfd_byte))
1980
put_word (abfd, offset, temp);
1981
if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1985
len = strlen (sym->name);
1986
if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1987
!= sizeof (bfd_byte))
1988
|| bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1991
nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1995
/* NLMLINK fills in offset values even if there is no data, so we do
1997
last = bfd_tell (abfd);
1998
if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1999
nlm_fixed_header (abfd)->codeImageOffset = last;
2000
if (nlm_fixed_header (abfd)->dataImageOffset == 0)
2001
nlm_fixed_header (abfd)->dataImageOffset = last;
2002
if (nlm_fixed_header (abfd)->customDataOffset == 0)
2003
nlm_fixed_header (abfd)->customDataOffset = last;
2004
if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
2005
nlm_fixed_header (abfd)->moduleDependencyOffset = last;
2006
if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
2007
nlm_fixed_header (abfd)->relocationFixupOffset = last;
2008
if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
2009
nlm_fixed_header (abfd)->externalReferencesOffset = last;
2010
if (nlm_fixed_header (abfd)->publicsOffset == 0)
2011
nlm_fixed_header (abfd)->publicsOffset = last;
2012
if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
2013
nlm_fixed_header (abfd)->debugInfoOffset = last;
2015
/* At this point everything has been written out except the fixed
2017
memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
2018
NLM_SIGNATURE_SIZE);
2019
nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2020
nlm_fixed_header (abfd)->codeStartOffset =
2021
(bfd_get_start_address (abfd)
2022
- nlm_get_text_low (abfd));
2024
/* We have no convenient way for the caller to pass in the exit
2025
procedure or the check unload procedure, so the caller must set
2026
the values in the header to the values of the symbols. */
2027
nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2028
if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2029
nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2030
nlm_get_text_low (abfd);
2032
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
2035
write_prefix_func = nlm_write_prefix_func (abfd);
2036
if (write_prefix_func)
2038
if (! (*write_prefix_func) (abfd))
2042
BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
2043
== nlm_optional_prefix_size (abfd));
2045
nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
2046
if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
2047
!= nlm_fixed_header_size (abfd))
2050
if (fixed_header != NULL)
2051
free (fixed_header);
2055
if (fixed_header != NULL)
2056
free (fixed_header);