1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc.
5 Written by Fred Fish @ Cygnus Support, using ELF support as the
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 /* The functions in this file do not use the names they appear to use.
30 This file is actually compiled multiple times, once for each size
31 of NLM target we are using. At each size we use a different name,
32 constructed by the macro nlmNAME. For example, the function which
33 is named nlm_symbol_type below is actually named nlm32_symbol_type
34 in the final executable. */
36 #define Nlm_External_Fixed_Header NlmNAME (External_Fixed_Header)
37 #define Nlm_External_Version_Header NlmNAME (External_Version_Header)
38 #define Nlm_External_Copyright_Header NlmNAME (External_Copyright_Header)
39 #define Nlm_External_Extended_Header NlmNAME (External_Extended_Header)
40 #define Nlm_External_Custom_Header NlmNAME (External_Custom_Header)
41 #define Nlm_External_Cygnus_Ext_Header NlmNAME (External_Cygnus_Ext_Header)
43 #define nlm_symbol_type nlmNAME (symbol_type)
44 #define nlm_get_symtab_upper_bound nlmNAME (get_symtab_upper_bound)
45 #define nlm_canonicalize_symtab nlmNAME (canonicalize_symtab)
46 #define nlm_make_empty_symbol nlmNAME (make_empty_symbol)
47 #define nlm_print_symbol nlmNAME (print_symbol)
48 #define nlm_get_symbol_info nlmNAME (get_symbol_info)
49 #define nlm_get_reloc_upper_bound nlmNAME (get_reloc_upper_bound)
50 #define nlm_canonicalize_reloc nlmNAME (canonicalize_reloc)
51 #define nlm_object_p nlmNAME (object_p)
52 #define nlm_set_section_contents nlmNAME (set_section_contents)
53 #define nlm_write_object_contents nlmNAME (write_object_contents)
55 #define nlm_swap_fixed_header_in(abfd,src,dst) \
56 (nlm_swap_fixed_header_in_func (abfd)) (abfd, src, dst)
57 #define nlm_swap_fixed_header_out(abfd,src,dst) \
58 (nlm_swap_fixed_header_out_func (abfd)) (abfd, src, dst)
60 /* 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 (abfd
, name
);
145 newsect
->vma
= 0; /* NLM's are relocatable. */
146 newsect
->size
= size
;
147 newsect
->filepos
= offset
;
148 newsect
->flags
= flags
;
149 newsect
->alignment_power
= bfd_log2 ((bfd_vma
) 0); /* FIXME */
154 /* Read and swap in the contents of all the auxiliary headers. Because of
155 the braindead design, we have to do strcmps on strings of indeterminate
156 length to figure out what each auxiliary header is. Even worse, we have
157 no way of knowing how many auxiliary headers there are or where the end
158 of the auxiliary headers are, except by finding something that doesn't
159 look like a known auxiliary header. This means that the first new type
160 of auxiliary header added will break all existing tools that don't
164 nlm_swap_auxiliary_headers_in (bfd
*abfd
)
172 position
= bfd_tell (abfd
);
173 amt
= sizeof (tempstr
);
174 if (bfd_bread ((void *) tempstr
, amt
, abfd
) != amt
)
176 if (bfd_seek (abfd
, position
, SEEK_SET
) != 0)
178 if (strncmp (tempstr
, "VeRsIoN#", 8) == 0)
180 Nlm_External_Version_Header thdr
;
183 if (bfd_bread ((void *) &thdr
, amt
, abfd
) != amt
)
185 memcpy (nlm_version_header (abfd
)->stamp
, thdr
.stamp
,
186 sizeof (thdr
.stamp
));
187 nlm_version_header (abfd
)->majorVersion
=
188 get_word (abfd
, (bfd_byte
*) thdr
.majorVersion
);
189 nlm_version_header (abfd
)->minorVersion
=
190 get_word (abfd
, (bfd_byte
*) thdr
.minorVersion
);
191 nlm_version_header (abfd
)->revision
=
192 get_word (abfd
, (bfd_byte
*) thdr
.revision
);
193 nlm_version_header (abfd
)->year
=
194 get_word (abfd
, (bfd_byte
*) thdr
.year
);
195 nlm_version_header (abfd
)->month
=
196 get_word (abfd
, (bfd_byte
*) thdr
.month
);
197 nlm_version_header (abfd
)->day
=
198 get_word (abfd
, (bfd_byte
*) thdr
.day
);
200 else if (strncmp (tempstr
, "MeSsAgEs", 8) == 0)
202 Nlm_External_Extended_Header thdr
;
205 if (bfd_bread ((void *) &thdr
, amt
, abfd
) != amt
)
207 memcpy (nlm_extended_header (abfd
)->stamp
, thdr
.stamp
,
208 sizeof (thdr
.stamp
));
209 nlm_extended_header (abfd
)->languageID
=
210 get_word (abfd
, (bfd_byte
*) thdr
.languageID
);
211 nlm_extended_header (abfd
)->messageFileOffset
=
212 get_word (abfd
, (bfd_byte
*) thdr
.messageFileOffset
);
213 nlm_extended_header (abfd
)->messageFileLength
=
214 get_word (abfd
, (bfd_byte
*) thdr
.messageFileLength
);
215 nlm_extended_header (abfd
)->messageCount
=
216 get_word (abfd
, (bfd_byte
*) thdr
.messageCount
);
217 nlm_extended_header (abfd
)->helpFileOffset
=
218 get_word (abfd
, (bfd_byte
*) thdr
.helpFileOffset
);
219 nlm_extended_header (abfd
)->helpFileLength
=
220 get_word (abfd
, (bfd_byte
*) thdr
.helpFileLength
);
221 nlm_extended_header (abfd
)->RPCDataOffset
=
222 get_word (abfd
, (bfd_byte
*) thdr
.RPCDataOffset
);
223 nlm_extended_header (abfd
)->RPCDataLength
=
224 get_word (abfd
, (bfd_byte
*) thdr
.RPCDataLength
);
225 nlm_extended_header (abfd
)->sharedCodeOffset
=
226 get_word (abfd
, (bfd_byte
*) thdr
.sharedCodeOffset
);
227 nlm_extended_header (abfd
)->sharedCodeLength
=
228 get_word (abfd
, (bfd_byte
*) thdr
.sharedCodeLength
);
229 nlm_extended_header (abfd
)->sharedDataOffset
=
230 get_word (abfd
, (bfd_byte
*) thdr
.sharedDataOffset
);
231 nlm_extended_header (abfd
)->sharedDataLength
=
232 get_word (abfd
, (bfd_byte
*) thdr
.sharedDataLength
);
233 nlm_extended_header (abfd
)->sharedRelocationFixupOffset
=
234 get_word (abfd
, (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
235 nlm_extended_header (abfd
)->sharedRelocationFixupCount
=
236 get_word (abfd
, (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
237 nlm_extended_header (abfd
)->sharedExternalReferenceOffset
=
238 get_word (abfd
, (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
239 nlm_extended_header (abfd
)->sharedExternalReferenceCount
=
240 get_word (abfd
, (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
241 nlm_extended_header (abfd
)->sharedPublicsOffset
=
242 get_word (abfd
, (bfd_byte
*) thdr
.sharedPublicsOffset
);
243 nlm_extended_header (abfd
)->sharedPublicsCount
=
244 get_word (abfd
, (bfd_byte
*) thdr
.sharedPublicsCount
);
245 nlm_extended_header (abfd
)->sharedDebugRecordOffset
=
246 get_word (abfd
, (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
247 nlm_extended_header (abfd
)->sharedDebugRecordCount
=
248 get_word (abfd
, (bfd_byte
*) thdr
.sharedDebugRecordCount
);
249 nlm_extended_header (abfd
)->SharedInitializationOffset
=
250 get_word (abfd
, (bfd_byte
*) thdr
.sharedInitializationOffset
);
251 nlm_extended_header (abfd
)->SharedExitProcedureOffset
=
252 get_word (abfd
, (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
253 nlm_extended_header (abfd
)->productID
=
254 get_word (abfd
, (bfd_byte
*) thdr
.productID
);
255 nlm_extended_header (abfd
)->reserved0
=
256 get_word (abfd
, (bfd_byte
*) thdr
.reserved0
);
257 nlm_extended_header (abfd
)->reserved1
=
258 get_word (abfd
, (bfd_byte
*) thdr
.reserved1
);
259 nlm_extended_header (abfd
)->reserved2
=
260 get_word (abfd
, (bfd_byte
*) thdr
.reserved2
);
261 nlm_extended_header (abfd
)->reserved3
=
262 get_word (abfd
, (bfd_byte
*) thdr
.reserved3
);
263 nlm_extended_header (abfd
)->reserved4
=
264 get_word (abfd
, (bfd_byte
*) thdr
.reserved4
);
265 nlm_extended_header (abfd
)->reserved5
=
266 get_word (abfd
, (bfd_byte
*) thdr
.reserved5
);
268 else if (strncmp (tempstr
, "CoPyRiGhT=", 10) == 0)
270 amt
= sizeof (nlm_copyright_header (abfd
)->stamp
);
271 if (bfd_bread ((void *) nlm_copyright_header (abfd
)->stamp
,
274 if (bfd_bread ((void *) &(nlm_copyright_header (abfd
)
275 ->copyrightMessageLength
),
276 (bfd_size_type
) 1, abfd
) != 1)
278 /* The copyright message is a variable length string. */
279 amt
= nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1;
280 if (bfd_bread ((void *) nlm_copyright_header (abfd
)->copyrightMessage
,
284 else if (strncmp (tempstr
, "CuStHeAd", 8) == 0)
286 Nlm_External_Custom_Header thdr
;
287 bfd_size_type hdrLength
;
289 bfd_size_type dataLength
;
293 /* Read the stamp ("CuStHeAd"). */
294 amt
= sizeof (thdr
.stamp
);
295 if (bfd_bread ((void *) thdr
.stamp
, amt
, abfd
) != amt
)
297 /* Read the length of this custom header. */
298 amt
= sizeof (thdr
.length
);
299 if (bfd_bread ((void *) thdr
.length
, amt
, abfd
) != amt
)
301 hdrLength
= get_word (abfd
, (bfd_byte
*) thdr
.length
);
302 /* Read further fields if we have them. */
303 if (hdrLength
< NLM_TARGET_LONG_SIZE
)
307 amt
= sizeof (thdr
.dataOffset
);
308 if (bfd_bread ((void *) thdr
.dataOffset
, amt
, abfd
) != amt
)
310 dataOffset
= get_word (abfd
, (bfd_byte
*) thdr
.dataOffset
);
312 if (hdrLength
< 2 * NLM_TARGET_LONG_SIZE
)
316 amt
= sizeof (thdr
.dataLength
);
317 if (bfd_bread ((void *) thdr
.dataLength
, amt
, abfd
) != amt
)
319 dataLength
= get_word (abfd
, (bfd_byte
*) thdr
.dataLength
);
321 if (hdrLength
< 2 * NLM_TARGET_LONG_SIZE
+ 8)
322 memset (dataStamp
, 0, sizeof (dataStamp
));
325 amt
= sizeof (dataStamp
);
326 if (bfd_bread ((void *) dataStamp
, amt
, abfd
) != amt
)
330 /* Read the rest of the header, if any. */
331 if (hdrLength
<= 2 * NLM_TARGET_LONG_SIZE
+ 8)
338 hdrLength
-= 2 * NLM_TARGET_LONG_SIZE
+ 8;
339 hdr
= bfd_alloc (abfd
, hdrLength
);
342 if (bfd_bread (hdr
, hdrLength
, abfd
) != hdrLength
)
346 /* If we have found a Cygnus header, process it. Otherwise,
347 just save the associated data without trying to interpret
349 if (strncmp (dataStamp
, "CyGnUsEx", 8) == 0)
355 BFD_ASSERT (hdrLength
== 0 && hdr
== NULL
);
357 pos
= bfd_tell (abfd
);
358 if (bfd_seek (abfd
, dataOffset
, SEEK_SET
) != 0)
360 contents
= bfd_alloc (abfd
, dataLength
);
361 if (contents
== NULL
)
363 if (bfd_bread (contents
, dataLength
, abfd
) != dataLength
)
365 if (bfd_seek (abfd
, pos
, SEEK_SET
) != 0)
368 memcpy (nlm_cygnus_ext_header (abfd
), "CyGnUsEx", 8);
369 nlm_cygnus_ext_header (abfd
)->offset
= dataOffset
;
370 nlm_cygnus_ext_header (abfd
)->length
= dataLength
;
372 /* This data this header points to provides a list of
373 the sections which were in the original object file
374 which was converted to become an NLM. We locate
375 those sections and add them to the BFD. Note that
376 this is likely to create a second .text, .data and
377 .bss section; retrieving the sections by name will
378 get the actual NLM sections, which is what we want to
379 happen. The sections from the original file, which
380 may be subsets of the NLM section, can only be found
381 using bfd_map_over_sections. */
383 pend
= p
+ dataLength
;
392 /* The format of this information is
393 null terminated section name
394 zeroes to adjust to 4 byte boundary
395 4 byte section data file pointer
396 4 byte section size. */
399 l
= strlen (name
) + 1;
400 l
= (l
+ 3) &~ (size_t) 3;
402 filepos
= H_GET_32 (abfd
, p
);
404 size
= H_GET_32 (abfd
, p
);
407 newsec
= bfd_make_section_anyway (abfd
, name
);
413 newsec
->filepos
= filepos
;
414 newsec
->flags
|= SEC_HAS_CONTENTS
;
420 memcpy (nlm_custom_header (abfd
)->stamp
, thdr
.stamp
,
421 sizeof (thdr
.stamp
));
422 nlm_custom_header (abfd
)->hdrLength
= hdrLength
;
423 nlm_custom_header (abfd
)->dataOffset
= dataOffset
;
424 nlm_custom_header (abfd
)->dataLength
= dataLength
;
425 memcpy (nlm_custom_header (abfd
)->dataStamp
, dataStamp
,
427 nlm_custom_header (abfd
)->hdr
= hdr
;
437 nlm_object_p (bfd
*abfd
)
439 struct nlm_obj_tdata
*preserved_tdata
= nlm_tdata (abfd
);
440 bfd_boolean (*backend_object_p
) (bfd
*);
441 void * x_fxdhdr
= NULL
;
442 Nlm_Internal_Fixed_Header
*i_fxdhdrp
;
443 struct nlm_obj_tdata
*new_tdata
= NULL
;
444 const char *signature
;
445 enum bfd_architecture arch
;
448 /* Some NLM formats have a prefix before the standard NLM fixed
450 backend_object_p
= nlm_backend_object_p_func (abfd
);
451 if (backend_object_p
)
453 if (!(*backend_object_p
) (abfd
))
454 goto got_wrong_format_error
;
457 /* Read in the fixed length portion of the NLM header in external format. */
458 amt
= nlm_fixed_header_size (abfd
);
459 x_fxdhdr
= bfd_malloc (amt
);
460 if (x_fxdhdr
== NULL
)
463 if (bfd_bread ((void *) x_fxdhdr
, amt
, abfd
) != amt
)
465 if (bfd_get_error () != bfd_error_system_call
)
466 goto got_wrong_format_error
;
471 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
472 the tdata pointer in the bfd. */
473 amt
= sizeof (struct nlm_obj_tdata
);
474 new_tdata
= bfd_zalloc (abfd
, amt
);
475 if (new_tdata
== NULL
)
478 nlm_tdata (abfd
) = new_tdata
;
480 i_fxdhdrp
= nlm_fixed_header (abfd
);
481 nlm_swap_fixed_header_in (abfd
, x_fxdhdr
, i_fxdhdrp
);
485 /* Check to see if we have an NLM file for this backend by matching
486 the NLM signature. */
487 signature
= nlm_signature (abfd
);
488 if (signature
!= NULL
489 && *signature
!= '\0'
490 && strncmp ((char *) i_fxdhdrp
->signature
, signature
,
491 NLM_SIGNATURE_SIZE
) != 0)
492 goto got_wrong_format_error
;
494 /* There's no supported way to discover the endianess of an NLM, so test for
495 a sane version number after doing byte swapping appropriate for this
496 XVEC. (Hack alert!) */
497 if (i_fxdhdrp
->version
> 0xFFFF)
498 goto got_wrong_format_error
;
500 /* There's no supported way to check for 32 bit versus 64 bit addresses,
501 so ignore this distinction for now. (FIXME) */
502 /* Swap in the rest of the required header. */
503 if (!nlm_swap_variable_header_in (abfd
))
505 if (bfd_get_error () != bfd_error_system_call
)
506 goto got_wrong_format_error
;
511 /* Add the sections supplied by all NLM's, and then read in the
512 auxiliary headers. Reading the auxiliary headers may create
513 additional sections described in the cygnus_ext header.
514 From this point on we assume that we have an NLM, and do not
515 treat errors as indicating the wrong format. */
516 if (!add_bfd_section (abfd
, NLM_CODE_NAME
,
517 i_fxdhdrp
->codeImageOffset
,
518 i_fxdhdrp
->codeImageSize
,
519 (SEC_CODE
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
521 || !add_bfd_section (abfd
, NLM_INITIALIZED_DATA_NAME
,
522 i_fxdhdrp
->dataImageOffset
,
523 i_fxdhdrp
->dataImageSize
,
524 (SEC_DATA
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
526 || !add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
528 i_fxdhdrp
->uninitializedDataSize
,
532 if (!nlm_swap_auxiliary_headers_in (abfd
))
535 if (nlm_fixed_header (abfd
)->numberOfRelocationFixups
!= 0
536 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
537 abfd
->flags
|= HAS_RELOC
;
538 if (nlm_fixed_header (abfd
)->numberOfPublics
!= 0
539 || nlm_fixed_header (abfd
)->numberOfDebugRecords
!= 0
540 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
541 abfd
->flags
|= HAS_SYMS
;
543 arch
= nlm_architecture (abfd
);
544 if (arch
!= bfd_arch_unknown
)
545 bfd_default_set_arch_mach (abfd
, arch
, (unsigned long) 0);
547 abfd
->flags
|= EXEC_P
;
548 bfd_get_start_address (abfd
) = nlm_fixed_header (abfd
)->codeStartOffset
;
552 got_wrong_format_error
:
553 bfd_set_error (bfd_error_wrong_format
);
555 nlm_tdata (abfd
) = preserved_tdata
;
556 if (new_tdata
!= NULL
)
557 bfd_release (abfd
, new_tdata
);
558 if (x_fxdhdr
!= NULL
)
564 /* Swap and write out the variable length header. All the fields must
565 exist in the NLM, and must exist in this order. */
568 nlm_swap_variable_header_out (bfd
*abfd
)
570 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
573 /* Write the description length and text members. */
574 amt
= sizeof (nlm_variable_header (abfd
)->descriptionLength
);
575 if (bfd_bwrite (& nlm_variable_header (abfd
)->descriptionLength
, amt
,
578 amt
= nlm_variable_header (abfd
)->descriptionLength
+ 1;
579 if (bfd_bwrite ((void *) nlm_variable_header (abfd
)->descriptionText
, amt
,
583 /* Convert and write the stackSize field. */
584 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->stackSize
, temp
);
586 if (bfd_bwrite (temp
, amt
, abfd
) != amt
)
589 /* Convert and write the reserved field. */
590 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->reserved
, temp
);
592 if (bfd_bwrite (temp
, amt
, abfd
) != amt
)
595 /* Write the oldThreadName field. This field is a fixed length string. */
596 amt
= sizeof (nlm_variable_header (abfd
)->oldThreadName
);
597 if (bfd_bwrite (nlm_variable_header (abfd
)->oldThreadName
, amt
,
601 /* Write the screen name length and text members. */
602 amt
= sizeof (nlm_variable_header (abfd
)->screenNameLength
);
603 if (bfd_bwrite (& nlm_variable_header (abfd
)->screenNameLength
, amt
,
606 amt
= nlm_variable_header (abfd
)->screenNameLength
+ 1;
607 if (bfd_bwrite (nlm_variable_header (abfd
)->screenName
, amt
, abfd
) != amt
)
610 /* Write the thread name length and text members. */
611 amt
= sizeof (nlm_variable_header (abfd
)->threadNameLength
);
612 if (bfd_bwrite (& nlm_variable_header (abfd
)->threadNameLength
, amt
,
615 amt
= nlm_variable_header (abfd
)->threadNameLength
+ 1;
616 if (bfd_bwrite (nlm_variable_header (abfd
)->threadName
, amt
, abfd
) != amt
)
621 /* Return whether there is a non-zero byte in a memory block. */
624 find_nonzero (void * buf
, size_t size
)
626 char *p
= (char *) buf
;
634 /* Swap out the contents of the auxiliary headers. We create those
635 auxiliary headers which have been set non-zero. We do not require
636 the caller to set up the stamp fields. */
639 nlm_swap_auxiliary_headers_out (bfd
*abfd
)
643 /* Write out the version header if there is one. */
644 if (find_nonzero (nlm_version_header (abfd
),
645 sizeof (Nlm_Internal_Version_Header
)))
647 Nlm_External_Version_Header thdr
;
649 memcpy (thdr
.stamp
, "VeRsIoN#", 8);
650 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->majorVersion
,
651 (bfd_byte
*) thdr
.majorVersion
);
652 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->minorVersion
,
653 (bfd_byte
*) thdr
.minorVersion
);
654 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->revision
,
655 (bfd_byte
*) thdr
.revision
);
656 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->year
,
657 (bfd_byte
*) thdr
.year
);
658 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->month
,
659 (bfd_byte
*) thdr
.month
);
660 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->day
,
661 (bfd_byte
*) thdr
.day
);
662 if (bfd_bwrite ((void *) &thdr
, (bfd_size_type
) sizeof (thdr
), abfd
)
667 /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
668 tag in order to make the NW4.x and NW5.x loaders happy. */
670 /* Write out the copyright header if there is one. */
671 if (find_nonzero (nlm_copyright_header (abfd
),
672 sizeof (Nlm_Internal_Copyright_Header
)))
674 Nlm_External_Copyright_Header thdr
;
676 memcpy (thdr
.stamp
, "CoPyRiGhT=", 10);
677 amt
= sizeof (thdr
.stamp
);
678 if (bfd_bwrite ((void *) thdr
.stamp
, amt
, abfd
) != amt
)
680 thdr
.copyrightMessageLength
[0] =
681 nlm_copyright_header (abfd
)->copyrightMessageLength
;
683 if (bfd_bwrite ((void *) thdr
.copyrightMessageLength
, amt
, abfd
) != amt
)
685 /* The copyright message is a variable length string. */
686 amt
= nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1;
687 if (bfd_bwrite ((void *) nlm_copyright_header (abfd
)->copyrightMessage
,
692 /* Write out the extended header if there is one. */
693 if (find_nonzero (nlm_extended_header (abfd
),
694 sizeof (Nlm_Internal_Extended_Header
)))
696 Nlm_External_Extended_Header thdr
;
698 memcpy (thdr
.stamp
, "MeSsAgEs", 8);
700 (bfd_vma
) nlm_extended_header (abfd
)->languageID
,
701 (bfd_byte
*) thdr
.languageID
);
703 (bfd_vma
) nlm_extended_header (abfd
)->messageFileOffset
,
704 (bfd_byte
*) thdr
.messageFileOffset
);
706 (bfd_vma
) nlm_extended_header (abfd
)->messageFileLength
,
707 (bfd_byte
*) thdr
.messageFileLength
);
709 (bfd_vma
) nlm_extended_header (abfd
)->messageCount
,
710 (bfd_byte
*) thdr
.messageCount
);
712 (bfd_vma
) nlm_extended_header (abfd
)->helpFileOffset
,
713 (bfd_byte
*) thdr
.helpFileOffset
);
715 (bfd_vma
) nlm_extended_header (abfd
)->helpFileLength
,
716 (bfd_byte
*) thdr
.helpFileLength
);
718 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataOffset
,
719 (bfd_byte
*) thdr
.RPCDataOffset
);
721 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataLength
,
722 (bfd_byte
*) thdr
.RPCDataLength
);
724 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeOffset
,
725 (bfd_byte
*) thdr
.sharedCodeOffset
);
727 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeLength
,
728 (bfd_byte
*) thdr
.sharedCodeLength
);
730 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataOffset
,
731 (bfd_byte
*) thdr
.sharedDataOffset
);
733 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataLength
,
734 (bfd_byte
*) thdr
.sharedDataLength
);
736 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupOffset
,
737 (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
739 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupCount
,
740 (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
742 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceOffset
,
743 (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
745 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceCount
,
746 (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
748 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsOffset
,
749 (bfd_byte
*) thdr
.sharedPublicsOffset
);
751 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsCount
,
752 (bfd_byte
*) thdr
.sharedPublicsCount
);
754 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordOffset
,
755 (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
757 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordCount
,
758 (bfd_byte
*) thdr
.sharedDebugRecordCount
);
760 (bfd_vma
) nlm_extended_header (abfd
)->SharedInitializationOffset
,
761 (bfd_byte
*) thdr
.sharedInitializationOffset
);
763 (bfd_vma
) nlm_extended_header (abfd
)->SharedExitProcedureOffset
,
764 (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
766 (bfd_vma
) nlm_extended_header (abfd
)->productID
,
767 (bfd_byte
*) thdr
.productID
);
769 (bfd_vma
) nlm_extended_header (abfd
)->reserved0
,
770 (bfd_byte
*) thdr
.reserved0
);
772 (bfd_vma
) nlm_extended_header (abfd
)->reserved1
,
773 (bfd_byte
*) thdr
.reserved1
);
775 (bfd_vma
) nlm_extended_header (abfd
)->reserved2
,
776 (bfd_byte
*) thdr
.reserved2
);
778 (bfd_vma
) nlm_extended_header (abfd
)->reserved3
,
779 (bfd_byte
*) thdr
.reserved3
);
781 (bfd_vma
) nlm_extended_header (abfd
)->reserved4
,
782 (bfd_byte
*) thdr
.reserved4
);
784 (bfd_vma
) nlm_extended_header (abfd
)->reserved5
,
785 (bfd_byte
*) thdr
.reserved5
);
786 if (bfd_bwrite ((void *) &thdr
, (bfd_size_type
) sizeof (thdr
), abfd
)
791 /* Write out the custom header if there is one. */
792 if (find_nonzero (nlm_custom_header (abfd
),
793 sizeof (Nlm_Internal_Custom_Header
)))
795 Nlm_External_Custom_Header thdr
;
797 bfd_size_type hdrLength
;
799 ds
= find_nonzero (nlm_custom_header (abfd
)->dataStamp
,
800 sizeof (nlm_custom_header (abfd
)->dataStamp
));
801 memcpy (thdr
.stamp
, "CuStHeAd", 8);
802 hdrLength
= (2 * NLM_TARGET_LONG_SIZE
+ (ds
? 8 : 0)
803 + nlm_custom_header (abfd
)->hdrLength
);
804 put_word (abfd
, hdrLength
, thdr
.length
);
805 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataOffset
,
807 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataLength
,
811 BFD_ASSERT (nlm_custom_header (abfd
)->hdrLength
== 0);
812 amt
= sizeof (thdr
) - sizeof (thdr
.dataStamp
);
813 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
818 memcpy (thdr
.dataStamp
, nlm_custom_header (abfd
)->dataStamp
,
819 sizeof (thdr
.dataStamp
));
821 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
823 amt
= nlm_custom_header (abfd
)->hdrLength
;
824 if (bfd_bwrite (nlm_custom_header (abfd
)->hdr
, amt
, abfd
) != amt
)
829 /* Write out the Cygnus debugging header if there is one. */
830 if (find_nonzero (nlm_cygnus_ext_header (abfd
),
831 sizeof (Nlm_Internal_Cygnus_Ext_Header
)))
833 Nlm_External_Custom_Header thdr
;
835 memcpy (thdr
.stamp
, "CuStHeAd", 8);
836 put_word (abfd
, (bfd_vma
) 2 * NLM_TARGET_LONG_SIZE
+ 8,
837 (bfd_byte
*) thdr
.length
);
838 put_word (abfd
, (bfd_vma
) nlm_cygnus_ext_header (abfd
)->offset
,
839 (bfd_byte
*) thdr
.dataOffset
);
840 put_word (abfd
, (bfd_vma
) nlm_cygnus_ext_header (abfd
)->length
,
841 (bfd_byte
*) thdr
.dataLength
);
842 memcpy (thdr
.dataStamp
, "CyGnUsEx", 8);
844 if (bfd_bwrite ((void *) &thdr
, amt
, abfd
) != amt
)
851 /* We read the NLM's public symbols and use it to generate a bfd symbol
852 table (hey, it's better than nothing) on a one-for-one basis. Thus
853 use the number of public symbols as the number of bfd symbols we will
854 have once we actually get around to reading them in.
856 Return the number of bytes required to hold the symtab vector, based on
857 the count plus 1, since we will NULL terminate the vector allocated based
861 nlm_get_symtab_upper_bound (bfd
*abfd
)
863 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form. */
865 long symtab_size
= 0;
867 i_fxdhdrp
= nlm_fixed_header (abfd
);
868 symcount
= (i_fxdhdrp
->numberOfPublics
869 + i_fxdhdrp
->numberOfDebugRecords
870 + i_fxdhdrp
->numberOfExternalReferences
);
871 symtab_size
= (symcount
+ 1) * (sizeof (asymbol
));
875 /* Slurp in nlm symbol table.
877 In the external (in-file) form, NLM export records are variable length,
878 with the following form:
880 1 byte length of the symbol name (N)
881 N bytes the symbol name
882 4 bytes the symbol offset from start of it's section
884 We also read in the debugging symbols and import records. Import
885 records are treated as undefined symbols. As we read the import
886 records we also read in the associated reloc information, which is
887 attached to the symbol.
889 The bfd symbols are copied to SYMvoid *S.
891 When we return, the bfd symcount is either zero or contains the correct
892 number of symbols. */
895 nlm_slurp_symbol_table (bfd
*abfd
)
897 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form. */
898 bfd_size_type totsymcount
; /* Number of NLM symbols. */
899 bfd_size_type symcount
; /* Counter of NLM symbols. */
900 nlm_symbol_type
*sym
; /* Pointer to current bfd symbol. */
901 unsigned char symlength
; /* Symbol length read into here. */
902 unsigned char symtype
; /* Type of debugging symbol. */
903 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Symbol offsets read into here. */
904 bfd_boolean (*read_import_func
) (bfd
*, nlm_symbol_type
*);
905 bfd_boolean (*set_public_section_func
) (bfd
*, nlm_symbol_type
*);
908 if (nlm_get_symbols (abfd
) != NULL
)
911 /* Read each raw NLM symbol, using the information to create a canonical bfd
914 Note that we allocate the initial bfd canonical symbol buffer based on a
915 one-to-one mapping of the NLM symbols to canonical symbols. We actually
916 use all the NLM symbols, so there will be no space left over at the end.
917 When we have all the symbols, we build the caller's pointer vector. */
920 i_fxdhdrp
= nlm_fixed_header (abfd
);
921 totsymcount
= (i_fxdhdrp
->numberOfPublics
922 + i_fxdhdrp
->numberOfDebugRecords
923 + i_fxdhdrp
->numberOfExternalReferences
);
924 if (totsymcount
== 0)
927 if (bfd_seek (abfd
, i_fxdhdrp
->publicsOffset
, SEEK_SET
) != 0)
930 amt
= totsymcount
* sizeof (nlm_symbol_type
);
931 sym
= bfd_zalloc (abfd
, amt
);
934 nlm_set_symbols (abfd
, sym
);
936 /* We use the bfd's symcount directly as the control count, so that early
937 termination of the loop leaves the symcount correct for the symbols that
940 set_public_section_func
= nlm_set_public_section_func (abfd
);
941 symcount
= i_fxdhdrp
->numberOfPublics
;
942 while (abfd
->symcount
< symcount
)
944 amt
= sizeof (symlength
);
945 if (bfd_bread ((void *) &symlength
, amt
, abfd
) != amt
)
948 sym
->symbol
.the_bfd
= abfd
;
949 sym
->symbol
.name
= bfd_alloc (abfd
, amt
+ 1);
950 if (!sym
->symbol
.name
)
952 if (bfd_bread ((void *) sym
->symbol
.name
, amt
, abfd
) != amt
)
954 /* Cast away const. */
955 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
957 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
959 sym
->symbol
.flags
= BSF_GLOBAL
| BSF_EXPORT
;
960 sym
->symbol
.value
= get_word (abfd
, temp
);
961 if (set_public_section_func
)
963 /* Most backends can use the code below, but unfortunately
964 some use a different scheme. */
965 if (! (*set_public_section_func
) (abfd
, sym
))
970 if (sym
->symbol
.value
& NLM_HIBIT
)
972 sym
->symbol
.value
&= ~NLM_HIBIT
;
973 sym
->symbol
.flags
|= BSF_FUNCTION
;
974 sym
->symbol
.section
=
975 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
978 sym
->symbol
.section
=
979 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
986 /* Read the debugging records. */
988 if (i_fxdhdrp
->numberOfDebugRecords
> 0)
990 if (bfd_seek (abfd
, i_fxdhdrp
->debugInfoOffset
, SEEK_SET
) != 0)
993 symcount
+= i_fxdhdrp
->numberOfDebugRecords
;
994 while (abfd
->symcount
< symcount
)
996 amt
= sizeof (symtype
);
997 if (bfd_bread ((void *) &symtype
, amt
, abfd
) != amt
)
1000 if (bfd_bread ((void *) temp
, amt
, abfd
) != amt
)
1002 amt
= sizeof (symlength
);
1003 if (bfd_bread ((void *) &symlength
, amt
, abfd
) != amt
)
1006 sym
->symbol
.the_bfd
= abfd
;
1007 sym
->symbol
.name
= bfd_alloc (abfd
, amt
+ 1);
1008 if (!sym
->symbol
.name
)
1010 if (bfd_bread ((void *) sym
->symbol
.name
, amt
, abfd
) != amt
)
1012 /* Cast away const. */
1013 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
1014 sym
->symbol
.flags
= BSF_LOCAL
;
1015 sym
->symbol
.value
= get_word (abfd
, temp
);
1018 sym
->symbol
.section
=
1019 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
1020 else if (symtype
== 1)
1022 sym
->symbol
.flags
|= BSF_FUNCTION
;
1023 sym
->symbol
.section
=
1024 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
1027 sym
->symbol
.section
= bfd_abs_section_ptr
;
1035 /* Read in the import records. We can only do this if we know how
1036 to read relocs for this target. */
1037 read_import_func
= nlm_read_import_func (abfd
);
1038 if (read_import_func
!= NULL
)
1040 if (bfd_seek (abfd
, i_fxdhdrp
->externalReferencesOffset
, SEEK_SET
) != 0)
1043 symcount
+= i_fxdhdrp
->numberOfExternalReferences
;
1044 while (abfd
->symcount
< symcount
)
1046 if (! (*read_import_func
) (abfd
, sym
))
1056 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
1057 symbol table fails. */
1060 nlm_canonicalize_symtab (bfd
*abfd
, asymbol
**alocation
)
1062 nlm_symbol_type
*symbase
;
1063 bfd_size_type counter
= 0;
1065 if (! nlm_slurp_symbol_table (abfd
))
1067 symbase
= nlm_get_symbols (abfd
);
1068 while (counter
< bfd_get_symcount (abfd
))
1070 *alocation
++ = &symbase
->symbol
;
1075 return bfd_get_symcount (abfd
);
1078 /* Make an NLM symbol. There is nothing special to do here. */
1081 nlm_make_empty_symbol (bfd
*abfd
)
1083 bfd_size_type amt
= sizeof (nlm_symbol_type
);
1084 nlm_symbol_type
*new = bfd_zalloc (abfd
, amt
);
1088 new->symbol
.the_bfd
= abfd
;
1089 return & new->symbol
;
1092 /* Get symbol information. */
1095 nlm_get_symbol_info (bfd
*ignore_abfd ATTRIBUTE_UNUSED
,
1099 bfd_symbol_info (symbol
, ret
);
1102 /* Print symbol information. */
1105 nlm_print_symbol (bfd
*abfd
,
1108 bfd_print_symbol_type how
)
1110 FILE *file
= (FILE *) afile
;
1114 case bfd_print_symbol_name
:
1115 case bfd_print_symbol_more
:
1117 fprintf (file
, "%s", symbol
->name
);
1119 case bfd_print_symbol_all
:
1120 bfd_print_symbol_vandf (abfd
, (void *) file
, symbol
);
1121 fprintf (file
, " %-5s", symbol
->section
->name
);
1123 fprintf (file
, " %s", symbol
->name
);
1128 /* Get the relocs for an NLM file. There are two types of relocs.
1129 Imports are relocs against symbols defined in other NLM files. We
1130 treat these as relocs against global symbols. Relocation fixups
1131 are internal relocs.
1133 The actual format used to store the relocs is machine specific. */
1135 /* Read in the relocation fixup information. This is stored in
1136 nlm_relocation_fixups, an array of arelent structures, and
1137 nlm_relocation_fixup_secs, an array of section pointers. The
1138 section pointers are needed because the relocs are not sorted by
1142 nlm_slurp_reloc_fixups (bfd
*abfd
)
1144 bfd_boolean (*read_func
) (bfd
*, nlm_symbol_type
*, asection
**, arelent
*);
1145 bfd_size_type count
, amt
;
1149 if (nlm_relocation_fixups (abfd
) != NULL
)
1151 read_func
= nlm_read_reloc_func (abfd
);
1152 if (read_func
== NULL
)
1155 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1159 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1160 amt
= count
* sizeof (arelent
);
1161 rels
= bfd_alloc (abfd
, amt
);
1162 amt
= count
* sizeof (asection
*);
1163 secs
= bfd_alloc (abfd
, amt
);
1164 if ((rels
== NULL
|| secs
== NULL
) && count
!= 0)
1166 nlm_relocation_fixups (abfd
) = rels
;
1167 nlm_relocation_fixup_secs (abfd
) = secs
;
1169 /* We have to read piece by piece, because we don't know how large
1170 the machine specific reloc information is. */
1171 while (count
-- != 0)
1173 if (! (*read_func
) (abfd
, NULL
, secs
, rels
))
1175 nlm_relocation_fixups (abfd
) = NULL
;
1176 nlm_relocation_fixup_secs (abfd
) = NULL
;
1186 /* Get the number of relocs. This really just returns an upper bound,
1187 since it does not attempt to distinguish them based on the section.
1188 That will be handled when they are actually read. */
1191 nlm_get_reloc_upper_bound (bfd
*abfd
, asection
*sec
)
1193 nlm_symbol_type
*syms
;
1194 bfd_size_type count
;
1197 /* If we don't know how to read relocs, just return 0. */
1198 if (nlm_read_reloc_func (abfd
) == NULL
)
1200 /* Make sure we have either the code or the data section. */
1201 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1204 syms
= nlm_get_symbols (abfd
);
1207 if (! nlm_slurp_symbol_table (abfd
))
1209 syms
= nlm_get_symbols (abfd
);
1212 ret
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1214 count
= bfd_get_symcount (abfd
);
1215 while (count
-- != 0)
1221 return (ret
+ 1) * sizeof (arelent
*);
1224 /* Get the relocs themselves. */
1227 nlm_canonicalize_reloc (bfd
*abfd
,
1234 bfd_size_type count
, i
;
1237 /* Get the relocation fixups. */
1238 rels
= nlm_relocation_fixups (abfd
);
1241 if (! nlm_slurp_reloc_fixups (abfd
))
1243 rels
= nlm_relocation_fixups (abfd
);
1245 secs
= nlm_relocation_fixup_secs (abfd
);
1248 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1249 for (i
= 0; i
< count
; i
++, rels
++, secs
++)
1258 /* Get the import symbols. */
1259 count
= bfd_get_symcount (abfd
);
1260 for (i
= 0; i
< count
; i
++, symbols
++)
1265 if (bfd_asymbol_flavour (sym
) == bfd_target_nlm_flavour
)
1267 nlm_symbol_type
*nlm_sym
;
1270 nlm_sym
= (nlm_symbol_type
*) sym
;
1271 for (j
= 0; j
< nlm_sym
->rcnt
; j
++)
1273 if (nlm_sym
->relocs
[j
].section
== sec
)
1275 *relptr
= &nlm_sym
->relocs
[j
].reloc
;
1276 (*relptr
)->sym_ptr_ptr
= symbols
;
1289 /* Compute the section file positions for an NLM file. All variable
1290 length data in the file headers must be set before this function is
1291 called. If the variable length data is changed later, the
1292 resulting object file will be incorrect. Unfortunately, there is
1293 no way to check this.
1295 This routine also sets the Size and Offset fields in the fixed
1298 It also looks over the symbols and moves any common symbols into
1299 the .bss section; NLM has no way to represent a common symbol.
1300 This approach means that either the symbols must already have been
1301 set at this point, or there must be no common symbols. We need to
1302 move the symbols at this point so that mangle_relocs can see the
1306 nlm_compute_section_file_positions (bfd
*abfd
)
1310 bfd_vma text
, data
, bss
;
1311 bfd_vma text_low
, data_low
;
1312 unsigned int text_align
, data_align
, other_align
;
1313 file_ptr text_ptr
, data_ptr
, other_ptr
;
1315 asymbol
**sym_ptr_ptr
;
1317 if (abfd
->output_has_begun
)
1320 /* Make sure we have a section to hold uninitialized data. */
1321 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1322 if (bss_sec
== NULL
)
1324 if (!add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
1325 (file_ptr
) 0, (bfd_size_type
) 0,
1328 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1331 abfd
->output_has_begun
= TRUE
;
1333 /* The fixed header. */
1334 sofar
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1336 /* The variable header. */
1337 sofar
+= (sizeof (nlm_variable_header (abfd
)->descriptionLength
)
1338 + nlm_variable_header (abfd
)->descriptionLength
+ 1
1339 + NLM_TARGET_LONG_SIZE
/* stackSize */
1340 + NLM_TARGET_LONG_SIZE
/* reserved */
1341 + sizeof (nlm_variable_header (abfd
)->oldThreadName
)
1342 + sizeof (nlm_variable_header (abfd
)->screenNameLength
)
1343 + nlm_variable_header (abfd
)->screenNameLength
+ 1
1344 + sizeof (nlm_variable_header (abfd
)->threadNameLength
)
1345 + nlm_variable_header (abfd
)->threadNameLength
+ 1);
1347 /* The auxiliary headers. */
1348 if (find_nonzero (nlm_version_header (abfd
),
1349 sizeof (Nlm_Internal_Version_Header
)))
1350 sofar
+= sizeof (Nlm_External_Version_Header
);
1351 if (find_nonzero (nlm_extended_header (abfd
),
1352 sizeof (Nlm_Internal_Extended_Header
)))
1353 sofar
+= sizeof (Nlm_External_Extended_Header
);
1354 if (find_nonzero (nlm_copyright_header (abfd
),
1355 sizeof (Nlm_Internal_Copyright_Header
)))
1356 sofar
+= (sizeof (Nlm_External_Copyright_Header
)
1357 + nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1);
1358 if (find_nonzero (nlm_custom_header (abfd
),
1359 sizeof (Nlm_Internal_Custom_Header
)))
1360 sofar
+= (sizeof (Nlm_External_Custom_Header
)
1361 + nlm_custom_header (abfd
)->hdrLength
);
1362 if (find_nonzero (nlm_cygnus_ext_header (abfd
),
1363 sizeof (Nlm_Internal_Cygnus_Ext_Header
)))
1364 sofar
+= sizeof (Nlm_External_Custom_Header
);
1366 /* Compute the section file positions in two passes. First get the
1367 sizes of the text and data sections, and then set the file
1368 positions. This code aligns the sections in the file using the
1369 same alignment restrictions that apply to the sections in memory;
1370 this may not be necessary. */
1372 text_low
= (bfd_vma
) - 1;
1375 data_low
= (bfd_vma
) - 1;
1379 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1383 sec
->size
= BFD_ALIGN (sec
->size
, 1 << sec
->alignment_power
);
1385 f
= bfd_get_section_flags (abfd
, sec
);
1389 if (bfd_get_section_vma (abfd
, sec
) < text_low
)
1390 text_low
= bfd_get_section_vma (abfd
, sec
);
1391 if (sec
->alignment_power
> text_align
)
1392 text_align
= sec
->alignment_power
;
1394 else if (f
& SEC_DATA
)
1397 if (bfd_get_section_vma (abfd
, sec
) < data_low
)
1398 data_low
= bfd_get_section_vma (abfd
, sec
);
1399 if (sec
->alignment_power
> data_align
)
1400 data_align
= sec
->alignment_power
;
1402 else if (f
& SEC_HAS_CONTENTS
)
1404 if (sec
->alignment_power
> other_align
)
1405 other_align
= sec
->alignment_power
;
1407 else if (f
& SEC_ALLOC
)
1411 nlm_set_text_low (abfd
, text_low
);
1412 nlm_set_data_low (abfd
, data_low
);
1414 if (nlm_no_uninitialized_data (abfd
))
1416 /* This NetWare format does not use uninitialized data. We must
1417 increase the size of the data section. We will never wind up
1418 writing those file locations, so they will remain zero. */
1423 text_ptr
= BFD_ALIGN (sofar
, 1 << text_align
);
1424 data_ptr
= BFD_ALIGN (text_ptr
+ text
, 1 << data_align
);
1425 other_ptr
= BFD_ALIGN (data_ptr
+ data
, 1 << other_align
);
1427 /* Fill in some fields in the header for which we now have the
1429 nlm_fixed_header (abfd
)->codeImageOffset
= text_ptr
;
1430 nlm_fixed_header (abfd
)->codeImageSize
= text
;
1431 nlm_fixed_header (abfd
)->dataImageOffset
= data_ptr
;
1432 nlm_fixed_header (abfd
)->dataImageSize
= data
;
1433 nlm_fixed_header (abfd
)->uninitializedDataSize
= bss
;
1435 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1439 f
= bfd_get_section_flags (abfd
, sec
);
1443 sec
->filepos
= text_ptr
;
1444 text_ptr
+= sec
->size
;
1446 else if (f
& SEC_DATA
)
1448 sec
->filepos
= data_ptr
;
1449 data_ptr
+= sec
->size
;
1451 else if (f
& SEC_HAS_CONTENTS
)
1453 sec
->filepos
= other_ptr
;
1454 other_ptr
+= sec
->size
;
1458 nlm_fixed_header (abfd
)->relocationFixupOffset
= other_ptr
;
1460 /* Move all common symbols into the .bss section. */
1462 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1463 if (sym_ptr_ptr
!= NULL
)
1468 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1470 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1477 if (!bfd_is_com_section (bfd_get_section (sym
)))
1480 /* Put the common symbol in the .bss section, and increase
1481 the size of the .bss section by the size of the common
1482 symbol (which is the old value of the symbol). */
1483 sym
->section
= bss_sec
;
1485 sym
->value
= bss_sec
->size
+ add
;
1487 add
= BFD_ALIGN (add
, 1 << bss_sec
->alignment_power
);
1491 if (nlm_no_uninitialized_data (abfd
))
1493 /* We could handle this case, but so far it hasn't been
1497 nlm_fixed_header (abfd
)->uninitializedDataSize
+= add
;
1498 bss_sec
->size
+= add
;
1505 /* Set the contents of a section. To do this we need to know where
1506 the section is going to be located in the output file. That means
1507 that the sizes of all the sections must be set, and all the
1508 variable size header information must be known. */
1511 nlm_set_section_contents (bfd
*abfd
,
1513 const void * location
,
1515 bfd_size_type count
)
1517 if (! abfd
->output_has_begun
1518 && ! nlm_compute_section_file_positions (abfd
))
1524 /* i386 NetWare has a very restricted set of relocs. In order for
1525 objcopy to work, the NLM i386 backend needs a chance to rework
1526 the section contents so that its set of relocs will work. If all
1527 the relocs are already acceptable, this will not do anything. */
1528 if (section
->reloc_count
!= 0)
1530 bfd_boolean (*mangle_relocs_func
)
1531 (bfd
*, asection
*, const void *, bfd_vma
, bfd_size_type
);
1533 mangle_relocs_func
= nlm_mangle_relocs_func (abfd
);
1534 if (mangle_relocs_func
!= NULL
)
1536 if (!(*mangle_relocs_func
) (abfd
, section
, location
,
1537 (bfd_vma
) offset
, count
))
1542 if (bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
) != 0
1543 || bfd_bwrite (location
, count
, abfd
) != count
)
1549 /* We need to sort a list of relocs associated with sections when we
1550 write out the external relocs. */
1553 nlm_external_reloc_compare (const void *p1
, const void *p2
)
1555 const struct reloc_and_sec
*r1
= (const struct reloc_and_sec
*) p1
;
1556 const struct reloc_and_sec
*r2
= (const struct reloc_and_sec
*) p2
;
1559 cmp
= strcmp ((*r1
->rel
->sym_ptr_ptr
)->name
,
1560 (*r2
->rel
->sym_ptr_ptr
)->name
);
1564 /* We sort by address within symbol to make the sort more stable and
1565 increase the chances that different hosts will generate bit for
1566 bit equivalent results. */
1567 return (int) (r1
->rel
->address
- r2
->rel
->address
);
1570 /* Write out an NLM file. We write out the information in this order:
1576 other sections (custom data, messages, help, shared NLM, RPC,
1577 module dependencies)
1579 external references (imports)
1580 public symbols (exports)
1582 This is similar to the order used by the NetWare tools; the
1583 difference is that NetWare puts the sections other than code, data
1584 and custom data at the end of the NLM. It is convenient for us to
1585 know where the sections are going to be before worrying about the
1586 size of the other information.
1588 By the time this function is called, all the section data should
1589 have been output using set_section_contents. Note that custom
1590 data, the message file, the help file, the shared NLM file, the RPC
1591 data, and the module dependencies are all considered to be
1592 sections; the caller is responsible for filling in the offset and
1593 length fields in the NLM headers. The relocation fixups and
1594 imports are both obtained from the list of relocs attached to each
1595 section. The exports and debugging records are obtained from the
1596 list of outsymbols. */
1599 nlm_write_object_contents (bfd
*abfd
)
1602 bfd_boolean (*write_import_func
) (bfd
*, asection
*, arelent
*);
1603 bfd_size_type external_reloc_count
, internal_reloc_count
, i
, c
;
1604 struct reloc_and_sec
*external_relocs
;
1605 asymbol
**sym_ptr_ptr
;
1607 bfd_boolean (*write_prefix_func
) (bfd
*);
1608 unsigned char *fixed_header
= NULL
;
1612 fixed_header
= bfd_malloc (nlm_fixed_header_size (abfd
));
1613 if (fixed_header
== NULL
)
1616 if (! abfd
->output_has_begun
1617 && ! nlm_compute_section_file_positions (abfd
))
1620 /* Write out the variable length headers. */
1621 pos
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1622 if (bfd_seek (abfd
, pos
, SEEK_SET
) != 0)
1624 if (! nlm_swap_variable_header_out (abfd
)
1625 || ! nlm_swap_auxiliary_headers_out (abfd
))
1627 bfd_set_error (bfd_error_system_call
);
1631 /* A weak check on whether the section file positions were
1633 if (bfd_tell (abfd
) > nlm_fixed_header (abfd
)->codeImageOffset
)
1635 bfd_set_error (bfd_error_invalid_operation
);
1639 /* Advance to the relocs. */
1640 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1644 /* The format of the relocation entries is dependent upon the
1645 particular target. We use an external routine to write the reloc
1647 write_import_func
= nlm_write_import_func (abfd
);
1649 /* Write out the internal relocation fixups. While we're looping
1650 over the relocs, we also count the external relocs, which is
1651 needed when they are written out below. */
1652 internal_reloc_count
= 0;
1653 external_reloc_count
= 0;
1654 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1656 arelent
**rel_ptr_ptr
, **rel_end
;
1658 if (sec
->reloc_count
== 0)
1661 /* We can only represent relocs within a code or data
1662 section. We ignore them for a debugging section. */
1663 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1666 /* We need to know how to write out imports */
1667 if (write_import_func
== NULL
)
1669 bfd_set_error (bfd_error_invalid_operation
);
1673 rel_ptr_ptr
= sec
->orelocation
;
1674 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1675 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1681 sym
= *rel
->sym_ptr_ptr
;
1683 if (! bfd_is_und_section (bfd_get_section (sym
)))
1685 ++internal_reloc_count
;
1686 if (! (*write_import_func
) (abfd
, sec
, rel
))
1690 ++external_reloc_count
;
1693 nlm_fixed_header (abfd
)->numberOfRelocationFixups
= internal_reloc_count
;
1695 /* Write out the imports (relocs against external symbols). These
1696 are output as a symbol name followed by all the relocs for that
1697 symbol, so we must first gather together all the relocs against
1698 external symbols and sort them. */
1699 amt
= external_reloc_count
* sizeof (struct reloc_and_sec
);
1700 external_relocs
= bfd_alloc (abfd
, amt
);
1701 if (external_relocs
== NULL
)
1704 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
1706 arelent
**rel_ptr_ptr
, **rel_end
;
1708 if (sec
->reloc_count
== 0)
1711 rel_ptr_ptr
= sec
->orelocation
;
1712 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1713 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1719 sym
= *rel
->sym_ptr_ptr
;
1721 if (! bfd_is_und_section (bfd_get_section (sym
)))
1724 external_relocs
[i
].rel
= rel
;
1725 external_relocs
[i
].sec
= sec
;
1730 BFD_ASSERT (i
== external_reloc_count
);
1732 /* Sort the external relocs by name. */
1733 qsort (external_relocs
, (size_t) external_reloc_count
,
1734 sizeof (struct reloc_and_sec
), nlm_external_reloc_compare
);
1736 /* Write out the external relocs. */
1737 nlm_fixed_header (abfd
)->externalReferencesOffset
= bfd_tell (abfd
);
1740 while (i
< external_reloc_count
)
1744 bfd_size_type j
, cnt
;
1748 rel
= external_relocs
[i
].rel
;
1749 sym
= *rel
->sym_ptr_ptr
;
1753 (j
< external_reloc_count
1754 && *external_relocs
[j
].rel
->sym_ptr_ptr
== sym
);
1758 if (! (*nlm_write_external_func (abfd
)) (abfd
, cnt
, sym
,
1759 &external_relocs
[i
]))
1765 nlm_fixed_header (abfd
)->numberOfExternalReferences
= c
;
1767 /* Write out the public symbols (exports). */
1768 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1769 if (sym_ptr_ptr
!= NULL
)
1771 bfd_vma (*get_public_offset_func
) (bfd
*, asymbol
*);
1772 bfd_boolean (*write_export_func
) (bfd
*, asymbol
*, bfd_vma
);
1776 nlm_fixed_header (abfd
)->publicsOffset
= bfd_tell (abfd
);
1777 get_public_offset_func
= nlm_get_public_offset_func (abfd
);
1778 write_export_func
= nlm_write_export_func (abfd
);
1780 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1781 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1786 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1790 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) == 0
1791 || bfd_is_und_section (bfd_get_section (sym
)))
1796 if (get_public_offset_func
)
1798 /* Most backends can use the code below, but
1799 unfortunately some use a different scheme. */
1800 offset
= (*get_public_offset_func
) (abfd
, sym
);
1804 offset
= bfd_asymbol_value (sym
);
1806 if (sec
->flags
& SEC_CODE
)
1808 offset
-= nlm_get_text_low (abfd
);
1809 offset
|= NLM_HIBIT
;
1811 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1813 /* SEC_ALLOC is for the .bss section. */
1814 offset
-= nlm_get_data_low (abfd
);
1818 /* We can't handle an exported symbol that is not in
1819 the code or data segment. */
1820 bfd_set_error (bfd_error_invalid_operation
);
1825 if (write_export_func
)
1827 if (! (*write_export_func
) (abfd
, sym
, offset
))
1832 len
= strlen (sym
->name
);
1833 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1834 != sizeof (bfd_byte
))
1835 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
1838 put_word (abfd
, offset
, temp
);
1839 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
)
1844 nlm_fixed_header (abfd
)->numberOfPublics
= c
;
1846 /* Write out the debugging records. The NLM conversion program
1847 wants to be able to inhibit this, so as a special hack if
1848 debugInfoOffset is set to -1 we don't write any debugging
1849 information. This can not be handled by fiddling with the
1850 symbol table, because exported symbols appear in both the
1851 exported symbol list and the debugging information. */
1852 if (nlm_fixed_header (abfd
)->debugInfoOffset
== (file_ptr
) - 1)
1854 nlm_fixed_header (abfd
)->debugInfoOffset
= 0;
1855 nlm_fixed_header (abfd
)->numberOfDebugRecords
= 0;
1859 nlm_fixed_header (abfd
)->debugInfoOffset
= bfd_tell (abfd
);
1861 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1862 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1863 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1868 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1872 /* The NLM notion of a debugging symbol is actually what
1873 BFD calls a local or global symbol. What BFD calls a
1874 debugging symbol NLM does not understand at all. */
1875 if ((sym
->flags
& (BSF_LOCAL
| BSF_GLOBAL
| BSF_EXPORT
)) == 0
1876 || (sym
->flags
& BSF_DEBUGGING
) != 0
1877 || bfd_is_und_section (bfd_get_section (sym
)))
1882 offset
= bfd_asymbol_value (sym
);
1884 if (sec
->flags
& SEC_CODE
)
1886 offset
-= nlm_get_text_low (abfd
);
1889 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1891 /* SEC_ALLOC is for the .bss section. */
1892 offset
-= nlm_get_data_low (abfd
);
1898 /* The type is 0 for data, 1 for code, 2 for absolute. */
1899 if (bfd_bwrite (&type
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1900 != sizeof (bfd_byte
))
1903 put_word (abfd
, offset
, temp
);
1904 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
)
1908 len
= strlen (sym
->name
);
1909 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
1910 != sizeof (bfd_byte
))
1911 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
1914 nlm_fixed_header (abfd
)->numberOfDebugRecords
= c
;
1918 /* NLMLINK fills in offset values even if there is no data, so we do
1920 last
= bfd_tell (abfd
);
1921 if (nlm_fixed_header (abfd
)->codeImageOffset
== 0)
1922 nlm_fixed_header (abfd
)->codeImageOffset
= last
;
1923 if (nlm_fixed_header (abfd
)->dataImageOffset
== 0)
1924 nlm_fixed_header (abfd
)->dataImageOffset
= last
;
1925 if (nlm_fixed_header (abfd
)->customDataOffset
== 0)
1926 nlm_fixed_header (abfd
)->customDataOffset
= last
;
1927 if (nlm_fixed_header (abfd
)->moduleDependencyOffset
== 0)
1928 nlm_fixed_header (abfd
)->moduleDependencyOffset
= last
;
1929 if (nlm_fixed_header (abfd
)->relocationFixupOffset
== 0)
1930 nlm_fixed_header (abfd
)->relocationFixupOffset
= last
;
1931 if (nlm_fixed_header (abfd
)->externalReferencesOffset
== 0)
1932 nlm_fixed_header (abfd
)->externalReferencesOffset
= last
;
1933 if (nlm_fixed_header (abfd
)->publicsOffset
== 0)
1934 nlm_fixed_header (abfd
)->publicsOffset
= last
;
1935 if (nlm_fixed_header (abfd
)->debugInfoOffset
== 0)
1936 nlm_fixed_header (abfd
)->debugInfoOffset
= last
;
1938 /* At this point everything has been written out except the fixed
1940 memcpy (nlm_fixed_header (abfd
)->signature
, nlm_signature (abfd
),
1941 NLM_SIGNATURE_SIZE
);
1942 nlm_fixed_header (abfd
)->version
= NLM_HEADER_VERSION
;
1943 nlm_fixed_header (abfd
)->codeStartOffset
=
1944 (bfd_get_start_address (abfd
)
1945 - nlm_get_text_low (abfd
));
1947 /* We have no convenient way for the caller to pass in the exit
1948 procedure or the check unload procedure, so the caller must set
1949 the values in the header to the values of the symbols. */
1950 nlm_fixed_header (abfd
)->exitProcedureOffset
-= nlm_get_text_low (abfd
);
1951 if (nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
!= 0)
1952 nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
-=
1953 nlm_get_text_low (abfd
);
1955 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0)
1958 write_prefix_func
= nlm_write_prefix_func (abfd
);
1959 if (write_prefix_func
)
1961 if (! (*write_prefix_func
) (abfd
))
1965 BFD_ASSERT ((bfd_size_type
) bfd_tell (abfd
)
1966 == nlm_optional_prefix_size (abfd
));
1968 nlm_swap_fixed_header_out (abfd
, nlm_fixed_header (abfd
), fixed_header
);
1969 if (bfd_bwrite (fixed_header
, nlm_fixed_header_size (abfd
), abfd
)
1970 != nlm_fixed_header_size (abfd
))
1973 if (fixed_header
!= NULL
)
1974 free (fixed_header
);
1978 if (fixed_header
!= NULL
)
1979 free (fixed_header
);