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