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
1342 It also looks over the symbols and moves any common symbols into
1343 the .bss section; NLM has no way to represent a common symbol.
1344 This approach means that either the symbols must already have been
1345 set at this point, or there must be no common symbols. We need to
1346 move the symbols at this point so that mangle_relocs can see the
1350 nlm_compute_section_file_positions (abfd)
1355 bfd_vma text, data, bss;
1356 bfd_vma text_low, data_low;
1357 int text_align, data_align, other_align;
1358 file_ptr text_ptr, data_ptr, other_ptr;
1359 asymbol **sym_ptr_ptr;
1361 if (abfd->output_has_begun == true)
1364 abfd->output_has_begun = true;
1366 /* The fixed header. */
1367 sofar = sizeof (Nlm_External_Fixed_Header);
1369 /* The variable header. */
1370 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1371 + nlm_variable_header (abfd) -> descriptionLength + 1
1372 + NLM_TARGET_LONG_SIZE /* stackSize */
1373 + NLM_TARGET_LONG_SIZE /* reserved */
1374 + sizeof (nlm_variable_header (abfd) -> oldThreadName)
1375 + sizeof (nlm_variable_header (abfd) -> screenNameLength)
1376 + nlm_variable_header (abfd) -> screenNameLength + 1
1377 + sizeof (nlm_variable_header (abfd) -> threadNameLength)
1378 + nlm_variable_header (abfd) -> threadNameLength + 1);
1380 /* The auxiliary headers. */
1381 if (find_nonzero ((PTR) nlm_version_header (abfd),
1382 sizeof (Nlm_Internal_Version_Header)))
1383 sofar += sizeof (Nlm_External_Version_Header);
1384 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1385 sizeof (Nlm_Internal_Extended_Header)))
1386 sofar += sizeof (Nlm_External_Extended_Header);
1387 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1388 sizeof (Nlm_Internal_Custom_Header)))
1389 sofar += sizeof (Nlm_External_Custom_Header);
1390 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1391 sizeof (Nlm_Internal_Copyright_Header)))
1392 sofar += (sizeof (Nlm_External_Copyright_Header)
1393 + nlm_copyright_header (abfd) -> copyrightMessageLength + 1);
1395 /* Compute the section file positions in two passes. First get the
1396 sizes of the text and data sections, and then set the file
1397 positions. This code aligns the sections in the file using the
1398 same alignment restrictions that apply to the sections in memory;
1399 this may not be necessary. */
1401 text_low = (bfd_vma) -1;
1404 data_low = (bfd_vma) -1;
1408 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1412 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1414 f = bfd_get_section_flags (abfd, sec);
1417 text += sec->_raw_size;
1418 if (bfd_get_section_vma (abfd, sec) < text_low)
1419 text_low = bfd_get_section_vma (abfd, sec);
1420 if (sec->alignment_power > text_align)
1421 text_align = sec->alignment_power;
1423 else if (f & SEC_DATA)
1425 data += sec->_raw_size;
1426 if (bfd_get_section_vma (abfd, sec) < data_low)
1427 data_low = bfd_get_section_vma (abfd, sec);
1428 if (sec->alignment_power > data_align)
1429 data_align = sec->alignment_power;
1431 else if (f & SEC_HAS_CONTENTS)
1433 if (sec->alignment_power > other_align)
1434 other_align = sec->alignment_power;
1436 else if (f & SEC_ALLOC)
1437 bss += sec->_raw_size;
1440 nlm_set_text_low (abfd, text_low);
1441 nlm_set_data_low (abfd, data_low);
1443 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1444 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1445 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1447 /* Fill in some fields in the header for which we now have the
1449 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1450 nlm_fixed_header (abfd)->codeImageSize = text;
1451 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1452 nlm_fixed_header (abfd)->dataImageSize = data;
1453 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1455 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1459 f = bfd_get_section_flags (abfd, sec);
1463 sec->filepos = text_ptr;
1464 text_ptr += sec->_raw_size;
1466 else if (f & SEC_DATA)
1468 sec->filepos = data_ptr;
1469 data_ptr += sec->_raw_size;
1471 else if (f & SEC_HAS_CONTENTS)
1473 sec->filepos = other_ptr;
1474 other_ptr += sec->_raw_size;
1478 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1480 /* Move all common symbols into the .bss section. */
1482 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1483 if (sym_ptr_ptr != NULL)
1489 /* Make sure we have a section to hold uninitialized data. */
1490 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1491 if (bss_sec == NULL)
1493 if (! add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1494 (file_ptr) 0, (bfd_size_type) 0,
1497 bss_sec = bfd_get_section_by_name (abfd,
1498 NLM_UNINITIALIZED_DATA_NAME);
1499 bss_sec->vma = data_low + data;
1502 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1504 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1511 if (! bfd_is_com_section (bfd_get_section (sym)))
1514 /* Put the common symbol in the .bss section, and increase
1515 the size of the .bss section by the size of the common
1516 symbol (which is the old value of the symbol). */
1517 sym->section = bss_sec;
1519 sym->value = bss_sec->_raw_size + add;
1521 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1523 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1524 bss_sec->_raw_size += add;
1530 /* Set the contents of a section. To do this we need to know where
1531 the section is going to be located in the output file. That means
1532 that the sizes of all the sections must be set, and all the
1533 variable size header information must be known. */
1536 nlm_set_section_contents (abfd, section, location, offset, count)
1541 bfd_size_type count;
1543 if (abfd->output_has_begun == false
1544 && nlm_compute_section_file_positions (abfd) == false)
1550 /* i386 NetWare has a very restricted set of relocs. In order for
1551 objcopy to work, the NLM i386 backend needs a chance to rework
1552 the section contents so that its set of relocs will work. If all
1553 the relocs are already acceptable, this will not do anything. */
1554 if (section->reloc_count != 0)
1556 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR data,
1558 bfd_size_type count));
1560 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1561 if (mangle_relocs_func != NULL)
1563 if (! (*mangle_relocs_func) (abfd, section, location,
1564 (bfd_vma) offset, count))
1569 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1570 || bfd_write (location, 1, count, abfd) != count)
1572 bfd_error = system_call_error;
1579 /* We need to sort a list of relocs associated with sections when we
1580 write out the external relocs. */
1582 struct reloc_and_sec
1589 nlm_external_reloc_compare (p1, p2)
1593 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1594 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1596 return strcmp ((*r1->rel->sym_ptr_ptr)->name,
1597 (*r2->rel->sym_ptr_ptr)->name);
1600 /* Write out an NLM file. We write out the information in this order:
1606 other sections (custom data, messages, help, shared NLM, RPC,
1607 module dependencies)
1609 external references (imports)
1610 public symbols (exports)
1612 This is similar to the order used by the NetWare tools; the
1613 difference is that NetWare puts the sections other than code, data
1614 and custom data at the end of the NLM. It is convenient for us to
1615 know where the sections are going to be before worrying about the
1616 size of the other information.
1618 By the time this function is called, all the section data should
1619 have been output using set_section_contents. Note that custom
1620 data, the message file, the help file, the shared NLM file, the RPC
1621 data, and the module dependencies are all considered to be
1622 sections; the caller is responsible for filling in the offset and
1623 length fields in the NLM headers. The relocation fixups and
1624 imports are both obtained from the list of relocs attached to each
1625 section. The exports and debugging records are obtained from the
1626 list of outsymbols. */
1629 nlm_write_object_contents (abfd)
1632 Nlm_External_Fixed_Header fixed_header;
1634 boolean (*write_reloc_func) PARAMS ((bfd *, asection *, arelent *));
1635 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1636 struct reloc_and_sec *external_relocs;
1637 asymbol **sym_ptr_ptr;
1639 if (abfd->output_has_begun == false
1640 && nlm_compute_section_file_positions (abfd) == false)
1643 /* Write out the variable length headers. */
1644 if (bfd_seek (abfd, sizeof (Nlm_External_Fixed_Header), SEEK_SET) != 0)
1646 bfd_error = system_call_error;
1649 if (nlm_swap_variable_header_out (abfd) == false
1650 || nlm_swap_auxiliary_headers_out (abfd) == false)
1652 bfd_error = system_call_error;
1656 /* A weak check on whether the section file positions were
1658 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1660 bfd_error = invalid_operation;
1664 /* Advance to the relocs. */
1665 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1668 bfd_error = system_call_error;
1672 /* The format of the relocation entries is dependent upon the
1673 particular target. We use an external routine to write the reloc
1675 write_reloc_func = nlm_write_reloc_func (abfd);
1677 /* Write out the internal relocation fixups. While we're looping
1678 over the relocs, we also count the external relocs, which is
1679 needed when they are written out below. */
1680 internal_reloc_count = 0;
1681 external_reloc_count = 0;
1682 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1684 arelent **rel_ptr_ptr, **rel_end;
1686 if (sec->reloc_count == 0)
1689 /* We can only represent relocs within a code or data
1691 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1693 bfd_error = invalid_operation;
1697 /* We need to know how to write out relocs. */
1698 if (write_reloc_func == NULL)
1700 bfd_error = invalid_operation;
1704 rel_ptr_ptr = sec->orelocation;
1705 rel_end = rel_ptr_ptr + sec->reloc_count;
1706 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1712 sym = *rel->sym_ptr_ptr;
1714 if (bfd_get_section (sym) != &bfd_und_section)
1716 ++internal_reloc_count;
1717 if ((*write_reloc_func) (abfd, sec, rel) == false)
1721 ++external_reloc_count;
1724 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1726 /* Write out the imports (relocs against external symbols). These
1727 are output as a symbol name followed by all the relocs for that
1728 symbol, so we must first gather together all the relocs against
1729 external symbols and sort them. */
1731 (struct reloc_and_sec *) bfd_alloc (abfd,
1732 (external_reloc_count
1733 * sizeof (struct reloc_and_sec)));
1734 if (external_relocs == (struct reloc_and_sec *) NULL)
1736 bfd_error = no_memory;
1740 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1742 arelent **rel_ptr_ptr, **rel_end;
1744 if (sec->reloc_count == 0)
1747 rel_ptr_ptr = sec->orelocation;
1748 rel_end = rel_ptr_ptr + sec->reloc_count;
1749 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1755 sym = *rel->sym_ptr_ptr;
1757 if (bfd_get_section (sym) != &bfd_und_section)
1760 external_relocs[i].rel = rel;
1761 external_relocs[i].sec = sec;
1766 BFD_ASSERT (i == external_reloc_count);
1768 /* Sort the external relocs by name. */
1769 qsort (external_relocs, external_reloc_count,
1770 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1772 /* Write out the external relocs. */
1773 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1776 while (i < external_reloc_count)
1781 bfd_size_type j, cnt;
1782 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1786 rel = external_relocs[i].rel;
1787 sym = *rel->sym_ptr_ptr;
1789 len = strlen (sym->name);
1790 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1791 != sizeof (bfd_byte))
1792 || bfd_write (sym->name, len, 1, abfd) != len)
1794 bfd_error = system_call_error;
1800 (j < external_reloc_count
1801 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1805 put_word (abfd, (bfd_vma) cnt, temp);
1806 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1808 bfd_error = system_call_error;
1814 if ((*write_reloc_func) (abfd, external_relocs[i].sec,
1815 external_relocs[i].rel) == false)
1820 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1822 /* Write out the public symbols (exports). */
1823 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1824 if (sym_ptr_ptr != (asymbol **) NULL)
1828 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1830 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1831 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1837 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1841 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1842 || bfd_get_section (sym) == &bfd_und_section)
1847 len = strlen (sym->name);
1848 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1849 != sizeof (bfd_byte))
1850 || bfd_write (sym->name, len, 1, abfd) != len)
1852 bfd_error = system_call_error;
1856 offset = bfd_asymbol_value (sym);
1858 if (sec->flags & SEC_CODE)
1860 offset -= nlm_get_text_low (abfd);
1861 offset |= NLM_HIBIT;
1863 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1865 /* SEC_ALLOC is for the .bss section. */
1866 offset -= nlm_get_data_low (abfd);
1870 /* We can't handle an exported symbol that is not in the
1871 code or data segment. */
1872 bfd_error = invalid_operation;
1876 put_word (abfd, offset, temp);
1877 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1879 bfd_error = system_call_error;
1883 nlm_fixed_header (abfd)->numberOfPublics = c;
1885 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1887 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1888 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1889 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1895 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1899 /* The NLM notion of a debugging symbol is actually what BFD
1900 calls a local or global symbol. What BFD calls a
1901 debugging symbol NLM does not understand at all. */
1902 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1903 || (sym->flags & BSF_DEBUGGING) != 0
1904 || bfd_get_section (sym) == &bfd_und_section)
1909 offset = bfd_asymbol_value (sym);
1911 if (sec->flags & SEC_CODE)
1913 offset -= nlm_get_text_low (abfd);
1916 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1918 offset -= nlm_get_data_low (abfd);
1924 /* The type is 0 for data, 1 for code, 2 for absolute. */
1925 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1926 != sizeof (bfd_byte))
1928 bfd_error = system_call_error;
1932 put_word (abfd, offset, temp);
1933 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1935 bfd_error = system_call_error;
1939 len = strlen (sym->name);
1940 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1941 != sizeof (bfd_byte))
1942 || bfd_write (sym->name, len, 1, abfd) != len)
1944 bfd_error = system_call_error;
1948 /* Exported symbols may get an additional debugging record
1949 without the prefix. */
1950 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
1954 s = strchr (sym->name, '@');
1959 if ((bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1960 != sizeof (bfd_byte))
1961 || (bfd_write (temp, sizeof (temp), 1, abfd)
1964 bfd_error = system_call_error;
1971 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1972 != sizeof (bfd_byte))
1973 || bfd_write (s, len, 1, abfd) != len)
1975 bfd_error = system_call_error;
1981 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1984 /* At this point everything has been written out except the fixed
1986 memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE,
1987 NLM_SIGNATURE_SIZE);
1988 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
1989 nlm_fixed_header (abfd)->codeStartOffset =
1990 bfd_get_start_address (abfd) - nlm_get_text_low (abfd);
1992 /* We have no convenient way for the caller to pass in the exit
1993 procedure or the check unload procedure, so the caller must set
1994 the values in the header to the values of the symbols. */
1995 if (nlm_fixed_header (abfd)->exitProcedureOffset != 0)
1996 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
1997 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
1998 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
1999 nlm_get_text_low (abfd);
2001 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), &fixed_header);
2002 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2003 || (bfd_write (&fixed_header, sizeof fixed_header, 1, abfd)
2004 != sizeof fixed_header))
2006 bfd_error = system_call_error;