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 /* Forward declarations of static functions */
56 static boolean add_bfd_section
57 PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
58 static void nlm_swap_fixed_header_in
59 PARAMS ((bfd *, Nlm_External_Fixed_Header *, Nlm_Internal_Fixed_Header *));
60 static void nlm_swap_fixed_header_out
61 PARAMS ((bfd *, Nlm_Internal_Fixed_Header *, Nlm_External_Fixed_Header *));
62 static boolean nlm_swap_variable_header_in
64 static boolean nlm_swap_variable_header_out
66 static boolean find_nonzero
67 PARAMS ((PTR, size_t));
68 static boolean nlm_swap_auxiliary_headers_in
70 static boolean nlm_swap_auxiliary_headers_out
72 static boolean nlm_slurp_symbol_table
74 static boolean nlm_slurp_reloc_fixups
76 static boolean nlm_compute_section_file_positions
78 static int nlm_external_reloc_compare
79 PARAMS ((const void *, const void *));
81 /* Should perhaps use put_offset, put_word, etc. For now, the two versions
82 can be handled by explicitly specifying 32 bits or "the long type". */
84 #define put_word bfd_h_put_64
85 #define get_word bfd_h_get_64
88 #define put_word bfd_h_put_32
89 #define get_word bfd_h_get_32
93 DEFUN (nlm_object_p, (abfd), bfd * abfd)
95 Nlm_External_Fixed_Header x_fxdhdr; /* Nlm file header, external form */
96 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
97 enum bfd_architecture arch;
99 /* Read in the fixed length portion of the NLM header in external format. */
101 if (bfd_read ((PTR) &x_fxdhdr, sizeof (x_fxdhdr), 1, abfd) !=
104 bfd_error = system_call_error;
108 /* Check to see if we have an NLM file by matching the NLM signature. */
110 if (strncmp (x_fxdhdr.signature, NLM_SIGNATURE, NLM_SIGNATURE_SIZE) != 0)
113 bfd_error = wrong_format;
117 /* There's no supported way to discover the endianess of an NLM, so test for
118 a sane version number after doing byte swapping appropriate for this
119 XVEC. (Hack alert!) */
121 if (get_word (abfd, (bfd_byte *) x_fxdhdr.version) > 0xFFFF)
126 /* There's no supported way to check for 32 bit versus 64 bit addresses,
127 so ignore this distinction for now. (FIXME) */
129 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
130 the tdata pointer in the bfd. */
132 nlm_tdata (abfd) = (struct nlm_obj_tdata *)
133 bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
134 if (nlm_tdata (abfd) == NULL)
136 bfd_error = no_memory;
140 /* FIXME: Any `wrong' exits below here will leak memory (tdata). */
142 /* Swap in the rest of the fixed length header. */
144 i_fxdhdrp = nlm_fixed_header (abfd);
145 nlm_swap_fixed_header_in (abfd, &x_fxdhdr, i_fxdhdrp);
147 if (!nlm_swap_variable_header_in (abfd)
148 || !nlm_swap_auxiliary_headers_in (abfd)
149 || !add_bfd_section (abfd, NLM_CODE_NAME,
150 i_fxdhdrp -> codeImageOffset,
151 i_fxdhdrp -> codeImageSize,
152 (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
154 || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
155 i_fxdhdrp -> dataImageOffset,
156 i_fxdhdrp -> dataImageSize,
157 (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
159 || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
161 i_fxdhdrp -> uninitializedDataSize,
167 if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
168 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
169 abfd->flags |= HAS_RELOC;
170 if (nlm_fixed_header (abfd)->numberOfPublics != 0
171 || nlm_fixed_header (abfd)->numberOfDebugRecords != 0)
172 abfd->flags |= HAS_SYMS;
174 arch = nlm_architecture (abfd);
175 if (arch != bfd_arch_unknown)
176 bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
178 return (abfd -> xvec);
181 /* Add a section to the bfd. */
184 DEFUN (add_bfd_section, (abfd, name, offset, size, flags),
188 bfd_size_type size AND
193 newsect = bfd_make_section (abfd, name);
198 newsect -> vma = 0; /* NLM's are relocatable. */
199 newsect -> _raw_size = size;
200 newsect -> filepos = offset;
201 newsect -> flags = flags;
202 newsect -> alignment_power = bfd_log2 (0); /* FIXME */
206 /* Translate an NLM fixed length file header in external format into an NLM
207 file header in internal format. */
210 DEFUN (nlm_swap_fixed_header_in, (abfd, src, dst),
212 Nlm_External_Fixed_Header * src AND
213 Nlm_Internal_Fixed_Header * dst)
215 memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
216 memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
218 get_word (abfd, (bfd_byte *) src -> version);
219 dst -> codeImageOffset =
220 get_word (abfd, (bfd_byte *) src -> codeImageOffset);
221 dst -> codeImageSize =
222 get_word (abfd, (bfd_byte *) src -> codeImageSize);
223 dst -> dataImageOffset =
224 get_word (abfd, (bfd_byte *) src -> dataImageOffset);
225 dst -> dataImageSize =
226 get_word (abfd, (bfd_byte *) src -> dataImageSize);
227 dst -> uninitializedDataSize =
228 get_word (abfd, (bfd_byte *) src -> uninitializedDataSize);
229 dst -> customDataOffset =
230 get_word (abfd, (bfd_byte *) src -> customDataOffset);
231 dst -> customDataSize =
232 get_word (abfd, (bfd_byte *) src -> customDataSize);
233 dst -> moduleDependencyOffset =
234 get_word (abfd, (bfd_byte *) src -> moduleDependencyOffset);
235 dst -> numberOfModuleDependencies =
236 get_word (abfd, (bfd_byte *) src -> numberOfModuleDependencies);
237 dst -> relocationFixupOffset =
238 get_word (abfd, (bfd_byte *) src -> relocationFixupOffset);
239 dst -> numberOfRelocationFixups =
240 get_word (abfd, (bfd_byte *) src -> numberOfRelocationFixups);
241 dst -> externalReferencesOffset =
242 get_word (abfd, (bfd_byte *) src -> externalReferencesOffset);
243 dst -> numberOfExternalReferences =
244 get_word (abfd, (bfd_byte *) src -> numberOfExternalReferences);
245 dst -> publicsOffset =
246 get_word (abfd, (bfd_byte *) src -> publicsOffset);
247 dst -> numberOfPublics =
248 get_word (abfd, (bfd_byte *) src -> numberOfPublics);
249 dst -> debugInfoOffset =
250 get_word (abfd, (bfd_byte *) src -> debugInfoOffset);
251 dst -> numberOfDebugRecords =
252 get_word (abfd, (bfd_byte *) src -> numberOfDebugRecords);
253 dst -> codeStartOffset =
254 get_word (abfd, (bfd_byte *) src -> codeStartOffset);
255 dst -> exitProcedureOffset =
256 get_word (abfd, (bfd_byte *) src -> exitProcedureOffset);
257 dst -> checkUnloadProcedureOffset =
258 get_word (abfd, (bfd_byte *) src -> checkUnloadProcedureOffset);
260 get_word (abfd, (bfd_byte *) src -> moduleType);
262 get_word (abfd, (bfd_byte *) src -> flags);
265 /* Translate an NLM fixed length file header in internal format into
266 an NLM file header in external format. */
269 DEFUN (nlm_swap_fixed_header_out, (abfd, src, dst),
271 Nlm_Internal_Fixed_Header * src AND
272 Nlm_External_Fixed_Header * dst)
274 memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
275 memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
276 put_word (abfd, (bfd_vma) src -> version,
277 (bfd_byte *) dst -> version);
278 put_word (abfd, (bfd_vma) src -> codeImageOffset,
279 (bfd_byte *) dst -> codeImageOffset);
280 put_word (abfd, (bfd_vma) src -> codeImageSize,
281 (bfd_byte *) dst -> codeImageSize);
282 put_word (abfd, (bfd_vma) src -> dataImageOffset,
283 (bfd_byte *) dst -> dataImageOffset);
284 put_word (abfd, (bfd_vma) src -> dataImageSize,
285 (bfd_byte *) dst -> dataImageSize);
286 put_word (abfd, (bfd_vma) src -> uninitializedDataSize,
287 (bfd_byte *) dst -> uninitializedDataSize);
288 put_word (abfd, (bfd_vma) src -> customDataOffset,
289 (bfd_byte *) dst -> customDataOffset);
290 put_word (abfd, (bfd_vma) src -> customDataSize,
291 (bfd_byte *) dst -> customDataSize);
292 put_word (abfd, (bfd_vma) src -> moduleDependencyOffset,
293 (bfd_byte *) dst -> moduleDependencyOffset);
294 put_word (abfd, (bfd_vma) src -> numberOfModuleDependencies,
295 (bfd_byte *) dst -> numberOfModuleDependencies);
296 put_word (abfd, (bfd_vma) src -> relocationFixupOffset,
297 (bfd_byte *) dst -> relocationFixupOffset);
298 put_word (abfd, (bfd_vma) src -> numberOfRelocationFixups,
299 (bfd_byte *) dst -> numberOfRelocationFixups);
300 put_word (abfd, (bfd_vma) src -> externalReferencesOffset,
301 (bfd_byte *) dst -> externalReferencesOffset);
302 put_word (abfd, (bfd_vma) src -> numberOfExternalReferences,
303 (bfd_byte *) dst -> numberOfExternalReferences);
304 put_word (abfd, (bfd_vma) src -> publicsOffset,
305 (bfd_byte *) dst -> publicsOffset);
306 put_word (abfd, (bfd_vma) src -> numberOfPublics,
307 (bfd_byte *) dst -> numberOfPublics);
308 put_word (abfd, (bfd_vma) src -> debugInfoOffset,
309 (bfd_byte *) dst -> debugInfoOffset);
310 put_word (abfd, (bfd_vma) src -> numberOfDebugRecords,
311 (bfd_byte *) dst -> numberOfDebugRecords);
312 put_word (abfd, (bfd_vma) src -> codeStartOffset,
313 (bfd_byte *) dst -> codeStartOffset);
314 put_word (abfd, (bfd_vma) src -> exitProcedureOffset,
315 (bfd_byte *) dst -> exitProcedureOffset);
316 put_word (abfd, (bfd_vma) src -> checkUnloadProcedureOffset,
317 (bfd_byte *) dst -> checkUnloadProcedureOffset);
318 put_word (abfd, (bfd_vma) src -> moduleType,
319 (bfd_byte *) dst -> moduleType);
320 put_word (abfd, (bfd_vma) src -> flags,
321 (bfd_byte *) dst -> flags);
324 /* Read and swap in the variable length header. All the fields must
325 exist in the NLM, and must exist in the order they are read here. */
328 DEFUN (nlm_swap_variable_header_in, (abfd),
331 unsigned char temp [NLM_TARGET_LONG_SIZE];
333 /* Read the description length and text members. */
335 if (bfd_read ((PTR) &nlm_variable_header (abfd) -> descriptionLength,
336 sizeof (nlm_variable_header (abfd) -> descriptionLength),
338 sizeof (nlm_variable_header (abfd) -> descriptionLength))
340 bfd_error = system_call_error;
343 if (bfd_read ((PTR) nlm_variable_header (abfd) -> descriptionText,
344 nlm_variable_header (abfd) -> descriptionLength + 1,
346 nlm_variable_header (abfd) -> descriptionLength + 1)
348 bfd_error = system_call_error;
352 /* Read and convert the stackSize field. */
354 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
356 bfd_error = system_call_error;
359 nlm_variable_header (abfd) -> stackSize = get_word (abfd, (bfd_byte *) temp);
361 /* Read and convert the reserved field. */
363 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
365 bfd_error = system_call_error;
368 nlm_variable_header (abfd) -> reserved = get_word (abfd, (bfd_byte *) temp);
370 /* Read the oldThreadName field. This field is a fixed length string. */
372 if (bfd_read ((PTR) nlm_variable_header (abfd) -> oldThreadName,
373 sizeof (nlm_variable_header (abfd) -> oldThreadName),
375 sizeof (nlm_variable_header (abfd) -> oldThreadName))
377 bfd_error = system_call_error;
381 /* Read the screen name length and text members. */
383 if (bfd_read ((PTR) &nlm_variable_header (abfd) -> screenNameLength,
384 sizeof (nlm_variable_header (abfd) -> screenNameLength),
386 sizeof (nlm_variable_header (abfd) -> screenNameLength))
388 bfd_error = system_call_error;
391 if (bfd_read ((PTR) nlm_variable_header (abfd) -> screenName,
392 nlm_variable_header (abfd) -> screenNameLength + 1,
394 nlm_variable_header (abfd) -> screenNameLength + 1)
396 bfd_error = system_call_error;
400 /* Read the thread name length and text members. */
402 if (bfd_read ((PTR) &nlm_variable_header (abfd) -> threadNameLength,
403 sizeof (nlm_variable_header (abfd) -> threadNameLength),
405 sizeof (nlm_variable_header (abfd) -> threadNameLength))
407 bfd_error = system_call_error;
410 if (bfd_read ((PTR) nlm_variable_header (abfd) -> threadName,
411 nlm_variable_header (abfd) -> threadNameLength + 1,
413 nlm_variable_header (abfd) -> threadNameLength + 1)
415 bfd_error = system_call_error;
421 /* Swap and write out the variable length header. All the fields must
422 exist in the NLM, and must exist in this order. */
425 DEFUN (nlm_swap_variable_header_out, (abfd),
428 unsigned char temp [NLM_TARGET_LONG_SIZE];
430 /* Write the description length and text members. */
432 if (bfd_write ((PTR) &nlm_variable_header (abfd) -> descriptionLength,
433 sizeof (nlm_variable_header (abfd) -> descriptionLength),
435 sizeof (nlm_variable_header (abfd) -> descriptionLength))
437 bfd_error = system_call_error;
440 if (bfd_write ((PTR) nlm_variable_header (abfd) -> descriptionText,
441 nlm_variable_header (abfd) -> descriptionLength + 1,
443 nlm_variable_header (abfd) -> descriptionLength + 1)
445 bfd_error = system_call_error;
449 /* Convert and write the stackSize field. */
451 put_word (abfd, (bfd_vma) nlm_variable_header (abfd) -> stackSize,
453 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
455 bfd_error = system_call_error;
459 /* Convert and write the reserved field. */
461 put_word (abfd, (bfd_vma) nlm_variable_header (abfd) -> reserved,
463 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
465 bfd_error = system_call_error;
469 /* Write the oldThreadName field. This field is a fixed length string. */
471 if (bfd_write ((PTR) nlm_variable_header (abfd) -> oldThreadName,
472 sizeof (nlm_variable_header (abfd) -> oldThreadName),
474 sizeof (nlm_variable_header (abfd) -> oldThreadName))
476 bfd_error = system_call_error;
480 /* Write the screen name length and text members. */
482 if (bfd_write ((PTR) &nlm_variable_header (abfd) -> screenNameLength,
483 sizeof (nlm_variable_header (abfd) -> screenNameLength),
485 sizeof (nlm_variable_header (abfd) -> screenNameLength))
487 bfd_error = system_call_error;
490 if (bfd_write ((PTR) nlm_variable_header (abfd) -> screenName,
491 nlm_variable_header (abfd) -> screenNameLength + 1,
493 nlm_variable_header (abfd) -> screenNameLength + 1)
495 bfd_error = system_call_error;
499 /* Write the thread name length and text members. */
501 if (bfd_write ((PTR) &nlm_variable_header (abfd) -> threadNameLength,
502 sizeof (nlm_variable_header (abfd) -> threadNameLength),
504 sizeof (nlm_variable_header (abfd) -> threadNameLength))
506 bfd_error = system_call_error;
509 if (bfd_write ((PTR) nlm_variable_header (abfd) -> threadName,
510 nlm_variable_header (abfd) -> threadNameLength + 1,
512 nlm_variable_header (abfd) -> threadNameLength + 1)
514 bfd_error = system_call_error;
520 /* Read and swap in the contents of all the auxiliary headers. Because of
521 the braindead design, we have to do strcmps on strings of indeterminate
522 length to figure out what each auxiliary header is. Even worse, we have
523 no way of knowing how many auxiliary headers there are or where the end
524 of the auxiliary headers are, except by finding something that doesn't
525 look like a known auxiliary header. This means that the first new type
526 of auxiliary header added will break all existing tools that don't
530 DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
533 unsigned char tempstr [16];
538 position = bfd_tell (abfd);
539 if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) !=
542 bfd_error = system_call_error;
545 if (bfd_seek (abfd, position, SEEK_SET) == -1)
547 bfd_error = system_call_error;
550 if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
552 Nlm_External_Version_Header thdr;
553 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
555 bfd_error = system_call_error;
558 memcpy (nlm_version_header (abfd) -> stamp, thdr.stamp,
559 sizeof (thdr.stamp));
560 nlm_version_header (abfd) -> majorVersion =
561 get_word (abfd, (bfd_byte *) thdr.majorVersion);
562 nlm_version_header (abfd) -> minorVersion =
563 get_word (abfd, (bfd_byte *) thdr.minorVersion);
564 nlm_version_header (abfd) -> revision =
565 get_word (abfd, (bfd_byte *) thdr.revision);
566 nlm_version_header (abfd) -> year =
567 get_word (abfd, (bfd_byte *) thdr.year);
568 nlm_version_header (abfd) -> month =
569 get_word (abfd, (bfd_byte *) thdr.month);
570 nlm_version_header (abfd) -> day =
571 get_word (abfd, (bfd_byte *) thdr.day);
573 else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
575 Nlm_External_Extended_Header thdr;
576 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
578 bfd_error = system_call_error;
581 memcpy (nlm_extended_header (abfd) -> stamp, thdr.stamp,
582 sizeof (thdr.stamp));
583 nlm_extended_header (abfd) -> languageID =
584 get_word (abfd, (bfd_byte *) thdr.languageID);
585 nlm_extended_header (abfd) -> messageFileOffset =
586 get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
587 nlm_extended_header (abfd) -> messageFileLength =
588 get_word (abfd, (bfd_byte *) thdr.messageFileLength);
589 nlm_extended_header (abfd) -> messageCount =
590 get_word (abfd, (bfd_byte *) thdr.messageCount);
591 nlm_extended_header (abfd) -> helpFileOffset =
592 get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
593 nlm_extended_header (abfd) -> helpFileLength =
594 get_word (abfd, (bfd_byte *) thdr.helpFileLength);
595 nlm_extended_header (abfd) -> RPCDataOffset =
596 get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
597 nlm_extended_header (abfd) -> RPCDataLength =
598 get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
599 nlm_extended_header (abfd) -> sharedCodeOffset =
600 get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
601 nlm_extended_header (abfd) -> sharedCodeLength =
602 get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
603 nlm_extended_header (abfd) -> sharedDataOffset =
604 get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
605 nlm_extended_header (abfd) -> sharedDataLength =
606 get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
607 nlm_extended_header (abfd) -> sharedRelocationFixupOffset =
608 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
609 nlm_extended_header (abfd) -> sharedRelocationFixupCount =
610 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
611 nlm_extended_header (abfd) -> sharedExternalReferenceOffset =
612 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
613 nlm_extended_header (abfd) -> sharedExternalReferenceCount =
614 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
615 nlm_extended_header (abfd) -> sharedPublicsOffset =
616 get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
617 nlm_extended_header (abfd) -> sharedPublicsCount =
618 get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
619 nlm_extended_header (abfd) -> SharedInitializationOffset =
620 get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
621 nlm_extended_header (abfd) -> SharedExitProcedureOffset =
622 get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
623 nlm_extended_header (abfd) -> productID =
624 get_word (abfd, (bfd_byte *) thdr.productID);
625 nlm_extended_header (abfd) -> reserved0 =
626 get_word (abfd, (bfd_byte *) thdr.reserved0);
627 nlm_extended_header (abfd) -> reserved1 =
628 get_word (abfd, (bfd_byte *) thdr.reserved1);
629 nlm_extended_header (abfd) -> reserved2 =
630 get_word (abfd, (bfd_byte *) thdr.reserved2);
631 nlm_extended_header (abfd) -> reserved3 =
632 get_word (abfd, (bfd_byte *) thdr.reserved3);
633 nlm_extended_header (abfd) -> reserved4 =
634 get_word (abfd, (bfd_byte *) thdr.reserved4);
635 nlm_extended_header (abfd) -> reserved5 =
636 get_word (abfd, (bfd_byte *) thdr.reserved5);
638 else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
640 Nlm_External_Custom_Header thdr;
641 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
643 bfd_error = system_call_error;
646 memcpy (nlm_custom_header (abfd) -> stamp, thdr.stamp,
647 sizeof (thdr.stamp));
648 nlm_custom_header (abfd) -> dataLength =
649 get_word (abfd, (bfd_byte *) thdr.dataLength);
650 nlm_custom_header (abfd) -> debugRecOffset =
651 get_word (abfd, (bfd_byte *) thdr.debugRecOffset);
652 nlm_custom_header (abfd) -> debugRecLength =
653 get_word (abfd, (bfd_byte *) thdr.debugRecLength);
655 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
657 Nlm_External_Copyright_Header thdr;
658 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
660 bfd_error = system_call_error;
663 memcpy (nlm_copyright_header (abfd) -> stamp, thdr.stamp,
664 sizeof (thdr.stamp));
665 nlm_copyright_header (abfd) -> copyrightMessageLength =
666 get_word (abfd, (bfd_byte *) thdr.copyrightMessageLength);
667 /* The copyright message is a variable length string. */
668 if (bfd_read ((PTR) nlm_copyright_header (abfd) -> copyrightMessage,
669 nlm_copyright_header (abfd) -> copyrightMessageLength + 1,
671 nlm_copyright_header (abfd) -> copyrightMessageLength + 1)
673 bfd_error = system_call_error;
685 /* Return whether there is a non-zero byte in a memory block. */
688 find_nonzero (buf, size)
692 char *p = (char *) buf;
700 /* Swap out the contents of the auxiliary headers. We create those
701 auxiliary headers which have been set non-zero. We do not require
702 the caller to set up the stamp fields. */
705 nlm_swap_auxiliary_headers_out (abfd)
708 /* Write out the version header if there is one. */
709 if (find_nonzero ((PTR) nlm_version_header (abfd),
710 sizeof (Nlm_Internal_Version_Header)))
712 Nlm_External_Version_Header thdr;
714 memcpy (thdr.stamp, "VeRsIoN#", 8);
715 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> majorVersion,
716 (bfd_byte *) thdr.majorVersion);
717 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> minorVersion,
718 (bfd_byte *) thdr.minorVersion);
719 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> revision,
720 (bfd_byte *) thdr.revision);
721 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> year,
722 (bfd_byte *) thdr.year);
723 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> month,
724 (bfd_byte *) thdr.month);
725 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> day,
726 (bfd_byte *) thdr.day);
727 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
729 bfd_error = system_call_error;
734 /* Write out the extended header if there is one. */
735 if (find_nonzero ((PTR) nlm_extended_header (abfd),
736 sizeof (Nlm_Internal_Extended_Header)))
738 Nlm_External_Extended_Header thdr;
740 memcpy (thdr.stamp, "MeSsAgEs", 8);
742 (bfd_vma) nlm_extended_header (abfd) -> languageID,
743 (bfd_byte *) thdr.languageID);
745 (bfd_vma) nlm_extended_header (abfd) -> messageFileOffset,
746 (bfd_byte *) thdr.messageFileOffset);
748 (bfd_vma) nlm_extended_header (abfd) -> messageFileLength,
749 (bfd_byte *) thdr.messageFileLength);
751 (bfd_vma) nlm_extended_header (abfd) -> messageCount,
752 (bfd_byte *) thdr.messageCount);
754 (bfd_vma) nlm_extended_header (abfd) -> helpFileOffset,
755 (bfd_byte *) thdr.helpFileOffset);
757 (bfd_vma) nlm_extended_header (abfd) -> helpFileLength,
758 (bfd_byte *) thdr.helpFileLength);
760 (bfd_vma) nlm_extended_header (abfd) -> RPCDataOffset,
761 (bfd_byte *) thdr.RPCDataOffset);
763 (bfd_vma) nlm_extended_header (abfd) -> RPCDataLength,
764 (bfd_byte *) thdr.RPCDataLength);
766 (bfd_vma) nlm_extended_header (abfd) -> sharedCodeOffset,
767 (bfd_byte *) thdr.sharedCodeOffset);
769 (bfd_vma) nlm_extended_header (abfd) -> sharedCodeLength,
770 (bfd_byte *) thdr.sharedCodeLength);
772 (bfd_vma) nlm_extended_header (abfd) -> sharedDataOffset,
773 (bfd_byte *) thdr.sharedDataOffset);
775 (bfd_vma) nlm_extended_header (abfd) -> sharedDataLength,
776 (bfd_byte *) thdr.sharedDataLength);
778 (bfd_vma) nlm_extended_header (abfd) -> sharedRelocationFixupOffset,
779 (bfd_byte *) thdr.sharedRelocationFixupOffset);
781 (bfd_vma) nlm_extended_header (abfd) -> sharedRelocationFixupCount,
782 (bfd_byte *) thdr.sharedRelocationFixupCount);
784 (bfd_vma) nlm_extended_header (abfd) -> sharedExternalReferenceOffset,
785 (bfd_byte *) thdr.sharedExternalReferenceOffset);
787 (bfd_vma) nlm_extended_header (abfd) -> sharedExternalReferenceCount,
788 (bfd_byte *) thdr.sharedExternalReferenceCount);
790 (bfd_vma) nlm_extended_header (abfd) -> sharedPublicsOffset,
791 (bfd_byte *) thdr.sharedPublicsOffset);
793 (bfd_vma) nlm_extended_header (abfd) -> sharedPublicsCount,
794 (bfd_byte *) thdr.sharedPublicsCount);
796 (bfd_vma) nlm_extended_header (abfd) -> SharedInitializationOffset,
797 (bfd_byte *) thdr.sharedInitializationOffset);
799 (bfd_vma) nlm_extended_header (abfd) -> SharedExitProcedureOffset,
800 (bfd_byte *) thdr.SharedExitProcedureOffset);
802 (bfd_vma) nlm_extended_header (abfd) -> productID,
803 (bfd_byte *) thdr.productID);
805 (bfd_vma) nlm_extended_header (abfd) -> reserved0,
806 (bfd_byte *) thdr.reserved0);
808 (bfd_vma) nlm_extended_header (abfd) -> reserved1,
809 (bfd_byte *) thdr.reserved1);
811 (bfd_vma) nlm_extended_header (abfd) -> reserved2,
812 (bfd_byte *) thdr.reserved2);
814 (bfd_vma) nlm_extended_header (abfd) -> reserved3,
815 (bfd_byte *) thdr.reserved3);
817 (bfd_vma) nlm_extended_header (abfd) -> reserved4,
818 (bfd_byte *) thdr.reserved4);
820 (bfd_vma) nlm_extended_header (abfd) -> reserved5,
821 (bfd_byte *) thdr.reserved5);
822 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
824 bfd_error = system_call_error;
829 /* Write out the custom header if there is one. */
830 if (find_nonzero ((PTR) nlm_custom_header (abfd),
831 sizeof (Nlm_Internal_Custom_Header)))
833 Nlm_External_Custom_Header thdr;
835 /* Right now we assume the custom header is always the suggested
836 format for alternate debugging records. */
837 BFD_ASSERT (nlm_custom_header (abfd) -> dataLength == 8);
839 memcpy (thdr.stamp, "CuStHeAd", 8);
840 put_word (abfd, (bfd_vma) nlm_custom_header (abfd) -> dataLength,
841 (bfd_byte *) thdr.dataLength);
842 put_word (abfd, (bfd_vma) nlm_custom_header (abfd) -> debugRecOffset,
843 (bfd_byte *) thdr.debugRecOffset);
844 put_word (abfd, (bfd_vma) nlm_custom_header (abfd) -> debugRecLength,
845 (bfd_byte *) thdr.debugRecLength);
846 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
848 bfd_error = system_call_error;
853 /* Write out the copyright header if there is one. */
854 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
855 sizeof (Nlm_Internal_Copyright_Header)))
857 Nlm_External_Copyright_Header thdr;
859 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
861 (bfd_vma) nlm_copyright_header (abfd) -> copyrightMessageLength,
862 (bfd_byte *) thdr.copyrightMessageLength);
863 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
865 bfd_error = system_call_error;
868 /* The copyright message is a variable length string. */
869 if (bfd_write ((PTR) nlm_copyright_header (abfd) -> copyrightMessage,
870 nlm_copyright_header (abfd) -> copyrightMessageLength + 1,
872 nlm_copyright_header (abfd) -> copyrightMessageLength + 1)
874 bfd_error = system_call_error;
882 /* We read the NLM's public symbols and use it to generate a bfd symbol
883 table (hey, it's better than nothing) on a one-for-one basis. Thus
884 use the number of public symbols as the number of bfd symbols we will
885 have once we actually get around to reading them in.
887 Return the number of bytes required to hold the symtab vector, based on
888 the count plus 1, since we will NULL terminate the vector allocated based
892 DEFUN (nlm_get_symtab_upper_bound, (abfd), bfd * abfd)
894 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
895 unsigned int symcount;
896 unsigned int symtab_size = 0;
898 i_fxdhdrp = nlm_fixed_header (abfd);
899 symcount = (i_fxdhdrp -> numberOfPublics
900 + i_fxdhdrp -> numberOfExternalReferences);
901 symtab_size = (symcount + 1) * (sizeof (asymbol));
902 return (symtab_size);
905 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
906 symbol table fails. */
909 nlm_get_symtab (abfd, alocation)
913 nlm_symbol_type *symbase;
914 bfd_size_type counter = 0;
916 if (nlm_slurp_symbol_table (abfd) == false)
918 symbase = nlm_get_symbols (abfd);
919 while (counter < bfd_get_symcount (abfd))
921 *alocation++ = &symbase->symbol;
925 *alocation = (asymbol *) NULL;
926 return bfd_get_symcount (abfd);
929 /* Make an NLM symbol. There is nothing special to do here. */
932 nlm_make_empty_symbol (abfd)
935 nlm_symbol_type *new;
937 new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
938 new->symbol.the_bfd = abfd;
942 /* Get symbol information. */
945 nlm_get_symbol_info (ignore_abfd, symbol, ret)
950 bfd_symbol_info (symbol, ret);
953 /* Print symbol information. */
956 nlm_print_symbol (abfd, afile, symbol, how)
960 bfd_print_symbol_type how;
962 FILE *file = (FILE *) afile;
966 case bfd_print_symbol_name:
967 case bfd_print_symbol_more:
969 fprintf (file,"%s", symbol->name);
971 case bfd_print_symbol_all:
972 bfd_print_symbol_vandf ((PTR) file, symbol);
973 fprintf (file, " %-5s", symbol->section->name);
975 fprintf (file," %s", symbol->name);
980 /* Slurp in nlm symbol table.
982 In the external (in-file) form, NLM export records are variable length,
983 with the following form:
985 1 byte length of the symbol name (N)
986 N bytes the symbol name
987 4 bytes the symbol offset from start of it's section
989 Note that we currently ignore the internal debug records. There is
990 a lot of duplication between the export records and the internal debug
991 records. We may in the future, want to merge the information from the
992 debug records with the information from the export records to produce
993 a more complete symbol table, treating additional information from the
994 debug records as static symbols. (FIXME)
996 We do read in the import records. These are treated as undefined
997 symbols. As we read them in we also read in the associated reloc
998 information, which is attached to the symbol.
1000 The bfd symbols are copied to SYMPTRS.
1002 When we return, the bfd symcount is either zero or contains the correct
1007 nlm_slurp_symbol_table (abfd)
1010 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
1011 bfd_size_type totsymcount; /* Number of NLM symbols */
1012 bfd_size_type symcount; /* Counter of NLM symbols */
1013 nlm_symbol_type *sym; /* Pointer to current bfd symbol */
1014 char symlength; /* Symbol length read into here */
1015 bfd_size_type rcount; /* Number of relocs */
1016 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
1017 boolean (*read_reloc_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1020 if (nlm_get_symbols (abfd) != NULL)
1023 /* Read each raw NLM symbol, using the information to create a canonical bfd
1026 Note that we allocate the initial bfd canonical symbol buffer based on a
1027 one-to-one mapping of the NLM symbols to canonical symbols. We actually
1028 use all the NLM symbols, so there will be no space left over at the end.
1029 When we have all the symbols, we build the caller's pointer vector. */
1031 abfd -> symcount = 0;
1032 i_fxdhdrp = nlm_fixed_header (abfd);
1033 totsymcount = (i_fxdhdrp -> numberOfPublics
1034 + i_fxdhdrp -> numberOfExternalReferences);
1035 if (totsymcount == 0)
1040 if (bfd_seek (abfd, i_fxdhdrp -> publicsOffset, SEEK_SET) == -1)
1042 bfd_error = system_call_error;
1046 sym = ((nlm_symbol_type *)
1047 bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
1048 nlm_set_symbols (abfd, sym);
1050 /* We use the bfd's symcount directly as the control count, so that early
1051 termination of the loop leaves the symcount correct for the symbols that
1054 symcount = i_fxdhdrp -> numberOfPublics;
1055 while (abfd -> symcount < symcount)
1057 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
1058 != sizeof (symlength))
1060 bfd_error = system_call_error;
1063 sym -> symbol.the_bfd = abfd;
1064 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
1065 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
1068 bfd_error = system_call_error;
1071 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1073 bfd_error = system_call_error;
1076 sym -> symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1077 sym -> symbol.value = get_word (abfd, temp);
1078 if (sym -> symbol.value & NLM_HIBIT)
1080 sym -> symbol.value &= ~NLM_HIBIT;
1081 sym -> symbol.flags |= BSF_FUNCTION;
1082 sym -> symbol.section =
1083 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1087 sym -> symbol.section =
1088 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1095 /* Read in the import records. We can only do this if we know how
1096 to read relocs for this target. */
1098 read_reloc_func = nlm_read_reloc_func (abfd);
1099 if (read_reloc_func != NULL)
1101 if (bfd_seek (abfd, i_fxdhdrp -> externalReferencesOffset, SEEK_SET)
1104 bfd_error = system_call_error;
1108 symcount += i_fxdhdrp -> numberOfExternalReferences;
1109 while (abfd -> symcount < symcount)
1111 struct nlm_relent *nlm_relocs;
1113 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
1114 != sizeof (symlength))
1116 bfd_error = system_call_error;
1119 sym -> symbol.the_bfd = abfd;
1120 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
1121 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
1124 bfd_error = system_call_error;
1127 sym -> symbol.flags = 0;
1128 sym -> symbol.value = 0;
1129 sym -> symbol.section = &bfd_und_section;
1130 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1132 bfd_error = system_call_error;
1135 rcount = get_word (abfd, temp);
1136 nlm_relocs = ((struct nlm_relent *)
1137 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
1138 sym -> relocs = nlm_relocs;
1140 while (sym -> rcnt < rcount)
1144 if ((*read_reloc_func) (abfd, sym, §ion,
1145 &nlm_relocs -> reloc)
1148 nlm_relocs -> section = section;
1161 /* Get the relocs for an NLM file. There are two types of relocs.
1162 Imports are relocs against symbols defined in other NLM files. We
1163 treat these as relocs against global symbols. Relocation fixups
1164 are internal relocs.
1166 The actual format used to store the relocs is machine specific. */
1168 /* Read in the relocation fixup information. This is stored in
1169 nlm_relocation_fixups, an array of arelent structures, and
1170 nlm_relocation_fixup_secs, an array of section pointers. The
1171 section pointers are needed because the relocs are not sorted by
1175 nlm_slurp_reloc_fixups (abfd)
1178 boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1180 bfd_size_type count;
1184 if (nlm_relocation_fixups (abfd) != NULL)
1186 read_func = nlm_read_reloc_func (abfd);
1187 if (read_func == NULL)
1190 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1193 bfd_error = system_call_error;
1197 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1198 rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
1199 secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
1200 if (rels == NULL || secs == NULL)
1202 bfd_error = no_memory;
1205 nlm_relocation_fixups (abfd) = rels;
1206 nlm_relocation_fixup_secs (abfd) = secs;
1208 /* We have to read piece by piece, because we don't know how large
1209 the machine specific reloc information is. */
1210 while (count-- != 0)
1212 if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
1214 nlm_relocation_fixups (abfd) = NULL;
1215 nlm_relocation_fixup_secs (abfd) = NULL;
1225 /* Get the number of relocs. This really just returns an upper bound,
1226 since it does not attempt to distinguish them based on the section.
1227 That will be handled when they are actually read. */
1230 nlm_get_reloc_upper_bound (abfd, sec)
1234 nlm_symbol_type *syms;
1235 bfd_size_type count;
1238 /* If we don't know how to read relocs, just return 0. */
1239 if (nlm_read_reloc_func (abfd) == NULL)
1241 /* Make sure we have either the code or the data section. */
1242 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1245 syms = nlm_get_symbols (abfd);
1248 if (nlm_slurp_symbol_table (abfd) == NULL)
1250 syms = nlm_get_symbols (abfd);
1253 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1255 count = bfd_get_symcount (abfd);
1256 while (count-- != 0)
1262 return (ret + 1) * sizeof (arelent *);
1265 /* Get the relocs themselves. */
1268 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1276 bfd_size_type count, i;
1279 /* Get the relocation fixups. */
1280 rels = nlm_relocation_fixups (abfd);
1283 if (nlm_slurp_reloc_fixups (abfd) == NULL)
1285 rels = nlm_relocation_fixups (abfd);
1289 secs = nlm_relocation_fixup_secs (abfd);
1292 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1293 for (i = 0; i < count; i++, rels++, secs++)
1302 /* Get the import symbols. */
1303 count = bfd_get_symcount (abfd);
1304 for (i = 0; i < count; i++, symbols++)
1309 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1311 nlm_symbol_type *nlm_sym;
1314 nlm_sym = (nlm_symbol_type *) sym;
1315 for (j = 0; j < nlm_sym->rcnt; j++)
1317 if (nlm_sym->relocs[j].section == sec)
1319 *relptr = &nlm_sym->relocs[j].reloc;
1320 (*relptr)->sym_ptr_ptr = symbols;
1333 /* Compute the section file positions for an NLM file. All variable
1334 length data in the file headers must be set before this function is
1335 called. If the variable length data is changed later, the
1336 resulting object file will be incorrect. Unfortunately, there is
1337 no way to check this.
1339 This routine also sets the Size and Offset fields in the fixed
1343 nlm_compute_section_file_positions (abfd)
1348 bfd_vma text, data, bss;
1349 bfd_vma text_low, data_low;
1350 int text_align, data_align, other_align;
1351 file_ptr text_ptr, data_ptr, other_ptr;
1353 if (abfd->output_has_begun == true)
1356 abfd->output_has_begun = true;
1358 /* The fixed header. */
1359 sofar = sizeof (Nlm_External_Fixed_Header);
1361 /* The variable header. */
1362 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1363 + nlm_variable_header (abfd) -> descriptionLength + 1
1364 + NLM_TARGET_LONG_SIZE /* stackSize */
1365 + NLM_TARGET_LONG_SIZE /* reserved */
1366 + sizeof (nlm_variable_header (abfd) -> oldThreadName)
1367 + sizeof (nlm_variable_header (abfd) -> screenNameLength)
1368 + nlm_variable_header (abfd) -> screenNameLength + 1
1369 + sizeof (nlm_variable_header (abfd) -> threadNameLength)
1370 + nlm_variable_header (abfd) -> threadNameLength + 1);
1372 /* The auxiliary headers. */
1373 if (find_nonzero ((PTR) nlm_version_header (abfd),
1374 sizeof (Nlm_Internal_Version_Header)))
1375 sofar += sizeof (Nlm_External_Version_Header);
1376 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1377 sizeof (Nlm_Internal_Extended_Header)))
1378 sofar += sizeof (Nlm_External_Extended_Header);
1379 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1380 sizeof (Nlm_Internal_Custom_Header)))
1381 sofar += sizeof (Nlm_External_Custom_Header);
1382 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1383 sizeof (Nlm_Internal_Copyright_Header)))
1384 sofar += (sizeof (Nlm_External_Copyright_Header)
1385 + nlm_copyright_header (abfd) -> copyrightMessageLength + 1);
1387 /* Compute the section file positions in two passes. First get the
1388 sizes of the text and data sections, and then set the file
1389 positions. This code aligns the sections in the file using the
1390 same alignment restrictions that apply to the sections in memory;
1391 this may not be necessary. */
1393 text_low = (bfd_vma) -1;
1396 data_low = (bfd_vma) -1;
1400 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1404 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1406 f = bfd_get_section_flags (abfd, sec);
1409 text += sec->_raw_size;
1410 if (bfd_get_section_vma (abfd, sec) < text_low)
1411 text_low = bfd_get_section_vma (abfd, sec);
1412 if (sec->alignment_power > text_align)
1413 text_align = sec->alignment_power;
1415 else if (f & SEC_DATA)
1417 data += sec->_raw_size;
1418 if (bfd_get_section_vma (abfd, sec) < data_low)
1419 data_low = bfd_get_section_vma (abfd, sec);
1420 if (sec->alignment_power > data_align)
1421 data_align = sec->alignment_power;
1423 else if (f & SEC_HAS_CONTENTS)
1425 if (sec->alignment_power > other_align)
1426 other_align = sec->alignment_power;
1428 else if (f & SEC_ALLOC)
1429 bss += sec->_raw_size;
1432 nlm_set_text_low (abfd, text_low);
1433 nlm_set_data_low (abfd, data_low);
1435 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1436 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1437 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1439 /* Fill in some fields in the header for which we now have the
1441 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1442 nlm_fixed_header (abfd)->codeImageSize = text;
1443 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1444 nlm_fixed_header (abfd)->dataImageSize = data;
1445 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1447 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1451 f = bfd_get_section_flags (abfd, sec);
1455 sec->filepos = text_ptr;
1456 text_ptr += sec->_raw_size;
1458 else if (f & SEC_DATA)
1460 sec->filepos = data_ptr;
1461 data_ptr += sec->_raw_size;
1463 else if (f & SEC_HAS_CONTENTS)
1465 sec->filepos = other_ptr;
1466 other_ptr += sec->_raw_size;
1470 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1475 /* Set the contents of a section. To do this we need to know where
1476 the section is going to be located in the output file. That means
1477 that the sizes of all the sections must be set, and all the
1478 variable size header information must be known. */
1481 nlm_set_section_contents (abfd, section, location, offset, count)
1486 bfd_size_type count;
1488 if (abfd->output_has_begun == false
1489 && nlm_compute_section_file_positions (abfd) == false)
1495 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1496 || bfd_write (location, 1, count, abfd) != count)
1498 bfd_error = system_call_error;
1505 /* We need to sort a list of relocs associated with sections when we
1506 write out the external relocs. */
1508 struct reloc_and_sec
1515 nlm_external_reloc_compare (p1, p2)
1519 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1520 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1522 return strcmp ((*r1->rel->sym_ptr_ptr)->name,
1523 (*r2->rel->sym_ptr_ptr)->name);
1526 /* Write out an NLM file. We write out the information in this order:
1532 other sections (custom data, messages, help, shared NLM, RPC,
1533 module dependencies)
1535 external references (imports)
1536 public symbols (exports)
1538 This is similar to the order used by the NetWare tools; the
1539 difference is that NetWare puts the sections other than code, data
1540 and custom data at the end of the NLM. It is convenient for us to
1541 know where the sections are going to be before worrying about the
1542 size of the other information.
1544 By the time this function is called, all the section data should
1545 have been output using set_section_contents. Note that custom
1546 data, the message file, the help file, the shared NLM file, the RPC
1547 data, and the module dependencies are all considered to be
1548 sections; the caller is responsible for filling in the offset and
1549 length fields in the NLM headers. The relocation fixups and
1550 imports are both obtained from the list of relocs attached to each
1551 section. The exports and debugging records are obtained from the
1552 list of outsymbols. */
1555 nlm_write_object_contents (abfd)
1558 Nlm_External_Fixed_Header fixed_header;
1560 boolean (*write_reloc_func) PARAMS ((bfd *, asection *, arelent *));
1561 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1562 struct reloc_and_sec *external_relocs;
1563 asymbol **sym_ptr_ptr;
1565 if (abfd->output_has_begun == false
1566 && nlm_compute_section_file_positions (abfd) == false)
1569 /* Write out the variable length headers. */
1570 if (bfd_seek (abfd, sizeof (Nlm_External_Fixed_Header), SEEK_SET) != 0)
1572 bfd_error = system_call_error;
1575 if (nlm_swap_variable_header_out (abfd) == false
1576 || nlm_swap_auxiliary_headers_out (abfd) == false)
1578 bfd_error = system_call_error;
1582 /* A weak check on whether the section file positions were
1584 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1586 bfd_error = invalid_operation;
1590 /* Advance to the relocs. */
1591 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1594 bfd_error = system_call_error;
1598 /* The format of the relocation entries is dependent upon the
1599 particular target. We use an external routine to write the reloc
1601 write_reloc_func = nlm_write_reloc_func (abfd);
1603 /* Write out the internal relocation fixups. While we're looping
1604 over the relocs, we also count the external relocs, which is
1605 needed when they are written out below. */
1606 internal_reloc_count = 0;
1607 external_reloc_count = 0;
1608 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1610 arelent **rel_ptr_ptr, **rel_end;
1612 if (sec->reloc_count == 0)
1615 /* We can only represent relocs within a code or data
1617 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1619 bfd_error = invalid_operation;
1623 /* We need to know how to write out relocs. */
1624 if (write_reloc_func == NULL)
1626 bfd_error = invalid_operation;
1630 rel_ptr_ptr = sec->orelocation;
1631 rel_end = rel_ptr_ptr + sec->reloc_count;
1632 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1638 sym = *rel->sym_ptr_ptr;
1640 if ((sym->flags & BSF_SECTION_SYM) != 0)
1642 ++internal_reloc_count;
1643 if ((*write_reloc_func) (abfd, sec, rel) == false)
1647 ++external_reloc_count;
1650 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1652 /* Write out the imports (relocs against external symbols). These
1653 are output as a symbol name followed by all the relocs for that
1654 symbol, so we must first gather together all the relocs against
1655 external symbols and sort them. */
1657 (struct reloc_and_sec *) bfd_alloc (abfd,
1658 (external_reloc_count
1659 * sizeof (struct reloc_and_sec)));
1660 if (external_relocs == (struct reloc_and_sec *) NULL)
1662 bfd_error = no_memory;
1666 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1668 arelent **rel_ptr_ptr, **rel_end;
1670 if (sec->reloc_count == 0)
1673 rel_ptr_ptr = sec->orelocation;
1674 rel_end = rel_ptr_ptr + sec->reloc_count;
1675 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1681 sym = *rel->sym_ptr_ptr;
1683 if ((sym->flags & BSF_SECTION_SYM) != 0)
1686 external_relocs[i].rel = rel;
1687 external_relocs[i].sec = sec;
1692 BFD_ASSERT (i == external_reloc_count);
1694 /* Sort the external relocs by name. */
1695 qsort (external_relocs, external_reloc_count,
1696 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1698 /* Write out the external relocs. */
1699 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1702 while (i < external_reloc_count)
1708 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1712 rel = external_relocs[i].rel;
1713 sym = *rel->sym_ptr_ptr;
1715 len = strlen (sym->name);
1716 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1717 != sizeof (bfd_byte))
1718 || bfd_write (sym->name, len, 1, abfd) != len)
1720 bfd_error = system_call_error;
1725 while (i < external_reloc_count
1726 && *external_relocs[i].rel->sym_ptr_ptr == sym)
1729 put_word (abfd, (bfd_vma) cnt, temp);
1730 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1732 bfd_error = system_call_error;
1738 if ((*write_reloc_func) (abfd, external_relocs[i].sec,
1739 external_relocs[i].rel) == false)
1744 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1746 /* Write out the public symbols (exports). */
1747 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1748 if (sym_ptr_ptr != (asymbol **) NULL)
1752 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1754 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1755 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1761 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1765 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0)
1770 len = strlen (sym->name);
1771 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1772 != sizeof (bfd_byte))
1773 || bfd_write (sym->name, len, 1, abfd) != len)
1775 bfd_error = system_call_error;
1779 offset = bfd_asymbol_value (sym);
1781 if (sec->flags & SEC_CODE)
1783 offset -= nlm_get_text_low (abfd);
1784 offset |= NLM_HIBIT;
1786 else if (sec->flags & SEC_DATA)
1788 offset -= nlm_get_data_low (abfd);
1792 /* We can't handle an exported symbol that is not in the
1793 code or data segment. */
1794 bfd_error = invalid_operation;
1798 put_word (abfd, offset, temp);
1799 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1801 bfd_error = system_call_error;
1805 nlm_fixed_header (abfd)->numberOfPublics = c;
1807 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1809 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1810 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1816 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1822 offset = bfd_asymbol_value (sym);
1824 if (sec->flags & SEC_CODE)
1826 offset -= nlm_get_text_low (abfd);
1829 else if (sec->flags & SEC_DATA)
1831 offset -= nlm_get_data_low (abfd);
1837 /* The type is 0 for data, 1 for code, 3 for absolute. */
1838 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1839 != sizeof (bfd_byte))
1841 bfd_error = system_call_error;
1845 put_word (abfd, offset, temp);
1846 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1848 bfd_error = system_call_error;
1852 len = strlen (sym->name);
1853 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1854 != sizeof (bfd_byte))
1855 || bfd_write (sym->name, len, 1, abfd) != len)
1857 bfd_error = system_call_error;
1861 /* Exported symbols may get an additional debugging record
1862 without the prefix. */
1863 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
1867 s = strchr (sym->name, '@');
1872 if ((bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1873 != sizeof (bfd_byte))
1874 || (bfd_write (temp, sizeof (temp), 1, abfd)
1877 bfd_error = system_call_error;
1884 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1885 != sizeof (bfd_byte))
1886 || bfd_write (s, len, 1, abfd) != len)
1888 bfd_error = system_call_error;
1894 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1897 /* At this point everything has been written out except the fixed
1899 memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE,
1900 NLM_SIGNATURE_SIZE);
1901 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
1902 nlm_fixed_header (abfd)->codeStartOffset =
1903 bfd_get_start_address (abfd) - nlm_get_text_low (abfd);
1905 /* We have no convenient way for the caller to pass in the exit
1906 procedure or the check unload procedure, so the caller must set
1907 the values in the header to the values of the symbols. */
1908 if (nlm_fixed_header (abfd)->exitProcedureOffset == 0)
1910 bfd_error = invalid_operation;
1913 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
1914 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
1915 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
1916 nlm_get_text_low (abfd);
1918 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), &fixed_header);
1919 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1920 || (bfd_write (&fixed_header, sizeof fixed_header, 1, abfd)
1921 != sizeof fixed_header))
1923 bfd_error = system_call_error;