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)
112 bfd_error = wrong_format;
116 /* There's no supported way to discover the endianess of an NLM, so test for
117 a sane version number after doing byte swapping appropriate for this
118 XVEC. (Hack alert!) */
120 if (get_word (abfd, (bfd_byte *) x_fxdhdr.version) > 0xFFFF)
122 bfd_error = wrong_format;
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.
131 FIXME: If we later decide this isn't the right format and the bfd
132 already had valid tdata, we've just blown away the tdata we wanted
133 to save for the right format. */
135 nlm_tdata (abfd) = (struct nlm_obj_tdata *)
136 bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
137 if (nlm_tdata (abfd) == NULL)
139 bfd_error = no_memory;
143 /* FIXME: Any return(NULL) exits below here will leak memory (tdata).
144 And a memory leak also means we lost the real tdata info we wanted
145 to save, because it was in the leaked memory. */
147 /* Swap in the rest of the fixed length header. */
149 i_fxdhdrp = nlm_fixed_header (abfd);
150 nlm_swap_fixed_header_in (abfd, &x_fxdhdr, i_fxdhdrp);
152 if (!nlm_swap_variable_header_in (abfd)
153 || !nlm_swap_auxiliary_headers_in (abfd)
154 || !add_bfd_section (abfd, NLM_CODE_NAME,
155 i_fxdhdrp -> codeImageOffset,
156 i_fxdhdrp -> codeImageSize,
157 (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
159 || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
160 i_fxdhdrp -> dataImageOffset,
161 i_fxdhdrp -> dataImageSize,
162 (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
164 || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
166 i_fxdhdrp -> uninitializedDataSize,
169 bfd_error = wrong_format;
173 if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
174 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
175 abfd->flags |= HAS_RELOC;
176 if (nlm_fixed_header (abfd)->numberOfPublics != 0
177 || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
178 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
179 abfd->flags |= HAS_SYMS;
181 arch = nlm_architecture (abfd);
182 if (arch != bfd_arch_unknown)
183 bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
185 return (abfd -> xvec);
188 /* Add a section to the bfd. */
191 DEFUN (add_bfd_section, (abfd, name, offset, size, flags),
195 bfd_size_type size AND
200 newsect = bfd_make_section (abfd, name);
205 newsect -> vma = 0; /* NLM's are relocatable. */
206 newsect -> _raw_size = size;
207 newsect -> filepos = offset;
208 newsect -> flags = flags;
209 newsect -> alignment_power = bfd_log2 (0); /* FIXME */
213 /* Translate an NLM fixed length file header in external format into an NLM
214 file header in internal format. */
217 DEFUN (nlm_swap_fixed_header_in, (abfd, src, dst),
219 Nlm_External_Fixed_Header * src AND
220 Nlm_Internal_Fixed_Header * dst)
222 memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
223 memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
225 get_word (abfd, (bfd_byte *) src -> version);
226 dst -> codeImageOffset =
227 get_word (abfd, (bfd_byte *) src -> codeImageOffset);
228 dst -> codeImageSize =
229 get_word (abfd, (bfd_byte *) src -> codeImageSize);
230 dst -> dataImageOffset =
231 get_word (abfd, (bfd_byte *) src -> dataImageOffset);
232 dst -> dataImageSize =
233 get_word (abfd, (bfd_byte *) src -> dataImageSize);
234 dst -> uninitializedDataSize =
235 get_word (abfd, (bfd_byte *) src -> uninitializedDataSize);
236 dst -> customDataOffset =
237 get_word (abfd, (bfd_byte *) src -> customDataOffset);
238 dst -> customDataSize =
239 get_word (abfd, (bfd_byte *) src -> customDataSize);
240 dst -> moduleDependencyOffset =
241 get_word (abfd, (bfd_byte *) src -> moduleDependencyOffset);
242 dst -> numberOfModuleDependencies =
243 get_word (abfd, (bfd_byte *) src -> numberOfModuleDependencies);
244 dst -> relocationFixupOffset =
245 get_word (abfd, (bfd_byte *) src -> relocationFixupOffset);
246 dst -> numberOfRelocationFixups =
247 get_word (abfd, (bfd_byte *) src -> numberOfRelocationFixups);
248 dst -> externalReferencesOffset =
249 get_word (abfd, (bfd_byte *) src -> externalReferencesOffset);
250 dst -> numberOfExternalReferences =
251 get_word (abfd, (bfd_byte *) src -> numberOfExternalReferences);
252 dst -> publicsOffset =
253 get_word (abfd, (bfd_byte *) src -> publicsOffset);
254 dst -> numberOfPublics =
255 get_word (abfd, (bfd_byte *) src -> numberOfPublics);
256 dst -> debugInfoOffset =
257 get_word (abfd, (bfd_byte *) src -> debugInfoOffset);
258 dst -> numberOfDebugRecords =
259 get_word (abfd, (bfd_byte *) src -> numberOfDebugRecords);
260 dst -> codeStartOffset =
261 get_word (abfd, (bfd_byte *) src -> codeStartOffset);
262 dst -> exitProcedureOffset =
263 get_word (abfd, (bfd_byte *) src -> exitProcedureOffset);
264 dst -> checkUnloadProcedureOffset =
265 get_word (abfd, (bfd_byte *) src -> checkUnloadProcedureOffset);
267 get_word (abfd, (bfd_byte *) src -> moduleType);
269 get_word (abfd, (bfd_byte *) src -> flags);
272 /* Translate an NLM fixed length file header in internal format into
273 an NLM file header in external format. */
276 DEFUN (nlm_swap_fixed_header_out, (abfd, src, dst),
278 Nlm_Internal_Fixed_Header * src AND
279 Nlm_External_Fixed_Header * dst)
281 memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
282 memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
283 put_word (abfd, (bfd_vma) src -> version,
284 (bfd_byte *) dst -> version);
285 put_word (abfd, (bfd_vma) src -> codeImageOffset,
286 (bfd_byte *) dst -> codeImageOffset);
287 put_word (abfd, (bfd_vma) src -> codeImageSize,
288 (bfd_byte *) dst -> codeImageSize);
289 put_word (abfd, (bfd_vma) src -> dataImageOffset,
290 (bfd_byte *) dst -> dataImageOffset);
291 put_word (abfd, (bfd_vma) src -> dataImageSize,
292 (bfd_byte *) dst -> dataImageSize);
293 put_word (abfd, (bfd_vma) src -> uninitializedDataSize,
294 (bfd_byte *) dst -> uninitializedDataSize);
295 put_word (abfd, (bfd_vma) src -> customDataOffset,
296 (bfd_byte *) dst -> customDataOffset);
297 put_word (abfd, (bfd_vma) src -> customDataSize,
298 (bfd_byte *) dst -> customDataSize);
299 put_word (abfd, (bfd_vma) src -> moduleDependencyOffset,
300 (bfd_byte *) dst -> moduleDependencyOffset);
301 put_word (abfd, (bfd_vma) src -> numberOfModuleDependencies,
302 (bfd_byte *) dst -> numberOfModuleDependencies);
303 put_word (abfd, (bfd_vma) src -> relocationFixupOffset,
304 (bfd_byte *) dst -> relocationFixupOffset);
305 put_word (abfd, (bfd_vma) src -> numberOfRelocationFixups,
306 (bfd_byte *) dst -> numberOfRelocationFixups);
307 put_word (abfd, (bfd_vma) src -> externalReferencesOffset,
308 (bfd_byte *) dst -> externalReferencesOffset);
309 put_word (abfd, (bfd_vma) src -> numberOfExternalReferences,
310 (bfd_byte *) dst -> numberOfExternalReferences);
311 put_word (abfd, (bfd_vma) src -> publicsOffset,
312 (bfd_byte *) dst -> publicsOffset);
313 put_word (abfd, (bfd_vma) src -> numberOfPublics,
314 (bfd_byte *) dst -> numberOfPublics);
315 put_word (abfd, (bfd_vma) src -> debugInfoOffset,
316 (bfd_byte *) dst -> debugInfoOffset);
317 put_word (abfd, (bfd_vma) src -> numberOfDebugRecords,
318 (bfd_byte *) dst -> numberOfDebugRecords);
319 put_word (abfd, (bfd_vma) src -> codeStartOffset,
320 (bfd_byte *) dst -> codeStartOffset);
321 put_word (abfd, (bfd_vma) src -> exitProcedureOffset,
322 (bfd_byte *) dst -> exitProcedureOffset);
323 put_word (abfd, (bfd_vma) src -> checkUnloadProcedureOffset,
324 (bfd_byte *) dst -> checkUnloadProcedureOffset);
325 put_word (abfd, (bfd_vma) src -> moduleType,
326 (bfd_byte *) dst -> moduleType);
327 put_word (abfd, (bfd_vma) src -> flags,
328 (bfd_byte *) dst -> flags);
331 /* Read and swap in the variable length header. All the fields must
332 exist in the NLM, and must exist in the order they are read here. */
335 DEFUN (nlm_swap_variable_header_in, (abfd),
338 unsigned char temp [NLM_TARGET_LONG_SIZE];
340 /* Read the description length and text members. */
342 if (bfd_read ((PTR) &nlm_variable_header (abfd) -> descriptionLength,
343 sizeof (nlm_variable_header (abfd) -> descriptionLength),
345 sizeof (nlm_variable_header (abfd) -> descriptionLength))
347 bfd_error = system_call_error;
350 if (bfd_read ((PTR) nlm_variable_header (abfd) -> descriptionText,
351 nlm_variable_header (abfd) -> descriptionLength + 1,
353 nlm_variable_header (abfd) -> descriptionLength + 1)
355 bfd_error = system_call_error;
359 /* Read and convert the stackSize field. */
361 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
363 bfd_error = system_call_error;
366 nlm_variable_header (abfd) -> stackSize = get_word (abfd, (bfd_byte *) temp);
368 /* Read and convert the reserved field. */
370 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
372 bfd_error = system_call_error;
375 nlm_variable_header (abfd) -> reserved = get_word (abfd, (bfd_byte *) temp);
377 /* Read the oldThreadName field. This field is a fixed length string. */
379 if (bfd_read ((PTR) nlm_variable_header (abfd) -> oldThreadName,
380 sizeof (nlm_variable_header (abfd) -> oldThreadName),
382 sizeof (nlm_variable_header (abfd) -> oldThreadName))
384 bfd_error = system_call_error;
388 /* Read the screen name length and text members. */
390 if (bfd_read ((PTR) &nlm_variable_header (abfd) -> screenNameLength,
391 sizeof (nlm_variable_header (abfd) -> screenNameLength),
393 sizeof (nlm_variable_header (abfd) -> screenNameLength))
395 bfd_error = system_call_error;
398 if (bfd_read ((PTR) nlm_variable_header (abfd) -> screenName,
399 nlm_variable_header (abfd) -> screenNameLength + 1,
401 nlm_variable_header (abfd) -> screenNameLength + 1)
403 bfd_error = system_call_error;
407 /* Read the thread name length and text members. */
409 if (bfd_read ((PTR) &nlm_variable_header (abfd) -> threadNameLength,
410 sizeof (nlm_variable_header (abfd) -> threadNameLength),
412 sizeof (nlm_variable_header (abfd) -> threadNameLength))
414 bfd_error = system_call_error;
417 if (bfd_read ((PTR) nlm_variable_header (abfd) -> threadName,
418 nlm_variable_header (abfd) -> threadNameLength + 1,
420 nlm_variable_header (abfd) -> threadNameLength + 1)
422 bfd_error = system_call_error;
428 /* Swap and write out the variable length header. All the fields must
429 exist in the NLM, and must exist in this order. */
432 DEFUN (nlm_swap_variable_header_out, (abfd),
435 unsigned char temp [NLM_TARGET_LONG_SIZE];
437 /* Write the description length and text members. */
439 if (bfd_write ((PTR) &nlm_variable_header (abfd) -> descriptionLength,
440 sizeof (nlm_variable_header (abfd) -> descriptionLength),
442 sizeof (nlm_variable_header (abfd) -> descriptionLength))
444 bfd_error = system_call_error;
447 if (bfd_write ((PTR) nlm_variable_header (abfd) -> descriptionText,
448 nlm_variable_header (abfd) -> descriptionLength + 1,
450 nlm_variable_header (abfd) -> descriptionLength + 1)
452 bfd_error = system_call_error;
456 /* Convert and write the stackSize field. */
458 put_word (abfd, (bfd_vma) nlm_variable_header (abfd) -> stackSize,
460 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
462 bfd_error = system_call_error;
466 /* Convert and write the reserved field. */
468 put_word (abfd, (bfd_vma) nlm_variable_header (abfd) -> reserved,
470 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
472 bfd_error = system_call_error;
476 /* Write the oldThreadName field. This field is a fixed length string. */
478 if (bfd_write ((PTR) nlm_variable_header (abfd) -> oldThreadName,
479 sizeof (nlm_variable_header (abfd) -> oldThreadName),
481 sizeof (nlm_variable_header (abfd) -> oldThreadName))
483 bfd_error = system_call_error;
487 /* Write the screen name length and text members. */
489 if (bfd_write ((PTR) &nlm_variable_header (abfd) -> screenNameLength,
490 sizeof (nlm_variable_header (abfd) -> screenNameLength),
492 sizeof (nlm_variable_header (abfd) -> screenNameLength))
494 bfd_error = system_call_error;
497 if (bfd_write ((PTR) nlm_variable_header (abfd) -> screenName,
498 nlm_variable_header (abfd) -> screenNameLength + 1,
500 nlm_variable_header (abfd) -> screenNameLength + 1)
502 bfd_error = system_call_error;
506 /* Write the thread name length and text members. */
508 if (bfd_write ((PTR) &nlm_variable_header (abfd) -> threadNameLength,
509 sizeof (nlm_variable_header (abfd) -> threadNameLength),
511 sizeof (nlm_variable_header (abfd) -> threadNameLength))
513 bfd_error = system_call_error;
516 if (bfd_write ((PTR) nlm_variable_header (abfd) -> threadName,
517 nlm_variable_header (abfd) -> threadNameLength + 1,
519 nlm_variable_header (abfd) -> threadNameLength + 1)
521 bfd_error = system_call_error;
527 /* Read and swap in the contents of all the auxiliary headers. Because of
528 the braindead design, we have to do strcmps on strings of indeterminate
529 length to figure out what each auxiliary header is. Even worse, we have
530 no way of knowing how many auxiliary headers there are or where the end
531 of the auxiliary headers are, except by finding something that doesn't
532 look like a known auxiliary header. This means that the first new type
533 of auxiliary header added will break all existing tools that don't
537 DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
540 unsigned char tempstr [16];
545 position = bfd_tell (abfd);
546 if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) !=
549 bfd_error = system_call_error;
552 if (bfd_seek (abfd, position, SEEK_SET) == -1)
554 bfd_error = system_call_error;
557 if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
559 Nlm_External_Version_Header thdr;
560 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
562 bfd_error = system_call_error;
565 memcpy (nlm_version_header (abfd) -> stamp, thdr.stamp,
566 sizeof (thdr.stamp));
567 nlm_version_header (abfd) -> majorVersion =
568 get_word (abfd, (bfd_byte *) thdr.majorVersion);
569 nlm_version_header (abfd) -> minorVersion =
570 get_word (abfd, (bfd_byte *) thdr.minorVersion);
571 nlm_version_header (abfd) -> revision =
572 get_word (abfd, (bfd_byte *) thdr.revision);
573 nlm_version_header (abfd) -> year =
574 get_word (abfd, (bfd_byte *) thdr.year);
575 nlm_version_header (abfd) -> month =
576 get_word (abfd, (bfd_byte *) thdr.month);
577 nlm_version_header (abfd) -> day =
578 get_word (abfd, (bfd_byte *) thdr.day);
580 else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
582 Nlm_External_Extended_Header thdr;
583 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
585 bfd_error = system_call_error;
588 memcpy (nlm_extended_header (abfd) -> stamp, thdr.stamp,
589 sizeof (thdr.stamp));
590 nlm_extended_header (abfd) -> languageID =
591 get_word (abfd, (bfd_byte *) thdr.languageID);
592 nlm_extended_header (abfd) -> messageFileOffset =
593 get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
594 nlm_extended_header (abfd) -> messageFileLength =
595 get_word (abfd, (bfd_byte *) thdr.messageFileLength);
596 nlm_extended_header (abfd) -> messageCount =
597 get_word (abfd, (bfd_byte *) thdr.messageCount);
598 nlm_extended_header (abfd) -> helpFileOffset =
599 get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
600 nlm_extended_header (abfd) -> helpFileLength =
601 get_word (abfd, (bfd_byte *) thdr.helpFileLength);
602 nlm_extended_header (abfd) -> RPCDataOffset =
603 get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
604 nlm_extended_header (abfd) -> RPCDataLength =
605 get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
606 nlm_extended_header (abfd) -> sharedCodeOffset =
607 get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
608 nlm_extended_header (abfd) -> sharedCodeLength =
609 get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
610 nlm_extended_header (abfd) -> sharedDataOffset =
611 get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
612 nlm_extended_header (abfd) -> sharedDataLength =
613 get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
614 nlm_extended_header (abfd) -> sharedRelocationFixupOffset =
615 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
616 nlm_extended_header (abfd) -> sharedRelocationFixupCount =
617 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
618 nlm_extended_header (abfd) -> sharedExternalReferenceOffset =
619 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
620 nlm_extended_header (abfd) -> sharedExternalReferenceCount =
621 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
622 nlm_extended_header (abfd) -> sharedPublicsOffset =
623 get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
624 nlm_extended_header (abfd) -> sharedPublicsCount =
625 get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
626 nlm_extended_header (abfd) -> SharedInitializationOffset =
627 get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
628 nlm_extended_header (abfd) -> SharedExitProcedureOffset =
629 get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
630 nlm_extended_header (abfd) -> productID =
631 get_word (abfd, (bfd_byte *) thdr.productID);
632 nlm_extended_header (abfd) -> reserved0 =
633 get_word (abfd, (bfd_byte *) thdr.reserved0);
634 nlm_extended_header (abfd) -> reserved1 =
635 get_word (abfd, (bfd_byte *) thdr.reserved1);
636 nlm_extended_header (abfd) -> reserved2 =
637 get_word (abfd, (bfd_byte *) thdr.reserved2);
638 nlm_extended_header (abfd) -> reserved3 =
639 get_word (abfd, (bfd_byte *) thdr.reserved3);
640 nlm_extended_header (abfd) -> reserved4 =
641 get_word (abfd, (bfd_byte *) thdr.reserved4);
642 nlm_extended_header (abfd) -> reserved5 =
643 get_word (abfd, (bfd_byte *) thdr.reserved5);
645 else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
647 Nlm_External_Custom_Header thdr;
648 if (bfd_read ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
650 bfd_error = system_call_error;
653 memcpy (nlm_custom_header (abfd) -> stamp, thdr.stamp,
654 sizeof (thdr.stamp));
655 nlm_custom_header (abfd) -> dataLength =
656 get_word (abfd, (bfd_byte *) thdr.dataLength);
657 nlm_custom_header (abfd) -> debugRecOffset =
658 get_word (abfd, (bfd_byte *) thdr.debugRecOffset);
659 nlm_custom_header (abfd) -> debugRecLength =
660 get_word (abfd, (bfd_byte *) thdr.debugRecLength);
662 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
664 Nlm_External_Copyright_Header thdr;
665 if (bfd_read ((PTR) &nlm_copyright_header (abfd)->stamp,
666 sizeof (nlm_copyright_header (abfd)->stamp),
668 != sizeof (nlm_copyright_header (abfd)->stamp))
670 bfd_error = system_call_error;
673 if (bfd_read ((PTR) &(nlm_copyright_header (abfd)
674 ->copyrightMessageLength),
677 bfd_error = system_call_error;
680 /* The copyright message is a variable length string. */
681 if (bfd_read ((PTR) nlm_copyright_header (abfd) -> copyrightMessage,
682 nlm_copyright_header (abfd) -> copyrightMessageLength + 1,
684 nlm_copyright_header (abfd) -> copyrightMessageLength + 1)
686 bfd_error = system_call_error;
698 /* Return whether there is a non-zero byte in a memory block. */
701 find_nonzero (buf, size)
705 char *p = (char *) buf;
713 /* Swap out the contents of the auxiliary headers. We create those
714 auxiliary headers which have been set non-zero. We do not require
715 the caller to set up the stamp fields. */
718 nlm_swap_auxiliary_headers_out (abfd)
721 /* Write out the version header if there is one. */
722 if (find_nonzero ((PTR) nlm_version_header (abfd),
723 sizeof (Nlm_Internal_Version_Header)))
725 Nlm_External_Version_Header thdr;
727 memcpy (thdr.stamp, "VeRsIoN#", 8);
728 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> majorVersion,
729 (bfd_byte *) thdr.majorVersion);
730 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> minorVersion,
731 (bfd_byte *) thdr.minorVersion);
732 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> revision,
733 (bfd_byte *) thdr.revision);
734 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> year,
735 (bfd_byte *) thdr.year);
736 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> month,
737 (bfd_byte *) thdr.month);
738 put_word (abfd, (bfd_vma) nlm_version_header (abfd) -> day,
739 (bfd_byte *) thdr.day);
740 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
742 bfd_error = system_call_error;
747 /* Write out the extended header if there is one. */
748 if (find_nonzero ((PTR) nlm_extended_header (abfd),
749 sizeof (Nlm_Internal_Extended_Header)))
751 Nlm_External_Extended_Header thdr;
753 memcpy (thdr.stamp, "MeSsAgEs", 8);
755 (bfd_vma) nlm_extended_header (abfd) -> languageID,
756 (bfd_byte *) thdr.languageID);
758 (bfd_vma) nlm_extended_header (abfd) -> messageFileOffset,
759 (bfd_byte *) thdr.messageFileOffset);
761 (bfd_vma) nlm_extended_header (abfd) -> messageFileLength,
762 (bfd_byte *) thdr.messageFileLength);
764 (bfd_vma) nlm_extended_header (abfd) -> messageCount,
765 (bfd_byte *) thdr.messageCount);
767 (bfd_vma) nlm_extended_header (abfd) -> helpFileOffset,
768 (bfd_byte *) thdr.helpFileOffset);
770 (bfd_vma) nlm_extended_header (abfd) -> helpFileLength,
771 (bfd_byte *) thdr.helpFileLength);
773 (bfd_vma) nlm_extended_header (abfd) -> RPCDataOffset,
774 (bfd_byte *) thdr.RPCDataOffset);
776 (bfd_vma) nlm_extended_header (abfd) -> RPCDataLength,
777 (bfd_byte *) thdr.RPCDataLength);
779 (bfd_vma) nlm_extended_header (abfd) -> sharedCodeOffset,
780 (bfd_byte *) thdr.sharedCodeOffset);
782 (bfd_vma) nlm_extended_header (abfd) -> sharedCodeLength,
783 (bfd_byte *) thdr.sharedCodeLength);
785 (bfd_vma) nlm_extended_header (abfd) -> sharedDataOffset,
786 (bfd_byte *) thdr.sharedDataOffset);
788 (bfd_vma) nlm_extended_header (abfd) -> sharedDataLength,
789 (bfd_byte *) thdr.sharedDataLength);
791 (bfd_vma) nlm_extended_header (abfd) -> sharedRelocationFixupOffset,
792 (bfd_byte *) thdr.sharedRelocationFixupOffset);
794 (bfd_vma) nlm_extended_header (abfd) -> sharedRelocationFixupCount,
795 (bfd_byte *) thdr.sharedRelocationFixupCount);
797 (bfd_vma) nlm_extended_header (abfd) -> sharedExternalReferenceOffset,
798 (bfd_byte *) thdr.sharedExternalReferenceOffset);
800 (bfd_vma) nlm_extended_header (abfd) -> sharedExternalReferenceCount,
801 (bfd_byte *) thdr.sharedExternalReferenceCount);
803 (bfd_vma) nlm_extended_header (abfd) -> sharedPublicsOffset,
804 (bfd_byte *) thdr.sharedPublicsOffset);
806 (bfd_vma) nlm_extended_header (abfd) -> sharedPublicsCount,
807 (bfd_byte *) thdr.sharedPublicsCount);
809 (bfd_vma) nlm_extended_header (abfd) -> SharedInitializationOffset,
810 (bfd_byte *) thdr.sharedInitializationOffset);
812 (bfd_vma) nlm_extended_header (abfd) -> SharedExitProcedureOffset,
813 (bfd_byte *) thdr.SharedExitProcedureOffset);
815 (bfd_vma) nlm_extended_header (abfd) -> productID,
816 (bfd_byte *) thdr.productID);
818 (bfd_vma) nlm_extended_header (abfd) -> reserved0,
819 (bfd_byte *) thdr.reserved0);
821 (bfd_vma) nlm_extended_header (abfd) -> reserved1,
822 (bfd_byte *) thdr.reserved1);
824 (bfd_vma) nlm_extended_header (abfd) -> reserved2,
825 (bfd_byte *) thdr.reserved2);
827 (bfd_vma) nlm_extended_header (abfd) -> reserved3,
828 (bfd_byte *) thdr.reserved3);
830 (bfd_vma) nlm_extended_header (abfd) -> reserved4,
831 (bfd_byte *) thdr.reserved4);
833 (bfd_vma) nlm_extended_header (abfd) -> reserved5,
834 (bfd_byte *) thdr.reserved5);
835 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
837 bfd_error = system_call_error;
842 /* Write out the custom header if there is one. */
843 if (find_nonzero ((PTR) nlm_custom_header (abfd),
844 sizeof (Nlm_Internal_Custom_Header)))
846 Nlm_External_Custom_Header thdr;
848 /* Right now we assume the custom header is always the suggested
849 format for alternate debugging records. */
850 BFD_ASSERT (nlm_custom_header (abfd) -> dataLength == 8);
852 memcpy (thdr.stamp, "CuStHeAd", 8);
853 put_word (abfd, (bfd_vma) nlm_custom_header (abfd) -> dataLength,
854 (bfd_byte *) thdr.dataLength);
855 put_word (abfd, (bfd_vma) nlm_custom_header (abfd) -> debugRecOffset,
856 (bfd_byte *) thdr.debugRecOffset);
857 put_word (abfd, (bfd_vma) nlm_custom_header (abfd) -> debugRecLength,
858 (bfd_byte *) thdr.debugRecLength);
859 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
861 bfd_error = system_call_error;
866 /* Write out the copyright header if there is one. */
867 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
868 sizeof (Nlm_Internal_Copyright_Header)))
870 Nlm_External_Copyright_Header thdr;
872 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
873 if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd)
874 != sizeof (thdr.stamp))
876 bfd_error = system_call_error;
879 thdr.copyrightMessageLength[0] =
880 nlm_copyright_header (abfd)->copyrightMessageLength;
881 if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1)
883 bfd_error = system_call_error;
886 /* The copyright message is a variable length string. */
887 if (bfd_write ((PTR) nlm_copyright_header (abfd) -> copyrightMessage,
888 nlm_copyright_header (abfd) -> copyrightMessageLength + 1,
890 nlm_copyright_header (abfd) -> copyrightMessageLength + 1)
892 bfd_error = system_call_error;
900 /* We read the NLM's public symbols and use it to generate a bfd symbol
901 table (hey, it's better than nothing) on a one-for-one basis. Thus
902 use the number of public symbols as the number of bfd symbols we will
903 have once we actually get around to reading them in.
905 Return the number of bytes required to hold the symtab vector, based on
906 the count plus 1, since we will NULL terminate the vector allocated based
910 DEFUN (nlm_get_symtab_upper_bound, (abfd), bfd * abfd)
912 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
913 unsigned int symcount;
914 unsigned int symtab_size = 0;
916 i_fxdhdrp = nlm_fixed_header (abfd);
917 symcount = (i_fxdhdrp -> numberOfPublics
918 + i_fxdhdrp -> numberOfDebugRecords
919 + i_fxdhdrp -> numberOfExternalReferences);
920 symtab_size = (symcount + 1) * (sizeof (asymbol));
921 return (symtab_size);
924 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
925 symbol table fails. */
928 nlm_get_symtab (abfd, alocation)
932 nlm_symbol_type *symbase;
933 bfd_size_type counter = 0;
935 if (nlm_slurp_symbol_table (abfd) == false)
937 symbase = nlm_get_symbols (abfd);
938 while (counter < bfd_get_symcount (abfd))
940 *alocation++ = &symbase->symbol;
944 *alocation = (asymbol *) NULL;
945 return bfd_get_symcount (abfd);
948 /* Make an NLM symbol. There is nothing special to do here. */
951 nlm_make_empty_symbol (abfd)
954 nlm_symbol_type *new;
956 new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
957 new->symbol.the_bfd = abfd;
961 /* Get symbol information. */
964 nlm_get_symbol_info (ignore_abfd, symbol, ret)
969 bfd_symbol_info (symbol, ret);
972 /* Print symbol information. */
975 nlm_print_symbol (abfd, afile, symbol, how)
979 bfd_print_symbol_type how;
981 FILE *file = (FILE *) afile;
985 case bfd_print_symbol_name:
986 case bfd_print_symbol_more:
988 fprintf (file,"%s", symbol->name);
990 case bfd_print_symbol_all:
991 bfd_print_symbol_vandf ((PTR) file, symbol);
992 fprintf (file, " %-5s", symbol->section->name);
994 fprintf (file," %s", symbol->name);
999 /* Slurp in nlm symbol table.
1001 In the external (in-file) form, NLM export records are variable length,
1002 with the following form:
1004 1 byte length of the symbol name (N)
1005 N bytes the symbol name
1006 4 bytes the symbol offset from start of it's section
1008 We also read in the debugging symbols and import records. Import
1009 records are treated as undefined symbols. As we read the import
1010 records we also read in the associated reloc information, which is
1011 attached to the symbol.
1013 The bfd symbols are copied to SYMPTRS.
1015 When we return, the bfd symcount is either zero or contains the correct
1020 nlm_slurp_symbol_table (abfd)
1023 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
1024 bfd_size_type totsymcount; /* Number of NLM symbols */
1025 bfd_size_type symcount; /* Counter of NLM symbols */
1026 nlm_symbol_type *sym; /* Pointer to current bfd symbol */
1027 unsigned char symlength; /* Symbol length read into here */
1028 unsigned char symtype; /* Type of debugging symbol */
1029 bfd_size_type rcount; /* Number of relocs */
1030 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
1031 boolean (*read_reloc_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1034 if (nlm_get_symbols (abfd) != NULL)
1037 /* Read each raw NLM symbol, using the information to create a canonical bfd
1040 Note that we allocate the initial bfd canonical symbol buffer based on a
1041 one-to-one mapping of the NLM symbols to canonical symbols. We actually
1042 use all the NLM symbols, so there will be no space left over at the end.
1043 When we have all the symbols, we build the caller's pointer vector. */
1045 abfd -> symcount = 0;
1046 i_fxdhdrp = nlm_fixed_header (abfd);
1047 totsymcount = (i_fxdhdrp -> numberOfPublics
1048 + i_fxdhdrp -> numberOfDebugRecords
1049 + i_fxdhdrp -> numberOfExternalReferences);
1050 if (totsymcount == 0)
1055 if (bfd_seek (abfd, i_fxdhdrp -> publicsOffset, SEEK_SET) == -1)
1057 bfd_error = system_call_error;
1061 sym = ((nlm_symbol_type *)
1062 bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
1063 nlm_set_symbols (abfd, sym);
1065 /* We use the bfd's symcount directly as the control count, so that early
1066 termination of the loop leaves the symcount correct for the symbols that
1069 symcount = i_fxdhdrp -> numberOfPublics;
1070 while (abfd -> symcount < symcount)
1072 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
1073 != sizeof (symlength))
1075 bfd_error = system_call_error;
1078 sym -> symbol.the_bfd = abfd;
1079 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
1080 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
1083 bfd_error = system_call_error;
1086 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1088 bfd_error = system_call_error;
1091 sym -> symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1092 sym -> symbol.value = get_word (abfd, temp);
1093 if (sym -> symbol.value & NLM_HIBIT)
1095 sym -> symbol.value &= ~NLM_HIBIT;
1096 sym -> symbol.flags |= BSF_FUNCTION;
1097 sym -> symbol.section =
1098 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1102 sym -> symbol.section =
1103 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1110 /* Read the debugging records. */
1112 if (i_fxdhdrp -> numberOfDebugRecords > 0)
1114 if (bfd_seek (abfd, i_fxdhdrp -> debugInfoOffset, SEEK_SET) == -1)
1116 bfd_error = system_call_error;
1120 symcount += i_fxdhdrp -> numberOfDebugRecords;
1121 while (abfd -> symcount < symcount)
1123 if ((bfd_read ((PTR) &symtype, sizeof (symtype), 1, abfd)
1124 != sizeof (symtype))
1125 || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)
1126 || (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
1127 != sizeof (symlength)))
1129 bfd_error = system_call_error;
1132 sym -> symbol.the_bfd = abfd;
1133 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
1134 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
1137 bfd_error = system_call_error;
1140 sym -> symbol.flags = BSF_LOCAL;
1141 sym -> symbol.value = get_word (abfd, temp);
1144 sym -> symbol.section =
1145 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1147 else if (symtype == 1)
1149 sym -> symbol.flags |= BSF_FUNCTION;
1150 sym -> symbol.section =
1151 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1155 sym -> symbol.section = &bfd_abs_section;
1163 /* Read in the import records. We can only do this if we know how
1164 to read relocs for this target. */
1166 read_reloc_func = nlm_read_reloc_func (abfd);
1167 if (read_reloc_func != NULL)
1169 if (bfd_seek (abfd, i_fxdhdrp -> externalReferencesOffset, SEEK_SET)
1172 bfd_error = system_call_error;
1176 symcount += i_fxdhdrp -> numberOfExternalReferences;
1177 while (abfd -> symcount < symcount)
1179 struct nlm_relent *nlm_relocs;
1181 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
1182 != sizeof (symlength))
1184 bfd_error = system_call_error;
1187 sym -> symbol.the_bfd = abfd;
1188 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
1189 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
1192 bfd_error = system_call_error;
1195 sym -> symbol.flags = 0;
1196 sym -> symbol.value = 0;
1197 sym -> symbol.section = &bfd_und_section;
1198 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1200 bfd_error = system_call_error;
1203 rcount = get_word (abfd, temp);
1204 nlm_relocs = ((struct nlm_relent *)
1205 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
1206 sym -> relocs = nlm_relocs;
1208 while (sym -> rcnt < rcount)
1212 if ((*read_reloc_func) (abfd, sym, §ion,
1213 &nlm_relocs -> reloc)
1216 nlm_relocs -> section = section;
1229 /* Get the relocs for an NLM file. There are two types of relocs.
1230 Imports are relocs against symbols defined in other NLM files. We
1231 treat these as relocs against global symbols. Relocation fixups
1232 are internal relocs.
1234 The actual format used to store the relocs is machine specific. */
1236 /* Read in the relocation fixup information. This is stored in
1237 nlm_relocation_fixups, an array of arelent structures, and
1238 nlm_relocation_fixup_secs, an array of section pointers. The
1239 section pointers are needed because the relocs are not sorted by
1243 nlm_slurp_reloc_fixups (abfd)
1246 boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1248 bfd_size_type count;
1252 if (nlm_relocation_fixups (abfd) != NULL)
1254 read_func = nlm_read_reloc_func (abfd);
1255 if (read_func == NULL)
1258 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1261 bfd_error = system_call_error;
1265 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1266 rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
1267 secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
1268 if (rels == NULL || secs == NULL)
1270 bfd_error = no_memory;
1273 nlm_relocation_fixups (abfd) = rels;
1274 nlm_relocation_fixup_secs (abfd) = secs;
1276 /* We have to read piece by piece, because we don't know how large
1277 the machine specific reloc information is. */
1278 while (count-- != 0)
1280 if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
1282 nlm_relocation_fixups (abfd) = NULL;
1283 nlm_relocation_fixup_secs (abfd) = NULL;
1293 /* Get the number of relocs. This really just returns an upper bound,
1294 since it does not attempt to distinguish them based on the section.
1295 That will be handled when they are actually read. */
1298 nlm_get_reloc_upper_bound (abfd, sec)
1302 nlm_symbol_type *syms;
1303 bfd_size_type count;
1306 /* If we don't know how to read relocs, just return 0. */
1307 if (nlm_read_reloc_func (abfd) == NULL)
1309 /* Make sure we have either the code or the data section. */
1310 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1313 syms = nlm_get_symbols (abfd);
1316 if (nlm_slurp_symbol_table (abfd) == false)
1318 syms = nlm_get_symbols (abfd);
1321 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1323 count = bfd_get_symcount (abfd);
1324 while (count-- != 0)
1330 return (ret + 1) * sizeof (arelent *);
1333 /* Get the relocs themselves. */
1336 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1344 bfd_size_type count, i;
1347 /* Get the relocation fixups. */
1348 rels = nlm_relocation_fixups (abfd);
1351 if (nlm_slurp_reloc_fixups (abfd) == false)
1353 rels = nlm_relocation_fixups (abfd);
1357 secs = nlm_relocation_fixup_secs (abfd);
1360 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1361 for (i = 0; i < count; i++, rels++, secs++)
1370 /* Get the import symbols. */
1371 count = bfd_get_symcount (abfd);
1372 for (i = 0; i < count; i++, symbols++)
1377 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1379 nlm_symbol_type *nlm_sym;
1382 nlm_sym = (nlm_symbol_type *) sym;
1383 for (j = 0; j < nlm_sym->rcnt; j++)
1385 if (nlm_sym->relocs[j].section == sec)
1387 *relptr = &nlm_sym->relocs[j].reloc;
1388 (*relptr)->sym_ptr_ptr = symbols;
1401 /* Compute the section file positions for an NLM file. All variable
1402 length data in the file headers must be set before this function is
1403 called. If the variable length data is changed later, the
1404 resulting object file will be incorrect. Unfortunately, there is
1405 no way to check this.
1407 This routine also sets the Size and Offset fields in the fixed
1410 It also looks over the symbols and moves any common symbols into
1411 the .bss section; NLM has no way to represent a common symbol.
1412 This approach means that either the symbols must already have been
1413 set at this point, or there must be no common symbols. We need to
1414 move the symbols at this point so that mangle_relocs can see the
1418 nlm_compute_section_file_positions (abfd)
1423 bfd_vma text, data, bss;
1424 bfd_vma text_low, data_low;
1425 int text_align, data_align, other_align;
1426 file_ptr text_ptr, data_ptr, other_ptr;
1428 asymbol **sym_ptr_ptr;
1430 if (abfd->output_has_begun == true)
1433 /* Make sure we have a section to hold uninitialized data. */
1434 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1435 if (bss_sec == NULL)
1437 if (! add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1438 (file_ptr) 0, (bfd_size_type) 0,
1441 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1444 abfd->output_has_begun = true;
1446 /* The fixed header. */
1447 sofar = sizeof (Nlm_External_Fixed_Header);
1449 /* The variable header. */
1450 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1451 + nlm_variable_header (abfd) -> descriptionLength + 1
1452 + NLM_TARGET_LONG_SIZE /* stackSize */
1453 + NLM_TARGET_LONG_SIZE /* reserved */
1454 + sizeof (nlm_variable_header (abfd) -> oldThreadName)
1455 + sizeof (nlm_variable_header (abfd) -> screenNameLength)
1456 + nlm_variable_header (abfd) -> screenNameLength + 1
1457 + sizeof (nlm_variable_header (abfd) -> threadNameLength)
1458 + nlm_variable_header (abfd) -> threadNameLength + 1);
1460 /* The auxiliary headers. */
1461 if (find_nonzero ((PTR) nlm_version_header (abfd),
1462 sizeof (Nlm_Internal_Version_Header)))
1463 sofar += sizeof (Nlm_External_Version_Header);
1464 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1465 sizeof (Nlm_Internal_Extended_Header)))
1466 sofar += sizeof (Nlm_External_Extended_Header);
1467 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1468 sizeof (Nlm_Internal_Custom_Header)))
1469 sofar += sizeof (Nlm_External_Custom_Header);
1470 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1471 sizeof (Nlm_Internal_Copyright_Header)))
1472 sofar += (sizeof (Nlm_External_Copyright_Header)
1473 + nlm_copyright_header (abfd) -> copyrightMessageLength + 1);
1475 /* Compute the section file positions in two passes. First get the
1476 sizes of the text and data sections, and then set the file
1477 positions. This code aligns the sections in the file using the
1478 same alignment restrictions that apply to the sections in memory;
1479 this may not be necessary. */
1481 text_low = (bfd_vma) -1;
1484 data_low = (bfd_vma) -1;
1488 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1492 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1494 f = bfd_get_section_flags (abfd, sec);
1497 text += sec->_raw_size;
1498 if (bfd_get_section_vma (abfd, sec) < text_low)
1499 text_low = bfd_get_section_vma (abfd, sec);
1500 if (sec->alignment_power > text_align)
1501 text_align = sec->alignment_power;
1503 else if (f & SEC_DATA)
1505 data += sec->_raw_size;
1506 if (bfd_get_section_vma (abfd, sec) < data_low)
1507 data_low = bfd_get_section_vma (abfd, sec);
1508 if (sec->alignment_power > data_align)
1509 data_align = sec->alignment_power;
1511 else if (f & SEC_HAS_CONTENTS)
1513 if (sec->alignment_power > other_align)
1514 other_align = sec->alignment_power;
1516 else if (f & SEC_ALLOC)
1517 bss += sec->_raw_size;
1520 nlm_set_text_low (abfd, text_low);
1521 nlm_set_data_low (abfd, data_low);
1523 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1524 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1525 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1527 /* Fill in some fields in the header for which we now have the
1529 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1530 nlm_fixed_header (abfd)->codeImageSize = text;
1531 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1532 nlm_fixed_header (abfd)->dataImageSize = data;
1533 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1535 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1539 f = bfd_get_section_flags (abfd, sec);
1543 sec->filepos = text_ptr;
1544 text_ptr += sec->_raw_size;
1546 else if (f & SEC_DATA)
1548 sec->filepos = data_ptr;
1549 data_ptr += sec->_raw_size;
1551 else if (f & SEC_HAS_CONTENTS)
1553 sec->filepos = other_ptr;
1554 other_ptr += sec->_raw_size;
1558 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1560 /* Move all common symbols into the .bss section. */
1562 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1563 if (sym_ptr_ptr != NULL)
1568 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1570 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1577 if (! bfd_is_com_section (bfd_get_section (sym)))
1580 /* Put the common symbol in the .bss section, and increase
1581 the size of the .bss section by the size of the common
1582 symbol (which is the old value of the symbol). */
1583 sym->section = bss_sec;
1585 sym->value = bss_sec->_raw_size + add;
1587 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1589 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1590 bss_sec->_raw_size += add;
1596 /* Set the contents of a section. To do this we need to know where
1597 the section is going to be located in the output file. That means
1598 that the sizes of all the sections must be set, and all the
1599 variable size header information must be known. */
1602 nlm_set_section_contents (abfd, section, location, offset, count)
1607 bfd_size_type count;
1609 if (abfd->output_has_begun == false
1610 && nlm_compute_section_file_positions (abfd) == false)
1616 /* i386 NetWare has a very restricted set of relocs. In order for
1617 objcopy to work, the NLM i386 backend needs a chance to rework
1618 the section contents so that its set of relocs will work. If all
1619 the relocs are already acceptable, this will not do anything. */
1620 if (section->reloc_count != 0)
1622 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1623 bfd_vma, bfd_size_type));
1625 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1626 if (mangle_relocs_func != NULL)
1628 if (! (*mangle_relocs_func) (abfd, section, location,
1629 (bfd_vma) offset, count))
1634 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1635 || bfd_write (location, 1, count, abfd) != count)
1637 bfd_error = system_call_error;
1644 /* We need to sort a list of relocs associated with sections when we
1645 write out the external relocs. */
1647 struct reloc_and_sec
1654 nlm_external_reloc_compare (p1, p2)
1658 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1659 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1661 return strcmp ((*r1->rel->sym_ptr_ptr)->name,
1662 (*r2->rel->sym_ptr_ptr)->name);
1665 /* Write out an NLM file. We write out the information in this order:
1671 other sections (custom data, messages, help, shared NLM, RPC,
1672 module dependencies)
1674 external references (imports)
1675 public symbols (exports)
1677 This is similar to the order used by the NetWare tools; the
1678 difference is that NetWare puts the sections other than code, data
1679 and custom data at the end of the NLM. It is convenient for us to
1680 know where the sections are going to be before worrying about the
1681 size of the other information.
1683 By the time this function is called, all the section data should
1684 have been output using set_section_contents. Note that custom
1685 data, the message file, the help file, the shared NLM file, the RPC
1686 data, and the module dependencies are all considered to be
1687 sections; the caller is responsible for filling in the offset and
1688 length fields in the NLM headers. The relocation fixups and
1689 imports are both obtained from the list of relocs attached to each
1690 section. The exports and debugging records are obtained from the
1691 list of outsymbols. */
1694 nlm_write_object_contents (abfd)
1697 Nlm_External_Fixed_Header fixed_header;
1699 boolean (*write_reloc_func) PARAMS ((bfd *, asection *, arelent *));
1700 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1701 struct reloc_and_sec *external_relocs;
1702 asymbol **sym_ptr_ptr;
1705 if (abfd->output_has_begun == false
1706 && nlm_compute_section_file_positions (abfd) == false)
1709 /* Write out the variable length headers. */
1710 if (bfd_seek (abfd, sizeof (Nlm_External_Fixed_Header), SEEK_SET) != 0)
1712 bfd_error = system_call_error;
1715 if (nlm_swap_variable_header_out (abfd) == false
1716 || nlm_swap_auxiliary_headers_out (abfd) == false)
1718 bfd_error = system_call_error;
1722 /* A weak check on whether the section file positions were
1724 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1726 bfd_error = invalid_operation;
1730 /* Advance to the relocs. */
1731 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1734 bfd_error = system_call_error;
1738 /* The format of the relocation entries is dependent upon the
1739 particular target. We use an external routine to write the reloc
1741 write_reloc_func = nlm_write_reloc_func (abfd);
1743 /* Write out the internal relocation fixups. While we're looping
1744 over the relocs, we also count the external relocs, which is
1745 needed when they are written out below. */
1746 internal_reloc_count = 0;
1747 external_reloc_count = 0;
1748 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1750 arelent **rel_ptr_ptr, **rel_end;
1752 if (sec->reloc_count == 0)
1755 /* We can only represent relocs within a code or data
1757 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1759 bfd_error = invalid_operation;
1763 /* We need to know how to write out relocs. */
1764 if (write_reloc_func == NULL)
1766 bfd_error = invalid_operation;
1770 rel_ptr_ptr = sec->orelocation;
1771 rel_end = rel_ptr_ptr + sec->reloc_count;
1772 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1778 sym = *rel->sym_ptr_ptr;
1780 if (bfd_get_section (sym) != &bfd_und_section)
1782 ++internal_reloc_count;
1783 if ((*write_reloc_func) (abfd, sec, rel) == false)
1787 ++external_reloc_count;
1790 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1792 /* Write out the imports (relocs against external symbols). These
1793 are output as a symbol name followed by all the relocs for that
1794 symbol, so we must first gather together all the relocs against
1795 external symbols and sort them. */
1797 (struct reloc_and_sec *) bfd_alloc (abfd,
1798 (external_reloc_count
1799 * sizeof (struct reloc_and_sec)));
1800 if (external_relocs == (struct reloc_and_sec *) NULL)
1802 bfd_error = no_memory;
1806 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1808 arelent **rel_ptr_ptr, **rel_end;
1810 if (sec->reloc_count == 0)
1813 rel_ptr_ptr = sec->orelocation;
1814 rel_end = rel_ptr_ptr + sec->reloc_count;
1815 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1821 sym = *rel->sym_ptr_ptr;
1823 if (bfd_get_section (sym) != &bfd_und_section)
1826 external_relocs[i].rel = rel;
1827 external_relocs[i].sec = sec;
1832 BFD_ASSERT (i == external_reloc_count);
1834 /* Sort the external relocs by name. */
1835 qsort (external_relocs, external_reloc_count,
1836 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1838 /* Write out the external relocs. */
1839 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1842 while (i < external_reloc_count)
1847 bfd_size_type j, cnt;
1848 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1852 rel = external_relocs[i].rel;
1853 sym = *rel->sym_ptr_ptr;
1855 len = strlen (sym->name);
1856 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1857 != sizeof (bfd_byte))
1858 || bfd_write (sym->name, len, 1, abfd) != len)
1860 bfd_error = system_call_error;
1866 (j < external_reloc_count
1867 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1871 put_word (abfd, (bfd_vma) cnt, temp);
1872 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1874 bfd_error = system_call_error;
1880 if ((*write_reloc_func) (abfd, external_relocs[i].sec,
1881 external_relocs[i].rel) == false)
1886 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1888 /* Write out the public symbols (exports). */
1889 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1890 if (sym_ptr_ptr != (asymbol **) NULL)
1894 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1896 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1897 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1902 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1906 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1907 || bfd_get_section (sym) == &bfd_und_section)
1912 len = strlen (sym->name);
1913 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1914 != sizeof (bfd_byte))
1915 || bfd_write (sym->name, len, 1, abfd) != len)
1917 bfd_error = system_call_error;
1921 offset = bfd_asymbol_value (sym);
1923 if (sec->flags & SEC_CODE)
1925 offset -= nlm_get_text_low (abfd);
1926 offset |= NLM_HIBIT;
1928 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1930 /* SEC_ALLOC is for the .bss section. */
1931 offset -= nlm_get_data_low (abfd);
1935 /* We can't handle an exported symbol that is not in the
1936 code or data segment. */
1937 bfd_error = invalid_operation;
1941 put_word (abfd, offset, temp);
1942 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1944 bfd_error = system_call_error;
1948 nlm_fixed_header (abfd)->numberOfPublics = c;
1950 /* Write out the debugging records. The NLM conversion program
1951 wants to be able to inhibit this, so as a special hack if
1952 debugInfoOffset is set to -1 we don't write any debugging
1953 information. This can not be handled by fiddling with the
1954 symbol table, because exported symbols appear in both the
1955 exported symbol list and the debugging information. */
1956 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) -1)
1958 nlm_fixed_header (abfd)->debugInfoOffset = 0;
1959 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1963 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1965 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1966 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1967 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1972 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1976 /* The NLM notion of a debugging symbol is actually what
1977 BFD calls a local or global symbol. What BFD calls a
1978 debugging symbol NLM does not understand at all. */
1979 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1980 || (sym->flags & BSF_DEBUGGING) != 0
1981 || bfd_get_section (sym) == &bfd_und_section)
1986 offset = bfd_asymbol_value (sym);
1988 if (sec->flags & SEC_CODE)
1990 offset -= nlm_get_text_low (abfd);
1993 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1995 offset -= nlm_get_data_low (abfd);
2001 /* The type is 0 for data, 1 for code, 2 for absolute. */
2002 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
2003 != sizeof (bfd_byte))
2005 bfd_error = system_call_error;
2009 put_word (abfd, offset, temp);
2010 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
2012 bfd_error = system_call_error;
2016 len = strlen (sym->name);
2017 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
2018 != sizeof (bfd_byte))
2019 || bfd_write (sym->name, len, 1, abfd) != len)
2021 bfd_error = system_call_error;
2025 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
2029 /* NLMLINK fills in offset values even if there is no data, so we do
2031 last = bfd_tell (abfd);
2032 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
2033 nlm_fixed_header (abfd)->codeImageOffset = last;
2034 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
2035 nlm_fixed_header (abfd)->dataImageOffset = last;
2036 if (nlm_fixed_header (abfd)->customDataOffset == 0)
2037 nlm_fixed_header (abfd)->customDataOffset = last;
2038 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
2039 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
2040 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
2041 nlm_fixed_header (abfd)->relocationFixupOffset = last;
2042 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
2043 nlm_fixed_header (abfd)->externalReferencesOffset = last;
2044 if (nlm_fixed_header (abfd)->publicsOffset == 0)
2045 nlm_fixed_header (abfd)->publicsOffset = last;
2046 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
2047 nlm_fixed_header (abfd)->debugInfoOffset = last;
2049 /* At this point everything has been written out except the fixed
2051 memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE,
2052 NLM_SIGNATURE_SIZE);
2053 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2054 nlm_fixed_header (abfd)->codeStartOffset =
2055 (bfd_get_start_address (abfd)
2056 - nlm_get_text_low (abfd));
2058 /* We have no convenient way for the caller to pass in the exit
2059 procedure or the check unload procedure, so the caller must set
2060 the values in the header to the values of the symbols. */
2061 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2062 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2063 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2064 nlm_get_text_low (abfd);
2066 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), &fixed_header);
2067 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2068 || (bfd_write (&fixed_header, sizeof fixed_header, 1, abfd)
2069 != sizeof fixed_header))
2071 bfd_error = system_call_error;