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_canonicalize_symtab nlmNAME(canonicalize_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 bfd_boolean add_bfd_section
63
PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
64
static bfd_boolean nlm_swap_variable_header_in
66
static bfd_boolean nlm_swap_variable_header_out
68
static bfd_boolean find_nonzero
69
PARAMS ((PTR, size_t));
70
static bfd_boolean nlm_swap_auxiliary_headers_in
72
static bfd_boolean nlm_swap_auxiliary_headers_out
74
static bfd_boolean nlm_slurp_symbol_table
76
static bfd_boolean nlm_slurp_reloc_fixups
78
static bfd_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
bfd_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. */
117
amt = nlm_fixed_header_size (abfd);
118
x_fxdhdr = (PTR) bfd_malloc (amt);
119
if (x_fxdhdr == NULL)
122
if (bfd_bread ((PTR) x_fxdhdr, amt, abfd) != amt)
124
if (bfd_get_error () != bfd_error_system_call)
125
goto got_wrong_format_error;
130
/* Allocate an instance of the nlm_obj_tdata structure and hook it up to
131
the tdata pointer in the bfd. */
132
amt = sizeof (struct nlm_obj_tdata);
133
new_tdata = (struct nlm_obj_tdata *) bfd_zalloc (abfd, amt);
134
if (new_tdata == NULL)
137
nlm_tdata (abfd) = new_tdata;
139
i_fxdhdrp = nlm_fixed_header (abfd);
140
nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
144
/* Check to see if we have an NLM file for this backend by matching
145
the NLM signature. */
146
signature = nlm_signature (abfd);
147
if (signature != NULL
148
&& *signature != '\0'
149
&& strncmp ((char *) i_fxdhdrp->signature, signature,
150
NLM_SIGNATURE_SIZE) != 0)
151
goto got_wrong_format_error;
153
/* There's no supported way to discover the endianess of an NLM, so test for
154
a sane version number after doing byte swapping appropriate for this
155
XVEC. (Hack alert!) */
156
if (i_fxdhdrp->version > 0xFFFF)
157
goto got_wrong_format_error;
159
/* There's no supported way to check for 32 bit versus 64 bit addresses,
160
so ignore this distinction for now. (FIXME) */
161
/* Swap in the rest of the required header. */
162
if (!nlm_swap_variable_header_in (abfd))
164
if (bfd_get_error () != bfd_error_system_call)
165
goto got_wrong_format_error;
170
/* Add the sections supplied by all NLM's, and then read in the
171
auxiliary headers. Reading the auxiliary headers may create
172
additional sections described in the cygnus_ext header.
173
From this point on we assume that we have an NLM, and do not
174
treat errors as indicating the wrong format. */
175
if (!add_bfd_section (abfd, NLM_CODE_NAME,
176
i_fxdhdrp->codeImageOffset,
177
i_fxdhdrp->codeImageSize,
178
(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
180
|| !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
181
i_fxdhdrp->dataImageOffset,
182
i_fxdhdrp->dataImageSize,
183
(SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
185
|| !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
187
i_fxdhdrp->uninitializedDataSize,
191
if (!nlm_swap_auxiliary_headers_in (abfd))
194
if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
195
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
196
abfd->flags |= HAS_RELOC;
197
if (nlm_fixed_header (abfd)->numberOfPublics != 0
198
|| nlm_fixed_header (abfd)->numberOfDebugRecords != 0
199
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
200
abfd->flags |= HAS_SYMS;
202
arch = nlm_architecture (abfd);
203
if (arch != bfd_arch_unknown)
204
bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
206
abfd->flags |= EXEC_P;
207
bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
211
got_wrong_format_error:
212
bfd_set_error (bfd_error_wrong_format);
214
nlm_tdata (abfd) = preserved_tdata;
215
if (new_tdata != NULL)
216
bfd_release (abfd, new_tdata);
217
if (x_fxdhdr != NULL)
222
/* Add a section to the bfd. */
225
add_bfd_section (abfd, name, offset, size, flags)
234
newsect = bfd_make_section (abfd, name);
238
newsect->vma = 0; /* NLM's are relocatable. */
239
newsect->_raw_size = size;
240
newsect->filepos = offset;
241
newsect->flags = flags;
242
newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */
247
/* Read and swap in the variable length header. All the fields must
248
exist in the NLM, and must exist in the order they are read here. */
251
nlm_swap_variable_header_in (abfd)
254
unsigned char temp[NLM_TARGET_LONG_SIZE];
257
/* Read the description length and text members. */
259
amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
260
if (bfd_bread ((PTR) &nlm_variable_header (abfd)->descriptionLength,
263
amt = nlm_variable_header (abfd)->descriptionLength + 1;
264
if (bfd_bread ((PTR) nlm_variable_header (abfd)->descriptionText,
268
/* Read and convert the stackSize field. */
271
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
273
nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
275
/* Read and convert the reserved field. */
278
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
280
nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
282
/* Read the oldThreadName field. This field is a fixed length string. */
284
amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
285
if (bfd_bread ((PTR) nlm_variable_header (abfd)->oldThreadName,
289
/* Read the screen name length and text members. */
291
amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
292
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->screenNameLength,
295
amt = nlm_variable_header (abfd)->screenNameLength + 1;
296
if (bfd_bread ((PTR) nlm_variable_header (abfd)->screenName,
300
/* Read the thread name length and text members. */
302
amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
303
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->threadNameLength,
306
amt = nlm_variable_header (abfd)->threadNameLength + 1;
307
if (bfd_bread ((PTR) nlm_variable_header (abfd)->threadName,
313
/* Swap and write out the variable length header. All the fields must
314
exist in the NLM, and must exist in this order. */
317
nlm_swap_variable_header_out (abfd)
320
unsigned char temp[NLM_TARGET_LONG_SIZE];
323
/* Write the description length and text members. */
324
amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
325
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->descriptionLength, amt,
328
amt = nlm_variable_header (abfd)->descriptionLength + 1;
329
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->descriptionText, amt,
333
/* Convert and write the stackSize field. */
334
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
337
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
340
/* Convert and write the reserved field. */
341
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
344
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
347
/* Write the oldThreadName field. This field is a fixed length string. */
348
amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
349
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->oldThreadName, amt,
353
/* Write the screen name length and text members. */
354
amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
355
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->screenNameLength, amt,
358
amt = nlm_variable_header (abfd)->screenNameLength + 1;
359
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->screenName, amt,
363
/* Write the thread name length and text members. */
364
amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
365
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->threadNameLength, amt,
368
amt = nlm_variable_header (abfd)->threadNameLength + 1;
369
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->threadName, amt,
375
/* Read and swap in the contents of all the auxiliary headers. Because of
376
the braindead design, we have to do strcmps on strings of indeterminate
377
length to figure out what each auxiliary header is. Even worse, we have
378
no way of knowing how many auxiliary headers there are or where the end
379
of the auxiliary headers are, except by finding something that doesn't
380
look like a known auxiliary header. This means that the first new type
381
of auxiliary header added will break all existing tools that don't
385
nlm_swap_auxiliary_headers_in (abfd)
394
position = bfd_tell (abfd);
395
amt = sizeof (tempstr);
396
if (bfd_bread ((PTR) tempstr, amt, abfd) != amt)
398
if (bfd_seek (abfd, position, SEEK_SET) != 0)
400
if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
402
Nlm_External_Version_Header thdr;
405
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
407
memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
408
sizeof (thdr.stamp));
409
nlm_version_header (abfd)->majorVersion =
410
get_word (abfd, (bfd_byte *) thdr.majorVersion);
411
nlm_version_header (abfd)->minorVersion =
412
get_word (abfd, (bfd_byte *) thdr.minorVersion);
413
nlm_version_header (abfd)->revision =
414
get_word (abfd, (bfd_byte *) thdr.revision);
415
nlm_version_header (abfd)->year =
416
get_word (abfd, (bfd_byte *) thdr.year);
417
nlm_version_header (abfd)->month =
418
get_word (abfd, (bfd_byte *) thdr.month);
419
nlm_version_header (abfd)->day =
420
get_word (abfd, (bfd_byte *) thdr.day);
422
else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
424
Nlm_External_Extended_Header thdr;
427
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
429
memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
430
sizeof (thdr.stamp));
431
nlm_extended_header (abfd)->languageID =
432
get_word (abfd, (bfd_byte *) thdr.languageID);
433
nlm_extended_header (abfd)->messageFileOffset =
434
get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
435
nlm_extended_header (abfd)->messageFileLength =
436
get_word (abfd, (bfd_byte *) thdr.messageFileLength);
437
nlm_extended_header (abfd)->messageCount =
438
get_word (abfd, (bfd_byte *) thdr.messageCount);
439
nlm_extended_header (abfd)->helpFileOffset =
440
get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
441
nlm_extended_header (abfd)->helpFileLength =
442
get_word (abfd, (bfd_byte *) thdr.helpFileLength);
443
nlm_extended_header (abfd)->RPCDataOffset =
444
get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
445
nlm_extended_header (abfd)->RPCDataLength =
446
get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
447
nlm_extended_header (abfd)->sharedCodeOffset =
448
get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
449
nlm_extended_header (abfd)->sharedCodeLength =
450
get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
451
nlm_extended_header (abfd)->sharedDataOffset =
452
get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
453
nlm_extended_header (abfd)->sharedDataLength =
454
get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
455
nlm_extended_header (abfd)->sharedRelocationFixupOffset =
456
get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
457
nlm_extended_header (abfd)->sharedRelocationFixupCount =
458
get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
459
nlm_extended_header (abfd)->sharedExternalReferenceOffset =
460
get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
461
nlm_extended_header (abfd)->sharedExternalReferenceCount =
462
get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
463
nlm_extended_header (abfd)->sharedPublicsOffset =
464
get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
465
nlm_extended_header (abfd)->sharedPublicsCount =
466
get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
467
nlm_extended_header (abfd)->sharedDebugRecordOffset =
468
get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
469
nlm_extended_header (abfd)->sharedDebugRecordCount =
470
get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
471
nlm_extended_header (abfd)->SharedInitializationOffset =
472
get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
473
nlm_extended_header (abfd)->SharedExitProcedureOffset =
474
get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
475
nlm_extended_header (abfd)->productID =
476
get_word (abfd, (bfd_byte *) thdr.productID);
477
nlm_extended_header (abfd)->reserved0 =
478
get_word (abfd, (bfd_byte *) thdr.reserved0);
479
nlm_extended_header (abfd)->reserved1 =
480
get_word (abfd, (bfd_byte *) thdr.reserved1);
481
nlm_extended_header (abfd)->reserved2 =
482
get_word (abfd, (bfd_byte *) thdr.reserved2);
483
nlm_extended_header (abfd)->reserved3 =
484
get_word (abfd, (bfd_byte *) thdr.reserved3);
485
nlm_extended_header (abfd)->reserved4 =
486
get_word (abfd, (bfd_byte *) thdr.reserved4);
487
nlm_extended_header (abfd)->reserved5 =
488
get_word (abfd, (bfd_byte *) thdr.reserved5);
490
else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
492
amt = sizeof (nlm_copyright_header (abfd)->stamp);
493
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->stamp,
496
if (bfd_bread ((PTR) &(nlm_copyright_header (abfd)
497
->copyrightMessageLength),
498
(bfd_size_type) 1, abfd) != 1)
500
/* The copyright message is a variable length string. */
501
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
502
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
506
else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
508
Nlm_External_Custom_Header thdr;
509
bfd_size_type hdrLength;
511
bfd_size_type dataLength;
515
/* Read the stamp ("CuStHeAd"). */
516
amt = sizeof (thdr.stamp);
517
if (bfd_bread ((PTR) thdr.stamp, amt, abfd) != amt)
519
/* Read the length of this custom header. */
520
amt = sizeof (thdr.length);
521
if (bfd_bread ((PTR) thdr.length, amt, abfd) != amt)
523
hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
524
/* Read further fields if we have them. */
525
if (hdrLength < NLM_TARGET_LONG_SIZE)
529
amt = sizeof (thdr.dataOffset);
530
if (bfd_bread ((PTR) thdr.dataOffset, amt, abfd) != amt)
532
dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
534
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
538
amt = sizeof (thdr.dataLength);
539
if (bfd_bread ((PTR) thdr.dataLength, amt, abfd) != amt)
541
dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
543
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
544
memset (dataStamp, 0, sizeof (dataStamp));
547
amt = sizeof (dataStamp);
548
if (bfd_bread ((PTR) dataStamp, amt, abfd) != amt)
552
/* Read the rest of the header, if any. */
553
if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
560
hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
561
hdr = bfd_alloc (abfd, hdrLength);
564
if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
568
/* If we have found a Cygnus header, process it. Otherwise,
569
just save the associated data without trying to interpret
571
if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
577
BFD_ASSERT (hdrLength == 0 && hdr == NULL);
579
pos = bfd_tell (abfd);
580
if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
582
contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
583
if (contents == NULL)
585
if (bfd_bread (contents, dataLength, abfd) != dataLength)
587
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
590
memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
591
nlm_cygnus_ext_header (abfd)->offset = dataOffset;
592
nlm_cygnus_ext_header (abfd)->length = dataLength;
594
/* This data this header points to provides a list of
595
the sections which were in the original object file
596
which was converted to become an NLM. We locate
597
those sections and add them to the BFD. Note that
598
this is likely to create a second .text, .data and
599
.bss section; retrieving the sections by name will
600
get the actual NLM sections, which is what we want to
601
happen. The sections from the original file, which
602
may be subsets of the NLM section, can only be found
603
using bfd_map_over_sections. */
605
pend = p + dataLength;
614
/* The format of this information is
615
null terminated section name
616
zeroes to adjust to 4 byte boundary
617
4 byte section data file pointer
622
l = strlen (name) + 1;
623
l = (l + 3) &~ (size_t) 3;
625
filepos = H_GET_32 (abfd, p);
627
size = H_GET_32 (abfd, p);
630
newsec = bfd_make_section_anyway (abfd, name);
631
if (newsec == (asection *) NULL)
633
newsec->_raw_size = size;
636
newsec->filepos = filepos;
637
newsec->flags |= SEC_HAS_CONTENTS;
643
memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
644
sizeof (thdr.stamp));
645
nlm_custom_header (abfd)->hdrLength = hdrLength;
646
nlm_custom_header (abfd)->dataOffset = dataOffset;
647
nlm_custom_header (abfd)->dataLength = dataLength;
648
memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
650
nlm_custom_header (abfd)->hdr = hdr;
659
/* Return whether there is a non-zero byte in a memory block. */
662
find_nonzero (buf, size)
666
char *p = (char *) buf;
674
/* Swap out the contents of the auxiliary headers. We create those
675
auxiliary headers which have been set non-zero. We do not require
676
the caller to set up the stamp fields. */
679
nlm_swap_auxiliary_headers_out (abfd)
684
/* Write out the version header if there is one. */
685
if (find_nonzero ((PTR) nlm_version_header (abfd),
686
sizeof (Nlm_Internal_Version_Header)))
688
Nlm_External_Version_Header thdr;
690
memcpy (thdr.stamp, "VeRsIoN#", 8);
691
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
692
(bfd_byte *) thdr.majorVersion);
693
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
694
(bfd_byte *) thdr.minorVersion);
695
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
696
(bfd_byte *) thdr.revision);
697
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
698
(bfd_byte *) thdr.year);
699
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
700
(bfd_byte *) thdr.month);
701
put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
702
(bfd_byte *) thdr.day);
703
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
708
/* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
709
tag in order to make the NW4.x and NW5.x loaders happy. */
711
/* Write out the copyright header if there is one. */
712
if (find_nonzero ((PTR) nlm_copyright_header (abfd),
713
sizeof (Nlm_Internal_Copyright_Header)))
715
Nlm_External_Copyright_Header thdr;
717
memcpy (thdr.stamp, "CoPyRiGhT=", 10);
718
amt = sizeof (thdr.stamp);
719
if (bfd_bwrite ((PTR) thdr.stamp, amt, abfd) != amt)
721
thdr.copyrightMessageLength[0] =
722
nlm_copyright_header (abfd)->copyrightMessageLength;
724
if (bfd_bwrite ((PTR) thdr.copyrightMessageLength, amt, abfd) != amt)
726
/* The copyright message is a variable length string. */
727
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
728
if (bfd_bwrite ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
733
/* Write out the extended header if there is one. */
734
if (find_nonzero ((PTR) nlm_extended_header (abfd),
735
sizeof (Nlm_Internal_Extended_Header)))
737
Nlm_External_Extended_Header thdr;
739
memcpy (thdr.stamp, "MeSsAgEs", 8);
741
(bfd_vma) nlm_extended_header (abfd)->languageID,
742
(bfd_byte *) thdr.languageID);
744
(bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
745
(bfd_byte *) thdr.messageFileOffset);
747
(bfd_vma) nlm_extended_header (abfd)->messageFileLength,
748
(bfd_byte *) thdr.messageFileLength);
750
(bfd_vma) nlm_extended_header (abfd)->messageCount,
751
(bfd_byte *) thdr.messageCount);
753
(bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
754
(bfd_byte *) thdr.helpFileOffset);
756
(bfd_vma) nlm_extended_header (abfd)->helpFileLength,
757
(bfd_byte *) thdr.helpFileLength);
759
(bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
760
(bfd_byte *) thdr.RPCDataOffset);
762
(bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
763
(bfd_byte *) thdr.RPCDataLength);
765
(bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
766
(bfd_byte *) thdr.sharedCodeOffset);
768
(bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
769
(bfd_byte *) thdr.sharedCodeLength);
771
(bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
772
(bfd_byte *) thdr.sharedDataOffset);
774
(bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
775
(bfd_byte *) thdr.sharedDataLength);
777
(bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
778
(bfd_byte *) thdr.sharedRelocationFixupOffset);
780
(bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
781
(bfd_byte *) thdr.sharedRelocationFixupCount);
783
(bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
784
(bfd_byte *) thdr.sharedExternalReferenceOffset);
786
(bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
787
(bfd_byte *) thdr.sharedExternalReferenceCount);
789
(bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
790
(bfd_byte *) thdr.sharedPublicsOffset);
792
(bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
793
(bfd_byte *) thdr.sharedPublicsCount);
795
(bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
796
(bfd_byte *) thdr.sharedDebugRecordOffset);
798
(bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
799
(bfd_byte *) thdr.sharedDebugRecordCount);
801
(bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
802
(bfd_byte *) thdr.sharedInitializationOffset);
804
(bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
805
(bfd_byte *) thdr.SharedExitProcedureOffset);
807
(bfd_vma) nlm_extended_header (abfd)->productID,
808
(bfd_byte *) thdr.productID);
810
(bfd_vma) nlm_extended_header (abfd)->reserved0,
811
(bfd_byte *) thdr.reserved0);
813
(bfd_vma) nlm_extended_header (abfd)->reserved1,
814
(bfd_byte *) thdr.reserved1);
816
(bfd_vma) nlm_extended_header (abfd)->reserved2,
817
(bfd_byte *) thdr.reserved2);
819
(bfd_vma) nlm_extended_header (abfd)->reserved3,
820
(bfd_byte *) thdr.reserved3);
822
(bfd_vma) nlm_extended_header (abfd)->reserved4,
823
(bfd_byte *) thdr.reserved4);
825
(bfd_vma) nlm_extended_header (abfd)->reserved5,
826
(bfd_byte *) thdr.reserved5);
827
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
832
/* Write out the custom header if there is one. */
833
if (find_nonzero ((PTR) nlm_custom_header (abfd),
834
sizeof (Nlm_Internal_Custom_Header)))
836
Nlm_External_Custom_Header thdr;
838
bfd_size_type hdrLength;
840
ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
841
sizeof (nlm_custom_header (abfd)->dataStamp));
842
memcpy (thdr.stamp, "CuStHeAd", 8);
843
hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
844
+ nlm_custom_header (abfd)->hdrLength);
845
put_word (abfd, hdrLength, thdr.length);
846
put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
848
put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
852
BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
853
amt = sizeof (thdr) - sizeof (thdr.dataStamp);
854
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
859
memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
860
sizeof (thdr.dataStamp));
862
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
864
amt = nlm_custom_header (abfd)->hdrLength;
865
if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
870
/* Write out the Cygnus debugging header if there is one. */
871
if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
872
sizeof (Nlm_Internal_Cygnus_Ext_Header)))
874
Nlm_External_Custom_Header thdr;
876
memcpy (thdr.stamp, "CuStHeAd", 8);
877
put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
878
(bfd_byte *) thdr.length);
879
put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
880
(bfd_byte *) thdr.dataOffset);
881
put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
882
(bfd_byte *) thdr.dataLength);
883
memcpy (thdr.dataStamp, "CyGnUsEx", 8);
885
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
892
/* We read the NLM's public symbols and use it to generate a bfd symbol
893
table (hey, it's better than nothing) on a one-for-one basis. Thus
894
use the number of public symbols as the number of bfd symbols we will
895
have once we actually get around to reading them in.
897
Return the number of bytes required to hold the symtab vector, based on
898
the count plus 1, since we will NULL terminate the vector allocated based
902
nlm_get_symtab_upper_bound (abfd)
905
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */
907
long symtab_size = 0;
909
i_fxdhdrp = nlm_fixed_header (abfd);
910
symcount = (i_fxdhdrp->numberOfPublics
911
+ i_fxdhdrp->numberOfDebugRecords
912
+ i_fxdhdrp->numberOfExternalReferences);
913
symtab_size = (symcount + 1) * (sizeof (asymbol));
914
return (symtab_size);
917
/* Note that bfd_get_symcount is guaranteed to be zero if slurping the
918
symbol table fails. */
921
nlm_canonicalize_symtab (abfd, alocation)
925
nlm_symbol_type *symbase;
926
bfd_size_type counter = 0;
928
if (! nlm_slurp_symbol_table (abfd))
930
symbase = nlm_get_symbols (abfd);
931
while (counter < bfd_get_symcount (abfd))
933
*alocation++ = &symbase->symbol;
937
*alocation = (asymbol *) NULL;
938
return bfd_get_symcount (abfd);
941
/* Make an NLM symbol. There is nothing special to do here. */
944
nlm_make_empty_symbol (abfd)
947
bfd_size_type amt = sizeof (nlm_symbol_type);
948
nlm_symbol_type *new = (nlm_symbol_type *) bfd_zalloc (abfd, amt);
951
new->symbol.the_bfd = abfd;
955
/* Get symbol information. */
958
nlm_get_symbol_info (ignore_abfd, symbol, ret)
959
bfd *ignore_abfd ATTRIBUTE_UNUSED;
963
bfd_symbol_info (symbol, ret);
966
/* Print symbol information. */
969
nlm_print_symbol (abfd, afile, symbol, how)
973
bfd_print_symbol_type how;
975
FILE *file = (FILE *) afile;
979
case bfd_print_symbol_name:
980
case bfd_print_symbol_more:
982
fprintf (file, "%s", symbol->name);
984
case bfd_print_symbol_all:
985
bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
986
fprintf (file, " %-5s", symbol->section->name);
988
fprintf (file, " %s", symbol->name);
993
/* Slurp in nlm symbol table.
995
In the external (in-file) form, NLM export records are variable length,
996
with the following form:
998
1 byte length of the symbol name (N)
999
N bytes the symbol name
1000
4 bytes the symbol offset from start of it's section
1002
We also read in the debugging symbols and import records. Import
1003
records are treated as undefined symbols. As we read the import
1004
records we also read in the associated reloc information, which is
1005
attached to the symbol.
1007
The bfd symbols are copied to SYMPTRS.
1009
When we return, the bfd symcount is either zero or contains the correct
1010
number of symbols. */
1013
nlm_slurp_symbol_table (abfd)
1016
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */
1017
bfd_size_type totsymcount; /* Number of NLM symbols. */
1018
bfd_size_type symcount; /* Counter of NLM symbols. */
1019
nlm_symbol_type *sym; /* Pointer to current bfd symbol. */
1020
unsigned char symlength; /* Symbol length read into here. */
1021
unsigned char symtype; /* Type of debugging symbol. */
1022
bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here. */
1023
bfd_boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
1024
bfd_boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
1027
if (nlm_get_symbols (abfd) != NULL)
1030
/* Read each raw NLM symbol, using the information to create a canonical bfd
1033
Note that we allocate the initial bfd canonical symbol buffer based on a
1034
one-to-one mapping of the NLM symbols to canonical symbols. We actually
1035
use all the NLM symbols, so there will be no space left over at the end.
1036
When we have all the symbols, we build the caller's pointer vector. */
1039
i_fxdhdrp = nlm_fixed_header (abfd);
1040
totsymcount = (i_fxdhdrp->numberOfPublics
1041
+ i_fxdhdrp->numberOfDebugRecords
1042
+ i_fxdhdrp->numberOfExternalReferences);
1043
if (totsymcount == 0)
1046
if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
1049
amt = totsymcount * sizeof (nlm_symbol_type);
1050
sym = ((nlm_symbol_type *) bfd_zalloc (abfd, amt));
1053
nlm_set_symbols (abfd, sym);
1055
/* We use the bfd's symcount directly as the control count, so that early
1056
termination of the loop leaves the symcount correct for the symbols that
1059
set_public_section_func = nlm_set_public_section_func (abfd);
1060
symcount = i_fxdhdrp->numberOfPublics;
1061
while (abfd->symcount < symcount)
1063
amt = sizeof (symlength);
1064
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
1067
sym->symbol.the_bfd = abfd;
1068
sym->symbol.name = bfd_alloc (abfd, amt + 1);
1069
if (!sym->symbol.name)
1071
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
1073
/* Cast away const. */
1074
((char *) (sym->symbol.name))[symlength] = '\0';
1075
amt = sizeof (temp);
1076
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
1078
sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1079
sym->symbol.value = get_word (abfd, temp);
1080
if (set_public_section_func)
1082
/* Most backends can use the code below, but unfortunately
1083
some use a different scheme. */
1084
if (! (*set_public_section_func) (abfd, sym))
1089
if (sym->symbol.value & NLM_HIBIT)
1091
sym->symbol.value &= ~NLM_HIBIT;
1092
sym->symbol.flags |= BSF_FUNCTION;
1093
sym->symbol.section =
1094
bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1098
sym->symbol.section =
1099
bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1107
/* Read the debugging records. */
1109
if (i_fxdhdrp->numberOfDebugRecords > 0)
1111
if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
1114
symcount += i_fxdhdrp->numberOfDebugRecords;
1115
while (abfd->symcount < symcount)
1117
amt = sizeof (symtype);
1118
if (bfd_bread ((PTR) &symtype, amt, abfd) != amt)
1120
amt = sizeof (temp);
1121
if (bfd_bread ((PTR) temp, amt, abfd) != amt)
1123
amt = sizeof (symlength);
1124
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
1127
sym->symbol.the_bfd = abfd;
1128
sym->symbol.name = bfd_alloc (abfd, amt + 1);
1129
if (!sym->symbol.name)
1131
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
1133
/* Cast away const. */
1134
((char *) (sym->symbol.name))[symlength] = '\0';
1135
sym->symbol.flags = BSF_LOCAL;
1136
sym->symbol.value = get_word (abfd, temp);
1139
sym->symbol.section =
1140
bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1142
else if (symtype == 1)
1144
sym->symbol.flags |= BSF_FUNCTION;
1145
sym->symbol.section =
1146
bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1150
sym->symbol.section = bfd_abs_section_ptr;
1158
/* Read in the import records. We can only do this if we know how
1159
to read relocs for this target. */
1160
read_import_func = nlm_read_import_func (abfd);
1161
if (read_import_func != NULL)
1163
if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
1166
symcount += i_fxdhdrp->numberOfExternalReferences;
1167
while (abfd->symcount < symcount)
1169
if (! (*read_import_func) (abfd, sym))
1179
/* Get the relocs for an NLM file. There are two types of relocs.
1180
Imports are relocs against symbols defined in other NLM files. We
1181
treat these as relocs against global symbols. Relocation fixups
1182
are internal relocs.
1184
The actual format used to store the relocs is machine specific. */
1186
/* Read in the relocation fixup information. This is stored in
1187
nlm_relocation_fixups, an array of arelent structures, and
1188
nlm_relocation_fixup_secs, an array of section pointers. The
1189
section pointers are needed because the relocs are not sorted by
1193
nlm_slurp_reloc_fixups (abfd)
1196
bfd_boolean (*read_func)
1197
PARAMS ((bfd *, nlm_symbol_type *, asection **, arelent *));
1198
bfd_size_type count, amt;
1202
if (nlm_relocation_fixups (abfd) != NULL)
1204
read_func = nlm_read_reloc_func (abfd);
1205
if (read_func == NULL)
1208
if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1212
count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1213
amt = count * sizeof (arelent);
1214
rels = (arelent *) bfd_alloc (abfd, amt);
1215
amt = count * sizeof (asection *);
1216
secs = (asection **) bfd_alloc (abfd, amt);
1217
if ((rels == NULL || secs == NULL) && count != 0)
1219
nlm_relocation_fixups (abfd) = rels;
1220
nlm_relocation_fixup_secs (abfd) = secs;
1222
/* We have to read piece by piece, because we don't know how large
1223
the machine specific reloc information is. */
1224
while (count-- != 0)
1226
if (! (*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels))
1228
nlm_relocation_fixups (abfd) = NULL;
1229
nlm_relocation_fixup_secs (abfd) = NULL;
1239
/* Get the number of relocs. This really just returns an upper bound,
1240
since it does not attempt to distinguish them based on the section.
1241
That will be handled when they are actually read. */
1244
nlm_get_reloc_upper_bound (abfd, sec)
1248
nlm_symbol_type *syms;
1249
bfd_size_type count;
1252
/* If we don't know how to read relocs, just return 0. */
1253
if (nlm_read_reloc_func (abfd) == NULL)
1255
/* Make sure we have either the code or the data section. */
1256
if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1259
syms = nlm_get_symbols (abfd);
1262
if (! nlm_slurp_symbol_table (abfd))
1264
syms = nlm_get_symbols (abfd);
1267
ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1269
count = bfd_get_symcount (abfd);
1270
while (count-- != 0)
1276
return (ret + 1) * sizeof (arelent *);
1279
/* Get the relocs themselves. */
1282
nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1290
bfd_size_type count, i;
1293
/* Get the relocation fixups. */
1294
rels = nlm_relocation_fixups (abfd);
1297
if (! nlm_slurp_reloc_fixups (abfd))
1299
rels = nlm_relocation_fixups (abfd);
1301
secs = nlm_relocation_fixup_secs (abfd);
1304
count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1305
for (i = 0; i < count; i++, rels++, secs++)
1314
/* Get the import symbols. */
1315
count = bfd_get_symcount (abfd);
1316
for (i = 0; i < count; i++, symbols++)
1321
if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1323
nlm_symbol_type *nlm_sym;
1326
nlm_sym = (nlm_symbol_type *) sym;
1327
for (j = 0; j < nlm_sym->rcnt; j++)
1329
if (nlm_sym->relocs[j].section == sec)
1331
*relptr = &nlm_sym->relocs[j].reloc;
1332
(*relptr)->sym_ptr_ptr = symbols;
1345
/* Compute the section file positions for an NLM file. All variable
1346
length data in the file headers must be set before this function is
1347
called. If the variable length data is changed later, the
1348
resulting object file will be incorrect. Unfortunately, there is
1349
no way to check this.
1351
This routine also sets the Size and Offset fields in the fixed
1354
It also looks over the symbols and moves any common symbols into
1355
the .bss section; NLM has no way to represent a common symbol.
1356
This approach means that either the symbols must already have been
1357
set at this point, or there must be no common symbols. We need to
1358
move the symbols at this point so that mangle_relocs can see the
1362
nlm_compute_section_file_positions (abfd)
1367
bfd_vma text, data, bss;
1368
bfd_vma text_low, data_low;
1369
unsigned int text_align, data_align, other_align;
1370
file_ptr text_ptr, data_ptr, other_ptr;
1372
asymbol **sym_ptr_ptr;
1374
if (abfd->output_has_begun)
1377
/* Make sure we have a section to hold uninitialized data. */
1378
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1379
if (bss_sec == NULL)
1381
if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1382
(file_ptr) 0, (bfd_size_type) 0,
1385
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1388
abfd->output_has_begun = TRUE;
1390
/* The fixed header. */
1391
sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1393
/* The variable header. */
1394
sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1395
+ nlm_variable_header (abfd)->descriptionLength + 1
1396
+ NLM_TARGET_LONG_SIZE /* stackSize */
1397
+ NLM_TARGET_LONG_SIZE /* reserved */
1398
+ sizeof (nlm_variable_header (abfd)->oldThreadName)
1399
+ sizeof (nlm_variable_header (abfd)->screenNameLength)
1400
+ nlm_variable_header (abfd)->screenNameLength + 1
1401
+ sizeof (nlm_variable_header (abfd)->threadNameLength)
1402
+ nlm_variable_header (abfd)->threadNameLength + 1);
1404
/* The auxiliary headers. */
1405
if (find_nonzero ((PTR) nlm_version_header (abfd),
1406
sizeof (Nlm_Internal_Version_Header)))
1407
sofar += sizeof (Nlm_External_Version_Header);
1408
if (find_nonzero ((PTR) nlm_extended_header (abfd),
1409
sizeof (Nlm_Internal_Extended_Header)))
1410
sofar += sizeof (Nlm_External_Extended_Header);
1411
if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1412
sizeof (Nlm_Internal_Copyright_Header)))
1413
sofar += (sizeof (Nlm_External_Copyright_Header)
1414
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1415
if (find_nonzero ((PTR) nlm_custom_header (abfd),
1416
sizeof (Nlm_Internal_Custom_Header)))
1417
sofar += (sizeof (Nlm_External_Custom_Header)
1418
+ nlm_custom_header (abfd)->hdrLength);
1419
if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
1420
sizeof (Nlm_Internal_Cygnus_Ext_Header)))
1421
sofar += sizeof (Nlm_External_Custom_Header);
1423
/* Compute the section file positions in two passes. First get the
1424
sizes of the text and data sections, and then set the file
1425
positions. This code aligns the sections in the file using the
1426
same alignment restrictions that apply to the sections in memory;
1427
this may not be necessary. */
1429
text_low = (bfd_vma) - 1;
1432
data_low = (bfd_vma) - 1;
1436
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1440
sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1442
f = bfd_get_section_flags (abfd, sec);
1445
text += sec->_raw_size;
1446
if (bfd_get_section_vma (abfd, sec) < text_low)
1447
text_low = bfd_get_section_vma (abfd, sec);
1448
if (sec->alignment_power > text_align)
1449
text_align = sec->alignment_power;
1451
else if (f & SEC_DATA)
1453
data += sec->_raw_size;
1454
if (bfd_get_section_vma (abfd, sec) < data_low)
1455
data_low = bfd_get_section_vma (abfd, sec);
1456
if (sec->alignment_power > data_align)
1457
data_align = sec->alignment_power;
1459
else if (f & SEC_HAS_CONTENTS)
1461
if (sec->alignment_power > other_align)
1462
other_align = sec->alignment_power;
1464
else if (f & SEC_ALLOC)
1465
bss += sec->_raw_size;
1468
nlm_set_text_low (abfd, text_low);
1469
nlm_set_data_low (abfd, data_low);
1471
if (nlm_no_uninitialized_data (abfd))
1473
/* This NetWare format does not use uninitialized data. We must
1474
increase the size of the data section. We will never wind up
1475
writing those file locations, so they will remain zero. */
1480
text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1481
data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1482
other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1484
/* Fill in some fields in the header for which we now have the
1486
nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1487
nlm_fixed_header (abfd)->codeImageSize = text;
1488
nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1489
nlm_fixed_header (abfd)->dataImageSize = data;
1490
nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1492
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1496
f = bfd_get_section_flags (abfd, sec);
1500
sec->filepos = text_ptr;
1501
text_ptr += sec->_raw_size;
1503
else if (f & SEC_DATA)
1505
sec->filepos = data_ptr;
1506
data_ptr += sec->_raw_size;
1508
else if (f & SEC_HAS_CONTENTS)
1510
sec->filepos = other_ptr;
1511
other_ptr += sec->_raw_size;
1515
nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1517
/* Move all common symbols into the .bss section. */
1519
sym_ptr_ptr = bfd_get_outsymbols (abfd);
1520
if (sym_ptr_ptr != NULL)
1525
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1527
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1534
if (!bfd_is_com_section (bfd_get_section (sym)))
1537
/* Put the common symbol in the .bss section, and increase
1538
the size of the .bss section by the size of the common
1539
symbol (which is the old value of the symbol). */
1540
sym->section = bss_sec;
1542
sym->value = bss_sec->_raw_size + add;
1544
add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1548
if (nlm_no_uninitialized_data (abfd))
1550
/* We could handle this case, but so far it hasn't been
1554
nlm_fixed_header (abfd)->uninitializedDataSize += add;
1555
bss_sec->_raw_size += add;
1562
/* Set the contents of a section. To do this we need to know where
1563
the section is going to be located in the output file. That means
1564
that the sizes of all the sections must be set, and all the
1565
variable size header information must be known. */
1568
nlm_set_section_contents (abfd, section, location, offset, count)
1573
bfd_size_type count;
1575
if (! abfd->output_has_begun
1576
&& ! nlm_compute_section_file_positions (abfd))
1582
/* i386 NetWare has a very restricted set of relocs. In order for
1583
objcopy to work, the NLM i386 backend needs a chance to rework
1584
the section contents so that its set of relocs will work. If all
1585
the relocs are already acceptable, this will not do anything. */
1586
if (section->reloc_count != 0)
1588
bfd_boolean (*mangle_relocs_func)
1589
PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
1591
mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1592
if (mangle_relocs_func != NULL)
1594
if (!(*mangle_relocs_func) (abfd, section, location,
1595
(bfd_vma) offset, count))
1600
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1601
|| bfd_bwrite (location, count, abfd) != count)
1607
/* We need to sort a list of relocs associated with sections when we
1608
write out the external relocs. */
1611
nlm_external_reloc_compare (p1, p2)
1615
const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1616
const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1619
cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1620
(*r2->rel->sym_ptr_ptr)->name);
1624
/* We sort by address within symbol to make the sort more stable and
1625
increase the chances that different hosts will generate bit for
1626
bit equivalent results. */
1627
return (int) (r1->rel->address - r2->rel->address);
1630
/* Write out an NLM file. We write out the information in this order:
1636
other sections (custom data, messages, help, shared NLM, RPC,
1637
module dependencies)
1639
external references (imports)
1640
public symbols (exports)
1642
This is similar to the order used by the NetWare tools; the
1643
difference is that NetWare puts the sections other than code, data
1644
and custom data at the end of the NLM. It is convenient for us to
1645
know where the sections are going to be before worrying about the
1646
size of the other information.
1648
By the time this function is called, all the section data should
1649
have been output using set_section_contents. Note that custom
1650
data, the message file, the help file, the shared NLM file, the RPC
1651
data, and the module dependencies are all considered to be
1652
sections; the caller is responsible for filling in the offset and
1653
length fields in the NLM headers. The relocation fixups and
1654
imports are both obtained from the list of relocs attached to each
1655
section. The exports and debugging records are obtained from the
1656
list of outsymbols. */
1659
nlm_write_object_contents (abfd)
1663
bfd_boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1664
bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1665
struct reloc_and_sec *external_relocs;
1666
asymbol **sym_ptr_ptr;
1668
bfd_boolean (*write_prefix_func) PARAMS ((bfd *));
1669
unsigned char *fixed_header = NULL;
1673
fixed_header = ((unsigned char *)
1674
bfd_malloc (nlm_fixed_header_size (abfd)));
1675
if (fixed_header == NULL)
1678
if (! abfd->output_has_begun
1679
&& ! nlm_compute_section_file_positions (abfd))
1682
/* Write out the variable length headers. */
1683
pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1684
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
1686
if (! nlm_swap_variable_header_out (abfd)
1687
|| ! nlm_swap_auxiliary_headers_out (abfd))
1689
bfd_set_error (bfd_error_system_call);
1693
/* A weak check on whether the section file positions were
1695
if (bfd_tell (abfd) > (ufile_ptr) nlm_fixed_header (abfd)->codeImageOffset)
1697
bfd_set_error (bfd_error_invalid_operation);
1701
/* Advance to the relocs. */
1702
if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1706
/* The format of the relocation entries is dependent upon the
1707
particular target. We use an external routine to write the reloc
1709
write_import_func = nlm_write_import_func (abfd);
1711
/* Write out the internal relocation fixups. While we're looping
1712
over the relocs, we also count the external relocs, which is
1713
needed when they are written out below. */
1714
internal_reloc_count = 0;
1715
external_reloc_count = 0;
1716
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1718
arelent **rel_ptr_ptr, **rel_end;
1720
if (sec->reloc_count == 0)
1723
/* We can only represent relocs within a code or data
1724
section. We ignore them for a debugging section. */
1725
if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1728
/* We need to know how to write out imports */
1729
if (write_import_func == NULL)
1731
bfd_set_error (bfd_error_invalid_operation);
1735
rel_ptr_ptr = sec->orelocation;
1736
rel_end = rel_ptr_ptr + sec->reloc_count;
1737
for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1743
sym = *rel->sym_ptr_ptr;
1745
if (! bfd_is_und_section (bfd_get_section (sym)))
1747
++internal_reloc_count;
1748
if (! (*write_import_func) (abfd, sec, rel))
1752
++external_reloc_count;
1755
nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1757
/* Write out the imports (relocs against external symbols). These
1758
are output as a symbol name followed by all the relocs for that
1759
symbol, so we must first gather together all the relocs against
1760
external symbols and sort them. */
1761
amt = external_reloc_count * sizeof (struct reloc_and_sec);
1762
external_relocs = (struct reloc_and_sec *) bfd_alloc (abfd, amt);
1763
if (external_relocs == (struct reloc_and_sec *) NULL)
1766
for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1768
arelent **rel_ptr_ptr, **rel_end;
1770
if (sec->reloc_count == 0)
1773
rel_ptr_ptr = sec->orelocation;
1774
rel_end = rel_ptr_ptr + sec->reloc_count;
1775
for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1781
sym = *rel->sym_ptr_ptr;
1783
if (! bfd_is_und_section (bfd_get_section (sym)))
1786
external_relocs[i].rel = rel;
1787
external_relocs[i].sec = sec;
1792
BFD_ASSERT (i == external_reloc_count);
1794
/* Sort the external relocs by name. */
1795
qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1796
sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1798
/* Write out the external relocs. */
1799
nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1802
while (i < external_reloc_count)
1806
bfd_size_type j, cnt;
1810
rel = external_relocs[i].rel;
1811
sym = *rel->sym_ptr_ptr;
1815
(j < external_reloc_count
1816
&& *external_relocs[j].rel->sym_ptr_ptr == sym);
1820
if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1821
&external_relocs[i]))
1827
nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1829
/* Write out the public symbols (exports). */
1830
sym_ptr_ptr = bfd_get_outsymbols (abfd);
1831
if (sym_ptr_ptr != (asymbol **) NULL)
1833
bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1834
bfd_boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1838
nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1839
get_public_offset_func = nlm_get_public_offset_func (abfd);
1840
write_export_func = nlm_write_export_func (abfd);
1842
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1843
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1848
bfd_byte temp[NLM_TARGET_LONG_SIZE];
1852
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1853
|| bfd_is_und_section (bfd_get_section (sym)))
1858
if (get_public_offset_func)
1860
/* Most backends can use the code below, but
1861
unfortunately some use a different scheme. */
1862
offset = (*get_public_offset_func) (abfd, sym);
1866
offset = bfd_asymbol_value (sym);
1868
if (sec->flags & SEC_CODE)
1870
offset -= nlm_get_text_low (abfd);
1871
offset |= NLM_HIBIT;
1873
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1875
/* SEC_ALLOC is for the .bss section. */
1876
offset -= nlm_get_data_low (abfd);
1880
/* We can't handle an exported symbol that is not in
1881
the code or data segment. */
1882
bfd_set_error (bfd_error_invalid_operation);
1887
if (write_export_func)
1889
if (! (*write_export_func) (abfd, sym, offset))
1894
len = strlen (sym->name);
1895
if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1896
!= sizeof (bfd_byte))
1897
|| bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1900
put_word (abfd, offset, temp);
1901
if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1906
nlm_fixed_header (abfd)->numberOfPublics = c;
1908
/* Write out the debugging records. The NLM conversion program
1909
wants to be able to inhibit this, so as a special hack if
1910
debugInfoOffset is set to -1 we don't write any debugging
1911
information. This can not be handled by fiddling with the
1912
symbol table, because exported symbols appear in both the
1913
exported symbol list and the debugging information. */
1914
if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1916
nlm_fixed_header (abfd)->debugInfoOffset = 0;
1917
nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1921
nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1923
sym_ptr_ptr = bfd_get_outsymbols (abfd);
1924
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1925
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1930
bfd_byte temp[NLM_TARGET_LONG_SIZE];
1934
/* The NLM notion of a debugging symbol is actually what
1935
BFD calls a local or global symbol. What BFD calls a
1936
debugging symbol NLM does not understand at all. */
1937
if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1938
|| (sym->flags & BSF_DEBUGGING) != 0
1939
|| bfd_is_und_section (bfd_get_section (sym)))
1944
offset = bfd_asymbol_value (sym);
1946
if (sec->flags & SEC_CODE)
1948
offset -= nlm_get_text_low (abfd);
1951
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1953
/* SEC_ALLOC is for the .bss section. */
1954
offset -= nlm_get_data_low (abfd);
1960
/* The type is 0 for data, 1 for code, 2 for absolute. */
1961
if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
1962
!= sizeof (bfd_byte))
1965
put_word (abfd, offset, temp);
1966
if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1970
len = strlen (sym->name);
1971
if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1972
!= sizeof (bfd_byte))
1973
|| bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1976
nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1980
/* NLMLINK fills in offset values even if there is no data, so we do
1982
last = bfd_tell (abfd);
1983
if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1984
nlm_fixed_header (abfd)->codeImageOffset = last;
1985
if (nlm_fixed_header (abfd)->dataImageOffset == 0)
1986
nlm_fixed_header (abfd)->dataImageOffset = last;
1987
if (nlm_fixed_header (abfd)->customDataOffset == 0)
1988
nlm_fixed_header (abfd)->customDataOffset = last;
1989
if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
1990
nlm_fixed_header (abfd)->moduleDependencyOffset = last;
1991
if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
1992
nlm_fixed_header (abfd)->relocationFixupOffset = last;
1993
if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
1994
nlm_fixed_header (abfd)->externalReferencesOffset = last;
1995
if (nlm_fixed_header (abfd)->publicsOffset == 0)
1996
nlm_fixed_header (abfd)->publicsOffset = last;
1997
if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
1998
nlm_fixed_header (abfd)->debugInfoOffset = last;
2000
/* At this point everything has been written out except the fixed
2002
memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
2003
NLM_SIGNATURE_SIZE);
2004
nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2005
nlm_fixed_header (abfd)->codeStartOffset =
2006
(bfd_get_start_address (abfd)
2007
- nlm_get_text_low (abfd));
2009
/* We have no convenient way for the caller to pass in the exit
2010
procedure or the check unload procedure, so the caller must set
2011
the values in the header to the values of the symbols. */
2012
nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2013
if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2014
nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2015
nlm_get_text_low (abfd);
2017
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
2020
write_prefix_func = nlm_write_prefix_func (abfd);
2021
if (write_prefix_func)
2023
if (! (*write_prefix_func) (abfd))
2027
BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
2028
== nlm_optional_prefix_size (abfd));
2030
nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
2031
if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
2032
!= nlm_fixed_header_size (abfd))
2035
if (fixed_header != NULL)
2036
free (fixed_header);
2040
if (fixed_header != NULL)
2041
free (fixed_header);