1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright (C) 1993-2015 Free Software Foundation, Inc.
4 Written by Fred Fish @ Cygnus Support, using ELF support as the
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, 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 /* Should perhaps use put_offset, put_word, etc. For now, the two versions
61 can be handled by explicitly specifying 32 bits or "the long type". */
63 #define put_word H_PUT_64
64 #define get_word H_GET_64
67 #define put_word H_PUT_32
68 #define get_word H_GET_32
71 /* Read and swap in the variable length header. All the fields must
72 exist in the NLM, and must exist in the order they are read here. */
75 nlm_swap_variable_header_in (bfd
*abfd
)
77 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
80 /* Read the description length and text members. */
81 amt
= sizeof (nlm_variable_header (abfd
)->descriptionLength
);
82 if (bfd_bread ((void *) &nlm_variable_header (abfd
)->descriptionLength
,
85 amt
= nlm_variable_header (abfd
)->descriptionLength
+ 1;
86 if (bfd_bread ((void *) nlm_variable_header (abfd
)->descriptionText
,
90 /* Read and convert the stackSize field. */
92 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
94 nlm_variable_header (abfd
)->stackSize
= get_word (abfd
, (bfd_byte
*) temp
);
96 /* Read and convert the reserved field. */
98 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
100 nlm_variable_header (abfd
)->reserved
= get_word (abfd
, (bfd_byte
*) temp
);
102 /* Read the oldThreadName field. This field is a fixed length string. */
103 amt
= sizeof (nlm_variable_header (abfd
)->oldThreadName
);
104 if (bfd_bread ((void *) nlm_variable_header (abfd
)->oldThreadName
,
108 /* Read the screen name length and text members. */
109 amt
= sizeof (nlm_variable_header (abfd
)->screenNameLength
);
110 if (bfd_bread ((void *) & nlm_variable_header (abfd
)->screenNameLength
,
113 amt
= nlm_variable_header (abfd
)->screenNameLength
+ 1;
114 if (bfd_bread ((void *) nlm_variable_header (abfd
)->screenName
,
118 /* Read the thread name length and text members. */
119 amt
= sizeof (nlm_variable_header (abfd
)->threadNameLength
);
120 if (bfd_bread ((void *) & nlm_variable_header (abfd
)->threadNameLength
,
123 amt
= nlm_variable_header (abfd
)->threadNameLength
+ 1;
124 if (bfd_bread ((void *) nlm_variable_header (abfd
)->threadName
,
130 /* Add a section to the bfd. */
133 add_bfd_section (bfd
*abfd
,
141 newsect
= bfd_make_section_with_flags (abfd
, name
, flags
);
145 newsect
->vma
= 0; /* NLM's are relocatable. */
146 newsect
->size
= size
;
147 newsect
->filepos
= offset
;
148 newsect
->alignment_power
= bfd_log2 ((bfd_vma
) 0); /* FIXME */
153 /* Read and swap in the contents of all the auxiliary headers. Because of
154 the braindead design, we have to do strcmps on strings of indeterminate
155 length to figure out what each auxiliary header is. Even worse, we have
156 no way of knowing how many auxiliary headers there are or where the end
157 of the auxiliary headers are, except by finding something that doesn't
158 look like a known auxiliary header. This means that the first new type
159 of auxiliary header added will break all existing tools that don't
163 nlm_swap_auxiliary_headers_in (bfd
*abfd
)
171 position
= bfd_tell (abfd
);
172 amt
= sizeof (tempstr
);
173 if (bfd_bread ((void *) tempstr
, amt
, abfd
) != amt
)
175 if (bfd_seek (abfd
, position
, SEEK_SET
) != 0)
177 if (CONST_STRNEQ (tempstr
, "VeRsIoN#"))
179 Nlm_External_Version_Header thdr
;
182 if (bfd_bread ((void *) &thdr
, amt
, abfd
) != amt
)
184 memcpy (nlm_version_header (abfd
)->stamp
, thdr
.stamp
,
185 sizeof (thdr
.stamp
));
186 nlm_version_header (abfd
)->majorVersion
=
187 get_word (abfd
, (bfd_byte
*) thdr
.majorVersion
);
188 nlm_version_header (abfd
)->minorVersion
=
189 get_word (abfd
, (bfd_byte
*) thdr
.minorVersion
);
190 nlm_version_header (abfd
)->revision
=
191 get_word (abfd
, (bfd_byte
*) thdr
.revision
);
192 nlm_version_header (abfd
)->year
=
193 get_word (abfd
, (bfd_byte
*) thdr
.year
);
194 nlm_version_header (abfd
)->month
=
195 get_word (abfd
, (bfd_byte
*) thdr
.month
);
196 nlm_version_header (abfd
)->day
=
197 get_word (abfd
, (bfd_byte
*) thdr
.day
);
199 else if (CONST_STRNEQ (tempstr
, "MeSsAgEs"))
201 Nlm_External_Extended_Header thdr
;
204 if (bfd_bread ((void *) &thdr
, amt
, abfd
) != amt
)
206 memcpy (nlm_extended_header (abfd
)->stamp
, thdr
.stamp
,
207 sizeof (thdr
.stamp
));
208 nlm_extended_header (abfd
)->languageID
=
209 get_word (abfd
, (bfd_byte
*) thdr
.languageID
);
210 nlm_extended_header (abfd
)->messageFileOffset
=
211 get_word (abfd
, (bfd_byte
*) thdr
.messageFileOffset
);
212 nlm_extended_header (abfd
)->messageFileLength
=
213 get_word (abfd
, (bfd_byte
*) thdr
.messageFileLength
);
214 nlm_extended_header (abfd
)->messageCount
=
215 get_word (abfd
, (bfd_byte
*) thdr
.messageCount
);
216 nlm_extended_header (abfd
)->helpFileOffset
=
217 get_word (abfd
, (bfd_byte
*) thdr
.helpFileOffset
);
218 nlm_extended_header (abfd
)->helpFileLength
=
219 get_word (abfd
, (bfd_byte
*) thdr
.helpFileLength
);
220 nlm_extended_header (abfd
)->RPCDataOffset
=
221 get_word (abfd
, (bfd_byte
*) thdr
.RPCDataOffset
);
222 nlm_extended_header (abfd
)->RPCDataLength
=
223 get_word (abfd
, (bfd_byte
*) thdr
.RPCDataLength
);
224 nlm_extended_header (abfd
)->sharedCodeOffset
=
225 get_word (abfd
, (bfd_byte
*) thdr
.sharedCodeOffset
);
226 nlm_extended_header (abfd
)->sharedCodeLength
=
227 get_word (abfd
, (bfd_byte
*) thdr
.sharedCodeLength
);
228 nlm_extended_header (abfd
)->sharedDataOffset
=
229 get_word (abfd
, (bfd_byte
*) thdr
.sharedDataOffset
);
230 nlm_extended_header (abfd
)->sharedDataLength
=
231 get_word (abfd
, (bfd_byte
*) thdr
.sharedDataLength
);
232 nlm_extended_header (abfd
)->sharedRelocationFixupOffset
=
233 get_word (abfd
, (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
234 nlm_extended_header (abfd
)->sharedRelocationFixupCount
=
235 get_word (abfd
, (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
236 nlm_extended_header (abfd
)->sharedExternalReferenceOffset
=
237 get_word (abfd
, (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
238 nlm_extended_header (abfd
)->sharedExternalReferenceCount
=
239 get_word (abfd
, (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
240 nlm_extended_header (abfd
)->sharedPublicsOffset
=
241 get_word (abfd
, (bfd_byte
*) thdr
.sharedPublicsOffset
);
242 nlm_extended_header (abfd
)->sharedPublicsCount
=
243 get_word (abfd
, (bfd_byte
*) thdr
.sharedPublicsCount
);
244 nlm_extended_header (abfd
)->sharedDebugRecordOffset
=
245 get_word (abfd
, (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
246 nlm_extended_header (abfd
)->sharedDebugRecordCount
=
247 get_word (abfd
, (bfd_byte
*) thdr
.sharedDebugRecordCount
);
248 nlm_extended_header (abfd
)->SharedInitializationOffset
=
249 get_word (abfd
, (bfd_byte
*) thdr
.sharedInitializationOffset
);
250 nlm_extended_header (abfd
)->SharedExitProcedureOffset
=
251 get_word (abfd
, (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
252 nlm_extended_header (abfd
)->productID
=
253 get_word (abfd
, (bfd_byte
*) thdr
.productID
);
254 nlm_extended_header (abfd
)->reserved0
=
255 get_word (abfd
, (bfd_byte
*) thdr
.reserved0
);
256 nlm_extended_header (abfd
)->reserved1
=
257 get_word (abfd
, (bfd_byte
*) thdr
.reserved1
);
258 nlm_extended_header (abfd
)->reserved2
=
259 get_word (abfd
, (bfd_byte
*) thdr
.reserved2
);
260 nlm_extended_header (abfd
)->reserved3
=
261 get_word (abfd
, (bfd_byte
*) thdr
.reserved3
);
262 nlm_extended_header (abfd
)->reserved4
=
263 get_word (abfd
, (bfd_byte
*) thdr
.reserved4
);
264 nlm_extended_header (abfd
)->reserved5
=
265 get_word (abfd
, (bfd_byte
*) thdr
.reserved5
);
267 else if (CONST_STRNEQ (tempstr
, "CoPyRiGhT="))
269 amt
= sizeof (nlm_copyright_header (abfd
)->stamp
);
270 if (bfd_bread ((void *) nlm_copyright_header (abfd
)->stamp
,
273 if (bfd_bread ((void *) &(nlm_copyright_header (abfd
)
274 ->copyrightMessageLength
),
275 (bfd_size_type
) 1, abfd
) != 1)
277 /* The copyright message is a variable length string. */
278 amt
= nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1;
279 if (bfd_bread ((void *) nlm_copyright_header (abfd
)->copyrightMessage
,
283 else if (CONST_STRNEQ (tempstr
, "CuStHeAd"))
285 Nlm_External_Custom_Header thdr
;
286 bfd_size_type hdrLength
;
288 bfd_size_type dataLength
;
292 /* Read the stamp ("CuStHeAd"). */
293 amt
= sizeof (thdr
.stamp
);
294 if (bfd_bread ((void *) thdr
.stamp
, amt
, abfd
) != amt
)
296 /* Read the length of this custom header. */
297 amt
= sizeof (thdr
.length
);
298 if (bfd_bread ((void *) thdr
.length
, amt
, abfd
) != amt
)
300 hdrLength
= get_word (abfd
, (bfd_byte
*) thdr
.length
);
301 /* Read further fields if we have them. */
302 if (hdrLength
< NLM_TARGET_LONG_SIZE
)
306 amt
= sizeof (thdr
.dataOffset
);
307 if (bfd_bread ((void *) thdr
.dataOffset
, amt
, abfd
) != amt
)
309 dataOffset
= get_word (abfd
, (bfd_byte
*) thdr
.dataOffset
);
311 if (hdrLength
< 2 * NLM_TARGET_LONG_SIZE
)
315 amt
= sizeof (thdr
.dataLength
);
316 if (bfd_bread ((void *) thdr
.dataLength
, amt
, abfd
) != amt
)
318 dataLength
= get_word (abfd
, (bfd_byte
*) thdr
.dataLength
);
320 if (hdrLength
< 2 * NLM_TARGET_LONG_SIZE
+ 8)
321 memset (dataStamp
, 0, sizeof (dataStamp
));
324 amt
= sizeof (dataStamp
);
325 if (bfd_bread ((void *) dataStamp
, amt
, abfd
) != amt
)
329 /* Read the rest of the header, if any. */
330 if (hdrLength
<= 2 * NLM_TARGET_LONG_SIZE
+ 8)
337 hdrLength
-= 2 * NLM_TARGET_LONG_SIZE
+ 8;
338 hdr
= bfd_alloc (abfd
, hdrLength
);
341 if (bfd_bread (hdr
, hdrLength
, abfd
) != hdrLength
)
345 /* If we have found a Cygnus header, process it. Otherwise,
346 just save the associated data without trying to interpret
348 if (CONST_STRNEQ (dataStamp
, "CyGnUsEx"))
354 BFD_ASSERT (hdrLength
== 0 && hdr
== NULL
);
356 pos
= bfd_tell (abfd
);
357 if (bfd_seek (abfd
, dataOffset
, SEEK_SET
) != 0)
359 contents
= bfd_alloc (abfd
, dataLength
);
360 if (contents
== NULL
)
362 if (bfd_bread (contents
, dataLength
, abfd
) != dataLength
)
364 if (bfd_seek (abfd
, pos
, SEEK_SET
) != 0)
367 LITMEMCPY (nlm_cygnus_ext_header (abfd
), "CyGnUsEx");
368 nlm_cygnus_ext_header (abfd
)->offset
= dataOffset
;
369 nlm_cygnus_ext_header (abfd
)->length
= dataLength
;
371 /* This data this header points to provides a list of
372 the sections which were in the original object file
373 which was converted to become an NLM. We locate
374 those sections and add them to the BFD. Note that
375 this is likely to create a second .text, .data and
376 .bss section; retrieving the sections by name will
377 get the actual NLM sections, which is what we want to
378 happen. The sections from the original file, which
379 may be subsets of the NLM section, can only be found
380 using bfd_map_over_sections. */
382 pend
= p
+ dataLength
;
391 /* The format of this information is
392 null terminated section name
393 zeroes to adjust to 4 byte boundary
394 4 byte section data file pointer
395 4 byte section size. */
398 l
= strlen (name
) + 1;
399 l
= (l
+ 3) &~ (size_t) 3;
401 filepos
= H_GET_32 (abfd
, p
);
403 size
= H_GET_32 (abfd
, p
);
406 newsec
= bfd_make_section_anyway (abfd
, name
);
412 newsec
->filepos
= filepos
;
413 newsec
->flags
|= SEC_HAS_CONTENTS
;
419 memcpy (nlm_custom_header (abfd
)->stamp
, thdr
.stamp
,
420 sizeof (thdr
.stamp
));
421 nlm_custom_header (abfd
)->hdrLength
= hdrLength
;
422 nlm_custom_header (abfd
)->dataOffset
= dataOffset
;
423 nlm_custom_header (abfd
)->dataLength
= dataLength
;
424 memcpy (nlm_custom_header (abfd
)->dataStamp
, dataStamp
,
426 nlm_custom_header (abfd
)->hdr
= hdr
;
436 nlm_object_p (bfd
*abfd
)
438 struct nlm_obj_tdata
*preserved_tdata
= nlm_tdata (abfd
);
439 bfd_boolean (*backend_object_p
) (bfd
*);
440 void * x_fxdhdr
= NULL
;
441 Nlm_Internal_Fixed_Header
*i_fxdhdrp
;
442 struct nlm_obj_tdata
*new_tdata
= NULL
;
443 const char *signature
;
444 enum bfd_architecture arch
;
447 /* Some NLM formats have a prefix before the standard NLM fixed
449 backend_object_p
= nlm_backend_object_p_func (abfd
);
450 if (backend_object_p
)
452 if (!(*backend_object_p
) (abfd
))
453 goto got_wrong_format_error
;
456 /* Read in the fixed length portion of the NLM header in external format. */
457 amt
= nlm_fixed_header_size (abfd
);
458 x_fxdhdr
= bfd_malloc (amt
);
459 if (x_fxdhdr
== NULL
)
462 if (bfd_bread ((void *) x_fxdhdr
, amt
, abfd
) != amt
)
464 if (bfd_get_error () != bfd_error_system_call
)
465 goto got_wrong_format_error
;
470 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
471 the tdata pointer in the bfd. */
472 amt
= sizeof (struct nlm_obj_tdata
);
473 new_tdata
= bfd_zalloc (abfd
, amt
);
474 if (new_tdata
== NULL
)
477 nlm_tdata (abfd
) = new_tdata
;
479 i_fxdhdrp
= nlm_fixed_header (abfd
);
480 nlm_swap_fixed_header_in (abfd
, x_fxdhdr
, i_fxdhdrp
);
484 /* Check to see if we have an NLM file for this backend by matching
485 the NLM signature. */
486 signature
= nlm_signature (abfd
);
487 if (signature
!= NULL
488 && *signature
!= '\0'
489 && strncmp ((char *) i_fxdhdrp
->signature
, signature
,
490 NLM_SIGNATURE_SIZE
) != 0)
491 goto got_wrong_format_error
;
493 /* There's no supported way to discover the endianness of an NLM, so test for
494 a sane version number after doing byte swapping appropriate for this
495 XVEC. (Hack alert!) */
496 if (i_fxdhdrp
->version
> 0xFFFF)
497 goto got_wrong_format_error
;
499 /* There's no supported way to check for 32 bit versus 64 bit addresses,
500 so ignore this distinction for now. (FIXME) */
501 /* Swap in the rest of the required header. */
502 if (!nlm_swap_variable_header_in (abfd
))
504 if (bfd_get_error () != bfd_error_system_call
)
505 goto got_wrong_format_error
;
510 /* Add the sections supplied by all NLM's, and then read in the
511 auxiliary headers. Reading the auxiliary headers may create
512 additional sections described in the cygnus_ext header.
513 From this point on we assume that we have an NLM, and do not
514 treat errors as indicating the wrong format. */
515 if (!add_bfd_section (abfd
, NLM_CODE_NAME
,
516 i_fxdhdrp
->codeImageOffset
,
517 i_fxdhdrp
->codeImageSize
,
518 (SEC_CODE
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
520 || !add_bfd_section (abfd
, NLM_INITIALIZED_DATA_NAME
,
521 i_fxdhdrp
->dataImageOffset
,
522 i_fxdhdrp
->dataImageSize
,
523 (SEC_DATA
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
525 || !add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
527 i_fxdhdrp
->uninitializedDataSize
,
531 if (!nlm_swap_auxiliary_headers_in (abfd
))
534 if (nlm_fixed_header (abfd
)->numberOfRelocationFixups
!= 0
535 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
536 abfd
->flags
|= HAS_RELOC
;
537 if (nlm_fixed_header (abfd
)->numberOfPublics
!= 0
538 || nlm_fixed_header (abfd
)->numberOfDebugRecords
!= 0
539 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
540 abfd
->flags
|= HAS_SYMS
;
542 arch
= nlm_architecture (abfd
);
543 if (arch
!= bfd_arch_unknown
)
544 bfd_default_set_arch_mach (abfd
, arch
, (unsigned long) 0);
546 abfd
->flags
|= EXEC_P
;
547 bfd_get_start_address (abfd
) = nlm_fixed_header (abfd
)->codeStartOffset
;
551 got_wrong_format_error
:
552 bfd_set_error (bfd_error_wrong_format
);
554 nlm_tdata (abfd
) = preserved_tdata
;
555 if (new_tdata
!= NULL
)
556 bfd_release (abfd
, new_tdata
);
557 if (x_fxdhdr
!= NULL
)
563 /* Swap and write out the variable length header. All the fields must
564 exist in the NLM, and must exist in this order. */
567 nlm_swap_variable_header_out (bfd
*abfd
)
569 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
572 /* Write the description length and text members. */
573 amt
= sizeof (nlm_variable_header (abfd
)->descriptionLength
);
574 if (bfd_bwrite (& nlm_variable_header (abfd
)->descriptionLength
, amt
,
577 amt
= nlm_variable_header (abfd
)->descriptionLength
+ 1;
578 if (bfd_bwrite ((void *) nlm_variable_header (abfd
)->descriptionText
, amt
,
582 /* Convert and write the stackSize field. */
583 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->stackSize
, temp
);
585 if (bfd_bwrite (temp
, amt
, abfd
) != amt
)
588 /* Convert and write the reserved field. */
589 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->reserved
, temp
);
591 if (bfd_bwrite (temp
, amt
, abfd
) != amt
)
594 /* Write the oldThreadName field. This field is a fixed length string. */
595 amt
= sizeof (nlm_variable_header (abfd
)->oldThreadName
);
596 if (bfd_bwrite (nlm_variable_header (abfd
)->oldThreadName
, amt
,
600 /* Write the screen name length and text members. */
601 amt
= sizeof (nlm_variable_header (abfd
)->screenNameLength
);
602 if (bfd_bwrite (& nlm_variable_header (abfd
)->screenNameLength
, amt
,
605 amt
= nlm_variable_header (abfd
)->screenNameLength
+ 1;
606 if (bfd_bwrite (nlm_variable_header (abfd
)->screenName
, amt
, abfd
) != amt
)
609 /* Write the thread name length and text members. */
610 amt
= sizeof (nlm_variable_header (abfd
)->threadNameLength
);
611 if (bfd_bwrite (& nlm_variable_header (abfd
)->threadNameLength
, amt
,
614 amt
= nlm_variable_header (abfd
)->threadNameLength
+ 1;
615 if (bfd_bwrite (nlm_variable_header (abfd
)->threadName
, amt
, abfd
) != amt
)
620 /* Return whether there is a non-zero byte in a memory block. */
623 find_nonzero (void * buf
, size_t size
)
625 char *p
= (char *) buf
;
633 /* Swap out the contents of the auxiliary headers. We create those
634 auxiliary headers which have been set non-zero. We do not require
635 the caller to set up the stamp fields. */
638 nlm_swap_auxiliary_headers_out (bfd
*abfd
)
642 /* Write out the version header if there is one. */
643 if (find_nonzero (nlm_version_header (abfd
),
644 sizeof (Nlm_Internal_Version_Header
)))
646 Nlm_External_Version_Header thdr
;
648 LITMEMCPY (thdr
.stamp
, "VeRsIoN#");
649 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->majorVersion
,
650 (bfd_byte
*) thdr
.majorVersion
);
651 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->minorVersion
,
652 (bfd_byte
*) thdr
.minorVersion
);
653 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->revision
,
654 (bfd_byte
*) thdr
.revision
);
655 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->year
,
656 (bfd_byte
*) thdr
.year
);
657 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->month
,
658 (bfd_byte
*) thdr
.month
);
659 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->day
,
660 (bfd_byte
*) thdr
.day
);
661 if (bfd_bwrite ((void *) &thdr
, (bfd_size_type
) sizeof (thdr
), abfd
)
666 /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
667 tag in order to make the NW4.x and NW5.x loaders happy. */
669 /* Write out the copyright header if there is one. */
670 if (find_nonzero (nlm_copyright_header (abfd
),
671 sizeof (Nlm_Internal_Copyright_Header
)))
673 Nlm_External_Copyright_Header thdr
;
675 LITMEMCPY (thdr
.stamp
, "CoPyRiGhT=");
676 amt
= sizeof (thdr
.stamp
);
677 if (bfd_bwrite ((void *) thdr
.stamp
, amt
, abfd
) != amt
)
679 thdr
.copyrightMessageLength
[0] =
680 nlm_copyright_header (abfd
)->copyrightMessageLength
;
682 if (bfd_bwrite ((void *) thdr
.copyrightMessageLength
, amt
, abfd
) != amt
)
684 /* The copyright message is a variable length string. */
685 amt
= nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1;
686 if (bfd_bwrite ((void *) nlm_copyright_header (abfd
)->copyrightMessage
,
691 /* Write out the extended header if there is one. */
692 if (find_nonzero (nlm_extended_header (abfd
),
693 sizeof (Nlm_Internal_Extended_Header
)))
695 Nlm_External_Extended_Header thdr
;
697 LITMEMCPY (thdr
.stamp
, "MeSsAgEs");
699 (bfd_vma
) nlm_extended_header (abfd
)->languageID
,
700 (bfd_byte
*) thdr
.languageID
);
702 (bfd_vma
) nlm_extended_header (abfd
)->messageFileOffset
,
703 (bfd_byte
*) thdr
.messageFileOffset
);
705 (bfd_vma
) nlm_extended_header (abfd
)->messageFileLength
,
706 (bfd_byte
*) thdr
.messageFileLength
);
708 (bfd_vma
) nlm_extended_header (abfd
)->messageCount
,
709 (bfd_byte
*) thdr
.messageCount
);
711 (bfd_vma
) nlm_extended_header (abfd
)->helpFileOffset
,
712 (bfd_byte
*) thdr
.helpFileOffset
);
714 (bfd_vma
) nlm_extended_header (abfd
)->helpFileLength
,
715 (bfd_byte
*) thdr
.helpFileLength
);
717 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataOffset
,
718 (bfd_byte
*) thdr
.RPCDataOffset
);
720 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataLength
,
721 (bfd_byte
*) thdr
.RPCDataLength
);
723 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeOffset
,
724 (bfd_byte
*) thdr
.sharedCodeOffset
);
726 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeLength
,
727 (bfd_byte
*) thdr
.sharedCodeLength
);
729 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataOffset
,
730 (bfd_byte
*) thdr
.sharedDataOffset
);
732 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataLength
,
733 (bfd_byte
*) thdr
.sharedDataLength
);
735 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupOffset
,
736 (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
738 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupCount
,
739 (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
741 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceOffset
,
742 (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
744 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceCount
,
745 (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
747 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsOffset
,
748 (bfd_byte
*) thdr
.sharedPublicsOffset
);
750 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsCount
,
751 (bfd_byte
*) thdr
.sharedPublicsCount
);
753 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordOffset
,
754 (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
756 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordCount
,
757 (bfd_byte
*) thdr
.sharedDebugRecordCount
);
759 (bfd_vma
) nlm_extended_header (abfd
)->SharedInitializationOffset
,
760 (bfd_byte
*) thdr
.sharedInitializationOffset
);
762 (bfd_vma
) nlm_extended_header (abfd
)->SharedExitProcedureOffset
,
763 (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
765 (bfd_vma
) nlm_extended_header (abfd
)->productID
,
766 (bfd_byte
*) thdr
.productID
);
768 (bfd_vma
) nlm_extended_header (abfd
)->reserved0
,
769 (bfd_byte
*) thdr
.reserved0
);
771 (bfd_vma
) nlm_extended_header (abfd
)->reserved1
,
772 (bfd_byte
*) thdr
.reserved1
);
774 (bfd_vma
) nlm_extended_header (abfd
)->reserved2
,
775 (bfd_byte
*) thdr
.reserved2
);
777 (bfd_vma
) nlm_extended_header (abfd
)->reserved3
,
778 (bfd_byte
*) thdr
.reserved3
);
780 (bfd_vma
) nlm_extended_header (abfd
)->reserved4
,
781 (bfd_byte
*) thdr
.reserved4
);
783 (bfd_vma
) nlm_extended_header (abfd
)->reserved5
,
784 (bfd_byte
*) thdr
.reserved5
);
785 if (bfd_bwrite ((void *) &thdr
, (bfd_size_type
) sizeof (thdr
), abfd
)
790 /* Write out the custom header if there is one. */
791 if (find_nonzero (nlm_custom_header (abfd
),
792 sizeof (Nlm_Internal_Custom_Header
)))
794 Nlm_External_Custom_Header thdr
;
796 bfd_size_type hdrLength
;
798 ds
= find_nonzero (nlm_custom_header (abfd
)->dataStamp
,
799 sizeof (nlm_custom_header (abfd
)->dataStamp
));
800 LITMEMCPY (thdr
.stamp
, "CuStHeAd");
801 hdrLength
= (2 * NLM_TARGET_LONG_SIZE
+ (ds
? 8 : 0)
802 + nlm_custom_header (abfd
)->hdrLength
);
803 put_word (abfd
, hdrLength
, thdr
.length
);
804 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataOffset
,
806 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataLength
,
810 BFD_ASSERT (nlm_custom_header (abfd
)->hdrLength
== 0);
811 amt
= sizeof (thdr
) - sizeof (thdr
.dataStamp
);
812 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
817 memcpy (thdr
.dataStamp
, nlm_custom_header (abfd
)->dataStamp
,
818 sizeof (thdr
.dataStamp
));
820 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
822 amt
= nlm_custom_header (abfd
)->hdrLength
;
823 if (bfd_bwrite (nlm_custom_header (abfd
)->hdr
, amt
, abfd
) != amt
)
828 /* Write out the Cygnus debugging header if there is one. */
829 if (find_nonzero (nlm_cygnus_ext_header (abfd
),
830 sizeof (Nlm_Internal_Cygnus_Ext_Header
)))
832 Nlm_External_Custom_Header thdr
;
834 LITMEMCPY (thdr
.stamp
, "CuStHeAd");
835 put_word (abfd
, (bfd_vma
) 2 * NLM_TARGET_LONG_SIZE
+ 8,
836 (bfd_byte
*) thdr
.length
);
837 put_word (abfd
, (bfd_vma
) nlm_cygnus_ext_header (abfd
)->offset
,
838 (bfd_byte
*) thdr
.dataOffset
);
839 put_word (abfd
, (bfd_vma
) nlm_cygnus_ext_header (abfd
)->length
,
840 (bfd_byte
*) thdr
.dataLength
);
841 LITMEMCPY (thdr
.dataStamp
, "CyGnUsEx");
843 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
850 /* We read the NLM's public symbols and use it to generate a bfd symbol
851 table (hey, it's better than nothing) on a one-for-one basis. Thus
852 use the number of public symbols as the number of bfd symbols we will
853 have once we actually get around to reading them in.
855 Return the number of bytes required to hold the symtab vector, based on
856 the count plus 1, since we will NULL terminate the vector allocated based
860 nlm_get_symtab_upper_bound (bfd
*abfd
)
862 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form. */
864 long symtab_size
= 0;
866 i_fxdhdrp
= nlm_fixed_header (abfd
);
867 symcount
= (i_fxdhdrp
->numberOfPublics
868 + i_fxdhdrp
->numberOfDebugRecords
869 + i_fxdhdrp
->numberOfExternalReferences
);
870 symtab_size
= (symcount
+ 1) * (sizeof (asymbol
));
874 /* Slurp in nlm symbol table.
876 In the external (in-file) form, NLM export records are variable length,
877 with the following form:
879 1 byte length of the symbol name (N)
880 N bytes the symbol name
881 4 bytes the symbol offset from start of it's section
883 We also read in the debugging symbols and import records. Import
884 records are treated as undefined symbols. As we read the import
885 records we also read in the associated reloc information, which is
886 attached to the symbol.
888 The bfd symbols are copied to SYMvoid *S.
890 When we return, the bfd symcount is either zero or contains the correct
891 number of symbols. */
894 nlm_slurp_symbol_table (bfd
*abfd
)
896 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form. */
897 bfd_size_type totsymcount
; /* Number of NLM symbols. */
898 bfd_size_type symcount
; /* Counter of NLM symbols. */
899 nlm_symbol_type
*sym
; /* Pointer to current bfd symbol. */
900 unsigned char symlength
; /* Symbol length read into here. */
901 unsigned char symtype
; /* Type of debugging symbol. */
902 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Symbol offsets read into here. */
903 bfd_boolean (*read_import_func
) (bfd
*, nlm_symbol_type
*);
904 bfd_boolean (*set_public_section_func
) (bfd
*, nlm_symbol_type
*);
907 if (nlm_get_symbols (abfd
) != NULL
)
910 /* Read each raw NLM symbol, using the information to create a canonical bfd
913 Note that we allocate the initial bfd canonical symbol buffer based on a
914 one-to-one mapping of the NLM symbols to canonical symbols. We actually
915 use all the NLM symbols, so there will be no space left over at the end.
916 When we have all the symbols, we build the caller's pointer vector. */
919 i_fxdhdrp
= nlm_fixed_header (abfd
);
920 totsymcount
= (i_fxdhdrp
->numberOfPublics
921 + i_fxdhdrp
->numberOfDebugRecords
922 + i_fxdhdrp
->numberOfExternalReferences
);
923 if (totsymcount
== 0)
926 if (bfd_seek (abfd
, i_fxdhdrp
->publicsOffset
, SEEK_SET
) != 0)
929 amt
= totsymcount
* sizeof (nlm_symbol_type
);
930 sym
= bfd_zalloc (abfd
, amt
);
933 nlm_set_symbols (abfd
, sym
);
935 /* We use the bfd's symcount directly as the control count, so that early
936 termination of the loop leaves the symcount correct for the symbols that
939 set_public_section_func
= nlm_set_public_section_func (abfd
);
940 symcount
= i_fxdhdrp
->numberOfPublics
;
941 while (abfd
->symcount
< symcount
)
943 amt
= sizeof (symlength
);
944 if (bfd_bread ((void *) &symlength
, amt
, abfd
) != amt
)
947 sym
->symbol
.the_bfd
= abfd
;
948 sym
->symbol
.name
= bfd_alloc (abfd
, amt
+ 1);
949 if (!sym
->symbol
.name
)
951 if (bfd_bread ((void *) sym
->symbol
.name
, amt
, abfd
) != amt
)
953 /* Cast away const. */
954 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
956 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
958 sym
->symbol
.flags
= BSF_GLOBAL
| BSF_EXPORT
;
959 sym
->symbol
.value
= get_word (abfd
, temp
);
960 if (set_public_section_func
)
962 /* Most backends can use the code below, but unfortunately
963 some use a different scheme. */
964 if (! (*set_public_section_func
) (abfd
, sym
))
969 if (sym
->symbol
.value
& NLM_HIBIT
)
971 sym
->symbol
.value
&= ~NLM_HIBIT
;
972 sym
->symbol
.flags
|= BSF_FUNCTION
;
973 sym
->symbol
.section
=
974 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
977 sym
->symbol
.section
=
978 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
985 /* Read the debugging records. */
987 if (i_fxdhdrp
->numberOfDebugRecords
> 0)
989 if (bfd_seek (abfd
, i_fxdhdrp
->debugInfoOffset
, SEEK_SET
) != 0)
992 symcount
+= i_fxdhdrp
->numberOfDebugRecords
;
993 while (abfd
->symcount
< symcount
)
995 amt
= sizeof (symtype
);
996 if (bfd_bread ((void *) &symtype
, amt
, abfd
) != amt
)
999 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
1001 amt
= sizeof (symlength
);
1002 if (bfd_bread ((void *) &symlength
, amt
, abfd
) != amt
)
1005 sym
->symbol
.the_bfd
= abfd
;
1006 sym
->symbol
.name
= bfd_alloc (abfd
, amt
+ 1);
1007 if (!sym
->symbol
.name
)
1009 if (bfd_bread ((void *) sym
->symbol
.name
, amt
, abfd
) != amt
)
1011 /* Cast away const. */
1012 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
1013 sym
->symbol
.flags
= BSF_LOCAL
;
1014 sym
->symbol
.value
= get_word (abfd
, temp
);
1017 sym
->symbol
.section
=
1018 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
1019 else if (symtype
== 1)
1021 sym
->symbol
.flags
|= BSF_FUNCTION
;
1022 sym
->symbol
.section
=
1023 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
1026 sym
->symbol
.section
= bfd_abs_section_ptr
;
1034 /* Read in the import records. We can only do this if we know how
1035 to read relocs for this target. */
1036 read_import_func
= nlm_read_import_func (abfd
);
1037 if (read_import_func
!= NULL
)
1039 if (bfd_seek (abfd
, i_fxdhdrp
->externalReferencesOffset
, SEEK_SET
) != 0)
1042 symcount
+= i_fxdhdrp
->numberOfExternalReferences
;
1043 while (abfd
->symcount
< symcount
)
1045 if (! (*read_import_func
) (abfd
, sym
))
1055 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
1056 symbol table fails. */
1059 nlm_canonicalize_symtab (bfd
*abfd
, asymbol
**alocation
)
1061 nlm_symbol_type
*symbase
;
1062 bfd_size_type counter
= 0;
1064 if (! nlm_slurp_symbol_table (abfd
))
1066 symbase
= nlm_get_symbols (abfd
);
1067 while (counter
< bfd_get_symcount (abfd
))
1069 *alocation
++ = &symbase
->symbol
;
1074 return bfd_get_symcount (abfd
);
1077 /* Make an NLM symbol. There is nothing special to do here. */
1080 nlm_make_empty_symbol (bfd
*abfd
)
1082 bfd_size_type amt
= sizeof (nlm_symbol_type
);
1083 nlm_symbol_type
*new = bfd_zalloc (abfd
, amt
);
1087 new->symbol
.the_bfd
= abfd
;
1088 return & new->symbol
;
1091 /* Get symbol information. */
1094 nlm_get_symbol_info (bfd
*ignore_abfd ATTRIBUTE_UNUSED
,
1098 bfd_symbol_info (symbol
, ret
);
1101 /* Print symbol information. */
1104 nlm_print_symbol (bfd
*abfd
,
1107 bfd_print_symbol_type how
)
1109 FILE *file
= (FILE *) afile
;
1113 case bfd_print_symbol_name
:
1114 case bfd_print_symbol_more
:
1116 fprintf (file
, "%s", symbol
->name
);
1118 case bfd_print_symbol_all
:
1119 bfd_print_symbol_vandf (abfd
, (void *) file
, symbol
);
1120 fprintf (file
, " %-5s", symbol
->section
->name
);
1122 fprintf (file
, " %s", symbol
->name
);
1127 /* Get the relocs for an NLM file. There are two types of relocs.
1128 Imports are relocs against symbols defined in other NLM files. We
1129 treat these as relocs against global symbols. Relocation fixups
1130 are internal relocs.
1132 The actual format used to store the relocs is machine specific. */
1134 /* Read in the relocation fixup information. This is stored in
1135 nlm_relocation_fixups, an array of arelent structures, and
1136 nlm_relocation_fixup_secs, an array of section pointers. The
1137 section pointers are needed because the relocs are not sorted by
1141 nlm_slurp_reloc_fixups (bfd
*abfd
)
1143 bfd_boolean (*read_func
) (bfd
*, nlm_symbol_type
*, asection
**, arelent
*);
1144 bfd_size_type count
, amt
;
1148 if (nlm_relocation_fixups (abfd
) != NULL
)
1150 read_func
= nlm_read_reloc_func (abfd
);
1151 if (read_func
== NULL
)
1154 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1158 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1159 amt
= count
* sizeof (arelent
);
1160 rels
= bfd_alloc (abfd
, amt
);
1161 amt
= count
* sizeof (asection
*);
1162 secs
= bfd_alloc (abfd
, amt
);
1163 if ((rels
== NULL
|| secs
== NULL
) && count
!= 0)
1165 nlm_relocation_fixups (abfd
) = rels
;
1166 nlm_relocation_fixup_secs (abfd
) = secs
;
1168 /* We have to read piece by piece, because we don't know how large
1169 the machine specific reloc information is. */
1170 while (count
-- != 0)
1172 if (! (*read_func
) (abfd
, NULL
, secs
, rels
))
1174 nlm_relocation_fixups (abfd
) = NULL
;
1175 nlm_relocation_fixup_secs (abfd
) = NULL
;
1185 /* Get the number of relocs. This really just returns an upper bound,
1186 since it does not attempt to distinguish them based on the section.
1187 That will be handled when they are actually read. */
1190 nlm_get_reloc_upper_bound (bfd
*abfd
, asection
*sec
)
1192 nlm_symbol_type
*syms
;
1193 bfd_size_type count
;
1196 /* If we don't know how to read relocs, just return 0. */
1197 if (nlm_read_reloc_func (abfd
) == NULL
)
1199 /* Make sure we have either the code or the data section. */
1200 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1203 syms
= nlm_get_symbols (abfd
);
1206 if (! nlm_slurp_symbol_table (abfd
))
1208 syms
= nlm_get_symbols (abfd
);
1211 ret
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1213 count
= bfd_get_symcount (abfd
);
1214 while (count
-- != 0)
1220 return (ret
+ 1) * sizeof (arelent
*);
1223 /* Get the relocs themselves. */
1226 nlm_canonicalize_reloc (bfd
*abfd
,
1233 bfd_size_type count
, i
;
1236 /* Get the relocation fixups. */
1237 rels
= nlm_relocation_fixups (abfd
);
1240 if (! nlm_slurp_reloc_fixups (abfd
))
1242 rels
= nlm_relocation_fixups (abfd
);
1244 secs
= nlm_relocation_fixup_secs (abfd
);
1247 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1248 for (i
= 0; i
< count
; i
++, rels
++, secs
++)
1257 /* Get the import symbols. */
1258 count
= bfd_get_symcount (abfd
);
1259 for (i
= 0; i
< count
; i
++, symbols
++)
1264 if (bfd_asymbol_flavour (sym
) == bfd_target_nlm_flavour
)
1266 nlm_symbol_type
*nlm_sym
;
1269 nlm_sym
= (nlm_symbol_type
*) sym
;
1270 for (j
= 0; j
< nlm_sym
->rcnt
; j
++)
1272 if (nlm_sym
->relocs
[j
].section
== sec
)
1274 *relptr
= &nlm_sym
->relocs
[j
].reloc
;
1275 (*relptr
)->sym_ptr_ptr
= symbols
;
1288 /* Compute the section file positions for an NLM file. All variable
1289 length data in the file headers must be set before this function is
1290 called. If the variable length data is changed later, the
1291 resulting object file will be incorrect. Unfortunately, there is
1292 no way to check this.
1294 This routine also sets the Size and Offset fields in the fixed
1297 It also looks over the symbols and moves any common symbols into
1298 the .bss section; NLM has no way to represent a common symbol.
1299 This approach means that either the symbols must already have been
1300 set at this point, or there must be no common symbols. We need to
1301 move the symbols at this point so that mangle_relocs can see the
1305 nlm_compute_section_file_positions (bfd
*abfd
)
1309 bfd_vma text
, data
, bss
;
1310 bfd_vma text_low
, data_low
;
1311 unsigned int text_align
, data_align
, other_align
;
1312 file_ptr text_ptr
, data_ptr
, other_ptr
;
1314 asymbol
**sym_ptr_ptr
;
1316 if (abfd
->output_has_begun
)
1319 /* Make sure we have a section to hold uninitialized data. */
1320 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1321 if (bss_sec
== NULL
)
1323 if (!add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
1324 (file_ptr
) 0, (bfd_size_type
) 0,
1327 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1330 abfd
->output_has_begun
= TRUE
;
1332 /* The fixed header. */
1333 sofar
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1335 /* The variable header. */
1336 sofar
+= (sizeof (nlm_variable_header (abfd
)->descriptionLength
)
1337 + nlm_variable_header (abfd
)->descriptionLength
+ 1
1338 + NLM_TARGET_LONG_SIZE
/* stackSize */
1339 + NLM_TARGET_LONG_SIZE
/* reserved */
1340 + sizeof (nlm_variable_header (abfd
)->oldThreadName
)
1341 + sizeof (nlm_variable_header (abfd
)->screenNameLength
)
1342 + nlm_variable_header (abfd
)->screenNameLength
+ 1
1343 + sizeof (nlm_variable_header (abfd
)->threadNameLength
)
1344 + nlm_variable_header (abfd
)->threadNameLength
+ 1);
1346 /* The auxiliary headers. */
1347 if (find_nonzero (nlm_version_header (abfd
),
1348 sizeof (Nlm_Internal_Version_Header
)))
1349 sofar
+= sizeof (Nlm_External_Version_Header
);
1350 if (find_nonzero (nlm_extended_header (abfd
),
1351 sizeof (Nlm_Internal_Extended_Header
)))
1352 sofar
+= sizeof (Nlm_External_Extended_Header
);
1353 if (find_nonzero (nlm_copyright_header (abfd
),
1354 sizeof (Nlm_Internal_Copyright_Header
)))
1355 sofar
+= (sizeof (Nlm_External_Copyright_Header
)
1356 + nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1);
1357 if (find_nonzero (nlm_custom_header (abfd
),
1358 sizeof (Nlm_Internal_Custom_Header
)))
1359 sofar
+= (sizeof (Nlm_External_Custom_Header
)
1360 + nlm_custom_header (abfd
)->hdrLength
);
1361 if (find_nonzero (nlm_cygnus_ext_header (abfd
),
1362 sizeof (Nlm_Internal_Cygnus_Ext_Header
)))
1363 sofar
+= sizeof (Nlm_External_Custom_Header
);
1365 /* Compute the section file positions in two passes. First get the
1366 sizes of the text and data sections, and then set the file
1367 positions. This code aligns the sections in the file using the
1368 same alignment restrictions that apply to the sections in memory;
1369 this may not be necessary. */
1371 text_low
= (bfd_vma
) - 1;
1374 data_low
= (bfd_vma
) - 1;
1378 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1382 sec
->size
= BFD_ALIGN (sec
->size
, 1 << sec
->alignment_power
);
1384 f
= bfd_get_section_flags (abfd
, sec
);
1388 if (bfd_get_section_vma (abfd
, sec
) < text_low
)
1389 text_low
= bfd_get_section_vma (abfd
, sec
);
1390 if (sec
->alignment_power
> text_align
)
1391 text_align
= sec
->alignment_power
;
1393 else if (f
& SEC_DATA
)
1396 if (bfd_get_section_vma (abfd
, sec
) < data_low
)
1397 data_low
= bfd_get_section_vma (abfd
, sec
);
1398 if (sec
->alignment_power
> data_align
)
1399 data_align
= sec
->alignment_power
;
1401 else if (f
& SEC_HAS_CONTENTS
)
1403 if (sec
->alignment_power
> other_align
)
1404 other_align
= sec
->alignment_power
;
1406 else if (f
& SEC_ALLOC
)
1410 nlm_set_text_low (abfd
, text_low
);
1411 nlm_set_data_low (abfd
, data_low
);
1413 if (nlm_no_uninitialized_data (abfd
))
1415 /* This NetWare format does not use uninitialized data. We must
1416 increase the size of the data section. We will never wind up
1417 writing those file locations, so they will remain zero. */
1422 text_ptr
= BFD_ALIGN (sofar
, 1 << text_align
);
1423 data_ptr
= BFD_ALIGN (text_ptr
+ text
, 1 << data_align
);
1424 other_ptr
= BFD_ALIGN (data_ptr
+ data
, 1 << other_align
);
1426 /* Fill in some fields in the header for which we now have the
1428 nlm_fixed_header (abfd
)->codeImageOffset
= text_ptr
;
1429 nlm_fixed_header (abfd
)->codeImageSize
= text
;
1430 nlm_fixed_header (abfd
)->dataImageOffset
= data_ptr
;
1431 nlm_fixed_header (abfd
)->dataImageSize
= data
;
1432 nlm_fixed_header (abfd
)->uninitializedDataSize
= bss
;
1434 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1438 f
= bfd_get_section_flags (abfd
, sec
);
1442 sec
->filepos
= text_ptr
;
1443 text_ptr
+= sec
->size
;
1445 else if (f
& SEC_DATA
)
1447 sec
->filepos
= data_ptr
;
1448 data_ptr
+= sec
->size
;
1450 else if (f
& SEC_HAS_CONTENTS
)
1452 sec
->filepos
= other_ptr
;
1453 other_ptr
+= sec
->size
;
1457 nlm_fixed_header (abfd
)->relocationFixupOffset
= other_ptr
;
1459 /* Move all common symbols into the .bss section. */
1461 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1462 if (sym_ptr_ptr
!= NULL
)
1467 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1469 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1476 if (!bfd_is_com_section (bfd_get_section (sym
)))
1479 /* Put the common symbol in the .bss section, and increase
1480 the size of the .bss section by the size of the common
1481 symbol (which is the old value of the symbol). */
1482 sym
->section
= bss_sec
;
1484 sym
->value
= bss_sec
->size
+ add
;
1486 add
= BFD_ALIGN (add
, 1 << bss_sec
->alignment_power
);
1490 if (nlm_no_uninitialized_data (abfd
))
1492 /* We could handle this case, but so far it hasn't been
1496 nlm_fixed_header (abfd
)->uninitializedDataSize
+= add
;
1497 bss_sec
->size
+= add
;
1504 /* Set the contents of a section. To do this we need to know where
1505 the section is going to be located in the output file. That means
1506 that the sizes of all the sections must be set, and all the
1507 variable size header information must be known. */
1510 nlm_set_section_contents (bfd
*abfd
,
1512 const void * location
,
1514 bfd_size_type count
)
1516 if (! abfd
->output_has_begun
1517 && ! nlm_compute_section_file_positions (abfd
))
1523 /* i386 NetWare has a very restricted set of relocs. In order for
1524 objcopy to work, the NLM i386 backend needs a chance to rework
1525 the section contents so that its set of relocs will work. If all
1526 the relocs are already acceptable, this will not do anything. */
1527 if (section
->reloc_count
!= 0)
1529 bfd_boolean (*mangle_relocs_func
)
1530 (bfd
*, asection
*, const void *, bfd_vma
, bfd_size_type
);
1532 mangle_relocs_func
= nlm_mangle_relocs_func (abfd
);
1533 if (mangle_relocs_func
!= NULL
)
1535 if (!(*mangle_relocs_func
) (abfd
, section
, location
,
1536 (bfd_vma
) offset
, count
))
1541 if (bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
) != 0
1542 || bfd_bwrite (location
, count
, abfd
) != count
)
1548 /* We need to sort a list of relocs associated with sections when we
1549 write out the external relocs. */
1552 nlm_external_reloc_compare (const void *p1
, const void *p2
)
1554 const struct reloc_and_sec
*r1
= (const struct reloc_and_sec
*) p1
;
1555 const struct reloc_and_sec
*r2
= (const struct reloc_and_sec
*) p2
;
1558 cmp
= strcmp ((*r1
->rel
->sym_ptr_ptr
)->name
,
1559 (*r2
->rel
->sym_ptr_ptr
)->name
);
1563 /* We sort by address within symbol to make the sort more stable and
1564 increase the chances that different hosts will generate bit for
1565 bit equivalent results. */
1566 return (int) (r1
->rel
->address
- r2
->rel
->address
);
1569 /* Write out an NLM file. We write out the information in this order:
1575 other sections (custom data, messages, help, shared NLM, RPC,
1576 module dependencies)
1578 external references (imports)
1579 public symbols (exports)
1581 This is similar to the order used by the NetWare tools; the
1582 difference is that NetWare puts the sections other than code, data
1583 and custom data at the end of the NLM. It is convenient for us to
1584 know where the sections are going to be before worrying about the
1585 size of the other information.
1587 By the time this function is called, all the section data should
1588 have been output using set_section_contents. Note that custom
1589 data, the message file, the help file, the shared NLM file, the RPC
1590 data, and the module dependencies are all considered to be
1591 sections; the caller is responsible for filling in the offset and
1592 length fields in the NLM headers. The relocation fixups and
1593 imports are both obtained from the list of relocs attached to each
1594 section. The exports and debugging records are obtained from the
1595 list of outsymbols. */
1598 nlm_write_object_contents (bfd
*abfd
)
1601 bfd_boolean (*write_import_func
) (bfd
*, asection
*, arelent
*);
1602 bfd_size_type external_reloc_count
, internal_reloc_count
, i
, c
;
1603 struct reloc_and_sec
*external_relocs
;
1604 asymbol
**sym_ptr_ptr
;
1606 bfd_boolean (*write_prefix_func
) (bfd
*);
1607 unsigned char *fixed_header
= NULL
;
1611 fixed_header
= bfd_malloc (nlm_fixed_header_size (abfd
));
1612 if (fixed_header
== NULL
)
1615 if (! abfd
->output_has_begun
1616 && ! nlm_compute_section_file_positions (abfd
))
1619 /* Write out the variable length headers. */
1620 pos
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1621 if (bfd_seek (abfd
, pos
, SEEK_SET
) != 0)
1623 if (! nlm_swap_variable_header_out (abfd
)
1624 || ! nlm_swap_auxiliary_headers_out (abfd
))
1626 bfd_set_error (bfd_error_system_call
);
1630 /* A weak check on whether the section file positions were
1632 if (bfd_tell (abfd
) > nlm_fixed_header (abfd
)->codeImageOffset
)
1634 bfd_set_error (bfd_error_invalid_operation
);
1638 /* Advance to the relocs. */
1639 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1643 /* The format of the relocation entries is dependent upon the
1644 particular target. We use an external routine to write the reloc
1646 write_import_func
= nlm_write_import_func (abfd
);
1648 /* Write out the internal relocation fixups. While we're looping
1649 over the relocs, we also count the external relocs, which is
1650 needed when they are written out below. */
1651 internal_reloc_count
= 0;
1652 external_reloc_count
= 0;
1653 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1655 arelent
**rel_ptr_ptr
, **rel_end
;
1657 if (sec
->reloc_count
== 0)
1660 /* We can only represent relocs within a code or data
1661 section. We ignore them for a debugging section. */
1662 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1665 /* We need to know how to write out imports */
1666 if (write_import_func
== NULL
)
1668 bfd_set_error (bfd_error_invalid_operation
);
1672 rel_ptr_ptr
= sec
->orelocation
;
1673 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1674 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1680 sym
= *rel
->sym_ptr_ptr
;
1682 if (! bfd_is_und_section (bfd_get_section (sym
)))
1684 ++internal_reloc_count
;
1685 if (! (*write_import_func
) (abfd
, sec
, rel
))
1689 ++external_reloc_count
;
1692 nlm_fixed_header (abfd
)->numberOfRelocationFixups
= internal_reloc_count
;
1694 /* Write out the imports (relocs against external symbols). These
1695 are output as a symbol name followed by all the relocs for that
1696 symbol, so we must first gather together all the relocs against
1697 external symbols and sort them. */
1698 amt
= external_reloc_count
* sizeof (struct reloc_and_sec
);
1699 external_relocs
= bfd_alloc (abfd
, amt
);
1700 if (external_relocs
== NULL
)
1703 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1705 arelent
**rel_ptr_ptr
, **rel_end
;
1707 if (sec
->reloc_count
== 0)
1710 rel_ptr_ptr
= sec
->orelocation
;
1711 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1712 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1718 sym
= *rel
->sym_ptr_ptr
;
1720 if (! bfd_is_und_section (bfd_get_section (sym
)))
1723 external_relocs
[i
].rel
= rel
;
1724 external_relocs
[i
].sec
= sec
;
1729 BFD_ASSERT (i
== external_reloc_count
);
1731 /* Sort the external relocs by name. */
1732 qsort (external_relocs
, (size_t) external_reloc_count
,
1733 sizeof (struct reloc_and_sec
), nlm_external_reloc_compare
);
1735 /* Write out the external relocs. */
1736 nlm_fixed_header (abfd
)->externalReferencesOffset
= bfd_tell (abfd
);
1739 while (i
< external_reloc_count
)
1743 bfd_size_type j
, cnt
;
1747 rel
= external_relocs
[i
].rel
;
1748 sym
= *rel
->sym_ptr_ptr
;
1752 (j
< external_reloc_count
1753 && *external_relocs
[j
].rel
->sym_ptr_ptr
== sym
);
1757 if (! (*nlm_write_external_func (abfd
)) (abfd
, cnt
, sym
,
1758 &external_relocs
[i
]))
1764 nlm_fixed_header (abfd
)->numberOfExternalReferences
= c
;
1766 /* Write out the public symbols (exports). */
1767 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1768 if (sym_ptr_ptr
!= NULL
)
1770 bfd_vma (*get_public_offset_func
) (bfd
*, asymbol
*);
1771 bfd_boolean (*write_export_func
) (bfd
*, asymbol
*, bfd_vma
);
1775 nlm_fixed_header (abfd
)->publicsOffset
= bfd_tell (abfd
);
1776 get_public_offset_func
= nlm_get_public_offset_func (abfd
);
1777 write_export_func
= nlm_write_export_func (abfd
);
1779 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1780 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1785 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1789 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) == 0
1790 || bfd_is_und_section (bfd_get_section (sym
)))
1795 if (get_public_offset_func
)
1797 /* Most backends can use the code below, but
1798 unfortunately some use a different scheme. */
1799 offset
= (*get_public_offset_func
) (abfd
, sym
);
1803 offset
= bfd_asymbol_value (sym
);
1805 if (sec
->flags
& SEC_CODE
)
1807 offset
-= nlm_get_text_low (abfd
);
1808 offset
|= NLM_HIBIT
;
1810 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1812 /* SEC_ALLOC is for the .bss section. */
1813 offset
-= nlm_get_data_low (abfd
);
1817 /* We can't handle an exported symbol that is not in
1818 the code or data segment. */
1819 bfd_set_error (bfd_error_invalid_operation
);
1824 if (write_export_func
)
1826 if (! (*write_export_func
) (abfd
, sym
, offset
))
1831 len
= strlen (sym
->name
);
1832 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1833 != sizeof (bfd_byte
))
1834 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
1837 put_word (abfd
, offset
, temp
);
1838 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
)
1843 nlm_fixed_header (abfd
)->numberOfPublics
= c
;
1845 /* Write out the debugging records. The NLM conversion program
1846 wants to be able to inhibit this, so as a special hack if
1847 debugInfoOffset is set to -1 we don't write any debugging
1848 information. This can not be handled by fiddling with the
1849 symbol table, because exported symbols appear in both the
1850 exported symbol list and the debugging information. */
1851 if (nlm_fixed_header (abfd
)->debugInfoOffset
== (file_ptr
) - 1)
1853 nlm_fixed_header (abfd
)->debugInfoOffset
= 0;
1854 nlm_fixed_header (abfd
)->numberOfDebugRecords
= 0;
1858 nlm_fixed_header (abfd
)->debugInfoOffset
= bfd_tell (abfd
);
1860 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1861 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1862 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1867 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1871 /* The NLM notion of a debugging symbol is actually what
1872 BFD calls a local or global symbol. What BFD calls a
1873 debugging symbol NLM does not understand at all. */
1874 if ((sym
->flags
& (BSF_LOCAL
| BSF_GLOBAL
| BSF_EXPORT
)) == 0
1875 || (sym
->flags
& BSF_DEBUGGING
) != 0
1876 || bfd_is_und_section (bfd_get_section (sym
)))
1881 offset
= bfd_asymbol_value (sym
);
1883 if (sec
->flags
& SEC_CODE
)
1885 offset
-= nlm_get_text_low (abfd
);
1888 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1890 /* SEC_ALLOC is for the .bss section. */
1891 offset
-= nlm_get_data_low (abfd
);
1897 /* The type is 0 for data, 1 for code, 2 for absolute. */
1898 if (bfd_bwrite (&type
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1899 != sizeof (bfd_byte
))
1902 put_word (abfd
, offset
, temp
);
1903 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
)
1907 len
= strlen (sym
->name
);
1908 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1909 != sizeof (bfd_byte
))
1910 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
1913 nlm_fixed_header (abfd
)->numberOfDebugRecords
= c
;
1917 /* NLMLINK fills in offset values even if there is no data, so we do
1919 last
= bfd_tell (abfd
);
1920 if (nlm_fixed_header (abfd
)->codeImageOffset
== 0)
1921 nlm_fixed_header (abfd
)->codeImageOffset
= last
;
1922 if (nlm_fixed_header (abfd
)->dataImageOffset
== 0)
1923 nlm_fixed_header (abfd
)->dataImageOffset
= last
;
1924 if (nlm_fixed_header (abfd
)->customDataOffset
== 0)
1925 nlm_fixed_header (abfd
)->customDataOffset
= last
;
1926 if (nlm_fixed_header (abfd
)->moduleDependencyOffset
== 0)
1927 nlm_fixed_header (abfd
)->moduleDependencyOffset
= last
;
1928 if (nlm_fixed_header (abfd
)->relocationFixupOffset
== 0)
1929 nlm_fixed_header (abfd
)->relocationFixupOffset
= last
;
1930 if (nlm_fixed_header (abfd
)->externalReferencesOffset
== 0)
1931 nlm_fixed_header (abfd
)->externalReferencesOffset
= last
;
1932 if (nlm_fixed_header (abfd
)->publicsOffset
== 0)
1933 nlm_fixed_header (abfd
)->publicsOffset
= last
;
1934 if (nlm_fixed_header (abfd
)->debugInfoOffset
== 0)
1935 nlm_fixed_header (abfd
)->debugInfoOffset
= last
;
1937 /* At this point everything has been written out except the fixed
1939 memcpy (nlm_fixed_header (abfd
)->signature
, nlm_signature (abfd
),
1940 NLM_SIGNATURE_SIZE
);
1941 nlm_fixed_header (abfd
)->version
= NLM_HEADER_VERSION
;
1942 nlm_fixed_header (abfd
)->codeStartOffset
=
1943 (bfd_get_start_address (abfd
)
1944 - nlm_get_text_low (abfd
));
1946 /* We have no convenient way for the caller to pass in the exit
1947 procedure or the check unload procedure, so the caller must set
1948 the values in the header to the values of the symbols. */
1949 nlm_fixed_header (abfd
)->exitProcedureOffset
-= nlm_get_text_low (abfd
);
1950 if (nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
!= 0)
1951 nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
-=
1952 nlm_get_text_low (abfd
);
1954 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0)
1957 write_prefix_func
= nlm_write_prefix_func (abfd
);
1958 if (write_prefix_func
)
1960 if (! (*write_prefix_func
) (abfd
))
1964 BFD_ASSERT ((bfd_size_type
) bfd_tell (abfd
)
1965 == nlm_optional_prefix_size (abfd
));
1967 nlm_swap_fixed_header_out (abfd
, nlm_fixed_header (abfd
), fixed_header
);
1968 if (bfd_bwrite (fixed_header
, nlm_fixed_header_size (abfd
), abfd
)
1969 != nlm_fixed_header_size (abfd
))
1972 if (fixed_header
!= NULL
)
1973 free (fixed_header
);
1977 if (fixed_header
!= NULL
)
1978 free (fixed_header
);