1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 Written by Fred Fish @ Cygnus Support, using ELF support as the
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include <string.h> /* For strrchr and friends */
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_get_symtab nlmNAME(get_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 boolean add_bfd_section
63 PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
64 static boolean nlm_swap_variable_header_in
66 static boolean nlm_swap_variable_header_out
68 static boolean find_nonzero
69 PARAMS ((PTR, size_t));
70 static boolean nlm_swap_auxiliary_headers_in
72 static boolean nlm_swap_auxiliary_headers_out
74 static boolean nlm_slurp_symbol_table
76 static boolean nlm_slurp_reloc_fixups
78 static 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 bfd_h_put_64
87 #define get_word bfd_h_get_64
90 #define put_word bfd_h_put_32
91 #define get_word bfd_h_get_32
98 struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
99 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;
106 /* Some NLM formats have a prefix before the standard NLM fixed
108 backend_object_p = nlm_backend_object_p_func (abfd);
109 if (backend_object_p)
111 if (!(*backend_object_p) (abfd))
112 goto got_wrong_format_error;
115 /* Read in the fixed length portion of the NLM header in external format. */
117 x_fxdhdr = (PTR) malloc (nlm_fixed_header_size (abfd));
118 if (x_fxdhdr == NULL)
120 bfd_set_error (bfd_error_no_memory);
124 if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=
125 nlm_fixed_header_size (abfd))
127 if (bfd_get_error () != bfd_error_system_call)
128 goto got_wrong_format_error;
133 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
134 the tdata pointer in the bfd. */
136 new_tdata = ((struct nlm_obj_tdata *)
137 bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)));
138 if (new_tdata == NULL)
140 bfd_set_error (bfd_error_no_memory);
144 nlm_tdata (abfd) = new_tdata;
146 i_fxdhdrp = nlm_fixed_header (abfd);
147 nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
151 /* Check to see if we have an NLM file for this backend by matching
152 the NLM signature. */
154 signature = nlm_signature (abfd);
155 if (signature != NULL
156 && *signature != '\0'
157 && strncmp ((char *) i_fxdhdrp->signature, signature,
158 NLM_SIGNATURE_SIZE) != 0)
159 goto got_wrong_format_error;
161 /* There's no supported way to discover the endianess of an NLM, so test for
162 a sane version number after doing byte swapping appropriate for this
163 XVEC. (Hack alert!) */
165 if (i_fxdhdrp->version > 0xFFFF)
166 goto got_wrong_format_error;
168 /* There's no supported way to check for 32 bit versus 64 bit addresses,
169 so ignore this distinction for now. (FIXME) */
171 /* Swap in the rest of the required header. */
172 if (!nlm_swap_variable_header_in (abfd))
174 if (bfd_get_error () != bfd_error_system_call)
175 goto got_wrong_format_error;
180 /* Add the sections supplied by all NLM's, and then read in the
181 auxiliary headers. Reading the auxiliary headers may create
182 additional sections described in the cygnus_ext header.
183 From this point on we assume that we have an NLM, and do not
184 treat errors as indicating the wrong format. */
186 if (!add_bfd_section (abfd, NLM_CODE_NAME,
187 i_fxdhdrp->codeImageOffset,
188 i_fxdhdrp->codeImageSize,
189 (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
191 || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
192 i_fxdhdrp->dataImageOffset,
193 i_fxdhdrp->dataImageSize,
194 (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
196 || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
198 i_fxdhdrp->uninitializedDataSize,
202 if (!nlm_swap_auxiliary_headers_in (abfd))
205 if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
206 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
207 abfd->flags |= HAS_RELOC;
208 if (nlm_fixed_header (abfd)->numberOfPublics != 0
209 || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
210 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
211 abfd->flags |= HAS_SYMS;
213 arch = nlm_architecture (abfd);
214 if (arch != bfd_arch_unknown)
215 bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
217 abfd->flags |= EXEC_P;
218 bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
222 got_wrong_format_error:
223 bfd_set_error (bfd_error_wrong_format);
225 nlm_tdata (abfd) = preserved_tdata;
226 if (new_tdata != NULL)
227 bfd_release (abfd, new_tdata);
228 if (x_fxdhdr != NULL)
233 /* Add a section to the bfd. */
236 add_bfd_section (abfd, name, offset, size, flags)
245 newsect = bfd_make_section (abfd, name);
250 newsect->vma = 0; /* NLM's are relocatable. */
251 newsect->_raw_size = size;
252 newsect->filepos = offset;
253 newsect->flags = flags;
254 newsect->alignment_power = bfd_log2 (0); /* FIXME */
258 /* Read and swap in the variable length header. All the fields must
259 exist in the NLM, and must exist in the order they are read here. */
262 nlm_swap_variable_header_in (abfd)
265 unsigned char temp[NLM_TARGET_LONG_SIZE];
267 /* Read the description length and text members. */
269 if (bfd_read ((PTR) & nlm_variable_header (abfd)->descriptionLength,
270 sizeof (nlm_variable_header (abfd)->descriptionLength),
272 sizeof (nlm_variable_header (abfd)->descriptionLength))
274 if (bfd_read ((PTR) nlm_variable_header (abfd)->descriptionText,
275 nlm_variable_header (abfd)->descriptionLength + 1,
277 nlm_variable_header (abfd)->descriptionLength + 1)
280 /* Read and convert the stackSize field. */
282 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
284 nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
286 /* Read and convert the reserved field. */
288 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
290 nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
292 /* Read the oldThreadName field. This field is a fixed length string. */
294 if (bfd_read ((PTR) nlm_variable_header (abfd)->oldThreadName,
295 sizeof (nlm_variable_header (abfd)->oldThreadName),
297 sizeof (nlm_variable_header (abfd)->oldThreadName))
300 /* Read the screen name length and text members. */
302 if (bfd_read ((PTR) & nlm_variable_header (abfd)->screenNameLength,
303 sizeof (nlm_variable_header (abfd)->screenNameLength),
305 sizeof (nlm_variable_header (abfd)->screenNameLength))
307 if (bfd_read ((PTR) nlm_variable_header (abfd)->screenName,
308 nlm_variable_header (abfd)->screenNameLength + 1,
310 nlm_variable_header (abfd)->screenNameLength + 1)
313 /* Read the thread name length and text members. */
315 if (bfd_read ((PTR) & nlm_variable_header (abfd)->threadNameLength,
316 sizeof (nlm_variable_header (abfd)->threadNameLength),
318 sizeof (nlm_variable_header (abfd)->threadNameLength))
320 if (bfd_read ((PTR) nlm_variable_header (abfd)->threadName,
321 nlm_variable_header (abfd)->threadNameLength + 1,
323 nlm_variable_header (abfd)->threadNameLength + 1)
328 /* Swap and write out the variable length header. All the fields must
329 exist in the NLM, and must exist in this order. */
332 nlm_swap_variable_header_out (abfd)
335 unsigned char temp[NLM_TARGET_LONG_SIZE];
337 /* Write the description length and text members. */
339 if (bfd_write ((PTR) & nlm_variable_header (abfd)->descriptionLength,
340 sizeof (nlm_variable_header (abfd)->descriptionLength),
342 sizeof (nlm_variable_header (abfd)->descriptionLength))
344 if (bfd_write ((PTR) nlm_variable_header (abfd)->descriptionText,
345 nlm_variable_header (abfd)->descriptionLength + 1,
347 nlm_variable_header (abfd)->descriptionLength + 1)
350 /* Convert and write the stackSize field. */
352 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
354 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
357 /* Convert and write the reserved field. */
359 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
361 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
364 /* Write the oldThreadName field. This field is a fixed length string. */
366 if (bfd_write ((PTR) nlm_variable_header (abfd)->oldThreadName,
367 sizeof (nlm_variable_header (abfd)->oldThreadName),
369 sizeof (nlm_variable_header (abfd)->oldThreadName))
372 /* Write the screen name length and text members. */
374 if (bfd_write ((PTR) & nlm_variable_header (abfd)->screenNameLength,
375 sizeof (nlm_variable_header (abfd)->screenNameLength),
377 sizeof (nlm_variable_header (abfd)->screenNameLength))
379 if (bfd_write ((PTR) nlm_variable_header (abfd)->screenName,
380 nlm_variable_header (abfd)->screenNameLength + 1,
382 nlm_variable_header (abfd)->screenNameLength + 1)
385 /* Write the thread name length and text members. */
387 if (bfd_write ((PTR) & nlm_variable_header (abfd)->threadNameLength,
388 sizeof (nlm_variable_header (abfd)->threadNameLength),
390 sizeof (nlm_variable_header (abfd)->threadNameLength))
392 if (bfd_write ((PTR) nlm_variable_header (abfd)->threadName,
393 nlm_variable_header (abfd)->threadNameLength + 1,
395 nlm_variable_header (abfd)->threadNameLength + 1)
400 /* Read and swap in the contents of all the auxiliary headers. Because of
401 the braindead design, we have to do strcmps on strings of indeterminate
402 length to figure out what each auxiliary header is. Even worse, we have
403 no way of knowing how many auxiliary headers there are or where the end
404 of the auxiliary headers are, except by finding something that doesn't
405 look like a known auxiliary header. This means that the first new type
406 of auxiliary header added will break all existing tools that don't
410 nlm_swap_auxiliary_headers_in (abfd)
418 position = bfd_tell (abfd);
419 if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) !=
422 if (bfd_seek (abfd, position, SEEK_SET) == -1)
424 if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
426 Nlm_External_Version_Header thdr;
427 if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
429 memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
430 sizeof (thdr.stamp));
431 nlm_version_header (abfd)->majorVersion =
432 get_word (abfd, (bfd_byte *) thdr.majorVersion);
433 nlm_version_header (abfd)->minorVersion =
434 get_word (abfd, (bfd_byte *) thdr.minorVersion);
435 nlm_version_header (abfd)->revision =
436 get_word (abfd, (bfd_byte *) thdr.revision);
437 nlm_version_header (abfd)->year =
438 get_word (abfd, (bfd_byte *) thdr.year);
439 nlm_version_header (abfd)->month =
440 get_word (abfd, (bfd_byte *) thdr.month);
441 nlm_version_header (abfd)->day =
442 get_word (abfd, (bfd_byte *) thdr.day);
444 else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
446 Nlm_External_Extended_Header thdr;
447 if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
449 memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
450 sizeof (thdr.stamp));
451 nlm_extended_header (abfd)->languageID =
452 get_word (abfd, (bfd_byte *) thdr.languageID);
453 nlm_extended_header (abfd)->messageFileOffset =
454 get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
455 nlm_extended_header (abfd)->messageFileLength =
456 get_word (abfd, (bfd_byte *) thdr.messageFileLength);
457 nlm_extended_header (abfd)->messageCount =
458 get_word (abfd, (bfd_byte *) thdr.messageCount);
459 nlm_extended_header (abfd)->helpFileOffset =
460 get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
461 nlm_extended_header (abfd)->helpFileLength =
462 get_word (abfd, (bfd_byte *) thdr.helpFileLength);
463 nlm_extended_header (abfd)->RPCDataOffset =
464 get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
465 nlm_extended_header (abfd)->RPCDataLength =
466 get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
467 nlm_extended_header (abfd)->sharedCodeOffset =
468 get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
469 nlm_extended_header (abfd)->sharedCodeLength =
470 get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
471 nlm_extended_header (abfd)->sharedDataOffset =
472 get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
473 nlm_extended_header (abfd)->sharedDataLength =
474 get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
475 nlm_extended_header (abfd)->sharedRelocationFixupOffset =
476 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
477 nlm_extended_header (abfd)->sharedRelocationFixupCount =
478 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
479 nlm_extended_header (abfd)->sharedExternalReferenceOffset =
480 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
481 nlm_extended_header (abfd)->sharedExternalReferenceCount =
482 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
483 nlm_extended_header (abfd)->sharedPublicsOffset =
484 get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
485 nlm_extended_header (abfd)->sharedPublicsCount =
486 get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
487 nlm_extended_header (abfd)->sharedDebugRecordOffset =
488 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
489 nlm_extended_header (abfd)->sharedDebugRecordCount =
490 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
491 nlm_extended_header (abfd)->SharedInitializationOffset =
492 get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
493 nlm_extended_header (abfd)->SharedExitProcedureOffset =
494 get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
495 nlm_extended_header (abfd)->productID =
496 get_word (abfd, (bfd_byte *) thdr.productID);
497 nlm_extended_header (abfd)->reserved0 =
498 get_word (abfd, (bfd_byte *) thdr.reserved0);
499 nlm_extended_header (abfd)->reserved1 =
500 get_word (abfd, (bfd_byte *) thdr.reserved1);
501 nlm_extended_header (abfd)->reserved2 =
502 get_word (abfd, (bfd_byte *) thdr.reserved2);
503 nlm_extended_header (abfd)->reserved3 =
504 get_word (abfd, (bfd_byte *) thdr.reserved3);
505 nlm_extended_header (abfd)->reserved4 =
506 get_word (abfd, (bfd_byte *) thdr.reserved4);
507 nlm_extended_header (abfd)->reserved5 =
508 get_word (abfd, (bfd_byte *) thdr.reserved5);
510 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
512 if (bfd_read ((PTR) nlm_copyright_header (abfd)->stamp,
513 sizeof (nlm_copyright_header (abfd)->stamp),
515 != sizeof (nlm_copyright_header (abfd)->stamp))
517 if (bfd_read ((PTR) & (nlm_copyright_header (abfd)
518 ->copyrightMessageLength),
521 /* The copyright message is a variable length string. */
522 if (bfd_read ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
523 nlm_copyright_header (abfd)->copyrightMessageLength + 1,
525 nlm_copyright_header (abfd)->copyrightMessageLength + 1)
528 else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
530 Nlm_External_Custom_Header thdr;
531 bfd_size_type hdrLength;
533 bfd_size_type dataLength;
537 /* Read the stamp ("CuStHeAd"). */
538 if (bfd_read ((PTR) thdr.stamp, 1, sizeof (thdr.stamp), abfd)
539 != sizeof (thdr.stamp))
541 /* Read the length of this custom header. */
542 if (bfd_read ((PTR) thdr.length, 1, sizeof (thdr.length), abfd)
543 != sizeof (thdr.length))
545 hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
546 /* Read further fields if we have them. */
547 if (hdrLength < NLM_TARGET_LONG_SIZE)
551 if (bfd_read ((PTR) thdr.dataOffset, 1,
552 sizeof (thdr.dataOffset), abfd)
553 != sizeof (thdr.dataOffset))
555 dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
557 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
561 if (bfd_read ((PTR) thdr.dataLength, 1,
562 sizeof (thdr.dataLength), abfd)
563 != sizeof (thdr.dataLength))
565 dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
567 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
568 memset (dataStamp, 0, sizeof (dataStamp));
571 if (bfd_read ((PTR) dataStamp, 1, sizeof (dataStamp), abfd)
572 != sizeof (dataStamp))
576 /* Read the rest of the header, if any. */
577 if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
584 hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
585 hdr = bfd_alloc (abfd, hdrLength);
588 bfd_set_error (bfd_error_no_memory);
591 if (bfd_read (hdr, 1, hdrLength, abfd) != hdrLength)
595 /* If we have found a Cygnus header, process it. Otherwise,
596 just save the associated data without trying to interpret
598 if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
604 BFD_ASSERT (hdrLength == 0 && hdr == NULL);
606 pos = bfd_tell (abfd);
607 if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
609 contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
610 if (contents == NULL)
612 bfd_set_error (bfd_error_no_memory);
615 if (bfd_read (contents, 1, dataLength, abfd) != dataLength)
617 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
620 memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
621 nlm_cygnus_ext_header (abfd)->offset = dataOffset;
622 nlm_cygnus_ext_header (abfd)->length = dataLength;
624 /* This data this header points to provides a list of
625 the sections which were in the original object file
626 which was converted to become an NLM. We locate
627 those sections and add them to the BFD. Note that
628 this is likely to create a second .text, .data and
629 .bss section; retrieving the sections by name will
630 get the actual NLM sections, which is what we want to
631 happen. The sections from the original file, which
632 may be subsets of the NLM section, can only be found
633 using bfd_map_over_sections. */
635 pend = p + dataLength;
644 /* The format of this information is
645 null terminated section name
646 zeroes to adjust to 4 byte boundary
647 4 byte section data file pointer
652 l = strlen (name) + 1;
655 filepos = bfd_h_get_32 (abfd, p);
657 size = bfd_h_get_32 (abfd, p);
660 newsec = bfd_make_section_anyway (abfd, name);
661 if (newsec == (asection *) NULL)
663 newsec->_raw_size = size;
666 newsec->filepos = filepos;
667 newsec->flags |= SEC_HAS_CONTENTS;
673 memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
674 sizeof (thdr.stamp));
675 nlm_custom_header (abfd)->hdrLength = hdrLength;
676 nlm_custom_header (abfd)->dataOffset = dataOffset;
677 nlm_custom_header (abfd)->dataLength = dataLength;
678 memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
680 nlm_custom_header (abfd)->hdr = hdr;
691 /* Return whether there is a non-zero byte in a memory block. */
694 find_nonzero (buf, size)
698 char *p = (char *) buf;
706 /* Swap out the contents of the auxiliary headers. We create those
707 auxiliary headers which have been set non-zero. We do not require
708 the caller to set up the stamp fields. */
711 nlm_swap_auxiliary_headers_out (abfd)
714 /* Write out the version header if there is one. */
715 if (find_nonzero ((PTR) nlm_version_header (abfd),
716 sizeof (Nlm_Internal_Version_Header)))
718 Nlm_External_Version_Header thdr;
720 memcpy (thdr.stamp, "VeRsIoN#", 8);
721 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
722 (bfd_byte *) thdr.majorVersion);
723 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
724 (bfd_byte *) thdr.minorVersion);
725 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
726 (bfd_byte *) thdr.revision);
727 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
728 (bfd_byte *) thdr.year);
729 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
730 (bfd_byte *) thdr.month);
731 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
732 (bfd_byte *) thdr.day);
733 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
737 /* Write out the extended header if there is one. */
738 if (find_nonzero ((PTR) nlm_extended_header (abfd),
739 sizeof (Nlm_Internal_Extended_Header)))
741 Nlm_External_Extended_Header thdr;
743 memcpy (thdr.stamp, "MeSsAgEs", 8);
745 (bfd_vma) nlm_extended_header (abfd)->languageID,
746 (bfd_byte *) thdr.languageID);
748 (bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
749 (bfd_byte *) thdr.messageFileOffset);
751 (bfd_vma) nlm_extended_header (abfd)->messageFileLength,
752 (bfd_byte *) thdr.messageFileLength);
754 (bfd_vma) nlm_extended_header (abfd)->messageCount,
755 (bfd_byte *) thdr.messageCount);
757 (bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
758 (bfd_byte *) thdr.helpFileOffset);
760 (bfd_vma) nlm_extended_header (abfd)->helpFileLength,
761 (bfd_byte *) thdr.helpFileLength);
763 (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
764 (bfd_byte *) thdr.RPCDataOffset);
766 (bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
767 (bfd_byte *) thdr.RPCDataLength);
769 (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
770 (bfd_byte *) thdr.sharedCodeOffset);
772 (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
773 (bfd_byte *) thdr.sharedCodeLength);
775 (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
776 (bfd_byte *) thdr.sharedDataOffset);
778 (bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
779 (bfd_byte *) thdr.sharedDataLength);
781 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
782 (bfd_byte *) thdr.sharedRelocationFixupOffset);
784 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
785 (bfd_byte *) thdr.sharedRelocationFixupCount);
787 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
788 (bfd_byte *) thdr.sharedExternalReferenceOffset);
790 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
791 (bfd_byte *) thdr.sharedExternalReferenceCount);
793 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
794 (bfd_byte *) thdr.sharedPublicsOffset);
796 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
797 (bfd_byte *) thdr.sharedPublicsCount);
799 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
800 (bfd_byte *) thdr.sharedDebugRecordOffset);
802 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
803 (bfd_byte *) thdr.sharedDebugRecordCount);
805 (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
806 (bfd_byte *) thdr.sharedInitializationOffset);
808 (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
809 (bfd_byte *) thdr.SharedExitProcedureOffset);
811 (bfd_vma) nlm_extended_header (abfd)->productID,
812 (bfd_byte *) thdr.productID);
814 (bfd_vma) nlm_extended_header (abfd)->reserved0,
815 (bfd_byte *) thdr.reserved0);
817 (bfd_vma) nlm_extended_header (abfd)->reserved1,
818 (bfd_byte *) thdr.reserved1);
820 (bfd_vma) nlm_extended_header (abfd)->reserved2,
821 (bfd_byte *) thdr.reserved2);
823 (bfd_vma) nlm_extended_header (abfd)->reserved3,
824 (bfd_byte *) thdr.reserved3);
826 (bfd_vma) nlm_extended_header (abfd)->reserved4,
827 (bfd_byte *) thdr.reserved4);
829 (bfd_vma) nlm_extended_header (abfd)->reserved5,
830 (bfd_byte *) thdr.reserved5);
831 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
836 /* Write out the copyright header if there is one. */
837 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
838 sizeof (Nlm_Internal_Copyright_Header)))
840 Nlm_External_Copyright_Header thdr;
842 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
843 if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd)
844 != sizeof (thdr.stamp))
846 thdr.copyrightMessageLength[0] =
847 nlm_copyright_header (abfd)->copyrightMessageLength;
848 if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1)
850 /* The copyright message is a variable length string. */
851 if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
852 nlm_copyright_header (abfd)->copyrightMessageLength + 1,
854 nlm_copyright_header (abfd)->copyrightMessageLength + 1)
858 /* Write out the custom header if there is one. */
859 if (find_nonzero ((PTR) nlm_custom_header (abfd),
860 sizeof (Nlm_Internal_Custom_Header)))
862 Nlm_External_Custom_Header thdr;
864 bfd_size_type hdrLength;
866 ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
867 sizeof (nlm_custom_header (abfd)->dataStamp));
868 memcpy (thdr.stamp, "CuStHeAd", 8);
869 hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
870 + nlm_custom_header (abfd)->hdrLength);
871 put_word (abfd, hdrLength, thdr.length);
872 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
874 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
878 BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
879 if (bfd_write ((PTR) &thdr, 1,
880 sizeof (thdr) - sizeof (thdr.dataStamp), abfd)
881 != sizeof (thdr) - sizeof (thdr.dataStamp))
886 memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
887 sizeof (thdr.dataStamp));
888 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
890 if (bfd_write (nlm_custom_header (abfd)->hdr, 1,
891 nlm_custom_header (abfd)->hdrLength, abfd)
892 != nlm_custom_header (abfd)->hdrLength)
897 /* Write out the Cygnus debugging header if there is one. */
898 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
899 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
901 Nlm_External_Custom_Header thdr;
903 memcpy (thdr.stamp, "CuStHeAd", 8);
904 put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
905 (bfd_byte *) thdr.length);
906 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
907 (bfd_byte *) thdr.dataOffset);
908 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
909 (bfd_byte *) thdr.dataLength);
910 memcpy (thdr.dataStamp, "CyGnUsEx", 8);
911 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
918 /* We read the NLM's public symbols and use it to generate a bfd symbol
919 table (hey, it's better than nothing) on a one-for-one basis. Thus
920 use the number of public symbols as the number of bfd symbols we will
921 have once we actually get around to reading them in.
923 Return the number of bytes required to hold the symtab vector, based on
924 the count plus 1, since we will NULL terminate the vector allocated based
928 nlm_get_symtab_upper_bound (abfd)
931 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
933 long symtab_size = 0;
935 i_fxdhdrp = nlm_fixed_header (abfd);
936 symcount = (i_fxdhdrp->numberOfPublics
937 + i_fxdhdrp->numberOfDebugRecords
938 + i_fxdhdrp->numberOfExternalReferences);
939 symtab_size = (symcount + 1) * (sizeof (asymbol));
940 return (symtab_size);
943 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
944 symbol table fails. */
947 nlm_get_symtab (abfd, alocation)
951 nlm_symbol_type *symbase;
952 bfd_size_type counter = 0;
954 if (nlm_slurp_symbol_table (abfd) == false)
956 symbase = nlm_get_symbols (abfd);
957 while (counter < bfd_get_symcount (abfd))
959 *alocation++ = &symbase->symbol;
963 *alocation = (asymbol *) NULL;
964 return bfd_get_symcount (abfd);
967 /* Make an NLM symbol. There is nothing special to do here. */
970 nlm_make_empty_symbol (abfd)
973 nlm_symbol_type *new;
975 new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
977 new->symbol.the_bfd = abfd;
981 /* Get symbol information. */
984 nlm_get_symbol_info (ignore_abfd, symbol, ret)
989 bfd_symbol_info (symbol, ret);
992 /* Print symbol information. */
995 nlm_print_symbol (abfd, afile, symbol, how)
999 bfd_print_symbol_type how;
1001 FILE *file = (FILE *) afile;
1005 case bfd_print_symbol_name:
1006 case bfd_print_symbol_more:
1008 fprintf (file, "%s", symbol->name);
1010 case bfd_print_symbol_all:
1011 bfd_print_symbol_vandf ((PTR) file, symbol);
1012 fprintf (file, " %-5s", symbol->section->name);
1014 fprintf (file, " %s", symbol->name);
1019 /* Slurp in nlm symbol table.
1021 In the external (in-file) form, NLM export records are variable length,
1022 with the following form:
1024 1 byte length of the symbol name (N)
1025 N bytes the symbol name
1026 4 bytes the symbol offset from start of it's section
1028 We also read in the debugging symbols and import records. Import
1029 records are treated as undefined symbols. As we read the import
1030 records we also read in the associated reloc information, which is
1031 attached to the symbol.
1033 The bfd symbols are copied to SYMPTRS.
1035 When we return, the bfd symcount is either zero or contains the correct
1040 nlm_slurp_symbol_table (abfd)
1043 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
1044 bfd_size_type totsymcount; /* Number of NLM symbols */
1045 bfd_size_type symcount; /* Counter of NLM symbols */
1046 nlm_symbol_type *sym; /* Pointer to current bfd symbol */
1047 unsigned char symlength; /* Symbol length read into here */
1048 unsigned char symtype; /* Type of debugging symbol */
1049 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
1050 boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
1051 boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
1053 if (nlm_get_symbols (abfd) != NULL)
1056 /* Read each raw NLM symbol, using the information to create a canonical bfd
1059 Note that we allocate the initial bfd canonical symbol buffer based on a
1060 one-to-one mapping of the NLM symbols to canonical symbols. We actually
1061 use all the NLM symbols, so there will be no space left over at the end.
1062 When we have all the symbols, we build the caller's pointer vector. */
1065 i_fxdhdrp = nlm_fixed_header (abfd);
1066 totsymcount = (i_fxdhdrp->numberOfPublics
1067 + i_fxdhdrp->numberOfDebugRecords
1068 + i_fxdhdrp->numberOfExternalReferences);
1069 if (totsymcount == 0)
1074 if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1)
1077 sym = ((nlm_symbol_type *)
1078 bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
1081 bfd_set_error (bfd_error_no_memory);
1084 nlm_set_symbols (abfd, sym);
1086 /* We use the bfd's symcount directly as the control count, so that early
1087 termination of the loop leaves the symcount correct for the symbols that
1090 set_public_section_func = nlm_set_public_section_func (abfd);
1091 symcount = i_fxdhdrp->numberOfPublics;
1092 while (abfd->symcount < symcount)
1094 if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
1095 != sizeof (symlength))
1097 sym->symbol.the_bfd = abfd;
1098 sym->symbol.name = bfd_alloc (abfd, symlength + 1);
1099 if (!sym->symbol.name)
1101 bfd_set_error (bfd_error_no_memory);
1104 if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
1107 /* Cast away const. */
1108 ((char *) (sym->symbol.name))[symlength] = '\0';
1109 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1111 sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1112 sym->symbol.value = get_word (abfd, temp);
1113 if (set_public_section_func)
1115 /* Most backends can use the code below, but unfortunately
1116 some use a different scheme. */
1117 if ((*set_public_section_func) (abfd, sym) == false)
1122 if (sym->symbol.value & NLM_HIBIT)
1124 sym->symbol.value &= ~NLM_HIBIT;
1125 sym->symbol.flags |= BSF_FUNCTION;
1126 sym->symbol.section =
1127 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1131 sym->symbol.section =
1132 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1140 /* Read the debugging records. */
1142 if (i_fxdhdrp->numberOfDebugRecords > 0)
1144 if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1)
1147 symcount += i_fxdhdrp->numberOfDebugRecords;
1148 while (abfd->symcount < symcount)
1150 if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd)
1151 != sizeof (symtype))
1152 || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)
1153 || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
1154 != sizeof (symlength)))
1156 sym->symbol.the_bfd = abfd;
1157 sym->symbol.name = bfd_alloc (abfd, symlength + 1);
1158 if (!sym->symbol.name)
1160 bfd_set_error (bfd_error_no_memory);
1163 if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
1166 /* Cast away const. */
1167 ((char *) (sym->symbol.name))[symlength] = '\0';
1168 sym->symbol.flags = BSF_LOCAL;
1169 sym->symbol.value = get_word (abfd, temp);
1172 sym->symbol.section =
1173 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1175 else if (symtype == 1)
1177 sym->symbol.flags |= BSF_FUNCTION;
1178 sym->symbol.section =
1179 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1183 sym->symbol.section = &bfd_abs_section;
1191 /* Read in the import records. We can only do this if we know how
1192 to read relocs for this target. */
1194 read_import_func = nlm_read_import_func (abfd);
1195 if (read_import_func != NULL)
1197 if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET)
1201 symcount += i_fxdhdrp->numberOfExternalReferences;
1202 while (abfd->symcount < symcount)
1204 if ((*read_import_func) (abfd, sym) == false)
1214 /* Get the relocs for an NLM file. There are two types of relocs.
1215 Imports are relocs against symbols defined in other NLM files. We
1216 treat these as relocs against global symbols. Relocation fixups
1217 are internal relocs.
1219 The actual format used to store the relocs is machine specific. */
1221 /* Read in the relocation fixup information. This is stored in
1222 nlm_relocation_fixups, an array of arelent structures, and
1223 nlm_relocation_fixup_secs, an array of section pointers. The
1224 section pointers are needed because the relocs are not sorted by
1228 nlm_slurp_reloc_fixups (abfd)
1231 boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1233 bfd_size_type count;
1237 if (nlm_relocation_fixups (abfd) != NULL)
1239 read_func = nlm_read_reloc_func (abfd);
1240 if (read_func == NULL)
1243 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1247 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1248 rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
1249 secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
1250 if ((rels == NULL || secs == NULL) && count != 0)
1252 bfd_set_error (bfd_error_no_memory);
1255 nlm_relocation_fixups (abfd) = rels;
1256 nlm_relocation_fixup_secs (abfd) = secs;
1258 /* We have to read piece by piece, because we don't know how large
1259 the machine specific reloc information is. */
1260 while (count-- != 0)
1262 if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
1264 nlm_relocation_fixups (abfd) = NULL;
1265 nlm_relocation_fixup_secs (abfd) = NULL;
1275 /* Get the number of relocs. This really just returns an upper bound,
1276 since it does not attempt to distinguish them based on the section.
1277 That will be handled when they are actually read. */
1280 nlm_get_reloc_upper_bound (abfd, sec)
1284 nlm_symbol_type *syms;
1285 bfd_size_type count;
1288 /* If we don't know how to read relocs, just return 0. */
1289 if (nlm_read_reloc_func (abfd) == NULL)
1291 /* Make sure we have either the code or the data section. */
1292 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1295 syms = nlm_get_symbols (abfd);
1298 if (nlm_slurp_symbol_table (abfd) == false)
1300 syms = nlm_get_symbols (abfd);
1303 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1305 count = bfd_get_symcount (abfd);
1306 while (count-- != 0)
1312 return (ret + 1) * sizeof (arelent *);
1315 /* Get the relocs themselves. */
1318 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1326 bfd_size_type count, i;
1329 /* Get the relocation fixups. */
1330 rels = nlm_relocation_fixups (abfd);
1333 if (nlm_slurp_reloc_fixups (abfd) == false)
1335 rels = nlm_relocation_fixups (abfd);
1337 secs = nlm_relocation_fixup_secs (abfd);
1340 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1341 for (i = 0; i < count; i++, rels++, secs++)
1350 /* Get the import symbols. */
1351 count = bfd_get_symcount (abfd);
1352 for (i = 0; i < count; i++, symbols++)
1357 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1359 nlm_symbol_type *nlm_sym;
1362 nlm_sym = (nlm_symbol_type *) sym;
1363 for (j = 0; j < nlm_sym->rcnt; j++)
1365 if (nlm_sym->relocs[j].section == sec)
1367 *relptr = &nlm_sym->relocs[j].reloc;
1368 (*relptr)->sym_ptr_ptr = symbols;
1381 /* Compute the section file positions for an NLM file. All variable
1382 length data in the file headers must be set before this function is
1383 called. If the variable length data is changed later, the
1384 resulting object file will be incorrect. Unfortunately, there is
1385 no way to check this.
1387 This routine also sets the Size and Offset fields in the fixed
1390 It also looks over the symbols and moves any common symbols into
1391 the .bss section; NLM has no way to represent a common symbol.
1392 This approach means that either the symbols must already have been
1393 set at this point, or there must be no common symbols. We need to
1394 move the symbols at this point so that mangle_relocs can see the
1398 nlm_compute_section_file_positions (abfd)
1403 bfd_vma text, data, bss;
1404 bfd_vma text_low, data_low;
1405 int text_align, data_align, other_align;
1406 file_ptr text_ptr, data_ptr, other_ptr;
1408 asymbol **sym_ptr_ptr;
1410 if (abfd->output_has_begun == true)
1413 /* Make sure we have a section to hold uninitialized data. */
1414 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1415 if (bss_sec == NULL)
1417 if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1418 (file_ptr) 0, (bfd_size_type) 0,
1421 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1424 abfd->output_has_begun = true;
1426 /* The fixed header. */
1427 sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1429 /* The variable header. */
1430 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1431 + nlm_variable_header (abfd)->descriptionLength + 1
1432 + NLM_TARGET_LONG_SIZE /* stackSize */
1433 + NLM_TARGET_LONG_SIZE /* reserved */
1434 + sizeof (nlm_variable_header (abfd)->oldThreadName)
1435 + sizeof (nlm_variable_header (abfd)->screenNameLength)
1436 + nlm_variable_header (abfd)->screenNameLength + 1
1437 + sizeof (nlm_variable_header (abfd)->threadNameLength)
1438 + nlm_variable_header (abfd)->threadNameLength + 1);
1440 /* The auxiliary headers. */
1441 if (find_nonzero ((PTR) nlm_version_header (abfd),
1442 sizeof (Nlm_Internal_Version_Header)))
1443 sofar += sizeof (Nlm_External_Version_Header);
1444 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1445 sizeof (Nlm_Internal_Extended_Header)))
1446 sofar += sizeof (Nlm_External_Extended_Header);
1447 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1448 sizeof (Nlm_Internal_Copyright_Header)))
1449 sofar += (sizeof (Nlm_External_Copyright_Header)
1450 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1451 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1452 sizeof (Nlm_Internal_Custom_Header)))
1453 sofar += (sizeof (Nlm_External_Custom_Header)
1454 + nlm_custom_header (abfd)->hdrLength);
1455 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
1456 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
1457 sofar += sizeof (Nlm_External_Custom_Header);
1459 /* Compute the section file positions in two passes. First get the
1460 sizes of the text and data sections, and then set the file
1461 positions. This code aligns the sections in the file using the
1462 same alignment restrictions that apply to the sections in memory;
1463 this may not be necessary. */
1465 text_low = (bfd_vma) - 1;
1468 data_low = (bfd_vma) - 1;
1472 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1476 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1478 f = bfd_get_section_flags (abfd, sec);
1481 text += sec->_raw_size;
1482 if (bfd_get_section_vma (abfd, sec) < text_low)
1483 text_low = bfd_get_section_vma (abfd, sec);
1484 if (sec->alignment_power > text_align)
1485 text_align = sec->alignment_power;
1487 else if (f & SEC_DATA)
1489 data += sec->_raw_size;
1490 if (bfd_get_section_vma (abfd, sec) < data_low)
1491 data_low = bfd_get_section_vma (abfd, sec);
1492 if (sec->alignment_power > data_align)
1493 data_align = sec->alignment_power;
1495 else if (f & SEC_HAS_CONTENTS)
1497 if (sec->alignment_power > other_align)
1498 other_align = sec->alignment_power;
1500 else if (f & SEC_ALLOC)
1501 bss += sec->_raw_size;
1504 nlm_set_text_low (abfd, text_low);
1505 nlm_set_data_low (abfd, data_low);
1507 if (nlm_no_uninitialized_data (abfd))
1509 /* This NetWare format does not use uninitialized data. We must
1510 increase the size of the data section. We will never wind up
1511 writing those file locations, so they will remain zero. */
1516 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1517 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1518 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1520 /* Fill in some fields in the header for which we now have the
1522 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1523 nlm_fixed_header (abfd)->codeImageSize = text;
1524 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1525 nlm_fixed_header (abfd)->dataImageSize = data;
1526 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1528 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1532 f = bfd_get_section_flags (abfd, sec);
1536 sec->filepos = text_ptr;
1537 text_ptr += sec->_raw_size;
1539 else if (f & SEC_DATA)
1541 sec->filepos = data_ptr;
1542 data_ptr += sec->_raw_size;
1544 else if (f & SEC_HAS_CONTENTS)
1546 sec->filepos = other_ptr;
1547 other_ptr += sec->_raw_size;
1551 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1553 /* Move all common symbols into the .bss section. */
1555 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1556 if (sym_ptr_ptr != NULL)
1561 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1563 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1570 if (!bfd_is_com_section (bfd_get_section (sym)))
1573 /* Put the common symbol in the .bss section, and increase
1574 the size of the .bss section by the size of the common
1575 symbol (which is the old value of the symbol). */
1576 sym->section = bss_sec;
1578 sym->value = bss_sec->_raw_size + add;
1580 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1584 if (nlm_no_uninitialized_data (abfd))
1586 /* We could handle this case, but so far it hasn't been
1590 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1591 bss_sec->_raw_size += add;
1598 /* Set the contents of a section. To do this we need to know where
1599 the section is going to be located in the output file. That means
1600 that the sizes of all the sections must be set, and all the
1601 variable size header information must be known. */
1604 nlm_set_section_contents (abfd, section, location, offset, count)
1609 bfd_size_type count;
1611 if (abfd->output_has_begun == false
1612 && nlm_compute_section_file_positions (abfd) == false)
1618 /* i386 NetWare has a very restricted set of relocs. In order for
1619 objcopy to work, the NLM i386 backend needs a chance to rework
1620 the section contents so that its set of relocs will work. If all
1621 the relocs are already acceptable, this will not do anything. */
1622 if (section->reloc_count != 0)
1624 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1625 bfd_vma, bfd_size_type));
1627 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1628 if (mangle_relocs_func != NULL)
1630 if (!(*mangle_relocs_func) (abfd, section, location,
1631 (bfd_vma) offset, count))
1636 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1637 || bfd_write (location, 1, count, abfd) != count)
1643 /* We need to sort a list of relocs associated with sections when we
1644 write out the external relocs. */
1647 nlm_external_reloc_compare (p1, p2)
1651 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1652 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1655 cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1656 (*r2->rel->sym_ptr_ptr)->name);
1660 /* We sort by address within symbol to make the sort more stable and
1661 increase the chances that different hosts will generate bit for
1662 bit equivalent results. */
1663 return (int) (r1->rel->address - r2->rel->address);
1666 /* Write out an NLM file. We write out the information in this order:
1672 other sections (custom data, messages, help, shared NLM, RPC,
1673 module dependencies)
1675 external references (imports)
1676 public symbols (exports)
1678 This is similar to the order used by the NetWare tools; the
1679 difference is that NetWare puts the sections other than code, data
1680 and custom data at the end of the NLM. It is convenient for us to
1681 know where the sections are going to be before worrying about the
1682 size of the other information.
1684 By the time this function is called, all the section data should
1685 have been output using set_section_contents. Note that custom
1686 data, the message file, the help file, the shared NLM file, the RPC
1687 data, and the module dependencies are all considered to be
1688 sections; the caller is responsible for filling in the offset and
1689 length fields in the NLM headers. The relocation fixups and
1690 imports are both obtained from the list of relocs attached to each
1691 section. The exports and debugging records are obtained from the
1692 list of outsymbols. */
1695 nlm_write_object_contents (abfd)
1699 boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1700 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1701 struct reloc_and_sec *external_relocs;
1702 asymbol **sym_ptr_ptr;
1704 boolean (*write_prefix_func) PARAMS ((bfd *));
1705 unsigned char *fixed_header = NULL;
1707 fixed_header = (unsigned char *) malloc (nlm_fixed_header_size (abfd));
1708 if (fixed_header == NULL)
1710 bfd_set_error (bfd_error_no_memory);
1714 if (abfd->output_has_begun == false
1715 && nlm_compute_section_file_positions (abfd) == false)
1718 /* Write out the variable length headers. */
1720 nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
1723 if (nlm_swap_variable_header_out (abfd) == false
1724 || nlm_swap_auxiliary_headers_out (abfd) == false)
1726 bfd_set_error (bfd_error_system_call);
1730 /* A weak check on whether the section file positions were
1732 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1734 bfd_set_error (bfd_error_invalid_operation);
1738 /* Advance to the relocs. */
1739 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1743 /* The format of the relocation entries is dependent upon the
1744 particular target. We use an external routine to write the reloc
1746 write_import_func = nlm_write_import_func (abfd);
1748 /* Write out the internal relocation fixups. While we're looping
1749 over the relocs, we also count the external relocs, which is
1750 needed when they are written out below. */
1751 internal_reloc_count = 0;
1752 external_reloc_count = 0;
1753 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1755 arelent **rel_ptr_ptr, **rel_end;
1757 if (sec->reloc_count == 0)
1760 /* We can only represent relocs within a code or data
1761 section. We ignore them for a debugging section. */
1762 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1765 /* We need to know how to write out imports */
1766 if (write_import_func == NULL)
1768 bfd_set_error (bfd_error_invalid_operation);
1772 rel_ptr_ptr = sec->orelocation;
1773 rel_end = rel_ptr_ptr + sec->reloc_count;
1774 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1780 sym = *rel->sym_ptr_ptr;
1782 if (bfd_get_section (sym) != &bfd_und_section)
1784 ++internal_reloc_count;
1785 if ((*write_import_func) (abfd, sec, rel) == false)
1789 ++external_reloc_count;
1792 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1794 /* Write out the imports (relocs against external symbols). These
1795 are output as a symbol name followed by all the relocs for that
1796 symbol, so we must first gather together all the relocs against
1797 external symbols and sort them. */
1799 (struct reloc_and_sec *) bfd_alloc (abfd,
1800 (external_reloc_count
1801 * sizeof (struct reloc_and_sec)));
1802 if (external_relocs == (struct reloc_and_sec *) NULL)
1804 bfd_set_error (bfd_error_no_memory);
1808 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1810 arelent **rel_ptr_ptr, **rel_end;
1812 if (sec->reloc_count == 0)
1815 rel_ptr_ptr = sec->orelocation;
1816 rel_end = rel_ptr_ptr + sec->reloc_count;
1817 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1823 sym = *rel->sym_ptr_ptr;
1825 if (bfd_get_section (sym) != &bfd_und_section)
1828 external_relocs[i].rel = rel;
1829 external_relocs[i].sec = sec;
1834 BFD_ASSERT (i == external_reloc_count);
1836 /* Sort the external relocs by name. */
1837 qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1838 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1840 /* Write out the external relocs. */
1841 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1844 while (i < external_reloc_count)
1848 bfd_size_type j, cnt;
1852 rel = external_relocs[i].rel;
1853 sym = *rel->sym_ptr_ptr;
1857 (j < external_reloc_count
1858 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1862 if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1863 &external_relocs[i])
1870 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1872 /* Write out the public symbols (exports). */
1873 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1874 if (sym_ptr_ptr != (asymbol **) NULL)
1876 bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1877 boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1881 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1882 get_public_offset_func = nlm_get_public_offset_func (abfd);
1883 write_export_func = nlm_write_export_func (abfd);
1885 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1886 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1891 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1895 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1896 || bfd_get_section (sym) == &bfd_und_section)
1901 if (get_public_offset_func)
1903 /* Most backends can use the code below, but
1904 unfortunately some use a different scheme. */
1905 offset = (*get_public_offset_func) (abfd, sym);
1909 offset = bfd_asymbol_value (sym);
1911 if (sec->flags & SEC_CODE)
1913 offset -= nlm_get_text_low (abfd);
1914 offset |= NLM_HIBIT;
1916 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1918 /* SEC_ALLOC is for the .bss section. */
1919 offset -= nlm_get_data_low (abfd);
1923 /* We can't handle an exported symbol that is not in
1924 the code or data segment. */
1925 bfd_set_error (bfd_error_invalid_operation);
1930 if (write_export_func)
1932 if ((*write_export_func) (abfd, sym, offset) == false)
1937 len = strlen (sym->name);
1938 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1939 != sizeof (bfd_byte))
1940 || bfd_write (sym->name, len, 1, abfd) != len)
1943 put_word (abfd, offset, temp);
1944 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1948 nlm_fixed_header (abfd)->numberOfPublics = c;
1950 /* Write out the debugging records. The NLM conversion program
1951 wants to be able to inhibit this, so as a special hack if
1952 debugInfoOffset is set to -1 we don't write any debugging
1953 information. This can not be handled by fiddling with the
1954 symbol table, because exported symbols appear in both the
1955 exported symbol list and the debugging information. */
1956 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1958 nlm_fixed_header (abfd)->debugInfoOffset = 0;
1959 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1963 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1965 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1966 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1967 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1972 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1976 /* The NLM notion of a debugging symbol is actually what
1977 BFD calls a local or global symbol. What BFD calls a
1978 debugging symbol NLM does not understand at all. */
1979 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1980 || (sym->flags & BSF_DEBUGGING) != 0
1981 || bfd_get_section (sym) == &bfd_und_section)
1986 offset = bfd_asymbol_value (sym);
1988 if (sec->flags & SEC_CODE)
1990 offset -= nlm_get_text_low (abfd);
1993 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1995 /* SEC_ALLOC is for the .bss section. */
1996 offset -= nlm_get_data_low (abfd);
2002 /* The type is 0 for data, 1 for code, 2 for absolute. */
2003 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
2004 != sizeof (bfd_byte))
2007 put_word (abfd, offset, temp);
2008 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
2011 len = strlen (sym->name);
2012 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
2013 != sizeof (bfd_byte))
2014 || bfd_write (sym->name, len, 1, abfd) != len)
2017 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
2021 /* NLMLINK fills in offset values even if there is no data, so we do
2023 last = bfd_tell (abfd);
2024 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
2025 nlm_fixed_header (abfd)->codeImageOffset = last;
2026 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
2027 nlm_fixed_header (abfd)->dataImageOffset = last;
2028 if (nlm_fixed_header (abfd)->customDataOffset == 0)
2029 nlm_fixed_header (abfd)->customDataOffset = last;
2030 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
2031 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
2032 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
2033 nlm_fixed_header (abfd)->relocationFixupOffset = last;
2034 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
2035 nlm_fixed_header (abfd)->externalReferencesOffset = last;
2036 if (nlm_fixed_header (abfd)->publicsOffset == 0)
2037 nlm_fixed_header (abfd)->publicsOffset = last;
2038 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
2039 nlm_fixed_header (abfd)->debugInfoOffset = last;
2041 /* At this point everything has been written out except the fixed
2043 memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
2044 NLM_SIGNATURE_SIZE);
2045 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2046 nlm_fixed_header (abfd)->codeStartOffset =
2047 (bfd_get_start_address (abfd)
2048 - nlm_get_text_low (abfd));
2050 /* We have no convenient way for the caller to pass in the exit
2051 procedure or the check unload procedure, so the caller must set
2052 the values in the header to the values of the symbols. */
2053 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2054 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2055 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2056 nlm_get_text_low (abfd);
2058 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
2061 write_prefix_func = nlm_write_prefix_func (abfd);
2062 if (write_prefix_func)
2064 if ((*write_prefix_func) (abfd) == false)
2068 BFD_ASSERT (bfd_tell (abfd) == nlm_optional_prefix_size (abfd));
2070 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
2071 if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
2072 != nlm_fixed_header_size (abfd))
2075 if (fixed_header != NULL)
2076 free (fixed_header);
2080 if (fixed_header != NULL)
2081 free (fixed_header);