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)
42 #define nlm_symbol_type nlmNAME(symbol_type)
43 #define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
44 #define nlm_get_symtab nlmNAME(get_symtab)
45 #define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
46 #define nlm_print_symbol nlmNAME(print_symbol)
47 #define nlm_get_symbol_info nlmNAME(get_symbol_info)
48 #define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
49 #define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
50 #define nlm_object_p nlmNAME(object_p)
51 #define nlm_set_section_contents nlmNAME(set_section_contents)
52 #define nlm_write_object_contents nlmNAME(write_object_contents)
54 #define nlm_swap_fixed_header_in(abfd,src,dst) \
55 (nlm_swap_fixed_header_in_func(abfd))(abfd,src,dst)
56 #define nlm_swap_fixed_header_out(abfd,src,dst) \
57 (nlm_swap_fixed_header_out_func(abfd))(abfd,src,dst)
59 /* Forward declarations of static functions */
61 static boolean add_bfd_section
62 PARAMS ((bfd
*, char *, file_ptr
, bfd_size_type
, flagword
));
63 static boolean nlm_swap_variable_header_in
65 static boolean nlm_swap_variable_header_out
67 static boolean find_nonzero
68 PARAMS ((PTR
, size_t));
69 static boolean nlm_swap_auxiliary_headers_in
71 static boolean nlm_swap_auxiliary_headers_out
73 static boolean nlm_slurp_symbol_table
75 static boolean nlm_slurp_reloc_fixups
77 static boolean nlm_compute_section_file_positions
79 static int nlm_external_reloc_compare
80 PARAMS ((const void *, const void *));
82 /* Should perhaps use put_offset, put_word, etc. For now, the two versions
83 can be handled by explicitly specifying 32 bits or "the long type". */
85 #define put_word bfd_h_put_64
86 #define get_word bfd_h_get_64
89 #define put_word bfd_h_put_32
90 #define get_word bfd_h_get_32
97 struct nlm_obj_tdata
*preserved_tdata
= nlm_tdata (abfd
);
98 boolean (*backend_object_p
) PARAMS ((bfd
*));
100 Nlm_Internal_Fixed_Header
*i_fxdhdrp
;
101 const char *signature
;
102 enum bfd_architecture arch
;
104 /* Some NLM formats have a prefix before the standard NLM fixed
106 backend_object_p
= nlm_backend_object_p_func (abfd
);
107 if (backend_object_p
)
109 if (!(*backend_object_p
) (abfd
))
110 goto got_wrong_format_error
;
113 /* Read in the fixed length portion of the NLM header in external format. */
115 x_fxdhdr
= (PTR
) malloc (nlm_fixed_header_size (abfd
));
116 if (x_fxdhdr
== NULL
)
118 bfd_set_error (bfd_error_no_memory
);
122 if (bfd_read ((PTR
) x_fxdhdr
, nlm_fixed_header_size (abfd
), 1, abfd
) !=
123 nlm_fixed_header_size (abfd
))
125 if (bfd_get_error () != bfd_error_system_call
)
126 goto got_wrong_format_error
;
131 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
132 the tdata pointer in the bfd. */
134 nlm_tdata (abfd
) = (struct nlm_obj_tdata
*)
135 bfd_zalloc (abfd
, sizeof (struct nlm_obj_tdata
));
136 if (nlm_tdata (abfd
) == NULL
)
138 bfd_set_error (bfd_error_no_memory
);
142 i_fxdhdrp
= nlm_fixed_header (abfd
);
143 nlm_swap_fixed_header_in (abfd
, x_fxdhdr
, i_fxdhdrp
);
145 /* Check to see if we have an NLM file for this backend by matching
146 the NLM signature. */
148 signature
= nlm_signature (abfd
);
149 if (signature
!= NULL
150 && *signature
!= '\0'
151 && strncmp ((char *) i_fxdhdrp
->signature
, signature
,
152 NLM_SIGNATURE_SIZE
) != 0)
153 goto got_wrong_format_error
;
155 /* There's no supported way to discover the endianess of an NLM, so test for
156 a sane version number after doing byte swapping appropriate for this
157 XVEC. (Hack alert!) */
159 if (i_fxdhdrp
->version
> 0xFFFF)
160 goto got_wrong_format_error
;
162 /* There's no supported way to check for 32 bit versus 64 bit addresses,
163 so ignore this distinction for now. (FIXME) */
165 /* FIXME: Any return(NULL) exits below here will leak memory (tdata).
166 And a memory leak also means we lost the real tdata info we wanted
167 to save, because it was in the leaked memory. */
169 /* Swap in the rest of the fixed length header. */
171 if (!nlm_swap_variable_header_in (abfd
)
172 || !nlm_swap_auxiliary_headers_in (abfd
)
173 || !add_bfd_section (abfd
, NLM_CODE_NAME
,
174 i_fxdhdrp
->codeImageOffset
,
175 i_fxdhdrp
->codeImageSize
,
176 (SEC_CODE
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
178 || !add_bfd_section (abfd
, NLM_INITIALIZED_DATA_NAME
,
179 i_fxdhdrp
->dataImageOffset
,
180 i_fxdhdrp
->dataImageSize
,
181 (SEC_DATA
| SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
183 || !add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
185 i_fxdhdrp
->uninitializedDataSize
,
187 goto got_wrong_format_error
;
189 if (nlm_fixed_header (abfd
)->numberOfRelocationFixups
!= 0
190 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
191 abfd
->flags
|= HAS_RELOC
;
192 if (nlm_fixed_header (abfd
)->numberOfPublics
!= 0
193 || nlm_fixed_header (abfd
)->numberOfDebugRecords
!= 0
194 || nlm_fixed_header (abfd
)->numberOfExternalReferences
!= 0)
195 abfd
->flags
|= HAS_SYMS
;
197 arch
= nlm_architecture (abfd
);
198 if (arch
!= bfd_arch_unknown
)
199 bfd_default_set_arch_mach (abfd
, arch
, (unsigned long) 0);
201 if (x_fxdhdr
!= NULL
)
205 got_wrong_format_error
:
206 bfd_set_error (bfd_error_wrong_format
);
208 nlm_tdata (abfd
) = preserved_tdata
;
209 if (x_fxdhdr
!= NULL
)
214 /* Add a section to the bfd. */
217 add_bfd_section (abfd
, name
, offset
, size
, flags
)
226 newsect
= bfd_make_section (abfd
, name
);
231 newsect
->vma
= 0; /* NLM's are relocatable. */
232 newsect
->_raw_size
= size
;
233 newsect
->filepos
= offset
;
234 newsect
->flags
= flags
;
235 newsect
->alignment_power
= bfd_log2 (0); /* FIXME */
239 /* Read and swap in the variable length header. All the fields must
240 exist in the NLM, and must exist in the order they are read here. */
243 nlm_swap_variable_header_in (abfd
)
246 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
248 /* Read the description length and text members. */
250 if (bfd_read ((PTR
) & nlm_variable_header (abfd
)->descriptionLength
,
251 sizeof (nlm_variable_header (abfd
)->descriptionLength
),
253 sizeof (nlm_variable_header (abfd
)->descriptionLength
))
255 if (bfd_read ((PTR
) nlm_variable_header (abfd
)->descriptionText
,
256 nlm_variable_header (abfd
)->descriptionLength
+ 1,
258 nlm_variable_header (abfd
)->descriptionLength
+ 1)
261 /* Read and convert the stackSize field. */
263 if (bfd_read ((PTR
) temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
265 nlm_variable_header (abfd
)->stackSize
= get_word (abfd
, (bfd_byte
*) temp
);
267 /* Read and convert the reserved field. */
269 if (bfd_read ((PTR
) temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
271 nlm_variable_header (abfd
)->reserved
= get_word (abfd
, (bfd_byte
*) temp
);
273 /* Read the oldThreadName field. This field is a fixed length string. */
275 if (bfd_read ((PTR
) nlm_variable_header (abfd
)->oldThreadName
,
276 sizeof (nlm_variable_header (abfd
)->oldThreadName
),
278 sizeof (nlm_variable_header (abfd
)->oldThreadName
))
281 /* Read the screen name length and text members. */
283 if (bfd_read ((PTR
) & nlm_variable_header (abfd
)->screenNameLength
,
284 sizeof (nlm_variable_header (abfd
)->screenNameLength
),
286 sizeof (nlm_variable_header (abfd
)->screenNameLength
))
288 if (bfd_read ((PTR
) nlm_variable_header (abfd
)->screenName
,
289 nlm_variable_header (abfd
)->screenNameLength
+ 1,
291 nlm_variable_header (abfd
)->screenNameLength
+ 1)
294 /* Read the thread name length and text members. */
296 if (bfd_read ((PTR
) & nlm_variable_header (abfd
)->threadNameLength
,
297 sizeof (nlm_variable_header (abfd
)->threadNameLength
),
299 sizeof (nlm_variable_header (abfd
)->threadNameLength
))
301 if (bfd_read ((PTR
) nlm_variable_header (abfd
)->threadName
,
302 nlm_variable_header (abfd
)->threadNameLength
+ 1,
304 nlm_variable_header (abfd
)->threadNameLength
+ 1)
309 /* Swap and write out the variable length header. All the fields must
310 exist in the NLM, and must exist in this order. */
313 nlm_swap_variable_header_out (abfd
)
316 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
318 /* Write the description length and text members. */
320 if (bfd_write ((PTR
) & nlm_variable_header (abfd
)->descriptionLength
,
321 sizeof (nlm_variable_header (abfd
)->descriptionLength
),
323 sizeof (nlm_variable_header (abfd
)->descriptionLength
))
325 if (bfd_write ((PTR
) nlm_variable_header (abfd
)->descriptionText
,
326 nlm_variable_header (abfd
)->descriptionLength
+ 1,
328 nlm_variable_header (abfd
)->descriptionLength
+ 1)
331 /* Convert and write the stackSize field. */
333 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->stackSize
,
335 if (bfd_write ((PTR
) temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
338 /* Convert and write the reserved field. */
340 put_word (abfd
, (bfd_vma
) nlm_variable_header (abfd
)->reserved
,
342 if (bfd_write ((PTR
) temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
345 /* Write the oldThreadName field. This field is a fixed length string. */
347 if (bfd_write ((PTR
) nlm_variable_header (abfd
)->oldThreadName
,
348 sizeof (nlm_variable_header (abfd
)->oldThreadName
),
350 sizeof (nlm_variable_header (abfd
)->oldThreadName
))
353 /* Write the screen name length and text members. */
355 if (bfd_write ((PTR
) & nlm_variable_header (abfd
)->screenNameLength
,
356 sizeof (nlm_variable_header (abfd
)->screenNameLength
),
358 sizeof (nlm_variable_header (abfd
)->screenNameLength
))
360 if (bfd_write ((PTR
) nlm_variable_header (abfd
)->screenName
,
361 nlm_variable_header (abfd
)->screenNameLength
+ 1,
363 nlm_variable_header (abfd
)->screenNameLength
+ 1)
366 /* Write the thread name length and text members. */
368 if (bfd_write ((PTR
) & nlm_variable_header (abfd
)->threadNameLength
,
369 sizeof (nlm_variable_header (abfd
)->threadNameLength
),
371 sizeof (nlm_variable_header (abfd
)->threadNameLength
))
373 if (bfd_write ((PTR
) nlm_variable_header (abfd
)->threadName
,
374 nlm_variable_header (abfd
)->threadNameLength
+ 1,
376 nlm_variable_header (abfd
)->threadNameLength
+ 1)
381 /* Read and swap in the contents of all the auxiliary headers. Because of
382 the braindead design, we have to do strcmps on strings of indeterminate
383 length to figure out what each auxiliary header is. Even worse, we have
384 no way of knowing how many auxiliary headers there are or where the end
385 of the auxiliary headers are, except by finding something that doesn't
386 look like a known auxiliary header. This means that the first new type
387 of auxiliary header added will break all existing tools that don't
391 nlm_swap_auxiliary_headers_in (abfd
)
399 position
= bfd_tell (abfd
);
400 if (bfd_read ((PTR
) tempstr
, sizeof (tempstr
), 1, abfd
) !=
403 if (bfd_seek (abfd
, position
, SEEK_SET
) == -1)
405 if (strncmp (tempstr
, "VeRsIoN#", 8) == 0)
407 Nlm_External_Version_Header thdr
;
408 if (bfd_read ((PTR
) & thdr
, sizeof (thdr
), 1, abfd
) != sizeof (thdr
))
410 memcpy (nlm_version_header (abfd
)->stamp
, thdr
.stamp
,
411 sizeof (thdr
.stamp
));
412 nlm_version_header (abfd
)->majorVersion
=
413 get_word (abfd
, (bfd_byte
*) thdr
.majorVersion
);
414 nlm_version_header (abfd
)->minorVersion
=
415 get_word (abfd
, (bfd_byte
*) thdr
.minorVersion
);
416 nlm_version_header (abfd
)->revision
=
417 get_word (abfd
, (bfd_byte
*) thdr
.revision
);
418 nlm_version_header (abfd
)->year
=
419 get_word (abfd
, (bfd_byte
*) thdr
.year
);
420 nlm_version_header (abfd
)->month
=
421 get_word (abfd
, (bfd_byte
*) thdr
.month
);
422 nlm_version_header (abfd
)->day
=
423 get_word (abfd
, (bfd_byte
*) thdr
.day
);
425 else if (strncmp (tempstr
, "MeSsAgEs", 8) == 0)
427 Nlm_External_Extended_Header thdr
;
428 if (bfd_read ((PTR
) & thdr
, sizeof (thdr
), 1, abfd
) != sizeof (thdr
))
430 memcpy (nlm_extended_header (abfd
)->stamp
, thdr
.stamp
,
431 sizeof (thdr
.stamp
));
432 nlm_extended_header (abfd
)->languageID
=
433 get_word (abfd
, (bfd_byte
*) thdr
.languageID
);
434 nlm_extended_header (abfd
)->messageFileOffset
=
435 get_word (abfd
, (bfd_byte
*) thdr
.messageFileOffset
);
436 nlm_extended_header (abfd
)->messageFileLength
=
437 get_word (abfd
, (bfd_byte
*) thdr
.messageFileLength
);
438 nlm_extended_header (abfd
)->messageCount
=
439 get_word (abfd
, (bfd_byte
*) thdr
.messageCount
);
440 nlm_extended_header (abfd
)->helpFileOffset
=
441 get_word (abfd
, (bfd_byte
*) thdr
.helpFileOffset
);
442 nlm_extended_header (abfd
)->helpFileLength
=
443 get_word (abfd
, (bfd_byte
*) thdr
.helpFileLength
);
444 nlm_extended_header (abfd
)->RPCDataOffset
=
445 get_word (abfd
, (bfd_byte
*) thdr
.RPCDataOffset
);
446 nlm_extended_header (abfd
)->RPCDataLength
=
447 get_word (abfd
, (bfd_byte
*) thdr
.RPCDataLength
);
448 nlm_extended_header (abfd
)->sharedCodeOffset
=
449 get_word (abfd
, (bfd_byte
*) thdr
.sharedCodeOffset
);
450 nlm_extended_header (abfd
)->sharedCodeLength
=
451 get_word (abfd
, (bfd_byte
*) thdr
.sharedCodeLength
);
452 nlm_extended_header (abfd
)->sharedDataOffset
=
453 get_word (abfd
, (bfd_byte
*) thdr
.sharedDataOffset
);
454 nlm_extended_header (abfd
)->sharedDataLength
=
455 get_word (abfd
, (bfd_byte
*) thdr
.sharedDataLength
);
456 nlm_extended_header (abfd
)->sharedRelocationFixupOffset
=
457 get_word (abfd
, (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
458 nlm_extended_header (abfd
)->sharedRelocationFixupCount
=
459 get_word (abfd
, (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
460 nlm_extended_header (abfd
)->sharedExternalReferenceOffset
=
461 get_word (abfd
, (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
462 nlm_extended_header (abfd
)->sharedExternalReferenceCount
=
463 get_word (abfd
, (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
464 nlm_extended_header (abfd
)->sharedPublicsOffset
=
465 get_word (abfd
, (bfd_byte
*) thdr
.sharedPublicsOffset
);
466 nlm_extended_header (abfd
)->sharedPublicsCount
=
467 get_word (abfd
, (bfd_byte
*) thdr
.sharedPublicsCount
);
468 nlm_extended_header (abfd
)->sharedDebugRecordOffset
=
469 get_word (abfd
, (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
470 nlm_extended_header (abfd
)->sharedDebugRecordCount
=
471 get_word (abfd
, (bfd_byte
*) thdr
.sharedDebugRecordCount
);
472 nlm_extended_header (abfd
)->SharedInitializationOffset
=
473 get_word (abfd
, (bfd_byte
*) thdr
.sharedInitializationOffset
);
474 nlm_extended_header (abfd
)->SharedExitProcedureOffset
=
475 get_word (abfd
, (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
476 nlm_extended_header (abfd
)->productID
=
477 get_word (abfd
, (bfd_byte
*) thdr
.productID
);
478 nlm_extended_header (abfd
)->reserved0
=
479 get_word (abfd
, (bfd_byte
*) thdr
.reserved0
);
480 nlm_extended_header (abfd
)->reserved1
=
481 get_word (abfd
, (bfd_byte
*) thdr
.reserved1
);
482 nlm_extended_header (abfd
)->reserved2
=
483 get_word (abfd
, (bfd_byte
*) thdr
.reserved2
);
484 nlm_extended_header (abfd
)->reserved3
=
485 get_word (abfd
, (bfd_byte
*) thdr
.reserved3
);
486 nlm_extended_header (abfd
)->reserved4
=
487 get_word (abfd
, (bfd_byte
*) thdr
.reserved4
);
488 nlm_extended_header (abfd
)->reserved5
=
489 get_word (abfd
, (bfd_byte
*) thdr
.reserved5
);
491 else if (strncmp (tempstr
, "CuStHeAd", 8) == 0)
493 Nlm_External_Custom_Header thdr
;
494 if (bfd_read ((PTR
) & thdr
, sizeof (thdr
), 1, abfd
) != sizeof (thdr
))
496 memcpy (nlm_custom_header (abfd
)->stamp
, thdr
.stamp
,
497 sizeof (thdr
.stamp
));
498 nlm_custom_header (abfd
)->dataLength
=
499 get_word (abfd
, (bfd_byte
*) thdr
.dataLength
);
500 nlm_custom_header (abfd
)->debugRecOffset
=
501 get_word (abfd
, (bfd_byte
*) thdr
.debugRecOffset
);
502 nlm_custom_header (abfd
)->debugRecLength
=
503 get_word (abfd
, (bfd_byte
*) thdr
.debugRecLength
);
505 else if (strncmp (tempstr
, "CoPyRiGhT=", 10) == 0)
507 if (bfd_read ((PTR
) nlm_copyright_header (abfd
)->stamp
,
508 sizeof (nlm_copyright_header (abfd
)->stamp
),
510 != sizeof (nlm_copyright_header (abfd
)->stamp
))
512 if (bfd_read ((PTR
) & (nlm_copyright_header (abfd
)
513 ->copyrightMessageLength
),
516 /* The copyright message is a variable length string. */
517 if (bfd_read ((PTR
) nlm_copyright_header (abfd
)->copyrightMessage
,
518 nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1,
520 nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1)
531 /* Return whether there is a non-zero byte in a memory block. */
534 find_nonzero (buf
, size
)
538 char *p
= (char *) buf
;
546 /* Swap out the contents of the auxiliary headers. We create those
547 auxiliary headers which have been set non-zero. We do not require
548 the caller to set up the stamp fields. */
551 nlm_swap_auxiliary_headers_out (abfd
)
554 /* Write out the version header if there is one. */
555 if (find_nonzero ((PTR
) nlm_version_header (abfd
),
556 sizeof (Nlm_Internal_Version_Header
)))
558 Nlm_External_Version_Header thdr
;
560 memcpy (thdr
.stamp
, "VeRsIoN#", 8);
561 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->majorVersion
,
562 (bfd_byte
*) thdr
.majorVersion
);
563 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->minorVersion
,
564 (bfd_byte
*) thdr
.minorVersion
);
565 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->revision
,
566 (bfd_byte
*) thdr
.revision
);
567 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->year
,
568 (bfd_byte
*) thdr
.year
);
569 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->month
,
570 (bfd_byte
*) thdr
.month
);
571 put_word (abfd
, (bfd_vma
) nlm_version_header (abfd
)->day
,
572 (bfd_byte
*) thdr
.day
);
573 if (bfd_write ((PTR
) & thdr
, sizeof (thdr
), 1, abfd
) != sizeof (thdr
))
577 /* Write out the extended header if there is one. */
578 if (find_nonzero ((PTR
) nlm_extended_header (abfd
),
579 sizeof (Nlm_Internal_Extended_Header
)))
581 Nlm_External_Extended_Header thdr
;
583 memcpy (thdr
.stamp
, "MeSsAgEs", 8);
585 (bfd_vma
) nlm_extended_header (abfd
)->languageID
,
586 (bfd_byte
*) thdr
.languageID
);
588 (bfd_vma
) nlm_extended_header (abfd
)->messageFileOffset
,
589 (bfd_byte
*) thdr
.messageFileOffset
);
591 (bfd_vma
) nlm_extended_header (abfd
)->messageFileLength
,
592 (bfd_byte
*) thdr
.messageFileLength
);
594 (bfd_vma
) nlm_extended_header (abfd
)->messageCount
,
595 (bfd_byte
*) thdr
.messageCount
);
597 (bfd_vma
) nlm_extended_header (abfd
)->helpFileOffset
,
598 (bfd_byte
*) thdr
.helpFileOffset
);
600 (bfd_vma
) nlm_extended_header (abfd
)->helpFileLength
,
601 (bfd_byte
*) thdr
.helpFileLength
);
603 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataOffset
,
604 (bfd_byte
*) thdr
.RPCDataOffset
);
606 (bfd_vma
) nlm_extended_header (abfd
)->RPCDataLength
,
607 (bfd_byte
*) thdr
.RPCDataLength
);
609 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeOffset
,
610 (bfd_byte
*) thdr
.sharedCodeOffset
);
612 (bfd_vma
) nlm_extended_header (abfd
)->sharedCodeLength
,
613 (bfd_byte
*) thdr
.sharedCodeLength
);
615 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataOffset
,
616 (bfd_byte
*) thdr
.sharedDataOffset
);
618 (bfd_vma
) nlm_extended_header (abfd
)->sharedDataLength
,
619 (bfd_byte
*) thdr
.sharedDataLength
);
621 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupOffset
,
622 (bfd_byte
*) thdr
.sharedRelocationFixupOffset
);
624 (bfd_vma
) nlm_extended_header (abfd
)->sharedRelocationFixupCount
,
625 (bfd_byte
*) thdr
.sharedRelocationFixupCount
);
627 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceOffset
,
628 (bfd_byte
*) thdr
.sharedExternalReferenceOffset
);
630 (bfd_vma
) nlm_extended_header (abfd
)->sharedExternalReferenceCount
,
631 (bfd_byte
*) thdr
.sharedExternalReferenceCount
);
633 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsOffset
,
634 (bfd_byte
*) thdr
.sharedPublicsOffset
);
636 (bfd_vma
) nlm_extended_header (abfd
)->sharedPublicsCount
,
637 (bfd_byte
*) thdr
.sharedPublicsCount
);
639 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordOffset
,
640 (bfd_byte
*) thdr
.sharedDebugRecordOffset
);
642 (bfd_vma
) nlm_extended_header (abfd
)->sharedDebugRecordCount
,
643 (bfd_byte
*) thdr
.sharedDebugRecordCount
);
645 (bfd_vma
) nlm_extended_header (abfd
)->SharedInitializationOffset
,
646 (bfd_byte
*) thdr
.sharedInitializationOffset
);
648 (bfd_vma
) nlm_extended_header (abfd
)->SharedExitProcedureOffset
,
649 (bfd_byte
*) thdr
.SharedExitProcedureOffset
);
651 (bfd_vma
) nlm_extended_header (abfd
)->productID
,
652 (bfd_byte
*) thdr
.productID
);
654 (bfd_vma
) nlm_extended_header (abfd
)->reserved0
,
655 (bfd_byte
*) thdr
.reserved0
);
657 (bfd_vma
) nlm_extended_header (abfd
)->reserved1
,
658 (bfd_byte
*) thdr
.reserved1
);
660 (bfd_vma
) nlm_extended_header (abfd
)->reserved2
,
661 (bfd_byte
*) thdr
.reserved2
);
663 (bfd_vma
) nlm_extended_header (abfd
)->reserved3
,
664 (bfd_byte
*) thdr
.reserved3
);
666 (bfd_vma
) nlm_extended_header (abfd
)->reserved4
,
667 (bfd_byte
*) thdr
.reserved4
);
669 (bfd_vma
) nlm_extended_header (abfd
)->reserved5
,
670 (bfd_byte
*) thdr
.reserved5
);
671 if (bfd_write ((PTR
) & thdr
, sizeof (thdr
), 1, abfd
) != sizeof (thdr
))
675 /* Write out the custom header if there is one. */
676 if (find_nonzero ((PTR
) nlm_custom_header (abfd
),
677 sizeof (Nlm_Internal_Custom_Header
)))
679 Nlm_External_Custom_Header thdr
;
681 /* Right now we assume the custom header is always the suggested
682 format for alternate debugging records. */
683 BFD_ASSERT (nlm_custom_header (abfd
)->dataLength
== 8);
685 memcpy (thdr
.stamp
, "CuStHeAd", 8);
686 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->dataLength
,
687 (bfd_byte
*) thdr
.dataLength
);
688 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->debugRecOffset
,
689 (bfd_byte
*) thdr
.debugRecOffset
);
690 put_word (abfd
, (bfd_vma
) nlm_custom_header (abfd
)->debugRecLength
,
691 (bfd_byte
*) thdr
.debugRecLength
);
692 if (bfd_write ((PTR
) & thdr
, sizeof (thdr
), 1, abfd
) != sizeof (thdr
))
696 /* Write out the copyright header if there is one. */
697 if (find_nonzero ((PTR
) nlm_copyright_header (abfd
),
698 sizeof (Nlm_Internal_Copyright_Header
)))
700 Nlm_External_Copyright_Header thdr
;
702 memcpy (thdr
.stamp
, "CoPyRiGhT=", 10);
703 if (bfd_write ((PTR
) thdr
.stamp
, sizeof (thdr
.stamp
), 1, abfd
)
704 != sizeof (thdr
.stamp
))
706 thdr
.copyrightMessageLength
[0] =
707 nlm_copyright_header (abfd
)->copyrightMessageLength
;
708 if (bfd_write ((PTR
) thdr
.copyrightMessageLength
, 1, 1, abfd
) != 1)
710 /* The copyright message is a variable length string. */
711 if (bfd_write ((PTR
) nlm_copyright_header (abfd
)->copyrightMessage
,
712 nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1,
714 nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1)
721 /* We read the NLM's public symbols and use it to generate a bfd symbol
722 table (hey, it's better than nothing) on a one-for-one basis. Thus
723 use the number of public symbols as the number of bfd symbols we will
724 have once we actually get around to reading them in.
726 Return the number of bytes required to hold the symtab vector, based on
727 the count plus 1, since we will NULL terminate the vector allocated based
731 nlm_get_symtab_upper_bound (abfd
)
734 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form */
736 long symtab_size
= 0;
738 i_fxdhdrp
= nlm_fixed_header (abfd
);
739 symcount
= (i_fxdhdrp
->numberOfPublics
740 + i_fxdhdrp
->numberOfDebugRecords
741 + i_fxdhdrp
->numberOfExternalReferences
);
742 symtab_size
= (symcount
+ 1) * (sizeof (asymbol
));
743 return (symtab_size
);
746 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
747 symbol table fails. */
750 nlm_get_symtab (abfd
, alocation
)
754 nlm_symbol_type
*symbase
;
755 bfd_size_type counter
= 0;
757 if (nlm_slurp_symbol_table (abfd
) == false)
759 symbase
= nlm_get_symbols (abfd
);
760 while (counter
< bfd_get_symcount (abfd
))
762 *alocation
++ = &symbase
->symbol
;
766 *alocation
= (asymbol
*) NULL
;
767 return bfd_get_symcount (abfd
);
770 /* Make an NLM symbol. There is nothing special to do here. */
773 nlm_make_empty_symbol (abfd
)
776 nlm_symbol_type
*new;
778 new = (nlm_symbol_type
*) bfd_zalloc (abfd
, sizeof (nlm_symbol_type
));
780 new->symbol
.the_bfd
= abfd
;
784 /* Get symbol information. */
787 nlm_get_symbol_info (ignore_abfd
, symbol
, ret
)
792 bfd_symbol_info (symbol
, ret
);
795 /* Print symbol information. */
798 nlm_print_symbol (abfd
, afile
, symbol
, how
)
802 bfd_print_symbol_type how
;
804 FILE *file
= (FILE *) afile
;
808 case bfd_print_symbol_name
:
809 case bfd_print_symbol_more
:
811 fprintf (file
, "%s", symbol
->name
);
813 case bfd_print_symbol_all
:
814 bfd_print_symbol_vandf ((PTR
) file
, symbol
);
815 fprintf (file
, " %-5s", symbol
->section
->name
);
817 fprintf (file
, " %s", symbol
->name
);
822 /* Slurp in nlm symbol table.
824 In the external (in-file) form, NLM export records are variable length,
825 with the following form:
827 1 byte length of the symbol name (N)
828 N bytes the symbol name
829 4 bytes the symbol offset from start of it's section
831 We also read in the debugging symbols and import records. Import
832 records are treated as undefined symbols. As we read the import
833 records we also read in the associated reloc information, which is
834 attached to the symbol.
836 The bfd symbols are copied to SYMPTRS.
838 When we return, the bfd symcount is either zero or contains the correct
843 nlm_slurp_symbol_table (abfd
)
846 Nlm_Internal_Fixed_Header
*i_fxdhdrp
; /* Nlm file header, internal form */
847 bfd_size_type totsymcount
; /* Number of NLM symbols */
848 bfd_size_type symcount
; /* Counter of NLM symbols */
849 nlm_symbol_type
*sym
; /* Pointer to current bfd symbol */
850 unsigned char symlength
; /* Symbol length read into here */
851 unsigned char symtype
; /* Type of debugging symbol */
852 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Symbol offsets read into here */
853 boolean (*read_import_func
) PARAMS ((bfd
*, nlm_symbol_type
*));
854 boolean (*set_public_section_func
) PARAMS ((bfd
*, nlm_symbol_type
*));
856 if (nlm_get_symbols (abfd
) != NULL
)
859 /* Read each raw NLM symbol, using the information to create a canonical bfd
862 Note that we allocate the initial bfd canonical symbol buffer based on a
863 one-to-one mapping of the NLM symbols to canonical symbols. We actually
864 use all the NLM symbols, so there will be no space left over at the end.
865 When we have all the symbols, we build the caller's pointer vector. */
868 i_fxdhdrp
= nlm_fixed_header (abfd
);
869 totsymcount
= (i_fxdhdrp
->numberOfPublics
870 + i_fxdhdrp
->numberOfDebugRecords
871 + i_fxdhdrp
->numberOfExternalReferences
);
872 if (totsymcount
== 0)
877 if (bfd_seek (abfd
, i_fxdhdrp
->publicsOffset
, SEEK_SET
) == -1)
880 sym
= ((nlm_symbol_type
*)
881 bfd_zalloc (abfd
, totsymcount
* sizeof (nlm_symbol_type
)));
884 bfd_set_error (bfd_error_no_memory
);
887 nlm_set_symbols (abfd
, sym
);
889 /* We use the bfd's symcount directly as the control count, so that early
890 termination of the loop leaves the symcount correct for the symbols that
893 set_public_section_func
= nlm_set_public_section_func (abfd
);
894 symcount
= i_fxdhdrp
->numberOfPublics
;
895 while (abfd
->symcount
< symcount
)
897 if (bfd_read ((PTR
) & symlength
, sizeof (symlength
), 1, abfd
)
898 != sizeof (symlength
))
900 sym
->symbol
.the_bfd
= abfd
;
901 sym
->symbol
.name
= bfd_alloc (abfd
, symlength
+ 1);
902 if (!sym
->symbol
.name
)
904 bfd_set_error (bfd_error_no_memory
);
907 if (bfd_read ((PTR
) sym
->symbol
.name
, symlength
, 1, abfd
)
910 /* Cast away const. */
911 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
912 if (bfd_read ((PTR
) temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
914 sym
->symbol
.flags
= BSF_GLOBAL
| BSF_EXPORT
;
915 sym
->symbol
.value
= get_word (abfd
, temp
);
916 if (set_public_section_func
)
918 /* Most backends can use the code below, but unfortunately
919 some use a different scheme. */
920 if ((*set_public_section_func
) (abfd
, sym
) == false)
925 if (sym
->symbol
.value
& NLM_HIBIT
)
927 sym
->symbol
.value
&= ~NLM_HIBIT
;
928 sym
->symbol
.flags
|= BSF_FUNCTION
;
929 sym
->symbol
.section
=
930 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
934 sym
->symbol
.section
=
935 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
943 /* Read the debugging records. */
945 if (i_fxdhdrp
->numberOfDebugRecords
> 0)
947 if (bfd_seek (abfd
, i_fxdhdrp
->debugInfoOffset
, SEEK_SET
) == -1)
950 symcount
+= i_fxdhdrp
->numberOfDebugRecords
;
951 while (abfd
->symcount
< symcount
)
953 if ((bfd_read ((PTR
) & symtype
, sizeof (symtype
), 1, abfd
)
955 || bfd_read ((PTR
) temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
)
956 || (bfd_read ((PTR
) & symlength
, sizeof (symlength
), 1, abfd
)
957 != sizeof (symlength
)))
959 sym
->symbol
.the_bfd
= abfd
;
960 sym
->symbol
.name
= bfd_alloc (abfd
, symlength
+ 1);
961 if (!sym
->symbol
.name
)
963 bfd_set_error (bfd_error_no_memory
);
966 if (bfd_read ((PTR
) sym
->symbol
.name
, symlength
, 1, abfd
)
969 /* Cast away const. */
970 ((char *) (sym
->symbol
.name
))[symlength
] = '\0';
971 sym
->symbol
.flags
= BSF_LOCAL
;
972 sym
->symbol
.value
= get_word (abfd
, temp
);
975 sym
->symbol
.section
=
976 bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
978 else if (symtype
== 1)
980 sym
->symbol
.flags
|= BSF_FUNCTION
;
981 sym
->symbol
.section
=
982 bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
986 sym
->symbol
.section
= &bfd_abs_section
;
994 /* Read in the import records. We can only do this if we know how
995 to read relocs for this target. */
997 read_import_func
= nlm_read_import_func (abfd
);
998 if (read_import_func
!= NULL
)
1000 if (bfd_seek (abfd
, i_fxdhdrp
->externalReferencesOffset
, SEEK_SET
)
1004 symcount
+= i_fxdhdrp
->numberOfExternalReferences
;
1005 while (abfd
->symcount
< symcount
)
1007 if ((*read_import_func
) (abfd
, sym
) == false)
1017 /* Get the relocs for an NLM file. There are two types of relocs.
1018 Imports are relocs against symbols defined in other NLM files. We
1019 treat these as relocs against global symbols. Relocation fixups
1020 are internal relocs.
1022 The actual format used to store the relocs is machine specific. */
1024 /* Read in the relocation fixup information. This is stored in
1025 nlm_relocation_fixups, an array of arelent structures, and
1026 nlm_relocation_fixup_secs, an array of section pointers. The
1027 section pointers are needed because the relocs are not sorted by
1031 nlm_slurp_reloc_fixups (abfd
)
1034 boolean (*read_func
) PARAMS ((bfd
*, nlm_symbol_type
*, asection
**,
1036 bfd_size_type count
;
1040 if (nlm_relocation_fixups (abfd
) != NULL
)
1042 read_func
= nlm_read_reloc_func (abfd
);
1043 if (read_func
== NULL
)
1046 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1050 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1051 rels
= (arelent
*) bfd_alloc (abfd
, count
* sizeof (arelent
));
1052 secs
= (asection
**) bfd_alloc (abfd
, count
* sizeof (asection
*));
1053 if (rels
== NULL
|| secs
== NULL
)
1055 bfd_set_error (bfd_error_no_memory
);
1058 nlm_relocation_fixups (abfd
) = rels
;
1059 nlm_relocation_fixup_secs (abfd
) = secs
;
1061 /* We have to read piece by piece, because we don't know how large
1062 the machine specific reloc information is. */
1063 while (count
-- != 0)
1065 if ((*read_func
) (abfd
, (nlm_symbol_type
*) NULL
, secs
, rels
) == false)
1067 nlm_relocation_fixups (abfd
) = NULL
;
1068 nlm_relocation_fixup_secs (abfd
) = NULL
;
1078 /* Get the number of relocs. This really just returns an upper bound,
1079 since it does not attempt to distinguish them based on the section.
1080 That will be handled when they are actually read. */
1083 nlm_get_reloc_upper_bound (abfd
, sec
)
1087 nlm_symbol_type
*syms
;
1088 bfd_size_type count
;
1091 /* If we don't know how to read relocs, just return 0. */
1092 if (nlm_read_reloc_func (abfd
) == NULL
)
1094 /* Make sure we have either the code or the data section. */
1095 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1098 syms
= nlm_get_symbols (abfd
);
1101 if (nlm_slurp_symbol_table (abfd
) == false)
1103 syms
= nlm_get_symbols (abfd
);
1106 ret
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1108 count
= bfd_get_symcount (abfd
);
1109 while (count
-- != 0)
1115 return (ret
+ 1) * sizeof (arelent
*);
1118 /* Get the relocs themselves. */
1121 nlm_canonicalize_reloc (abfd
, sec
, relptr
, symbols
)
1129 bfd_size_type count
, i
;
1132 /* Get the relocation fixups. */
1133 rels
= nlm_relocation_fixups (abfd
);
1136 if (nlm_slurp_reloc_fixups (abfd
) == false)
1138 rels
= nlm_relocation_fixups (abfd
);
1142 secs
= nlm_relocation_fixup_secs (abfd
);
1145 count
= nlm_fixed_header (abfd
)->numberOfRelocationFixups
;
1146 for (i
= 0; i
< count
; i
++, rels
++, secs
++)
1155 /* Get the import symbols. */
1156 count
= bfd_get_symcount (abfd
);
1157 for (i
= 0; i
< count
; i
++, symbols
++)
1162 if (bfd_asymbol_flavour (sym
) == bfd_target_nlm_flavour
)
1164 nlm_symbol_type
*nlm_sym
;
1167 nlm_sym
= (nlm_symbol_type
*) sym
;
1168 for (j
= 0; j
< nlm_sym
->rcnt
; j
++)
1170 if (nlm_sym
->relocs
[j
].section
== sec
)
1172 *relptr
= &nlm_sym
->relocs
[j
].reloc
;
1173 (*relptr
)->sym_ptr_ptr
= symbols
;
1186 /* Compute the section file positions for an NLM file. All variable
1187 length data in the file headers must be set before this function is
1188 called. If the variable length data is changed later, the
1189 resulting object file will be incorrect. Unfortunately, there is
1190 no way to check this.
1192 This routine also sets the Size and Offset fields in the fixed
1195 It also looks over the symbols and moves any common symbols into
1196 the .bss section; NLM has no way to represent a common symbol.
1197 This approach means that either the symbols must already have been
1198 set at this point, or there must be no common symbols. We need to
1199 move the symbols at this point so that mangle_relocs can see the
1203 nlm_compute_section_file_positions (abfd
)
1208 bfd_vma text
, data
, bss
;
1209 bfd_vma text_low
, data_low
;
1210 int text_align
, data_align
, other_align
;
1211 file_ptr text_ptr
, data_ptr
, other_ptr
;
1213 asymbol
**sym_ptr_ptr
;
1215 if (abfd
->output_has_begun
== true)
1218 /* Make sure we have a section to hold uninitialized data. */
1219 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1220 if (bss_sec
== NULL
)
1222 if (!add_bfd_section (abfd
, NLM_UNINITIALIZED_DATA_NAME
,
1223 (file_ptr
) 0, (bfd_size_type
) 0,
1226 bss_sec
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
1229 abfd
->output_has_begun
= true;
1231 /* The fixed header. */
1232 sofar
= nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
);
1234 /* The variable header. */
1235 sofar
+= (sizeof (nlm_variable_header (abfd
)->descriptionLength
)
1236 + nlm_variable_header (abfd
)->descriptionLength
+ 1
1237 + NLM_TARGET_LONG_SIZE
/* stackSize */
1238 + NLM_TARGET_LONG_SIZE
/* reserved */
1239 + sizeof (nlm_variable_header (abfd
)->oldThreadName
)
1240 + sizeof (nlm_variable_header (abfd
)->screenNameLength
)
1241 + nlm_variable_header (abfd
)->screenNameLength
+ 1
1242 + sizeof (nlm_variable_header (abfd
)->threadNameLength
)
1243 + nlm_variable_header (abfd
)->threadNameLength
+ 1);
1245 /* The auxiliary headers. */
1246 if (find_nonzero ((PTR
) nlm_version_header (abfd
),
1247 sizeof (Nlm_Internal_Version_Header
)))
1248 sofar
+= sizeof (Nlm_External_Version_Header
);
1249 if (find_nonzero ((PTR
) nlm_extended_header (abfd
),
1250 sizeof (Nlm_Internal_Extended_Header
)))
1251 sofar
+= sizeof (Nlm_External_Extended_Header
);
1252 if (find_nonzero ((PTR
) nlm_custom_header (abfd
),
1253 sizeof (Nlm_Internal_Custom_Header
)))
1254 sofar
+= sizeof (Nlm_External_Custom_Header
);
1255 if (find_nonzero ((PTR
) nlm_copyright_header (abfd
),
1256 sizeof (Nlm_Internal_Copyright_Header
)))
1257 sofar
+= (sizeof (Nlm_External_Copyright_Header
)
1258 + nlm_copyright_header (abfd
)->copyrightMessageLength
+ 1);
1260 /* Compute the section file positions in two passes. First get the
1261 sizes of the text and data sections, and then set the file
1262 positions. This code aligns the sections in the file using the
1263 same alignment restrictions that apply to the sections in memory;
1264 this may not be necessary. */
1266 text_low
= (bfd_vma
) - 1;
1269 data_low
= (bfd_vma
) - 1;
1273 for (sec
= abfd
->sections
; sec
!= (asection
*) NULL
; sec
= sec
->next
)
1277 sec
->_raw_size
= BFD_ALIGN (sec
->_raw_size
, 1 << sec
->alignment_power
);
1279 f
= bfd_get_section_flags (abfd
, sec
);
1282 text
+= sec
->_raw_size
;
1283 if (bfd_get_section_vma (abfd
, sec
) < text_low
)
1284 text_low
= bfd_get_section_vma (abfd
, sec
);
1285 if (sec
->alignment_power
> text_align
)
1286 text_align
= sec
->alignment_power
;
1288 else if (f
& SEC_DATA
)
1290 data
+= sec
->_raw_size
;
1291 if (bfd_get_section_vma (abfd
, sec
) < data_low
)
1292 data_low
= bfd_get_section_vma (abfd
, sec
);
1293 if (sec
->alignment_power
> data_align
)
1294 data_align
= sec
->alignment_power
;
1296 else if (f
& SEC_HAS_CONTENTS
)
1298 if (sec
->alignment_power
> other_align
)
1299 other_align
= sec
->alignment_power
;
1301 else if (f
& SEC_ALLOC
)
1302 bss
+= sec
->_raw_size
;
1305 nlm_set_text_low (abfd
, text_low
);
1306 nlm_set_data_low (abfd
, data_low
);
1308 if (nlm_no_uninitialized_data (abfd
))
1310 /* This NetWare format does not use uninitialized data. We must
1311 increase the size of the data section. We will never wind up
1312 writing those file locations, so they will remain zero. */
1317 text_ptr
= BFD_ALIGN (sofar
, 1 << text_align
);
1318 data_ptr
= BFD_ALIGN (text_ptr
+ text
, 1 << data_align
);
1319 other_ptr
= BFD_ALIGN (data_ptr
+ data
, 1 << other_align
);
1321 /* Fill in some fields in the header for which we now have the
1323 nlm_fixed_header (abfd
)->codeImageOffset
= text_ptr
;
1324 nlm_fixed_header (abfd
)->codeImageSize
= text
;
1325 nlm_fixed_header (abfd
)->dataImageOffset
= data_ptr
;
1326 nlm_fixed_header (abfd
)->dataImageSize
= data
;
1327 nlm_fixed_header (abfd
)->uninitializedDataSize
= bss
;
1329 for (sec
= abfd
->sections
; sec
!= (asection
*) NULL
; sec
= sec
->next
)
1333 f
= bfd_get_section_flags (abfd
, sec
);
1337 sec
->filepos
= text_ptr
;
1338 text_ptr
+= sec
->_raw_size
;
1340 else if (f
& SEC_DATA
)
1342 sec
->filepos
= data_ptr
;
1343 data_ptr
+= sec
->_raw_size
;
1345 else if (f
& SEC_HAS_CONTENTS
)
1347 sec
->filepos
= other_ptr
;
1348 other_ptr
+= sec
->_raw_size
;
1352 nlm_fixed_header (abfd
)->relocationFixupOffset
= other_ptr
;
1354 /* Move all common symbols into the .bss section. */
1356 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1357 if (sym_ptr_ptr
!= NULL
)
1362 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1364 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1371 if (!bfd_is_com_section (bfd_get_section (sym
)))
1374 /* Put the common symbol in the .bss section, and increase
1375 the size of the .bss section by the size of the common
1376 symbol (which is the old value of the symbol). */
1377 sym
->section
= bss_sec
;
1379 sym
->value
= bss_sec
->_raw_size
+ add
;
1381 add
= BFD_ALIGN (add
, 1 << bss_sec
->alignment_power
);
1385 if (nlm_no_uninitialized_data (abfd
))
1387 /* We could handle this case, but so far it hasn't been
1391 nlm_fixed_header (abfd
)->uninitializedDataSize
+= add
;
1392 bss_sec
->_raw_size
+= add
;
1399 /* Set the contents of a section. To do this we need to know where
1400 the section is going to be located in the output file. That means
1401 that the sizes of all the sections must be set, and all the
1402 variable size header information must be known. */
1405 nlm_set_section_contents (abfd
, section
, location
, offset
, count
)
1410 bfd_size_type count
;
1412 if (abfd
->output_has_begun
== false
1413 && nlm_compute_section_file_positions (abfd
) == false)
1419 /* i386 NetWare has a very restricted set of relocs. In order for
1420 objcopy to work, the NLM i386 backend needs a chance to rework
1421 the section contents so that its set of relocs will work. If all
1422 the relocs are already acceptable, this will not do anything. */
1423 if (section
->reloc_count
!= 0)
1425 boolean (*mangle_relocs_func
) PARAMS ((bfd
*, asection
*, PTR
,
1426 bfd_vma
, bfd_size_type
));
1428 mangle_relocs_func
= nlm_mangle_relocs_func (abfd
);
1429 if (mangle_relocs_func
!= NULL
)
1431 if (!(*mangle_relocs_func
) (abfd
, section
, location
,
1432 (bfd_vma
) offset
, count
))
1437 if (bfd_seek (abfd
, (file_ptr
) (section
->filepos
+ offset
), SEEK_SET
) != 0
1438 || bfd_write (location
, 1, count
, abfd
) != count
)
1444 /* We need to sort a list of relocs associated with sections when we
1445 write out the external relocs. */
1448 nlm_external_reloc_compare (p1
, p2
)
1452 const struct reloc_and_sec
*r1
= (const struct reloc_and_sec
*) p1
;
1453 const struct reloc_and_sec
*r2
= (const struct reloc_and_sec
*) p2
;
1456 cmp
= strcmp ((*r1
->rel
->sym_ptr_ptr
)->name
,
1457 (*r2
->rel
->sym_ptr_ptr
)->name
);
1461 /* We sort by address within symbol to make the sort more stable and
1462 increase the chances that different hosts will generate bit for
1463 bit equivalent results. */
1464 return (int) (r1
->rel
->address
- r2
->rel
->address
);
1467 /* Write out an NLM file. We write out the information in this order:
1473 other sections (custom data, messages, help, shared NLM, RPC,
1474 module dependencies)
1476 external references (imports)
1477 public symbols (exports)
1479 This is similar to the order used by the NetWare tools; the
1480 difference is that NetWare puts the sections other than code, data
1481 and custom data at the end of the NLM. It is convenient for us to
1482 know where the sections are going to be before worrying about the
1483 size of the other information.
1485 By the time this function is called, all the section data should
1486 have been output using set_section_contents. Note that custom
1487 data, the message file, the help file, the shared NLM file, the RPC
1488 data, and the module dependencies are all considered to be
1489 sections; the caller is responsible for filling in the offset and
1490 length fields in the NLM headers. The relocation fixups and
1491 imports are both obtained from the list of relocs attached to each
1492 section. The exports and debugging records are obtained from the
1493 list of outsymbols. */
1496 nlm_write_object_contents (abfd
)
1500 boolean (*write_import_func
) PARAMS ((bfd
*, asection
*, arelent
*));
1501 bfd_size_type external_reloc_count
, internal_reloc_count
, i
, c
;
1502 struct reloc_and_sec
*external_relocs
;
1503 asymbol
**sym_ptr_ptr
;
1505 boolean (*write_prefix_func
) PARAMS ((bfd
*));
1506 unsigned char *fixed_header
= NULL
;
1508 fixed_header
= (unsigned char *) malloc (nlm_fixed_header_size (abfd
));
1509 if (fixed_header
== NULL
)
1511 bfd_set_error (bfd_error_no_memory
);
1515 if (abfd
->output_has_begun
== false
1516 && nlm_compute_section_file_positions (abfd
) == false)
1519 /* Write out the variable length headers. */
1521 nlm_optional_prefix_size (abfd
) + nlm_fixed_header_size (abfd
),
1524 if (nlm_swap_variable_header_out (abfd
) == false
1525 || nlm_swap_auxiliary_headers_out (abfd
) == false)
1527 bfd_set_error (bfd_error_system_call
);
1531 /* A weak check on whether the section file positions were
1533 if (bfd_tell (abfd
) > nlm_fixed_header (abfd
)->codeImageOffset
)
1535 bfd_set_error (bfd_error_invalid_operation
);
1539 /* Advance to the relocs. */
1540 if (bfd_seek (abfd
, nlm_fixed_header (abfd
)->relocationFixupOffset
,
1544 /* The format of the relocation entries is dependent upon the
1545 particular target. We use an external routine to write the reloc
1547 write_import_func
= nlm_write_import_func (abfd
);
1549 /* Write out the internal relocation fixups. While we're looping
1550 over the relocs, we also count the external relocs, which is
1551 needed when they are written out below. */
1552 internal_reloc_count
= 0;
1553 external_reloc_count
= 0;
1554 for (sec
= abfd
->sections
; sec
!= (asection
*) NULL
; sec
= sec
->next
)
1556 arelent
**rel_ptr_ptr
, **rel_end
;
1558 if (sec
->reloc_count
== 0)
1561 /* We can only represent relocs within a code or data
1562 section. We ignore them for a debugging section. */
1563 if ((bfd_get_section_flags (abfd
, sec
) & (SEC_CODE
| SEC_DATA
)) == 0)
1566 /* We need to know how to write out imports */
1567 if (write_import_func
== NULL
)
1569 bfd_set_error (bfd_error_invalid_operation
);
1573 rel_ptr_ptr
= sec
->orelocation
;
1574 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1575 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1581 sym
= *rel
->sym_ptr_ptr
;
1583 if (bfd_get_section (sym
) != &bfd_und_section
)
1585 ++internal_reloc_count
;
1586 if ((*write_import_func
) (abfd
, sec
, rel
) == false)
1590 ++external_reloc_count
;
1593 nlm_fixed_header (abfd
)->numberOfRelocationFixups
= internal_reloc_count
;
1595 /* Write out the imports (relocs against external symbols). These
1596 are output as a symbol name followed by all the relocs for that
1597 symbol, so we must first gather together all the relocs against
1598 external symbols and sort them. */
1600 (struct reloc_and_sec
*) bfd_alloc (abfd
,
1601 (external_reloc_count
1602 * sizeof (struct reloc_and_sec
)));
1603 if (external_relocs
== (struct reloc_and_sec
*) NULL
)
1605 bfd_set_error (bfd_error_no_memory
);
1609 for (sec
= abfd
->sections
; sec
!= (asection
*) NULL
; sec
= sec
->next
)
1611 arelent
**rel_ptr_ptr
, **rel_end
;
1613 if (sec
->reloc_count
== 0)
1616 rel_ptr_ptr
= sec
->orelocation
;
1617 rel_end
= rel_ptr_ptr
+ sec
->reloc_count
;
1618 for (; rel_ptr_ptr
< rel_end
; rel_ptr_ptr
++)
1624 sym
= *rel
->sym_ptr_ptr
;
1626 if (bfd_get_section (sym
) != &bfd_und_section
)
1629 external_relocs
[i
].rel
= rel
;
1630 external_relocs
[i
].sec
= sec
;
1635 BFD_ASSERT (i
== external_reloc_count
);
1637 /* Sort the external relocs by name. */
1638 qsort ((PTR
) external_relocs
, (size_t) external_reloc_count
,
1639 sizeof (struct reloc_and_sec
), nlm_external_reloc_compare
);
1641 /* Write out the external relocs. */
1642 nlm_fixed_header (abfd
)->externalReferencesOffset
= bfd_tell (abfd
);
1645 while (i
< external_reloc_count
)
1649 bfd_size_type j
, cnt
;
1653 rel
= external_relocs
[i
].rel
;
1654 sym
= *rel
->sym_ptr_ptr
;
1658 (j
< external_reloc_count
1659 && *external_relocs
[j
].rel
->sym_ptr_ptr
== sym
);
1663 if ((*nlm_write_external_func (abfd
)) (abfd
, cnt
, sym
,
1664 &external_relocs
[i
])
1671 nlm_fixed_header (abfd
)->numberOfExternalReferences
= c
;
1673 /* Write out the public symbols (exports). */
1674 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1675 if (sym_ptr_ptr
!= (asymbol
**) NULL
)
1677 bfd_vma (*get_public_offset_func
) PARAMS ((bfd
*, asymbol
*));
1678 boolean (*write_export_func
) PARAMS ((bfd
*, asymbol
*, bfd_vma
));
1682 nlm_fixed_header (abfd
)->publicsOffset
= bfd_tell (abfd
);
1683 get_public_offset_func
= nlm_get_public_offset_func (abfd
);
1684 write_export_func
= nlm_write_export_func (abfd
);
1686 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1687 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1692 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1696 if ((sym
->flags
& (BSF_EXPORT
| BSF_GLOBAL
)) == 0
1697 || bfd_get_section (sym
) == &bfd_und_section
)
1702 if (get_public_offset_func
)
1704 /* Most backends can use the code below, but
1705 unfortunately some use a different scheme. */
1706 offset
= (*get_public_offset_func
) (abfd
, sym
);
1710 offset
= bfd_asymbol_value (sym
);
1712 if (sec
->flags
& SEC_CODE
)
1714 offset
-= nlm_get_text_low (abfd
);
1715 offset
|= NLM_HIBIT
;
1717 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1719 /* SEC_ALLOC is for the .bss section. */
1720 offset
-= nlm_get_data_low (abfd
);
1724 /* We can't handle an exported symbol that is not in
1725 the code or data segment. */
1726 bfd_set_error (bfd_error_invalid_operation
);
1731 if (write_export_func
)
1733 if ((*write_export_func
) (abfd
, sym
, offset
) == false)
1738 len
= strlen (sym
->name
);
1739 if ((bfd_write (&len
, sizeof (bfd_byte
), 1, abfd
)
1740 != sizeof (bfd_byte
))
1741 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
1744 put_word (abfd
, offset
, temp
);
1745 if (bfd_write (temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
1749 nlm_fixed_header (abfd
)->numberOfPublics
= c
;
1751 /* Write out the debugging records. The NLM conversion program
1752 wants to be able to inhibit this, so as a special hack if
1753 debugInfoOffset is set to -1 we don't write any debugging
1754 information. This can not be handled by fiddling with the
1755 symbol table, because exported symbols appear in both the
1756 exported symbol list and the debugging information. */
1757 if (nlm_fixed_header (abfd
)->debugInfoOffset
== (file_ptr
) - 1)
1759 nlm_fixed_header (abfd
)->debugInfoOffset
= 0;
1760 nlm_fixed_header (abfd
)->numberOfDebugRecords
= 0;
1764 nlm_fixed_header (abfd
)->debugInfoOffset
= bfd_tell (abfd
);
1766 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
1767 sym_end
= sym_ptr_ptr
+ bfd_get_symcount (abfd
);
1768 for (; sym_ptr_ptr
< sym_end
; sym_ptr_ptr
++)
1773 bfd_byte temp
[NLM_TARGET_LONG_SIZE
];
1777 /* The NLM notion of a debugging symbol is actually what
1778 BFD calls a local or global symbol. What BFD calls a
1779 debugging symbol NLM does not understand at all. */
1780 if ((sym
->flags
& (BSF_LOCAL
| BSF_GLOBAL
| BSF_EXPORT
)) == 0
1781 || (sym
->flags
& BSF_DEBUGGING
) != 0
1782 || bfd_get_section (sym
) == &bfd_und_section
)
1787 offset
= bfd_asymbol_value (sym
);
1789 if (sec
->flags
& SEC_CODE
)
1791 offset
-= nlm_get_text_low (abfd
);
1794 else if (sec
->flags
& (SEC_DATA
| SEC_ALLOC
))
1796 /* SEC_ALLOC is for the .bss section. */
1797 offset
-= nlm_get_data_low (abfd
);
1803 /* The type is 0 for data, 1 for code, 2 for absolute. */
1804 if (bfd_write (&type
, sizeof (bfd_byte
), 1, abfd
)
1805 != sizeof (bfd_byte
))
1808 put_word (abfd
, offset
, temp
);
1809 if (bfd_write (temp
, sizeof (temp
), 1, abfd
) != sizeof (temp
))
1812 len
= strlen (sym
->name
);
1813 if ((bfd_write (&len
, sizeof (bfd_byte
), 1, abfd
)
1814 != sizeof (bfd_byte
))
1815 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
1818 nlm_fixed_header (abfd
)->numberOfDebugRecords
= c
;
1822 /* NLMLINK fills in offset values even if there is no data, so we do
1824 last
= bfd_tell (abfd
);
1825 if (nlm_fixed_header (abfd
)->codeImageOffset
== 0)
1826 nlm_fixed_header (abfd
)->codeImageOffset
= last
;
1827 if (nlm_fixed_header (abfd
)->dataImageOffset
== 0)
1828 nlm_fixed_header (abfd
)->dataImageOffset
= last
;
1829 if (nlm_fixed_header (abfd
)->customDataOffset
== 0)
1830 nlm_fixed_header (abfd
)->customDataOffset
= last
;
1831 if (nlm_fixed_header (abfd
)->moduleDependencyOffset
== 0)
1832 nlm_fixed_header (abfd
)->moduleDependencyOffset
= last
;
1833 if (nlm_fixed_header (abfd
)->relocationFixupOffset
== 0)
1834 nlm_fixed_header (abfd
)->relocationFixupOffset
= last
;
1835 if (nlm_fixed_header (abfd
)->externalReferencesOffset
== 0)
1836 nlm_fixed_header (abfd
)->externalReferencesOffset
= last
;
1837 if (nlm_fixed_header (abfd
)->publicsOffset
== 0)
1838 nlm_fixed_header (abfd
)->publicsOffset
= last
;
1839 if (nlm_fixed_header (abfd
)->debugInfoOffset
== 0)
1840 nlm_fixed_header (abfd
)->debugInfoOffset
= last
;
1842 /* At this point everything has been written out except the fixed
1844 memcpy (nlm_fixed_header (abfd
)->signature
, nlm_signature (abfd
),
1845 NLM_SIGNATURE_SIZE
);
1846 nlm_fixed_header (abfd
)->version
= NLM_HEADER_VERSION
;
1847 nlm_fixed_header (abfd
)->codeStartOffset
=
1848 (bfd_get_start_address (abfd
)
1849 - nlm_get_text_low (abfd
));
1851 /* We have no convenient way for the caller to pass in the exit
1852 procedure or the check unload procedure, so the caller must set
1853 the values in the header to the values of the symbols. */
1854 nlm_fixed_header (abfd
)->exitProcedureOffset
-= nlm_get_text_low (abfd
);
1855 if (nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
!= 0)
1856 nlm_fixed_header (abfd
)->checkUnloadProcedureOffset
-=
1857 nlm_get_text_low (abfd
);
1859 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
1862 write_prefix_func
= nlm_write_prefix_func (abfd
);
1863 if (write_prefix_func
)
1865 if ((*write_prefix_func
) (abfd
) == false)
1869 BFD_ASSERT (bfd_tell (abfd
) == nlm_optional_prefix_size (abfd
));
1871 nlm_swap_fixed_header_out (abfd
, nlm_fixed_header (abfd
), fixed_header
);
1872 if (bfd_write (fixed_header
, nlm_fixed_header_size (abfd
), 1, abfd
)
1873 != nlm_fixed_header_size (abfd
))
1876 if (fixed_header
!= NULL
)
1877 free (fixed_header
);
1881 if (fixed_header
!= NULL
)
1882 free (fixed_header
);