1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright (C) 1993-2017 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 /* See PR 21840 for a reproducer. */
355 if (hdrLength
!= 0 || hdr
!= NULL
)
358 pos
= bfd_tell (abfd
);
359 if (bfd_seek (abfd
, dataOffset
, SEEK_SET
) != 0)
361 contents
= bfd_alloc (abfd
, dataLength
);
362 if (contents
== NULL
)
364 if (bfd_bread (contents
, dataLength
, abfd
) != dataLength
)
366 if (bfd_seek (abfd
, pos
, SEEK_SET
) != 0)
369 LITMEMCPY (nlm_cygnus_ext_header (abfd
), "CyGnUsEx");
370 nlm_cygnus_ext_header (abfd
)->offset
= dataOffset
;
371 nlm_cygnus_ext_header (abfd
)->length
= dataLength
;
373 /* This data this header points to provides a list of
374 the sections which were in the original object file
375 which was converted to become an NLM. We locate
376 those sections and add them to the BFD. Note that
377 this is likely to create a second .text, .data and
378 .bss section; retrieving the sections by name will
379 get the actual NLM sections, which is what we want to
380 happen. The sections from the original file, which
381 may be subsets of the NLM section, can only be found
382 using bfd_map_over_sections. */
384 pend
= p
+ dataLength
;
393 /* The format of this information is
394 null terminated section name
395 zeroes to adjust to 4 byte boundary
396 4 byte section data file pointer
397 4 byte section size. */
400 l
= strlen (name
) + 1;
401 l
= (l
+ 3) &~ (size_t) 3;
403 filepos
= H_GET_32 (abfd
, p
);
405 size
= H_GET_32 (abfd
, p
);
408 newsec
= bfd_make_section_anyway (abfd
, name
);
414 newsec
->filepos
= filepos
;
415 newsec
->flags
|= SEC_HAS_CONTENTS
;
421 memcpy (nlm_custom_header (abfd
)->stamp
, thdr
.stamp
,
422 sizeof (thdr
.stamp
));
423 nlm_custom_header (abfd
)->hdrLength
= hdrLength
;
424 nlm_custom_header (abfd
)->dataOffset
= dataOffset
;
425 nlm_custom_header (abfd
)->dataLength
= dataLength
;
426 memcpy (nlm_custom_header (abfd
)->dataStamp
, dataStamp
,
428 nlm_custom_header (abfd
)->hdr
= hdr
;
438 nlm_object_p (bfd
*abfd
)
440 struct nlm_obj_tdata
*preserved_tdata
= nlm_tdata (abfd
);
441 bfd_boolean (*backend_object_p
) (bfd
*);
442 void * x_fxdhdr
= NULL
;
443 Nlm_Internal_Fixed_Header
*i_fxdhdrp
;
444 struct nlm_obj_tdata
*new_tdata
= NULL
;
445 const char *signature
;
446 enum bfd_architecture arch
;
449 /* Some NLM formats have a prefix before the standard NLM fixed
451 backend_object_p
= nlm_backend_object_p_func (abfd
);
452 if (backend_object_p
)
454 if (!(*backend_object_p
) (abfd
))
455 goto got_wrong_format_error
;
458 /* Read in the fixed length portion of the NLM header in external format. */
459 amt
= nlm_fixed_header_size (abfd
);
460 x_fxdhdr
= bfd_malloc (amt
);
461 if (x_fxdhdr
== NULL
)
464 if (bfd_bread ((void *) x_fxdhdr
, amt
, abfd
) != amt
)
466 if (bfd_get_error () != bfd_error_system_call
)
467 goto got_wrong_format_error
;
472 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
473 the tdata pointer in the bfd. */
474 amt
= sizeof (struct nlm_obj_tdata
);
475 new_tdata
= bfd_zalloc (abfd
, amt
);
476 if (new_tdata
== NULL
)
479 nlm_tdata (abfd
) = new_tdata
;
481 i_fxdhdrp
= nlm_fixed_header (abfd
);
482 nlm_swap_fixed_header_in (abfd
, x_fxdhdr
, i_fxdhdrp
);
486 /* Check to see if we have an NLM file for this backend by matching
487 the NLM signature. */
488 signature
= nlm_signature (abfd
);
489 if (signature
!= NULL
490 && *signature
!= '\0'
491 && strncmp ((char *) i_fxdhdrp
->signature
, signature
,
492 NLM_SIGNATURE_SIZE
) != 0)
493 goto got_wrong_format_error
;
495 /* There's no supported way to discover the endianness of an NLM, so test for
496 a sane version number after doing byte swapping appropriate for this
497 XVEC. (Hack alert!) */
498 if (i_fxdhdrp
->version
> 0xFFFF)
499 goto got_wrong_format_error
;
501 /* There's no supported way to check for 32 bit versus 64 bit addresses,
502 so ignore this distinction for now. (FIXME) */
503 /* Swap in the rest of the required header. */
504 if (!nlm_swap_variable_header_in (abfd
))
506 if (bfd_get_error () != bfd_error_system_call
)
507 goto got_wrong_format_error
;
512 /* Add the sections supplied by all NLM's, and then read in the
513 auxiliary headers. Reading the auxiliary headers may create
514 additional sections described in the cygnus_ext header.
515 From this point on we assume that we have an NLM, and do not
516 treat errors as indicating the wrong format. */
517 if (!add_bfd_section (abfd
, NLM_CODE_NAME
,
518 i_fxdhdrp
->codeImageOffset
,
519 i_fxdhdrp
->codeImageSize
,
520 (SEC_CODE
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
522 || !add_bfd_section (abfd
, NLM_INITIALIZED_DATA_NAME
,
523 i_fxdhdrp
->dataImageOffset
,
524 i_fxdhdrp
->dataImageSize
,
525 (SEC_DATA
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
527 || !add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
529 i_fxdhdrp
->uninitializedDataSize
,
533 if (!nlm_swap_auxiliary_headers_in (abfd
))
536 if (nlm_fixed_header (abfd
)->numberOfRelocationFixups
!= 0
537 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
538 abfd
->flags
|= HAS_RELOC
;
539 if (nlm_fixed_header (abfd
)->numberOfPublics
!= 0
540 || nlm_fixed_header (abfd
)->numberOfDebugRecords
!= 0
541 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
542 abfd
->flags
|= HAS_SYMS
;
544 arch
= nlm_architecture (abfd
);
545 if (arch
!= bfd_arch_unknown
)
546 bfd_default_set_arch_mach (abfd
, arch
, (unsigned long) 0);
548 abfd
->flags
|= EXEC_P
;
549 bfd_get_start_address (abfd
) = nlm_fixed_header (abfd
)->codeStartOffset
;
553 got_wrong_format_error
:
554 bfd_set_error (bfd_error_wrong_format
);
556 nlm_tdata (abfd
) = preserved_tdata
;
557 if (new_tdata
!= NULL
)
558 bfd_release (abfd
, new_tdata
);
559 if (x_fxdhdr
!= NULL
)
565 /* Swap and write out the variable length header. All the fields must
566 exist in the NLM, and must exist in this order. */
569 nlm_swap_variable_header_out (bfd
*abfd
)
571 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
574 /* Write the description length and text members. */
575 amt
= sizeof (nlm_variable_header (abfd
)->descriptionLength
);
576 if (bfd_bwrite (& nlm_variable_header (abfd
)->descriptionLength
, amt
,
579 amt
= nlm_variable_header (abfd
)->descriptionLength
+ 1;
580 if (bfd_bwrite ((void *) nlm_variable_header (abfd
)->descriptionText
, amt
,
584 /* Convert and write the stackSize field. */
585 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->stackSize
, temp
);
587 if (bfd_bwrite (temp
, amt
, abfd
) != amt
)
590 /* Convert and write the reserved field. */
591 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->reserved
, temp
);
593 if (bfd_bwrite (temp
, amt
, abfd
) != amt
)
596 /* Write the oldThreadName field. This field is a fixed length string. */
597 amt
= sizeof (nlm_variable_header (abfd
)->oldThreadName
);
598 if (bfd_bwrite (nlm_variable_header (abfd
)->oldThreadName
, amt
,
602 /* Write the screen name length and text members. */
603 amt
= sizeof (nlm_variable_header (abfd
)->screenNameLength
);
604 if (bfd_bwrite (& nlm_variable_header (abfd
)->screenNameLength
, amt
,
607 amt
= nlm_variable_header (abfd
)->screenNameLength
+ 1;
608 if (bfd_bwrite (nlm_variable_header (abfd
)->screenName
, amt
, abfd
) != amt
)
611 /* Write the thread name length and text members. */
612 amt
= sizeof (nlm_variable_header (abfd
)->threadNameLength
);
613 if (bfd_bwrite (& nlm_variable_header (abfd
)->threadNameLength
, amt
,
616 amt
= nlm_variable_header (abfd
)->threadNameLength
+ 1;
617 if (bfd_bwrite (nlm_variable_header (abfd
)->threadName
, amt
, abfd
) != amt
)
622 /* Return whether there is a non-zero byte in a memory block. */
625 find_nonzero (void * buf
, size_t size
)
627 char *p
= (char *) buf
;
635 /* Swap out the contents of the auxiliary headers. We create those
636 auxiliary headers which have been set non-zero. We do not require
637 the caller to set up the stamp fields. */
640 nlm_swap_auxiliary_headers_out (bfd
*abfd
)
644 /* Write out the version header if there is one. */
645 if (find_nonzero (nlm_version_header (abfd
),
646 sizeof (Nlm_Internal_Version_Header
)))
648 Nlm_External_Version_Header thdr
;
650 LITMEMCPY (thdr
.stamp
, "VeRsIoN#");
651 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->majorVersion
,
652 (bfd_byte
*) thdr
.majorVersion
);
653 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->minorVersion
,
654 (bfd_byte
*) thdr
.minorVersion
);
655 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->revision
,
656 (bfd_byte
*) thdr
.revision
);
657 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->year
,
658 (bfd_byte
*) thdr
.year
);
659 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->month
,
660 (bfd_byte
*) thdr
.month
);
661 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->day
,
662 (bfd_byte
*) thdr
.day
);
663 if (bfd_bwrite ((void *) &thdr
, (bfd_size_type
) sizeof (thdr
), abfd
)
668 /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
669 tag in order to make the NW4.x and NW5.x loaders happy. */
671 /* Write out the copyright header if there is one. */
672 if (find_nonzero (nlm_copyright_header (abfd
),
673 sizeof (Nlm_Internal_Copyright_Header
)))
675 Nlm_External_Copyright_Header thdr
;
677 LITMEMCPY (thdr
.stamp
, "CoPyRiGhT=");
678 amt
= sizeof (thdr
.stamp
);
679 if (bfd_bwrite ((void *) thdr
.stamp
, amt
, abfd
) != amt
)
681 thdr
.copyrightMessageLength
[0] =
682 nlm_copyright_header (abfd
)->copyrightMessageLength
;
684 if (bfd_bwrite ((void *) thdr
.copyrightMessageLength
, amt
, abfd
) != amt
)
686 /* The copyright message is a variable length string. */
687 amt
= nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1;
688 if (bfd_bwrite ((void *) nlm_copyright_header (abfd
)->copyrightMessage
,
693 /* Write out the extended header if there is one. */
694 if (find_nonzero (nlm_extended_header (abfd
),
695 sizeof (Nlm_Internal_Extended_Header
)))
697 Nlm_External_Extended_Header thdr
;
699 LITMEMCPY (thdr
.stamp
, "MeSsAgEs");
701 (bfd_vma
) nlm_extended_header (abfd
)->languageID
,
702 (bfd_byte
*) thdr
.languageID
);
704 (bfd_vma
) nlm_extended_header (abfd
)->messageFileOffset
,
705 (bfd_byte
*) thdr
.messageFileOffset
);
707 (bfd_vma
) nlm_extended_header (abfd
)->messageFileLength
,
708 (bfd_byte
*) thdr
.messageFileLength
);
710 (bfd_vma
) nlm_extended_header (abfd
)->messageCount
,
711 (bfd_byte
*) thdr
.messageCount
);
713 (bfd_vma
) nlm_extended_header (abfd
)->helpFileOffset
,
714 (bfd_byte
*) thdr
.helpFileOffset
);
716 (bfd_vma
) nlm_extended_header (abfd
)->helpFileLength
,
717 (bfd_byte
*) thdr
.helpFileLength
);
719 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataOffset
,
720 (bfd_byte
*) thdr
.RPCDataOffset
);
722 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataLength
,
723 (bfd_byte
*) thdr
.RPCDataLength
);
725 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeOffset
,
726 (bfd_byte
*) thdr
.sharedCodeOffset
);
728 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeLength
,
729 (bfd_byte
*) thdr
.sharedCodeLength
);
731 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataOffset
,
732 (bfd_byte
*) thdr
.sharedDataOffset
);
734 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataLength
,
735 (bfd_byte
*) thdr
.sharedDataLength
);
737 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupOffset
,
738 (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
740 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupCount
,
741 (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
743 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceOffset
,
744 (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
746 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceCount
,
747 (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
749 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsOffset
,
750 (bfd_byte
*) thdr
.sharedPublicsOffset
);
752 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsCount
,
753 (bfd_byte
*) thdr
.sharedPublicsCount
);
755 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordOffset
,
756 (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
758 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordCount
,
759 (bfd_byte
*) thdr
.sharedDebugRecordCount
);
761 (bfd_vma
) nlm_extended_header (abfd
)->SharedInitializationOffset
,
762 (bfd_byte
*) thdr
.sharedInitializationOffset
);
764 (bfd_vma
) nlm_extended_header (abfd
)->SharedExitProcedureOffset
,
765 (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
767 (bfd_vma
) nlm_extended_header (abfd
)->productID
,
768 (bfd_byte
*) thdr
.productID
);
770 (bfd_vma
) nlm_extended_header (abfd
)->reserved0
,
771 (bfd_byte
*) thdr
.reserved0
);
773 (bfd_vma
) nlm_extended_header (abfd
)->reserved1
,
774 (bfd_byte
*) thdr
.reserved1
);
776 (bfd_vma
) nlm_extended_header (abfd
)->reserved2
,
777 (bfd_byte
*) thdr
.reserved2
);
779 (bfd_vma
) nlm_extended_header (abfd
)->reserved3
,
780 (bfd_byte
*) thdr
.reserved3
);
782 (bfd_vma
) nlm_extended_header (abfd
)->reserved4
,
783 (bfd_byte
*) thdr
.reserved4
);
785 (bfd_vma
) nlm_extended_header (abfd
)->reserved5
,
786 (bfd_byte
*) thdr
.reserved5
);
787 if (bfd_bwrite ((void *) &thdr
, (bfd_size_type
) sizeof (thdr
), abfd
)
792 /* Write out the custom header if there is one. */
793 if (find_nonzero (nlm_custom_header (abfd
),
794 sizeof (Nlm_Internal_Custom_Header
)))
796 Nlm_External_Custom_Header thdr
;
798 bfd_size_type hdrLength
;
800 ds
= find_nonzero (nlm_custom_header (abfd
)->dataStamp
,
801 sizeof (nlm_custom_header (abfd
)->dataStamp
));
802 LITMEMCPY (thdr
.stamp
, "CuStHeAd");
803 hdrLength
= (2 * NLM_TARGET_LONG_SIZE
+ (ds
? 8 : 0)
804 + nlm_custom_header (abfd
)->hdrLength
);
805 put_word (abfd
, hdrLength
, thdr
.length
);
806 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataOffset
,
808 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataLength
,
812 BFD_ASSERT (nlm_custom_header (abfd
)->hdrLength
== 0);
813 amt
= sizeof (thdr
) - sizeof (thdr
.dataStamp
);
814 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
819 memcpy (thdr
.dataStamp
, nlm_custom_header (abfd
)->dataStamp
,
820 sizeof (thdr
.dataStamp
));
822 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
824 amt
= nlm_custom_header (abfd
)->hdrLength
;
825 if (bfd_bwrite (nlm_custom_header (abfd
)->hdr
, amt
, abfd
) != amt
)
830 /* Write out the Cygnus debugging header if there is one. */
831 if (find_nonzero (nlm_cygnus_ext_header (abfd
),
832 sizeof (Nlm_Internal_Cygnus_Ext_Header
)))
834 Nlm_External_Custom_Header thdr
;
836 LITMEMCPY (thdr
.stamp
, "CuStHeAd");
837 put_word (abfd
, (bfd_vma
) 2 * NLM_TARGET_LONG_SIZE
+ 8,
838 (bfd_byte
*) thdr
.length
);
839 put_word (abfd
, (bfd_vma
) nlm_cygnus_ext_header (abfd
)->offset
,
840 (bfd_byte
*) thdr
.dataOffset
);
841 put_word (abfd
, (bfd_vma
) nlm_cygnus_ext_header (abfd
)->length
,
842 (bfd_byte
*) thdr
.dataLength
);
843 LITMEMCPY (thdr
.dataStamp
, "CyGnUsEx");
845 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
852 /* We read the NLM's public symbols and use it to generate a bfd symbol
853 table (hey, it's better than nothing) on a one-for-one basis. Thus
854 use the number of public symbols as the number of bfd symbols we will
855 have once we actually get around to reading them in.
857 Return the number of bytes required to hold the symtab vector, based on
858 the count plus 1, since we will NULL terminate the vector allocated based
862 nlm_get_symtab_upper_bound (bfd
*abfd
)
864 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form. */
866 long symtab_size
= 0;
868 i_fxdhdrp
= nlm_fixed_header (abfd
);
869 symcount
= (i_fxdhdrp
->numberOfPublics
870 + i_fxdhdrp
->numberOfDebugRecords
871 + i_fxdhdrp
->numberOfExternalReferences
);
872 symtab_size
= (symcount
+ 1) * (sizeof (asymbol
));
876 /* Slurp in nlm symbol table.
878 In the external (in-file) form, NLM export records are variable length,
879 with the following form:
881 1 byte length of the symbol name (N)
882 N bytes the symbol name
883 4 bytes the symbol offset from start of it's section
885 We also read in the debugging symbols and import records. Import
886 records are treated as undefined symbols. As we read the import
887 records we also read in the associated reloc information, which is
888 attached to the symbol.
890 The bfd symbols are copied to SYMvoid *S.
892 When we return, the bfd symcount is either zero or contains the correct
893 number of symbols. */
896 nlm_slurp_symbol_table (bfd
*abfd
)
898 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form. */
899 bfd_size_type totsymcount
; /* Number of NLM symbols. */
900 bfd_size_type symcount
; /* Counter of NLM symbols. */
901 nlm_symbol_type
*sym
; /* Pointer to current bfd symbol. */
902 unsigned char symlength
; /* Symbol length read into here. */
903 unsigned char symtype
; /* Type of debugging symbol. */
904 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Symbol offsets read into here. */
905 bfd_boolean (*read_import_func
) (bfd
*, nlm_symbol_type
*);
906 bfd_boolean (*set_public_section_func
) (bfd
*, nlm_symbol_type
*);
909 if (nlm_get_symbols (abfd
) != NULL
)
912 /* Read each raw NLM symbol, using the information to create a canonical bfd
915 Note that we allocate the initial bfd canonical symbol buffer based on a
916 one-to-one mapping of the NLM symbols to canonical symbols. We actually
917 use all the NLM symbols, so there will be no space left over at the end.
918 When we have all the symbols, we build the caller's pointer vector. */
921 i_fxdhdrp
= nlm_fixed_header (abfd
);
922 totsymcount
= (i_fxdhdrp
->numberOfPublics
923 + i_fxdhdrp
->numberOfDebugRecords
924 + i_fxdhdrp
->numberOfExternalReferences
);
925 if (totsymcount
== 0)
928 if (bfd_seek (abfd
, i_fxdhdrp
->publicsOffset
, SEEK_SET
) != 0)
931 amt
= totsymcount
* sizeof (nlm_symbol_type
);
932 sym
= bfd_zalloc (abfd
, amt
);
935 nlm_set_symbols (abfd
, sym
);
937 /* We use the bfd's symcount directly as the control count, so that early
938 termination of the loop leaves the symcount correct for the symbols that
941 set_public_section_func
= nlm_set_public_section_func (abfd
);
942 symcount
= i_fxdhdrp
->numberOfPublics
;
943 while (abfd
->symcount
< symcount
)
945 amt
= sizeof (symlength
);
946 if (bfd_bread ((void *) &symlength
, amt
, abfd
) != amt
)
949 sym
->symbol
.the_bfd
= abfd
;
950 sym
->symbol
.name
= bfd_alloc (abfd
, amt
+ 1);
951 if (!sym
->symbol
.name
)
953 if (bfd_bread ((void *) sym
->symbol
.name
, amt
, abfd
) != amt
)
955 /* Cast away const. */
956 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
958 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
960 sym
->symbol
.flags
= BSF_GLOBAL
| BSF_EXPORT
;
961 sym
->symbol
.value
= get_word (abfd
, temp
);
962 if (set_public_section_func
)
964 /* Most backends can use the code below, but unfortunately
965 some use a different scheme. */
966 if (! (*set_public_section_func
) (abfd
, sym
))
971 if (sym
->symbol
.value
& NLM_HIBIT
)
973 sym
->symbol
.value
&= ~NLM_HIBIT
;
974 sym
->symbol
.flags
|= BSF_FUNCTION
;
975 sym
->symbol
.section
=
976 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
979 sym
->symbol
.section
=
980 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
987 /* Read the debugging records. */
989 if (i_fxdhdrp
->numberOfDebugRecords
> 0)
991 if (bfd_seek (abfd
, i_fxdhdrp
->debugInfoOffset
, SEEK_SET
) != 0)
994 symcount
+= i_fxdhdrp
->numberOfDebugRecords
;
995 while (abfd
->symcount
< symcount
)
997 amt
= sizeof (symtype
);
998 if (bfd_bread ((void *) &symtype
, amt
, abfd
) != amt
)
1000 amt
= sizeof (temp
);
1001 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
1003 amt
= sizeof (symlength
);
1004 if (bfd_bread ((void *) &symlength
, amt
, abfd
) != amt
)
1007 sym
->symbol
.the_bfd
= abfd
;
1008 sym
->symbol
.name
= bfd_alloc (abfd
, amt
+ 1);
1009 if (!sym
->symbol
.name
)
1011 if (bfd_bread ((void *) sym
->symbol
.name
, amt
, abfd
) != amt
)
1013 /* Cast away const. */
1014 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
1015 sym
->symbol
.flags
= BSF_LOCAL
;
1016 sym
->symbol
.value
= get_word (abfd
, temp
);
1019 sym
->symbol
.section
=
1020 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
1021 else if (symtype
== 1)
1023 sym
->symbol
.flags
|= BSF_FUNCTION
;
1024 sym
->symbol
.section
=
1025 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
1028 sym
->symbol
.section
= bfd_abs_section_ptr
;
1036 /* Read in the import records. We can only do this if we know how
1037 to read relocs for this target. */
1038 read_import_func
= nlm_read_import_func (abfd
);
1039 if (read_import_func
!= NULL
)
1041 if (bfd_seek (abfd
, i_fxdhdrp
->externalReferencesOffset
, SEEK_SET
) != 0)
1044 symcount
+= i_fxdhdrp
->numberOfExternalReferences
;
1045 while (abfd
->symcount
< symcount
)
1047 if (! (*read_import_func
) (abfd
, sym
))
1057 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
1058 symbol table fails. */
1061 nlm_canonicalize_symtab (bfd
*abfd
, asymbol
**alocation
)
1063 nlm_symbol_type
*symbase
;
1064 bfd_size_type counter
= 0;
1066 if (! nlm_slurp_symbol_table (abfd
))
1068 symbase
= nlm_get_symbols (abfd
);
1069 while (counter
< bfd_get_symcount (abfd
))
1071 *alocation
++ = &symbase
->symbol
;
1076 return bfd_get_symcount (abfd
);
1079 /* Make an NLM symbol. There is nothing special to do here. */
1082 nlm_make_empty_symbol (bfd
*abfd
)
1084 bfd_size_type amt
= sizeof (nlm_symbol_type
);
1085 nlm_symbol_type
*new = bfd_zalloc (abfd
, amt
);
1089 new->symbol
.the_bfd
= abfd
;
1090 return & new->symbol
;
1093 /* Get symbol information. */
1096 nlm_get_symbol_info (bfd
*ignore_abfd ATTRIBUTE_UNUSED
,
1100 bfd_symbol_info (symbol
, ret
);
1103 /* Print symbol information. */
1106 nlm_print_symbol (bfd
*abfd
,
1109 bfd_print_symbol_type how
)
1111 FILE *file
= (FILE *) afile
;
1115 case bfd_print_symbol_name
:
1116 case bfd_print_symbol_more
:
1118 fprintf (file
, "%s", symbol
->name
);
1120 case bfd_print_symbol_all
:
1121 bfd_print_symbol_vandf (abfd
, (void *) file
, symbol
);
1122 fprintf (file
, " %-5s", symbol
->section
->name
);
1124 fprintf (file
, " %s", symbol
->name
);
1129 /* Get the relocs for an NLM file. There are two types of relocs.
1130 Imports are relocs against symbols defined in other NLM files. We
1131 treat these as relocs against global symbols. Relocation fixups
1132 are internal relocs.
1134 The actual format used to store the relocs is machine specific. */
1136 /* Read in the relocation fixup information. This is stored in
1137 nlm_relocation_fixups, an array of arelent structures, and
1138 nlm_relocation_fixup_secs, an array of section pointers. The
1139 section pointers are needed because the relocs are not sorted by
1143 nlm_slurp_reloc_fixups (bfd
*abfd
)
1145 bfd_boolean (*read_func
) (bfd
*, nlm_symbol_type
*, asection
**, arelent
*);
1146 bfd_size_type count
, amt
;
1150 if (nlm_relocation_fixups (abfd
) != NULL
)
1152 read_func
= nlm_read_reloc_func (abfd
);
1153 if (read_func
== NULL
)
1156 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1160 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1161 amt
= count
* sizeof (arelent
);
1162 rels
= bfd_alloc (abfd
, amt
);
1163 amt
= count
* sizeof (asection
*);
1164 secs
= bfd_alloc (abfd
, amt
);
1165 if ((rels
== NULL
|| secs
== NULL
) && count
!= 0)
1167 nlm_relocation_fixups (abfd
) = rels
;
1168 nlm_relocation_fixup_secs (abfd
) = secs
;
1170 /* We have to read piece by piece, because we don't know how large
1171 the machine specific reloc information is. */
1172 while (count
-- != 0)
1174 if (! (*read_func
) (abfd
, NULL
, secs
, rels
))
1176 nlm_relocation_fixups (abfd
) = NULL
;
1177 nlm_relocation_fixup_secs (abfd
) = NULL
;
1187 /* Get the number of relocs. This really just returns an upper bound,
1188 since it does not attempt to distinguish them based on the section.
1189 That will be handled when they are actually read. */
1192 nlm_get_reloc_upper_bound (bfd
*abfd
, asection
*sec
)
1194 nlm_symbol_type
*syms
;
1195 bfd_size_type count
;
1198 /* If we don't know how to read relocs, just return 0. */
1199 if (nlm_read_reloc_func (abfd
) == NULL
)
1201 /* Make sure we have either the code or the data section. */
1202 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1205 syms
= nlm_get_symbols (abfd
);
1208 if (! nlm_slurp_symbol_table (abfd
))
1210 syms
= nlm_get_symbols (abfd
);
1213 ret
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1215 count
= bfd_get_symcount (abfd
);
1216 while (count
-- != 0)
1222 return (ret
+ 1) * sizeof (arelent
*);
1225 /* Get the relocs themselves. */
1228 nlm_canonicalize_reloc (bfd
*abfd
,
1235 bfd_size_type count
, i
;
1238 /* Get the relocation fixups. */
1239 rels
= nlm_relocation_fixups (abfd
);
1242 if (! nlm_slurp_reloc_fixups (abfd
))
1244 rels
= nlm_relocation_fixups (abfd
);
1246 secs
= nlm_relocation_fixup_secs (abfd
);
1249 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1250 for (i
= 0; i
< count
; i
++, rels
++, secs
++)
1259 /* Get the import symbols. */
1260 count
= bfd_get_symcount (abfd
);
1261 for (i
= 0; i
< count
; i
++, symbols
++)
1266 if (bfd_asymbol_flavour (sym
) == bfd_target_nlm_flavour
)
1268 nlm_symbol_type
*nlm_sym
;
1271 nlm_sym
= (nlm_symbol_type
*) sym
;
1272 for (j
= 0; j
< nlm_sym
->rcnt
; j
++)
1274 if (nlm_sym
->relocs
[j
].section
== sec
)
1276 *relptr
= &nlm_sym
->relocs
[j
].reloc
;
1277 (*relptr
)->sym_ptr_ptr
= symbols
;
1290 /* Compute the section file positions for an NLM file. All variable
1291 length data in the file headers must be set before this function is
1292 called. If the variable length data is changed later, the
1293 resulting object file will be incorrect. Unfortunately, there is
1294 no way to check this.
1296 This routine also sets the Size and Offset fields in the fixed
1299 It also looks over the symbols and moves any common symbols into
1300 the .bss section; NLM has no way to represent a common symbol.
1301 This approach means that either the symbols must already have been
1302 set at this point, or there must be no common symbols. We need to
1303 move the symbols at this point so that mangle_relocs can see the
1307 nlm_compute_section_file_positions (bfd
*abfd
)
1311 bfd_vma text
, data
, bss
;
1312 bfd_vma text_low
, data_low
;
1313 unsigned int text_align
, data_align
, other_align
;
1314 file_ptr text_ptr
, data_ptr
, other_ptr
;
1316 asymbol
**sym_ptr_ptr
;
1318 if (abfd
->output_has_begun
)
1321 /* Make sure we have a section to hold uninitialized data. */
1322 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1323 if (bss_sec
== NULL
)
1325 if (!add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
1326 (file_ptr
) 0, (bfd_size_type
) 0,
1329 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1332 abfd
->output_has_begun
= TRUE
;
1334 /* The fixed header. */
1335 sofar
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1337 /* The variable header. */
1338 sofar
+= (sizeof (nlm_variable_header (abfd
)->descriptionLength
)
1339 + nlm_variable_header (abfd
)->descriptionLength
+ 1
1340 + NLM_TARGET_LONG_SIZE
/* stackSize */
1341 + NLM_TARGET_LONG_SIZE
/* reserved */
1342 + sizeof (nlm_variable_header (abfd
)->oldThreadName
)
1343 + sizeof (nlm_variable_header (abfd
)->screenNameLength
)
1344 + nlm_variable_header (abfd
)->screenNameLength
+ 1
1345 + sizeof (nlm_variable_header (abfd
)->threadNameLength
)
1346 + nlm_variable_header (abfd
)->threadNameLength
+ 1);
1348 /* The auxiliary headers. */
1349 if (find_nonzero (nlm_version_header (abfd
),
1350 sizeof (Nlm_Internal_Version_Header
)))
1351 sofar
+= sizeof (Nlm_External_Version_Header
);
1352 if (find_nonzero (nlm_extended_header (abfd
),
1353 sizeof (Nlm_Internal_Extended_Header
)))
1354 sofar
+= sizeof (Nlm_External_Extended_Header
);
1355 if (find_nonzero (nlm_copyright_header (abfd
),
1356 sizeof (Nlm_Internal_Copyright_Header
)))
1357 sofar
+= (sizeof (Nlm_External_Copyright_Header
)
1358 + nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1);
1359 if (find_nonzero (nlm_custom_header (abfd
),
1360 sizeof (Nlm_Internal_Custom_Header
)))
1361 sofar
+= (sizeof (Nlm_External_Custom_Header
)
1362 + nlm_custom_header (abfd
)->hdrLength
);
1363 if (find_nonzero (nlm_cygnus_ext_header (abfd
),
1364 sizeof (Nlm_Internal_Cygnus_Ext_Header
)))
1365 sofar
+= sizeof (Nlm_External_Custom_Header
);
1367 /* Compute the section file positions in two passes. First get the
1368 sizes of the text and data sections, and then set the file
1369 positions. This code aligns the sections in the file using the
1370 same alignment restrictions that apply to the sections in memory;
1371 this may not be necessary. */
1373 text_low
= (bfd_vma
) - 1;
1376 data_low
= (bfd_vma
) - 1;
1380 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1384 sec
->size
= BFD_ALIGN (sec
->size
, 1 << sec
->alignment_power
);
1386 f
= bfd_get_section_flags (abfd
, sec
);
1390 if (bfd_get_section_vma (abfd
, sec
) < text_low
)
1391 text_low
= bfd_get_section_vma (abfd
, sec
);
1392 if (sec
->alignment_power
> text_align
)
1393 text_align
= sec
->alignment_power
;
1395 else if (f
& SEC_DATA
)
1398 if (bfd_get_section_vma (abfd
, sec
) < data_low
)
1399 data_low
= bfd_get_section_vma (abfd
, sec
);
1400 if (sec
->alignment_power
> data_align
)
1401 data_align
= sec
->alignment_power
;
1403 else if (f
& SEC_HAS_CONTENTS
)
1405 if (sec
->alignment_power
> other_align
)
1406 other_align
= sec
->alignment_power
;
1408 else if (f
& SEC_ALLOC
)
1412 nlm_set_text_low (abfd
, text_low
);
1413 nlm_set_data_low (abfd
, data_low
);
1415 if (nlm_no_uninitialized_data (abfd
))
1417 /* This NetWare format does not use uninitialized data. We must
1418 increase the size of the data section. We will never wind up
1419 writing those file locations, so they will remain zero. */
1424 text_ptr
= BFD_ALIGN (sofar
, 1 << text_align
);
1425 data_ptr
= BFD_ALIGN (text_ptr
+ text
, 1 << data_align
);
1426 other_ptr
= BFD_ALIGN (data_ptr
+ data
, 1 << other_align
);
1428 /* Fill in some fields in the header for which we now have the
1430 nlm_fixed_header (abfd
)->codeImageOffset
= text_ptr
;
1431 nlm_fixed_header (abfd
)->codeImageSize
= text
;
1432 nlm_fixed_header (abfd
)->dataImageOffset
= data_ptr
;
1433 nlm_fixed_header (abfd
)->dataImageSize
= data
;
1434 nlm_fixed_header (abfd
)->uninitializedDataSize
= bss
;
1436 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1440 f
= bfd_get_section_flags (abfd
, sec
);
1444 sec
->filepos
= text_ptr
;
1445 text_ptr
+= sec
->size
;
1447 else if (f
& SEC_DATA
)
1449 sec
->filepos
= data_ptr
;
1450 data_ptr
+= sec
->size
;
1452 else if (f
& SEC_HAS_CONTENTS
)
1454 sec
->filepos
= other_ptr
;
1455 other_ptr
+= sec
->size
;
1459 nlm_fixed_header (abfd
)->relocationFixupOffset
= other_ptr
;
1461 /* Move all common symbols into the .bss section. */
1463 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1464 if (sym_ptr_ptr
!= NULL
)
1469 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1471 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1478 if (!bfd_is_com_section (bfd_get_section (sym
)))
1481 /* Put the common symbol in the .bss section, and increase
1482 the size of the .bss section by the size of the common
1483 symbol (which is the old value of the symbol). */
1484 sym
->section
= bss_sec
;
1486 sym
->value
= bss_sec
->size
+ add
;
1488 add
= BFD_ALIGN (add
, 1 << bss_sec
->alignment_power
);
1492 if (nlm_no_uninitialized_data (abfd
))
1494 /* We could handle this case, but so far it hasn't been
1498 nlm_fixed_header (abfd
)->uninitializedDataSize
+= add
;
1499 bss_sec
->size
+= add
;
1506 /* Set the contents of a section. To do this we need to know where
1507 the section is going to be located in the output file. That means
1508 that the sizes of all the sections must be set, and all the
1509 variable size header information must be known. */
1512 nlm_set_section_contents (bfd
*abfd
,
1514 const void * location
,
1516 bfd_size_type count
)
1518 if (! abfd
->output_has_begun
1519 && ! nlm_compute_section_file_positions (abfd
))
1525 /* i386 NetWare has a very restricted set of relocs. In order for
1526 objcopy to work, the NLM i386 backend needs a chance to rework
1527 the section contents so that its set of relocs will work. If all
1528 the relocs are already acceptable, this will not do anything. */
1529 if (section
->reloc_count
!= 0)
1531 bfd_boolean (*mangle_relocs_func
)
1532 (bfd
*, asection
*, const void *, bfd_vma
, bfd_size_type
);
1534 mangle_relocs_func
= nlm_mangle_relocs_func (abfd
);
1535 if (mangle_relocs_func
!= NULL
)
1537 if (!(*mangle_relocs_func
) (abfd
, section
, location
,
1538 (bfd_vma
) offset
, count
))
1543 if (bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
) != 0
1544 || bfd_bwrite (location
, count
, abfd
) != count
)
1550 /* We need to sort a list of relocs associated with sections when we
1551 write out the external relocs. */
1554 nlm_external_reloc_compare (const void *p1
, const void *p2
)
1556 const struct reloc_and_sec
*r1
= (const struct reloc_and_sec
*) p1
;
1557 const struct reloc_and_sec
*r2
= (const struct reloc_and_sec
*) p2
;
1560 cmp
= strcmp ((*r1
->rel
->sym_ptr_ptr
)->name
,
1561 (*r2
->rel
->sym_ptr_ptr
)->name
);
1565 /* We sort by address within symbol to make the sort more stable and
1566 increase the chances that different hosts will generate bit for
1567 bit equivalent results. */
1568 return (int) (r1
->rel
->address
- r2
->rel
->address
);
1571 /* Write out an NLM file. We write out the information in this order:
1577 other sections (custom data, messages, help, shared NLM, RPC,
1578 module dependencies)
1580 external references (imports)
1581 public symbols (exports)
1583 This is similar to the order used by the NetWare tools; the
1584 difference is that NetWare puts the sections other than code, data
1585 and custom data at the end of the NLM. It is convenient for us to
1586 know where the sections are going to be before worrying about the
1587 size of the other information.
1589 By the time this function is called, all the section data should
1590 have been output using set_section_contents. Note that custom
1591 data, the message file, the help file, the shared NLM file, the RPC
1592 data, and the module dependencies are all considered to be
1593 sections; the caller is responsible for filling in the offset and
1594 length fields in the NLM headers. The relocation fixups and
1595 imports are both obtained from the list of relocs attached to each
1596 section. The exports and debugging records are obtained from the
1597 list of outsymbols. */
1600 nlm_write_object_contents (bfd
*abfd
)
1603 bfd_boolean (*write_import_func
) (bfd
*, asection
*, arelent
*);
1604 bfd_size_type external_reloc_count
, internal_reloc_count
, i
, c
;
1605 struct reloc_and_sec
*external_relocs
;
1606 asymbol
**sym_ptr_ptr
;
1608 bfd_boolean (*write_prefix_func
) (bfd
*);
1609 unsigned char *fixed_header
= NULL
;
1613 fixed_header
= bfd_malloc (nlm_fixed_header_size (abfd
));
1614 if (fixed_header
== NULL
)
1617 if (! abfd
->output_has_begun
1618 && ! nlm_compute_section_file_positions (abfd
))
1621 /* Write out the variable length headers. */
1622 pos
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1623 if (bfd_seek (abfd
, pos
, SEEK_SET
) != 0)
1625 if (! nlm_swap_variable_header_out (abfd
)
1626 || ! nlm_swap_auxiliary_headers_out (abfd
))
1628 bfd_set_error (bfd_error_system_call
);
1632 /* A weak check on whether the section file positions were
1634 if (bfd_tell (abfd
) > nlm_fixed_header (abfd
)->codeImageOffset
)
1636 bfd_set_error (bfd_error_invalid_operation
);
1640 /* Advance to the relocs. */
1641 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1645 /* The format of the relocation entries is dependent upon the
1646 particular target. We use an external routine to write the reloc
1648 write_import_func
= nlm_write_import_func (abfd
);
1650 /* Write out the internal relocation fixups. While we're looping
1651 over the relocs, we also count the external relocs, which is
1652 needed when they are written out below. */
1653 internal_reloc_count
= 0;
1654 external_reloc_count
= 0;
1655 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1657 arelent
**rel_ptr_ptr
, **rel_end
;
1659 if (sec
->reloc_count
== 0)
1662 /* We can only represent relocs within a code or data
1663 section. We ignore them for a debugging section. */
1664 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1667 /* We need to know how to write out imports */
1668 if (write_import_func
== NULL
)
1670 bfd_set_error (bfd_error_invalid_operation
);
1674 rel_ptr_ptr
= sec
->orelocation
;
1675 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1676 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1682 sym
= *rel
->sym_ptr_ptr
;
1684 if (! bfd_is_und_section (bfd_get_section (sym
)))
1686 ++internal_reloc_count
;
1687 if (! (*write_import_func
) (abfd
, sec
, rel
))
1691 ++external_reloc_count
;
1694 nlm_fixed_header (abfd
)->numberOfRelocationFixups
= internal_reloc_count
;
1696 /* Write out the imports (relocs against external symbols). These
1697 are output as a symbol name followed by all the relocs for that
1698 symbol, so we must first gather together all the relocs against
1699 external symbols and sort them. */
1700 amt
= external_reloc_count
* sizeof (struct reloc_and_sec
);
1701 external_relocs
= bfd_alloc (abfd
, amt
);
1702 if (external_relocs
== NULL
)
1705 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1707 arelent
**rel_ptr_ptr
, **rel_end
;
1709 if (sec
->reloc_count
== 0)
1712 rel_ptr_ptr
= sec
->orelocation
;
1713 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1714 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1720 sym
= *rel
->sym_ptr_ptr
;
1722 if (! bfd_is_und_section (bfd_get_section (sym
)))
1725 external_relocs
[i
].rel
= rel
;
1726 external_relocs
[i
].sec
= sec
;
1731 BFD_ASSERT (i
== external_reloc_count
);
1733 /* Sort the external relocs by name. */
1734 qsort (external_relocs
, (size_t) external_reloc_count
,
1735 sizeof (struct reloc_and_sec
), nlm_external_reloc_compare
);
1737 /* Write out the external relocs. */
1738 nlm_fixed_header (abfd
)->externalReferencesOffset
= bfd_tell (abfd
);
1741 while (i
< external_reloc_count
)
1745 bfd_size_type j
, cnt
;
1749 rel
= external_relocs
[i
].rel
;
1750 sym
= *rel
->sym_ptr_ptr
;
1754 (j
< external_reloc_count
1755 && *external_relocs
[j
].rel
->sym_ptr_ptr
== sym
);
1759 if (! (*nlm_write_external_func (abfd
)) (abfd
, cnt
, sym
,
1760 &external_relocs
[i
]))
1766 nlm_fixed_header (abfd
)->numberOfExternalReferences
= c
;
1768 /* Write out the public symbols (exports). */
1769 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1770 if (sym_ptr_ptr
!= NULL
)
1772 bfd_vma (*get_public_offset_func
) (bfd
*, asymbol
*);
1773 bfd_boolean (*write_export_func
) (bfd
*, asymbol
*, bfd_vma
);
1777 nlm_fixed_header (abfd
)->publicsOffset
= bfd_tell (abfd
);
1778 get_public_offset_func
= nlm_get_public_offset_func (abfd
);
1779 write_export_func
= nlm_write_export_func (abfd
);
1781 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1782 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1787 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1791 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) == 0
1792 || bfd_is_und_section (bfd_get_section (sym
)))
1797 if (get_public_offset_func
)
1799 /* Most backends can use the code below, but
1800 unfortunately some use a different scheme. */
1801 offset
= (*get_public_offset_func
) (abfd
, sym
);
1805 offset
= bfd_asymbol_value (sym
);
1807 if (sec
->flags
& SEC_CODE
)
1809 offset
-= nlm_get_text_low (abfd
);
1810 offset
|= NLM_HIBIT
;
1812 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1814 /* SEC_ALLOC is for the .bss section. */
1815 offset
-= nlm_get_data_low (abfd
);
1819 /* We can't handle an exported symbol that is not in
1820 the code or data segment. */
1821 bfd_set_error (bfd_error_invalid_operation
);
1826 if (write_export_func
)
1828 if (! (*write_export_func
) (abfd
, sym
, offset
))
1833 len
= strlen (sym
->name
);
1834 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1835 != sizeof (bfd_byte
))
1836 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
1839 put_word (abfd
, offset
, temp
);
1840 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
)
1845 nlm_fixed_header (abfd
)->numberOfPublics
= c
;
1847 /* Write out the debugging records. The NLM conversion program
1848 wants to be able to inhibit this, so as a special hack if
1849 debugInfoOffset is set to -1 we don't write any debugging
1850 information. This can not be handled by fiddling with the
1851 symbol table, because exported symbols appear in both the
1852 exported symbol list and the debugging information. */
1853 if (nlm_fixed_header (abfd
)->debugInfoOffset
== (file_ptr
) - 1)
1855 nlm_fixed_header (abfd
)->debugInfoOffset
= 0;
1856 nlm_fixed_header (abfd
)->numberOfDebugRecords
= 0;
1860 nlm_fixed_header (abfd
)->debugInfoOffset
= bfd_tell (abfd
);
1862 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1863 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1864 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1869 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1873 /* The NLM notion of a debugging symbol is actually what
1874 BFD calls a local or global symbol. What BFD calls a
1875 debugging symbol NLM does not understand at all. */
1876 if ((sym
->flags
& (BSF_LOCAL
| BSF_GLOBAL
| BSF_EXPORT
)) == 0
1877 || (sym
->flags
& BSF_DEBUGGING
) != 0
1878 || bfd_is_und_section (bfd_get_section (sym
)))
1883 offset
= bfd_asymbol_value (sym
);
1885 if (sec
->flags
& SEC_CODE
)
1887 offset
-= nlm_get_text_low (abfd
);
1890 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1892 /* SEC_ALLOC is for the .bss section. */
1893 offset
-= nlm_get_data_low (abfd
);
1899 /* The type is 0 for data, 1 for code, 2 for absolute. */
1900 if (bfd_bwrite (&type
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1901 != sizeof (bfd_byte
))
1904 put_word (abfd
, offset
, temp
);
1905 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
)
1909 len
= strlen (sym
->name
);
1910 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1911 != sizeof (bfd_byte
))
1912 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
1915 nlm_fixed_header (abfd
)->numberOfDebugRecords
= c
;
1919 /* NLMLINK fills in offset values even if there is no data, so we do
1921 last
= bfd_tell (abfd
);
1922 if (nlm_fixed_header (abfd
)->codeImageOffset
== 0)
1923 nlm_fixed_header (abfd
)->codeImageOffset
= last
;
1924 if (nlm_fixed_header (abfd
)->dataImageOffset
== 0)
1925 nlm_fixed_header (abfd
)->dataImageOffset
= last
;
1926 if (nlm_fixed_header (abfd
)->customDataOffset
== 0)
1927 nlm_fixed_header (abfd
)->customDataOffset
= last
;
1928 if (nlm_fixed_header (abfd
)->moduleDependencyOffset
== 0)
1929 nlm_fixed_header (abfd
)->moduleDependencyOffset
= last
;
1930 if (nlm_fixed_header (abfd
)->relocationFixupOffset
== 0)
1931 nlm_fixed_header (abfd
)->relocationFixupOffset
= last
;
1932 if (nlm_fixed_header (abfd
)->externalReferencesOffset
== 0)
1933 nlm_fixed_header (abfd
)->externalReferencesOffset
= last
;
1934 if (nlm_fixed_header (abfd
)->publicsOffset
== 0)
1935 nlm_fixed_header (abfd
)->publicsOffset
= last
;
1936 if (nlm_fixed_header (abfd
)->debugInfoOffset
== 0)
1937 nlm_fixed_header (abfd
)->debugInfoOffset
= last
;
1939 /* At this point everything has been written out except the fixed
1941 memcpy (nlm_fixed_header (abfd
)->signature
, nlm_signature (abfd
),
1942 NLM_SIGNATURE_SIZE
);
1943 nlm_fixed_header (abfd
)->version
= NLM_HEADER_VERSION
;
1944 nlm_fixed_header (abfd
)->codeStartOffset
=
1945 (bfd_get_start_address (abfd
)
1946 - nlm_get_text_low (abfd
));
1948 /* We have no convenient way for the caller to pass in the exit
1949 procedure or the check unload procedure, so the caller must set
1950 the values in the header to the values of the symbols. */
1951 nlm_fixed_header (abfd
)->exitProcedureOffset
-= nlm_get_text_low (abfd
);
1952 if (nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
!= 0)
1953 nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
-=
1954 nlm_get_text_low (abfd
);
1956 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0)
1959 write_prefix_func
= nlm_write_prefix_func (abfd
);
1960 if (write_prefix_func
)
1962 if (! (*write_prefix_func
) (abfd
))
1966 BFD_ASSERT ((bfd_size_type
) bfd_tell (abfd
)
1967 == nlm_optional_prefix_size (abfd
));
1969 nlm_swap_fixed_header_out (abfd
, nlm_fixed_header (abfd
), fixed_header
);
1970 if (bfd_bwrite (fixed_header
, nlm_fixed_header_size (abfd
), abfd
)
1971 != nlm_fixed_header_size (abfd
))
1974 if (fixed_header
!= NULL
)
1975 free (fixed_header
);
1979 if (fixed_header
!= NULL
)
1980 free (fixed_header
);