* hosts/alphalinux.h (TRAD_CORE_EXTRA_SIZE_ALLOWED): Expand to 4096.
[binutils.git] / bfd / nlmcode.h
blob63ac0c300f7632422d3d25e1d3969d87aec0efc6
1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright (C) 1993, 94, 95, 1998 Free Software Foundation, Inc.
4 Written by Fred Fish @ Cygnus Support, using ELF support as the
5 template.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26 #include "libnlm.h"
28 /* The functions in this file do not use the names they appear to use.
29 This file is actually compiled multiple times, once for each size
30 of NLM target we are using. At each size we use a different name,
31 constructed by the macro nlmNAME. For example, the function which
32 is named nlm_symbol_type below is actually named nlm32_symbol_type
33 in the final executable. */
35 #define Nlm_External_Fixed_Header NlmNAME(External_Fixed_Header)
36 #define Nlm_External_Version_Header NlmNAME(External_Version_Header)
37 #define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header)
38 #define Nlm_External_Extended_Header NlmNAME(External_Extended_Header)
39 #define Nlm_External_Custom_Header NlmNAME(External_Custom_Header)
40 #define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header)
42 #define nlm_symbol_type nlmNAME(symbol_type)
43 #define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
44 #define nlm_get_symtab nlmNAME(get_symtab)
45 #define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
46 #define nlm_print_symbol nlmNAME(print_symbol)
47 #define nlm_get_symbol_info nlmNAME(get_symbol_info)
48 #define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
49 #define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
50 #define nlm_object_p nlmNAME(object_p)
51 #define nlm_set_section_contents nlmNAME(set_section_contents)
52 #define nlm_write_object_contents nlmNAME(write_object_contents)
54 #define nlm_swap_fixed_header_in(abfd,src,dst) \
55 (nlm_swap_fixed_header_in_func(abfd))(abfd,src,dst)
56 #define nlm_swap_fixed_header_out(abfd,src,dst) \
57 (nlm_swap_fixed_header_out_func(abfd))(abfd,src,dst)
59 /* Forward declarations of static functions */
61 static boolean add_bfd_section
62 PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
63 static boolean nlm_swap_variable_header_in
64 PARAMS ((bfd *));
65 static boolean nlm_swap_variable_header_out
66 PARAMS ((bfd *));
67 static boolean find_nonzero
68 PARAMS ((PTR, size_t));
69 static boolean nlm_swap_auxiliary_headers_in
70 PARAMS ((bfd *));
71 static boolean nlm_swap_auxiliary_headers_out
72 PARAMS ((bfd *));
73 static boolean nlm_slurp_symbol_table
74 PARAMS ((bfd *));
75 static boolean nlm_slurp_reloc_fixups
76 PARAMS ((bfd *));
77 static boolean nlm_compute_section_file_positions
78 PARAMS ((bfd *));
79 static int nlm_external_reloc_compare
80 PARAMS ((const void *, const void *));
82 /* Should perhaps use put_offset, put_word, etc. For now, the two versions
83 can be handled by explicitly specifying 32 bits or "the long type". */
84 #if ARCH_SIZE == 64
85 #define put_word bfd_h_put_64
86 #define get_word bfd_h_get_64
87 #endif
88 #if ARCH_SIZE == 32
89 #define put_word bfd_h_put_32
90 #define get_word bfd_h_get_32
91 #endif
93 const bfd_target *
94 nlm_object_p (abfd)
95 bfd *abfd;
97 struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
98 boolean (*backend_object_p) PARAMS ((bfd *));
99 PTR x_fxdhdr = NULL;
100 Nlm_Internal_Fixed_Header *i_fxdhdrp;
101 struct nlm_obj_tdata *new_tdata = NULL;
102 const char *signature;
103 enum bfd_architecture arch;
105 /* Some NLM formats have a prefix before the standard NLM fixed
106 header. */
107 backend_object_p = nlm_backend_object_p_func (abfd);
108 if (backend_object_p)
110 if (!(*backend_object_p) (abfd))
111 goto got_wrong_format_error;
114 /* Read in the fixed length portion of the NLM header in external format. */
116 x_fxdhdr = (PTR) bfd_malloc ((size_t) nlm_fixed_header_size (abfd));
117 if (x_fxdhdr == NULL)
118 goto got_no_match;
120 if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=
121 nlm_fixed_header_size (abfd))
123 if (bfd_get_error () != bfd_error_system_call)
124 goto got_wrong_format_error;
125 else
126 goto got_no_match;
129 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
130 the tdata pointer in the bfd. */
132 new_tdata = ((struct nlm_obj_tdata *)
133 bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)));
134 if (new_tdata == NULL)
135 goto got_no_match;
137 nlm_tdata (abfd) = new_tdata;
139 i_fxdhdrp = nlm_fixed_header (abfd);
140 nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
141 free (x_fxdhdr);
142 x_fxdhdr = NULL;
144 /* Check to see if we have an NLM file for this backend by matching
145 the NLM signature. */
147 signature = nlm_signature (abfd);
148 if (signature != NULL
149 && *signature != '\0'
150 && strncmp ((char *) i_fxdhdrp->signature, signature,
151 NLM_SIGNATURE_SIZE) != 0)
152 goto got_wrong_format_error;
154 /* There's no supported way to discover the endianess of an NLM, so test for
155 a sane version number after doing byte swapping appropriate for this
156 XVEC. (Hack alert!) */
158 if (i_fxdhdrp->version > 0xFFFF)
159 goto got_wrong_format_error;
161 /* There's no supported way to check for 32 bit versus 64 bit addresses,
162 so ignore this distinction for now. (FIXME) */
164 /* Swap in the rest of the required header. */
165 if (!nlm_swap_variable_header_in (abfd))
167 if (bfd_get_error () != bfd_error_system_call)
168 goto got_wrong_format_error;
169 else
170 goto got_no_match;
173 /* Add the sections supplied by all NLM's, and then read in the
174 auxiliary headers. Reading the auxiliary headers may create
175 additional sections described in the cygnus_ext header.
176 From this point on we assume that we have an NLM, and do not
177 treat errors as indicating the wrong format. */
179 if (!add_bfd_section (abfd, NLM_CODE_NAME,
180 i_fxdhdrp->codeImageOffset,
181 i_fxdhdrp->codeImageSize,
182 (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
183 | SEC_RELOC))
184 || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
185 i_fxdhdrp->dataImageOffset,
186 i_fxdhdrp->dataImageSize,
187 (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
188 | SEC_RELOC))
189 || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
190 (file_ptr) 0,
191 i_fxdhdrp->uninitializedDataSize,
192 SEC_ALLOC))
193 goto got_no_match;
195 if (!nlm_swap_auxiliary_headers_in (abfd))
196 goto got_no_match;
198 if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
199 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
200 abfd->flags |= HAS_RELOC;
201 if (nlm_fixed_header (abfd)->numberOfPublics != 0
202 || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
203 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
204 abfd->flags |= HAS_SYMS;
206 arch = nlm_architecture (abfd);
207 if (arch != bfd_arch_unknown)
208 bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
210 abfd->flags |= EXEC_P;
211 bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
213 return (abfd->xvec);
215 got_wrong_format_error:
216 bfd_set_error (bfd_error_wrong_format);
217 got_no_match:
218 nlm_tdata (abfd) = preserved_tdata;
219 if (new_tdata != NULL)
220 bfd_release (abfd, new_tdata);
221 if (x_fxdhdr != NULL)
222 free (x_fxdhdr);
223 return (NULL);
226 /* Add a section to the bfd. */
228 static boolean
229 add_bfd_section (abfd, name, offset, size, flags)
230 bfd *abfd;
231 char *name;
232 file_ptr offset;
233 bfd_size_type size;
234 flagword flags;
236 asection *newsect;
238 newsect = bfd_make_section (abfd, name);
239 if (newsect == NULL)
241 return (false);
243 newsect->vma = 0; /* NLM's are relocatable. */
244 newsect->_raw_size = size;
245 newsect->filepos = offset;
246 newsect->flags = flags;
247 newsect->alignment_power = bfd_log2 (0); /* FIXME */
248 return (true);
251 /* Read and swap in the variable length header. All the fields must
252 exist in the NLM, and must exist in the order they are read here. */
254 static boolean
255 nlm_swap_variable_header_in (abfd)
256 bfd *abfd;
258 unsigned char temp[NLM_TARGET_LONG_SIZE];
260 /* Read the description length and text members. */
262 if (bfd_read ((PTR) & nlm_variable_header (abfd)->descriptionLength,
263 sizeof (nlm_variable_header (abfd)->descriptionLength),
264 1, abfd) !=
265 sizeof (nlm_variable_header (abfd)->descriptionLength))
266 return (false);
267 if (bfd_read ((PTR) nlm_variable_header (abfd)->descriptionText,
268 nlm_variable_header (abfd)->descriptionLength + 1,
269 1, abfd) !=
270 (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1)
271 return (false);
273 /* Read and convert the stackSize field. */
275 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
276 return (false);
277 nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
279 /* Read and convert the reserved field. */
281 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
282 return (false);
283 nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
285 /* Read the oldThreadName field. This field is a fixed length string. */
287 if (bfd_read ((PTR) nlm_variable_header (abfd)->oldThreadName,
288 sizeof (nlm_variable_header (abfd)->oldThreadName),
289 1, abfd) !=
290 sizeof (nlm_variable_header (abfd)->oldThreadName))
291 return (false);
293 /* Read the screen name length and text members. */
295 if (bfd_read ((PTR) & nlm_variable_header (abfd)->screenNameLength,
296 sizeof (nlm_variable_header (abfd)->screenNameLength),
297 1, abfd) !=
298 sizeof (nlm_variable_header (abfd)->screenNameLength))
299 return (false);
300 if (bfd_read ((PTR) nlm_variable_header (abfd)->screenName,
301 nlm_variable_header (abfd)->screenNameLength + 1,
302 1, abfd) !=
303 (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1)
304 return (false);
306 /* Read the thread name length and text members. */
308 if (bfd_read ((PTR) & nlm_variable_header (abfd)->threadNameLength,
309 sizeof (nlm_variable_header (abfd)->threadNameLength),
310 1, abfd) !=
311 sizeof (nlm_variable_header (abfd)->threadNameLength))
312 return (false);
313 if (bfd_read ((PTR) nlm_variable_header (abfd)->threadName,
314 nlm_variable_header (abfd)->threadNameLength + 1,
315 1, abfd) !=
316 (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1)
317 return (false);
318 return (true);
321 /* Swap and write out the variable length header. All the fields must
322 exist in the NLM, and must exist in this order. */
324 static boolean
325 nlm_swap_variable_header_out (abfd)
326 bfd *abfd;
328 unsigned char temp[NLM_TARGET_LONG_SIZE];
330 /* Write the description length and text members. */
332 if (bfd_write ((PTR) & nlm_variable_header (abfd)->descriptionLength,
333 sizeof (nlm_variable_header (abfd)->descriptionLength),
334 1, abfd) !=
335 sizeof (nlm_variable_header (abfd)->descriptionLength))
336 return (false);
337 if (bfd_write ((PTR) nlm_variable_header (abfd)->descriptionText,
338 nlm_variable_header (abfd)->descriptionLength + 1,
339 1, abfd) !=
340 (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1)
341 return (false);
343 /* Convert and write the stackSize field. */
345 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
346 (bfd_byte *) temp);
347 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
348 return (false);
350 /* Convert and write the reserved field. */
352 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
353 (bfd_byte *) temp);
354 if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
355 return (false);
357 /* Write the oldThreadName field. This field is a fixed length string. */
359 if (bfd_write ((PTR) nlm_variable_header (abfd)->oldThreadName,
360 sizeof (nlm_variable_header (abfd)->oldThreadName),
361 1, abfd) !=
362 sizeof (nlm_variable_header (abfd)->oldThreadName))
363 return (false);
365 /* Write the screen name length and text members. */
367 if (bfd_write ((PTR) & nlm_variable_header (abfd)->screenNameLength,
368 sizeof (nlm_variable_header (abfd)->screenNameLength),
369 1, abfd) !=
370 sizeof (nlm_variable_header (abfd)->screenNameLength))
371 return (false);
372 if (bfd_write ((PTR) nlm_variable_header (abfd)->screenName,
373 nlm_variable_header (abfd)->screenNameLength + 1,
374 1, abfd) !=
375 (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1)
376 return (false);
378 /* Write the thread name length and text members. */
380 if (bfd_write ((PTR) & nlm_variable_header (abfd)->threadNameLength,
381 sizeof (nlm_variable_header (abfd)->threadNameLength),
382 1, abfd) !=
383 sizeof (nlm_variable_header (abfd)->threadNameLength))
384 return (false);
385 if (bfd_write ((PTR) nlm_variable_header (abfd)->threadName,
386 nlm_variable_header (abfd)->threadNameLength + 1,
387 1, abfd) !=
388 (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1)
389 return (false);
390 return (true);
393 /* Read and swap in the contents of all the auxiliary headers. Because of
394 the braindead design, we have to do strcmps on strings of indeterminate
395 length to figure out what each auxiliary header is. Even worse, we have
396 no way of knowing how many auxiliary headers there are or where the end
397 of the auxiliary headers are, except by finding something that doesn't
398 look like a known auxiliary header. This means that the first new type
399 of auxiliary header added will break all existing tools that don't
400 recognize it. */
402 static boolean
403 nlm_swap_auxiliary_headers_in (abfd)
404 bfd *abfd;
406 char tempstr[16];
407 long position;
409 for (;;)
411 position = bfd_tell (abfd);
412 if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) !=
413 sizeof (tempstr))
414 return (false);
415 if (bfd_seek (abfd, position, SEEK_SET) == -1)
416 return (false);
417 if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
419 Nlm_External_Version_Header thdr;
420 if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
421 return (false);
422 memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
423 sizeof (thdr.stamp));
424 nlm_version_header (abfd)->majorVersion =
425 get_word (abfd, (bfd_byte *) thdr.majorVersion);
426 nlm_version_header (abfd)->minorVersion =
427 get_word (abfd, (bfd_byte *) thdr.minorVersion);
428 nlm_version_header (abfd)->revision =
429 get_word (abfd, (bfd_byte *) thdr.revision);
430 nlm_version_header (abfd)->year =
431 get_word (abfd, (bfd_byte *) thdr.year);
432 nlm_version_header (abfd)->month =
433 get_word (abfd, (bfd_byte *) thdr.month);
434 nlm_version_header (abfd)->day =
435 get_word (abfd, (bfd_byte *) thdr.day);
437 else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
439 Nlm_External_Extended_Header thdr;
440 if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
441 return (false);
442 memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
443 sizeof (thdr.stamp));
444 nlm_extended_header (abfd)->languageID =
445 get_word (abfd, (bfd_byte *) thdr.languageID);
446 nlm_extended_header (abfd)->messageFileOffset =
447 get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
448 nlm_extended_header (abfd)->messageFileLength =
449 get_word (abfd, (bfd_byte *) thdr.messageFileLength);
450 nlm_extended_header (abfd)->messageCount =
451 get_word (abfd, (bfd_byte *) thdr.messageCount);
452 nlm_extended_header (abfd)->helpFileOffset =
453 get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
454 nlm_extended_header (abfd)->helpFileLength =
455 get_word (abfd, (bfd_byte *) thdr.helpFileLength);
456 nlm_extended_header (abfd)->RPCDataOffset =
457 get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
458 nlm_extended_header (abfd)->RPCDataLength =
459 get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
460 nlm_extended_header (abfd)->sharedCodeOffset =
461 get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
462 nlm_extended_header (abfd)->sharedCodeLength =
463 get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
464 nlm_extended_header (abfd)->sharedDataOffset =
465 get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
466 nlm_extended_header (abfd)->sharedDataLength =
467 get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
468 nlm_extended_header (abfd)->sharedRelocationFixupOffset =
469 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
470 nlm_extended_header (abfd)->sharedRelocationFixupCount =
471 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
472 nlm_extended_header (abfd)->sharedExternalReferenceOffset =
473 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
474 nlm_extended_header (abfd)->sharedExternalReferenceCount =
475 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
476 nlm_extended_header (abfd)->sharedPublicsOffset =
477 get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
478 nlm_extended_header (abfd)->sharedPublicsCount =
479 get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
480 nlm_extended_header (abfd)->sharedDebugRecordOffset =
481 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
482 nlm_extended_header (abfd)->sharedDebugRecordCount =
483 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
484 nlm_extended_header (abfd)->SharedInitializationOffset =
485 get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
486 nlm_extended_header (abfd)->SharedExitProcedureOffset =
487 get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
488 nlm_extended_header (abfd)->productID =
489 get_word (abfd, (bfd_byte *) thdr.productID);
490 nlm_extended_header (abfd)->reserved0 =
491 get_word (abfd, (bfd_byte *) thdr.reserved0);
492 nlm_extended_header (abfd)->reserved1 =
493 get_word (abfd, (bfd_byte *) thdr.reserved1);
494 nlm_extended_header (abfd)->reserved2 =
495 get_word (abfd, (bfd_byte *) thdr.reserved2);
496 nlm_extended_header (abfd)->reserved3 =
497 get_word (abfd, (bfd_byte *) thdr.reserved3);
498 nlm_extended_header (abfd)->reserved4 =
499 get_word (abfd, (bfd_byte *) thdr.reserved4);
500 nlm_extended_header (abfd)->reserved5 =
501 get_word (abfd, (bfd_byte *) thdr.reserved5);
503 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
505 if (bfd_read ((PTR) nlm_copyright_header (abfd)->stamp,
506 sizeof (nlm_copyright_header (abfd)->stamp),
507 1, abfd)
508 != sizeof (nlm_copyright_header (abfd)->stamp))
509 return (false);
510 if (bfd_read ((PTR) & (nlm_copyright_header (abfd)
511 ->copyrightMessageLength),
512 1, 1, abfd) != 1)
513 return (false);
514 /* The copyright message is a variable length string. */
515 if (bfd_read ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
516 nlm_copyright_header (abfd)->copyrightMessageLength + 1,
517 1, abfd) !=
518 ((bfd_size_type)
519 nlm_copyright_header (abfd)->copyrightMessageLength + 1))
520 return (false);
522 else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
524 Nlm_External_Custom_Header thdr;
525 bfd_size_type hdrLength;
526 file_ptr dataOffset;
527 bfd_size_type dataLength;
528 char dataStamp[8];
529 PTR hdr;
531 /* Read the stamp ("CuStHeAd"). */
532 if (bfd_read ((PTR) thdr.stamp, 1, sizeof (thdr.stamp), abfd)
533 != sizeof (thdr.stamp))
534 return false;
535 /* Read the length of this custom header. */
536 if (bfd_read ((PTR) thdr.length, 1, sizeof (thdr.length), abfd)
537 != sizeof (thdr.length))
538 return false;
539 hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
540 /* Read further fields if we have them. */
541 if (hdrLength < NLM_TARGET_LONG_SIZE)
542 dataOffset = 0;
543 else
545 if (bfd_read ((PTR) thdr.dataOffset, 1,
546 sizeof (thdr.dataOffset), abfd)
547 != sizeof (thdr.dataOffset))
548 return false;
549 dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
551 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
552 dataLength = 0;
553 else
555 if (bfd_read ((PTR) thdr.dataLength, 1,
556 sizeof (thdr.dataLength), abfd)
557 != sizeof (thdr.dataLength))
558 return false;
559 dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
561 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
562 memset (dataStamp, 0, sizeof (dataStamp));
563 else
565 if (bfd_read ((PTR) dataStamp, 1, sizeof (dataStamp), abfd)
566 != sizeof (dataStamp))
567 return false;
570 /* Read the rest of the header, if any. */
571 if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
573 hdr = NULL;
574 hdrLength = 0;
576 else
578 hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
579 hdr = bfd_alloc (abfd, hdrLength);
580 if (hdr == NULL)
581 return false;
582 if (bfd_read (hdr, 1, hdrLength, abfd) != hdrLength)
583 return false;
586 /* If we have found a Cygnus header, process it. Otherwise,
587 just save the associated data without trying to interpret
588 it. */
589 if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
591 file_ptr pos;
592 bfd_byte *contents;
593 bfd_byte *p, *pend;
595 BFD_ASSERT (hdrLength == 0 && hdr == NULL);
597 pos = bfd_tell (abfd);
598 if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
599 return false;
600 contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
601 if (contents == NULL)
602 return false;
603 if (bfd_read (contents, 1, dataLength, abfd) != dataLength)
604 return false;
605 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
606 return false;
608 memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
609 nlm_cygnus_ext_header (abfd)->offset = dataOffset;
610 nlm_cygnus_ext_header (abfd)->length = dataLength;
612 /* This data this header points to provides a list of
613 the sections which were in the original object file
614 which was converted to become an NLM. We locate
615 those sections and add them to the BFD. Note that
616 this is likely to create a second .text, .data and
617 .bss section; retrieving the sections by name will
618 get the actual NLM sections, which is what we want to
619 happen. The sections from the original file, which
620 may be subsets of the NLM section, can only be found
621 using bfd_map_over_sections. */
622 p = contents;
623 pend = p + dataLength;
624 while (p < pend)
626 char *name;
627 size_t l;
628 file_ptr filepos;
629 bfd_size_type size;
630 asection *newsec;
632 /* The format of this information is
633 null terminated section name
634 zeroes to adjust to 4 byte boundary
635 4 byte section data file pointer
636 4 byte section size
639 name = (char *) p;
640 l = strlen (name) + 1;
641 l = (l + 3) &~ 3;
642 p += l;
643 filepos = bfd_h_get_32 (abfd, p);
644 p += 4;
645 size = bfd_h_get_32 (abfd, p);
646 p += 4;
648 newsec = bfd_make_section_anyway (abfd, name);
649 if (newsec == (asection *) NULL)
650 return false;
651 newsec->_raw_size = size;
652 if (filepos != 0)
654 newsec->filepos = filepos;
655 newsec->flags |= SEC_HAS_CONTENTS;
659 else
661 memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
662 sizeof (thdr.stamp));
663 nlm_custom_header (abfd)->hdrLength = hdrLength;
664 nlm_custom_header (abfd)->dataOffset = dataOffset;
665 nlm_custom_header (abfd)->dataLength = dataLength;
666 memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
667 sizeof (dataStamp));
668 nlm_custom_header (abfd)->hdr = hdr;
671 else
673 break;
676 return (true);
679 /* Return whether there is a non-zero byte in a memory block. */
681 static boolean
682 find_nonzero (buf, size)
683 PTR buf;
684 size_t size;
686 char *p = (char *) buf;
688 while (size-- != 0)
689 if (*p++ != 0)
690 return true;
691 return false;
694 /* Swap out the contents of the auxiliary headers. We create those
695 auxiliary headers which have been set non-zero. We do not require
696 the caller to set up the stamp fields. */
698 static boolean
699 nlm_swap_auxiliary_headers_out (abfd)
700 bfd *abfd;
702 /* Write out the version header if there is one. */
703 if (find_nonzero ((PTR) nlm_version_header (abfd),
704 sizeof (Nlm_Internal_Version_Header)))
706 Nlm_External_Version_Header thdr;
708 memcpy (thdr.stamp, "VeRsIoN#", 8);
709 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
710 (bfd_byte *) thdr.majorVersion);
711 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
712 (bfd_byte *) thdr.minorVersion);
713 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
714 (bfd_byte *) thdr.revision);
715 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
716 (bfd_byte *) thdr.year);
717 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
718 (bfd_byte *) thdr.month);
719 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
720 (bfd_byte *) thdr.day);
721 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
722 return false;
725 /* Write out the extended header if there is one. */
726 if (find_nonzero ((PTR) nlm_extended_header (abfd),
727 sizeof (Nlm_Internal_Extended_Header)))
729 Nlm_External_Extended_Header thdr;
731 memcpy (thdr.stamp, "MeSsAgEs", 8);
732 put_word (abfd,
733 (bfd_vma) nlm_extended_header (abfd)->languageID,
734 (bfd_byte *) thdr.languageID);
735 put_word (abfd,
736 (bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
737 (bfd_byte *) thdr.messageFileOffset);
738 put_word (abfd,
739 (bfd_vma) nlm_extended_header (abfd)->messageFileLength,
740 (bfd_byte *) thdr.messageFileLength);
741 put_word (abfd,
742 (bfd_vma) nlm_extended_header (abfd)->messageCount,
743 (bfd_byte *) thdr.messageCount);
744 put_word (abfd,
745 (bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
746 (bfd_byte *) thdr.helpFileOffset);
747 put_word (abfd,
748 (bfd_vma) nlm_extended_header (abfd)->helpFileLength,
749 (bfd_byte *) thdr.helpFileLength);
750 put_word (abfd,
751 (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
752 (bfd_byte *) thdr.RPCDataOffset);
753 put_word (abfd,
754 (bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
755 (bfd_byte *) thdr.RPCDataLength);
756 put_word (abfd,
757 (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
758 (bfd_byte *) thdr.sharedCodeOffset);
759 put_word (abfd,
760 (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
761 (bfd_byte *) thdr.sharedCodeLength);
762 put_word (abfd,
763 (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
764 (bfd_byte *) thdr.sharedDataOffset);
765 put_word (abfd,
766 (bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
767 (bfd_byte *) thdr.sharedDataLength);
768 put_word (abfd,
769 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
770 (bfd_byte *) thdr.sharedRelocationFixupOffset);
771 put_word (abfd,
772 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
773 (bfd_byte *) thdr.sharedRelocationFixupCount);
774 put_word (abfd,
775 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
776 (bfd_byte *) thdr.sharedExternalReferenceOffset);
777 put_word (abfd,
778 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
779 (bfd_byte *) thdr.sharedExternalReferenceCount);
780 put_word (abfd,
781 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
782 (bfd_byte *) thdr.sharedPublicsOffset);
783 put_word (abfd,
784 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
785 (bfd_byte *) thdr.sharedPublicsCount);
786 put_word (abfd,
787 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
788 (bfd_byte *) thdr.sharedDebugRecordOffset);
789 put_word (abfd,
790 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
791 (bfd_byte *) thdr.sharedDebugRecordCount);
792 put_word (abfd,
793 (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
794 (bfd_byte *) thdr.sharedInitializationOffset);
795 put_word (abfd,
796 (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
797 (bfd_byte *) thdr.SharedExitProcedureOffset);
798 put_word (abfd,
799 (bfd_vma) nlm_extended_header (abfd)->productID,
800 (bfd_byte *) thdr.productID);
801 put_word (abfd,
802 (bfd_vma) nlm_extended_header (abfd)->reserved0,
803 (bfd_byte *) thdr.reserved0);
804 put_word (abfd,
805 (bfd_vma) nlm_extended_header (abfd)->reserved1,
806 (bfd_byte *) thdr.reserved1);
807 put_word (abfd,
808 (bfd_vma) nlm_extended_header (abfd)->reserved2,
809 (bfd_byte *) thdr.reserved2);
810 put_word (abfd,
811 (bfd_vma) nlm_extended_header (abfd)->reserved3,
812 (bfd_byte *) thdr.reserved3);
813 put_word (abfd,
814 (bfd_vma) nlm_extended_header (abfd)->reserved4,
815 (bfd_byte *) thdr.reserved4);
816 put_word (abfd,
817 (bfd_vma) nlm_extended_header (abfd)->reserved5,
818 (bfd_byte *) thdr.reserved5);
819 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
820 return false;
824 /* Write out the copyright header if there is one. */
825 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
826 sizeof (Nlm_Internal_Copyright_Header)))
828 Nlm_External_Copyright_Header thdr;
830 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
831 if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd)
832 != sizeof (thdr.stamp))
833 return false;
834 thdr.copyrightMessageLength[0] =
835 nlm_copyright_header (abfd)->copyrightMessageLength;
836 if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1)
837 return false;
838 /* The copyright message is a variable length string. */
839 if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
840 nlm_copyright_header (abfd)->copyrightMessageLength + 1,
841 1, abfd) !=
842 ((bfd_size_type)
843 nlm_copyright_header (abfd)->copyrightMessageLength + 1))
844 return false;
847 /* Write out the custom header if there is one. */
848 if (find_nonzero ((PTR) nlm_custom_header (abfd),
849 sizeof (Nlm_Internal_Custom_Header)))
851 Nlm_External_Custom_Header thdr;
852 boolean ds;
853 bfd_size_type hdrLength;
855 ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
856 sizeof (nlm_custom_header (abfd)->dataStamp));
857 memcpy (thdr.stamp, "CuStHeAd", 8);
858 hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
859 + nlm_custom_header (abfd)->hdrLength);
860 put_word (abfd, hdrLength, thdr.length);
861 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
862 thdr.dataOffset);
863 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
864 thdr.dataLength);
865 if (! ds)
867 BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
868 if (bfd_write ((PTR) &thdr, 1,
869 sizeof (thdr) - sizeof (thdr.dataStamp), abfd)
870 != sizeof (thdr) - sizeof (thdr.dataStamp))
871 return false;
873 else
875 memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
876 sizeof (thdr.dataStamp));
877 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
878 return false;
879 if (bfd_write (nlm_custom_header (abfd)->hdr, 1,
880 nlm_custom_header (abfd)->hdrLength, abfd)
881 != nlm_custom_header (abfd)->hdrLength)
882 return false;
886 /* Write out the Cygnus debugging header if there is one. */
887 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
888 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
890 Nlm_External_Custom_Header thdr;
892 memcpy (thdr.stamp, "CuStHeAd", 8);
893 put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
894 (bfd_byte *) thdr.length);
895 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
896 (bfd_byte *) thdr.dataOffset);
897 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
898 (bfd_byte *) thdr.dataLength);
899 memcpy (thdr.dataStamp, "CyGnUsEx", 8);
900 if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
901 return false;
904 return true;
907 /* We read the NLM's public symbols and use it to generate a bfd symbol
908 table (hey, it's better than nothing) on a one-for-one basis. Thus
909 use the number of public symbols as the number of bfd symbols we will
910 have once we actually get around to reading them in.
912 Return the number of bytes required to hold the symtab vector, based on
913 the count plus 1, since we will NULL terminate the vector allocated based
914 on this size. */
916 long
917 nlm_get_symtab_upper_bound (abfd)
918 bfd *abfd;
920 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
921 long symcount;
922 long symtab_size = 0;
924 i_fxdhdrp = nlm_fixed_header (abfd);
925 symcount = (i_fxdhdrp->numberOfPublics
926 + i_fxdhdrp->numberOfDebugRecords
927 + i_fxdhdrp->numberOfExternalReferences);
928 symtab_size = (symcount + 1) * (sizeof (asymbol));
929 return (symtab_size);
932 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
933 symbol table fails. */
935 long
936 nlm_get_symtab (abfd, alocation)
937 bfd *abfd;
938 asymbol **alocation;
940 nlm_symbol_type *symbase;
941 bfd_size_type counter = 0;
943 if (nlm_slurp_symbol_table (abfd) == false)
944 return -1;
945 symbase = nlm_get_symbols (abfd);
946 while (counter < bfd_get_symcount (abfd))
948 *alocation++ = &symbase->symbol;
949 symbase++;
950 counter++;
952 *alocation = (asymbol *) NULL;
953 return bfd_get_symcount (abfd);
956 /* Make an NLM symbol. There is nothing special to do here. */
958 asymbol *
959 nlm_make_empty_symbol (abfd)
960 bfd *abfd;
962 nlm_symbol_type *new;
964 new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
965 if (new)
966 new->symbol.the_bfd = abfd;
967 return &new->symbol;
970 /* Get symbol information. */
972 void
973 nlm_get_symbol_info (ignore_abfd, symbol, ret)
974 bfd *ignore_abfd;
975 asymbol *symbol;
976 symbol_info *ret;
978 bfd_symbol_info (symbol, ret);
981 /* Print symbol information. */
983 void
984 nlm_print_symbol (abfd, afile, symbol, how)
985 bfd *abfd;
986 PTR afile;
987 asymbol *symbol;
988 bfd_print_symbol_type how;
990 FILE *file = (FILE *) afile;
992 switch (how)
994 case bfd_print_symbol_name:
995 case bfd_print_symbol_more:
996 if (symbol->name)
997 fprintf (file, "%s", symbol->name);
998 break;
999 case bfd_print_symbol_all:
1000 bfd_print_symbol_vandf ((PTR) file, symbol);
1001 fprintf (file, " %-5s", symbol->section->name);
1002 if (symbol->name)
1003 fprintf (file, " %s", symbol->name);
1004 break;
1008 /* Slurp in nlm symbol table.
1010 In the external (in-file) form, NLM export records are variable length,
1011 with the following form:
1013 1 byte length of the symbol name (N)
1014 N bytes the symbol name
1015 4 bytes the symbol offset from start of it's section
1017 We also read in the debugging symbols and import records. Import
1018 records are treated as undefined symbols. As we read the import
1019 records we also read in the associated reloc information, which is
1020 attached to the symbol.
1022 The bfd symbols are copied to SYMPTRS.
1024 When we return, the bfd symcount is either zero or contains the correct
1025 number of symbols.
1028 static boolean
1029 nlm_slurp_symbol_table (abfd)
1030 bfd *abfd;
1032 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
1033 bfd_size_type totsymcount; /* Number of NLM symbols */
1034 bfd_size_type symcount; /* Counter of NLM symbols */
1035 nlm_symbol_type *sym; /* Pointer to current bfd symbol */
1036 unsigned char symlength; /* Symbol length read into here */
1037 unsigned char symtype; /* Type of debugging symbol */
1038 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
1039 boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
1040 boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
1042 if (nlm_get_symbols (abfd) != NULL)
1043 return (true);
1045 /* Read each raw NLM symbol, using the information to create a canonical bfd
1046 symbol table entry.
1048 Note that we allocate the initial bfd canonical symbol buffer based on a
1049 one-to-one mapping of the NLM symbols to canonical symbols. We actually
1050 use all the NLM symbols, so there will be no space left over at the end.
1051 When we have all the symbols, we build the caller's pointer vector. */
1053 abfd->symcount = 0;
1054 i_fxdhdrp = nlm_fixed_header (abfd);
1055 totsymcount = (i_fxdhdrp->numberOfPublics
1056 + i_fxdhdrp->numberOfDebugRecords
1057 + i_fxdhdrp->numberOfExternalReferences);
1058 if (totsymcount == 0)
1060 return (true);
1063 if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1)
1064 return (false);
1066 sym = ((nlm_symbol_type *)
1067 bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
1068 if (!sym)
1069 return false;
1070 nlm_set_symbols (abfd, sym);
1072 /* We use the bfd's symcount directly as the control count, so that early
1073 termination of the loop leaves the symcount correct for the symbols that
1074 were read. */
1076 set_public_section_func = nlm_set_public_section_func (abfd);
1077 symcount = i_fxdhdrp->numberOfPublics;
1078 while (abfd->symcount < symcount)
1080 if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
1081 != sizeof (symlength))
1082 return (false);
1083 sym->symbol.the_bfd = abfd;
1084 sym->symbol.name = bfd_alloc (abfd, symlength + 1);
1085 if (!sym->symbol.name)
1086 return false;
1087 if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
1088 != symlength)
1089 return (false);
1090 /* Cast away const. */
1091 ((char *) (sym->symbol.name))[symlength] = '\0';
1092 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1093 return (false);
1094 sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1095 sym->symbol.value = get_word (abfd, temp);
1096 if (set_public_section_func)
1098 /* Most backends can use the code below, but unfortunately
1099 some use a different scheme. */
1100 if ((*set_public_section_func) (abfd, sym) == false)
1101 return false;
1103 else
1105 if (sym->symbol.value & NLM_HIBIT)
1107 sym->symbol.value &= ~NLM_HIBIT;
1108 sym->symbol.flags |= BSF_FUNCTION;
1109 sym->symbol.section =
1110 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1112 else
1114 sym->symbol.section =
1115 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1118 sym->rcnt = 0;
1119 abfd->symcount++;
1120 sym++;
1123 /* Read the debugging records. */
1125 if (i_fxdhdrp->numberOfDebugRecords > 0)
1127 if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1)
1128 return (false);
1130 symcount += i_fxdhdrp->numberOfDebugRecords;
1131 while (abfd->symcount < symcount)
1133 if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd)
1134 != sizeof (symtype))
1135 || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)
1136 || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
1137 != sizeof (symlength)))
1138 return false;
1139 sym->symbol.the_bfd = abfd;
1140 sym->symbol.name = bfd_alloc (abfd, symlength + 1);
1141 if (!sym->symbol.name)
1142 return false;
1143 if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
1144 != symlength)
1145 return (false);
1146 /* Cast away const. */
1147 ((char *) (sym->symbol.name))[symlength] = '\0';
1148 sym->symbol.flags = BSF_LOCAL;
1149 sym->symbol.value = get_word (abfd, temp);
1150 if (symtype == 0)
1152 sym->symbol.section =
1153 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1155 else if (symtype == 1)
1157 sym->symbol.flags |= BSF_FUNCTION;
1158 sym->symbol.section =
1159 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1161 else
1163 sym->symbol.section = bfd_abs_section_ptr;
1165 sym->rcnt = 0;
1166 abfd->symcount++;
1167 sym++;
1171 /* Read in the import records. We can only do this if we know how
1172 to read relocs for this target. */
1174 read_import_func = nlm_read_import_func (abfd);
1175 if (read_import_func != NULL)
1177 if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET)
1178 == -1)
1179 return (false);
1181 symcount += i_fxdhdrp->numberOfExternalReferences;
1182 while (abfd->symcount < symcount)
1184 if ((*read_import_func) (abfd, sym) == false)
1185 return false;
1186 sym++;
1187 abfd->symcount++;
1191 return (true);
1194 /* Get the relocs for an NLM file. There are two types of relocs.
1195 Imports are relocs against symbols defined in other NLM files. We
1196 treat these as relocs against global symbols. Relocation fixups
1197 are internal relocs.
1199 The actual format used to store the relocs is machine specific. */
1201 /* Read in the relocation fixup information. This is stored in
1202 nlm_relocation_fixups, an array of arelent structures, and
1203 nlm_relocation_fixup_secs, an array of section pointers. The
1204 section pointers are needed because the relocs are not sorted by
1205 section. */
1207 static boolean
1208 nlm_slurp_reloc_fixups (abfd)
1209 bfd *abfd;
1211 boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1212 arelent *));
1213 bfd_size_type count;
1214 arelent *rels;
1215 asection **secs;
1217 if (nlm_relocation_fixups (abfd) != NULL)
1218 return true;
1219 read_func = nlm_read_reloc_func (abfd);
1220 if (read_func == NULL)
1221 return true;
1223 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1224 SEEK_SET) != 0)
1225 return false;
1227 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1228 rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
1229 secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
1230 if ((rels == NULL || secs == NULL) && count != 0)
1231 return false;
1232 nlm_relocation_fixups (abfd) = rels;
1233 nlm_relocation_fixup_secs (abfd) = secs;
1235 /* We have to read piece by piece, because we don't know how large
1236 the machine specific reloc information is. */
1237 while (count-- != 0)
1239 if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
1241 nlm_relocation_fixups (abfd) = NULL;
1242 nlm_relocation_fixup_secs (abfd) = NULL;
1243 return false;
1245 ++secs;
1246 ++rels;
1249 return true;
1252 /* Get the number of relocs. This really just returns an upper bound,
1253 since it does not attempt to distinguish them based on the section.
1254 That will be handled when they are actually read. */
1256 long
1257 nlm_get_reloc_upper_bound (abfd, sec)
1258 bfd *abfd;
1259 asection *sec;
1261 nlm_symbol_type *syms;
1262 bfd_size_type count;
1263 unsigned int ret;
1265 /* If we don't know how to read relocs, just return 0. */
1266 if (nlm_read_reloc_func (abfd) == NULL)
1267 return -1;
1268 /* Make sure we have either the code or the data section. */
1269 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1270 return 0;
1272 syms = nlm_get_symbols (abfd);
1273 if (syms == NULL)
1275 if (nlm_slurp_symbol_table (abfd) == false)
1276 return -1;
1277 syms = nlm_get_symbols (abfd);
1280 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1282 count = bfd_get_symcount (abfd);
1283 while (count-- != 0)
1285 ret += syms->rcnt;
1286 ++syms;
1289 return (ret + 1) * sizeof (arelent *);
1292 /* Get the relocs themselves. */
1294 long
1295 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1296 bfd *abfd;
1297 asection *sec;
1298 arelent **relptr;
1299 asymbol **symbols;
1301 arelent *rels;
1302 asection **secs;
1303 bfd_size_type count, i;
1304 unsigned int ret;
1306 /* Get the relocation fixups. */
1307 rels = nlm_relocation_fixups (abfd);
1308 if (rels == NULL)
1310 if (nlm_slurp_reloc_fixups (abfd) == false)
1311 return -1;
1312 rels = nlm_relocation_fixups (abfd);
1314 secs = nlm_relocation_fixup_secs (abfd);
1316 ret = 0;
1317 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1318 for (i = 0; i < count; i++, rels++, secs++)
1320 if (*secs == sec)
1322 *relptr++ = rels;
1323 ++ret;
1327 /* Get the import symbols. */
1328 count = bfd_get_symcount (abfd);
1329 for (i = 0; i < count; i++, symbols++)
1331 asymbol *sym;
1333 sym = *symbols;
1334 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1336 nlm_symbol_type *nlm_sym;
1337 bfd_size_type j;
1339 nlm_sym = (nlm_symbol_type *) sym;
1340 for (j = 0; j < nlm_sym->rcnt; j++)
1342 if (nlm_sym->relocs[j].section == sec)
1344 *relptr = &nlm_sym->relocs[j].reloc;
1345 (*relptr)->sym_ptr_ptr = symbols;
1346 ++relptr;
1347 ++ret;
1353 *relptr = NULL;
1355 return ret;
1358 /* Compute the section file positions for an NLM file. All variable
1359 length data in the file headers must be set before this function is
1360 called. If the variable length data is changed later, the
1361 resulting object file will be incorrect. Unfortunately, there is
1362 no way to check this.
1364 This routine also sets the Size and Offset fields in the fixed
1365 header.
1367 It also looks over the symbols and moves any common symbols into
1368 the .bss section; NLM has no way to represent a common symbol.
1369 This approach means that either the symbols must already have been
1370 set at this point, or there must be no common symbols. We need to
1371 move the symbols at this point so that mangle_relocs can see the
1372 final values. */
1374 static boolean
1375 nlm_compute_section_file_positions (abfd)
1376 bfd *abfd;
1378 file_ptr sofar;
1379 asection *sec;
1380 bfd_vma text, data, bss;
1381 bfd_vma text_low, data_low;
1382 unsigned int text_align, data_align, other_align;
1383 file_ptr text_ptr, data_ptr, other_ptr;
1384 asection *bss_sec;
1385 asymbol **sym_ptr_ptr;
1387 if (abfd->output_has_begun == true)
1388 return true;
1390 /* Make sure we have a section to hold uninitialized data. */
1391 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1392 if (bss_sec == NULL)
1394 if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1395 (file_ptr) 0, (bfd_size_type) 0,
1396 SEC_ALLOC))
1397 return false;
1398 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1401 abfd->output_has_begun = true;
1403 /* The fixed header. */
1404 sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1406 /* The variable header. */
1407 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1408 + nlm_variable_header (abfd)->descriptionLength + 1
1409 + NLM_TARGET_LONG_SIZE /* stackSize */
1410 + NLM_TARGET_LONG_SIZE /* reserved */
1411 + sizeof (nlm_variable_header (abfd)->oldThreadName)
1412 + sizeof (nlm_variable_header (abfd)->screenNameLength)
1413 + nlm_variable_header (abfd)->screenNameLength + 1
1414 + sizeof (nlm_variable_header (abfd)->threadNameLength)
1415 + nlm_variable_header (abfd)->threadNameLength + 1);
1417 /* The auxiliary headers. */
1418 if (find_nonzero ((PTR) nlm_version_header (abfd),
1419 sizeof (Nlm_Internal_Version_Header)))
1420 sofar += sizeof (Nlm_External_Version_Header);
1421 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1422 sizeof (Nlm_Internal_Extended_Header)))
1423 sofar += sizeof (Nlm_External_Extended_Header);
1424 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1425 sizeof (Nlm_Internal_Copyright_Header)))
1426 sofar += (sizeof (Nlm_External_Copyright_Header)
1427 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1428 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1429 sizeof (Nlm_Internal_Custom_Header)))
1430 sofar += (sizeof (Nlm_External_Custom_Header)
1431 + nlm_custom_header (abfd)->hdrLength);
1432 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
1433 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
1434 sofar += sizeof (Nlm_External_Custom_Header);
1436 /* Compute the section file positions in two passes. First get the
1437 sizes of the text and data sections, and then set the file
1438 positions. This code aligns the sections in the file using the
1439 same alignment restrictions that apply to the sections in memory;
1440 this may not be necessary. */
1441 text = 0;
1442 text_low = (bfd_vma) - 1;
1443 text_align = 0;
1444 data = 0;
1445 data_low = (bfd_vma) - 1;
1446 data_align = 0;
1447 bss = 0;
1448 other_align = 0;
1449 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1451 flagword f;
1453 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1455 f = bfd_get_section_flags (abfd, sec);
1456 if (f & SEC_CODE)
1458 text += sec->_raw_size;
1459 if (bfd_get_section_vma (abfd, sec) < text_low)
1460 text_low = bfd_get_section_vma (abfd, sec);
1461 if (sec->alignment_power > text_align)
1462 text_align = sec->alignment_power;
1464 else if (f & SEC_DATA)
1466 data += sec->_raw_size;
1467 if (bfd_get_section_vma (abfd, sec) < data_low)
1468 data_low = bfd_get_section_vma (abfd, sec);
1469 if (sec->alignment_power > data_align)
1470 data_align = sec->alignment_power;
1472 else if (f & SEC_HAS_CONTENTS)
1474 if (sec->alignment_power > other_align)
1475 other_align = sec->alignment_power;
1477 else if (f & SEC_ALLOC)
1478 bss += sec->_raw_size;
1481 nlm_set_text_low (abfd, text_low);
1482 nlm_set_data_low (abfd, data_low);
1484 if (nlm_no_uninitialized_data (abfd))
1486 /* This NetWare format does not use uninitialized data. We must
1487 increase the size of the data section. We will never wind up
1488 writing those file locations, so they will remain zero. */
1489 data += bss;
1490 bss = 0;
1493 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1494 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1495 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1497 /* Fill in some fields in the header for which we now have the
1498 information. */
1499 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1500 nlm_fixed_header (abfd)->codeImageSize = text;
1501 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1502 nlm_fixed_header (abfd)->dataImageSize = data;
1503 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1505 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1507 flagword f;
1509 f = bfd_get_section_flags (abfd, sec);
1511 if (f & SEC_CODE)
1513 sec->filepos = text_ptr;
1514 text_ptr += sec->_raw_size;
1516 else if (f & SEC_DATA)
1518 sec->filepos = data_ptr;
1519 data_ptr += sec->_raw_size;
1521 else if (f & SEC_HAS_CONTENTS)
1523 sec->filepos = other_ptr;
1524 other_ptr += sec->_raw_size;
1528 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1530 /* Move all common symbols into the .bss section. */
1532 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1533 if (sym_ptr_ptr != NULL)
1535 asymbol **sym_end;
1536 bfd_vma add;
1538 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1539 add = 0;
1540 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1542 asymbol *sym;
1543 bfd_vma size;
1545 sym = *sym_ptr_ptr;
1547 if (!bfd_is_com_section (bfd_get_section (sym)))
1548 continue;
1550 /* Put the common symbol in the .bss section, and increase
1551 the size of the .bss section by the size of the common
1552 symbol (which is the old value of the symbol). */
1553 sym->section = bss_sec;
1554 size = sym->value;
1555 sym->value = bss_sec->_raw_size + add;
1556 add += size;
1557 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1559 if (add != 0)
1561 if (nlm_no_uninitialized_data (abfd))
1563 /* We could handle this case, but so far it hasn't been
1564 necessary. */
1565 abort ();
1567 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1568 bss_sec->_raw_size += add;
1572 return true;
1575 /* Set the contents of a section. To do this we need to know where
1576 the section is going to be located in the output file. That means
1577 that the sizes of all the sections must be set, and all the
1578 variable size header information must be known. */
1580 boolean
1581 nlm_set_section_contents (abfd, section, location, offset, count)
1582 bfd *abfd;
1583 asection *section;
1584 PTR location;
1585 file_ptr offset;
1586 bfd_size_type count;
1588 if (abfd->output_has_begun == false
1589 && nlm_compute_section_file_positions (abfd) == false)
1590 return false;
1592 if (count == 0)
1593 return true;
1595 /* i386 NetWare has a very restricted set of relocs. In order for
1596 objcopy to work, the NLM i386 backend needs a chance to rework
1597 the section contents so that its set of relocs will work. If all
1598 the relocs are already acceptable, this will not do anything. */
1599 if (section->reloc_count != 0)
1601 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1602 bfd_vma, bfd_size_type));
1604 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1605 if (mangle_relocs_func != NULL)
1607 if (!(*mangle_relocs_func) (abfd, section, location,
1608 (bfd_vma) offset, count))
1609 return false;
1613 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1614 || bfd_write (location, 1, count, abfd) != count)
1615 return false;
1617 return true;
1620 /* We need to sort a list of relocs associated with sections when we
1621 write out the external relocs. */
1623 static int
1624 nlm_external_reloc_compare (p1, p2)
1625 const void *p1;
1626 const void *p2;
1628 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1629 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1630 int cmp;
1632 cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1633 (*r2->rel->sym_ptr_ptr)->name);
1634 if (cmp != 0)
1635 return cmp;
1637 /* We sort by address within symbol to make the sort more stable and
1638 increase the chances that different hosts will generate bit for
1639 bit equivalent results. */
1640 return (int) (r1->rel->address - r2->rel->address);
1643 /* Write out an NLM file. We write out the information in this order:
1644 fixed header
1645 variable header
1646 auxiliary headers
1647 code sections
1648 data sections
1649 other sections (custom data, messages, help, shared NLM, RPC,
1650 module dependencies)
1651 relocation fixups
1652 external references (imports)
1653 public symbols (exports)
1654 debugging records
1655 This is similar to the order used by the NetWare tools; the
1656 difference is that NetWare puts the sections other than code, data
1657 and custom data at the end of the NLM. It is convenient for us to
1658 know where the sections are going to be before worrying about the
1659 size of the other information.
1661 By the time this function is called, all the section data should
1662 have been output using set_section_contents. Note that custom
1663 data, the message file, the help file, the shared NLM file, the RPC
1664 data, and the module dependencies are all considered to be
1665 sections; the caller is responsible for filling in the offset and
1666 length fields in the NLM headers. The relocation fixups and
1667 imports are both obtained from the list of relocs attached to each
1668 section. The exports and debugging records are obtained from the
1669 list of outsymbols. */
1671 boolean
1672 nlm_write_object_contents (abfd)
1673 bfd *abfd;
1675 asection *sec;
1676 boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1677 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1678 struct reloc_and_sec *external_relocs;
1679 asymbol **sym_ptr_ptr;
1680 file_ptr last;
1681 boolean (*write_prefix_func) PARAMS ((bfd *));
1682 unsigned char *fixed_header = NULL;
1684 fixed_header = ((unsigned char *)
1685 bfd_malloc ((size_t) nlm_fixed_header_size (abfd)));
1686 if (fixed_header == NULL)
1687 goto error_return;
1689 if (abfd->output_has_begun == false
1690 && nlm_compute_section_file_positions (abfd) == false)
1691 goto error_return;
1693 /* Write out the variable length headers. */
1694 if (bfd_seek (abfd,
1695 nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
1696 SEEK_SET) != 0)
1697 goto error_return;
1698 if (nlm_swap_variable_header_out (abfd) == false
1699 || nlm_swap_auxiliary_headers_out (abfd) == false)
1701 bfd_set_error (bfd_error_system_call);
1702 goto error_return;
1705 /* A weak check on whether the section file positions were
1706 reasonable. */
1707 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1709 bfd_set_error (bfd_error_invalid_operation);
1710 goto error_return;
1713 /* Advance to the relocs. */
1714 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1715 SEEK_SET) != 0)
1716 goto error_return;
1718 /* The format of the relocation entries is dependent upon the
1719 particular target. We use an external routine to write the reloc
1720 out. */
1721 write_import_func = nlm_write_import_func (abfd);
1723 /* Write out the internal relocation fixups. While we're looping
1724 over the relocs, we also count the external relocs, which is
1725 needed when they are written out below. */
1726 internal_reloc_count = 0;
1727 external_reloc_count = 0;
1728 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1730 arelent **rel_ptr_ptr, **rel_end;
1732 if (sec->reloc_count == 0)
1733 continue;
1735 /* We can only represent relocs within a code or data
1736 section. We ignore them for a debugging section. */
1737 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1738 continue;
1740 /* We need to know how to write out imports */
1741 if (write_import_func == NULL)
1743 bfd_set_error (bfd_error_invalid_operation);
1744 goto error_return;
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++)
1751 arelent *rel;
1752 asymbol *sym;
1754 rel = *rel_ptr_ptr;
1755 sym = *rel->sym_ptr_ptr;
1757 if (! bfd_is_und_section (bfd_get_section (sym)))
1759 ++internal_reloc_count;
1760 if ((*write_import_func) (abfd, sec, rel) == false)
1761 goto error_return;
1763 else
1764 ++external_reloc_count;
1767 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1769 /* Write out the imports (relocs against external symbols). These
1770 are output as a symbol name followed by all the relocs for that
1771 symbol, so we must first gather together all the relocs against
1772 external symbols and sort them. */
1773 external_relocs =
1774 (struct reloc_and_sec *) bfd_alloc (abfd,
1775 (external_reloc_count
1776 * sizeof (struct reloc_and_sec)));
1777 if (external_relocs == (struct reloc_and_sec *) NULL)
1778 goto error_return;
1779 i = 0;
1780 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1782 arelent **rel_ptr_ptr, **rel_end;
1784 if (sec->reloc_count == 0)
1785 continue;
1787 rel_ptr_ptr = sec->orelocation;
1788 rel_end = rel_ptr_ptr + sec->reloc_count;
1789 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1791 arelent *rel;
1792 asymbol *sym;
1794 rel = *rel_ptr_ptr;
1795 sym = *rel->sym_ptr_ptr;
1797 if (! bfd_is_und_section (bfd_get_section (sym)))
1798 continue;
1800 external_relocs[i].rel = rel;
1801 external_relocs[i].sec = sec;
1802 ++i;
1806 BFD_ASSERT (i == external_reloc_count);
1808 /* Sort the external relocs by name. */
1809 qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1810 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1812 /* Write out the external relocs. */
1813 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1814 c = 0;
1815 i = 0;
1816 while (i < external_reloc_count)
1818 arelent *rel;
1819 asymbol *sym;
1820 bfd_size_type j, cnt;
1822 ++c;
1824 rel = external_relocs[i].rel;
1825 sym = *rel->sym_ptr_ptr;
1827 cnt = 0;
1828 for (j = i;
1829 (j < external_reloc_count
1830 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1831 j++)
1832 ++cnt;
1834 if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1835 &external_relocs[i])
1836 == false)
1837 goto error_return;
1839 i += cnt;
1842 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1844 /* Write out the public symbols (exports). */
1845 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1846 if (sym_ptr_ptr != (asymbol **) NULL)
1848 bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1849 boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1851 asymbol **sym_end;
1853 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1854 get_public_offset_func = nlm_get_public_offset_func (abfd);
1855 write_export_func = nlm_write_export_func (abfd);
1856 c = 0;
1857 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1858 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1860 asymbol *sym;
1861 bfd_byte len;
1862 bfd_vma offset;
1863 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1865 sym = *sym_ptr_ptr;
1867 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1868 || bfd_is_und_section (bfd_get_section (sym)))
1869 continue;
1871 ++c;
1873 if (get_public_offset_func)
1875 /* Most backends can use the code below, but
1876 unfortunately some use a different scheme. */
1877 offset = (*get_public_offset_func) (abfd, sym);
1879 else
1881 offset = bfd_asymbol_value (sym);
1882 sec = sym->section;
1883 if (sec->flags & SEC_CODE)
1885 offset -= nlm_get_text_low (abfd);
1886 offset |= NLM_HIBIT;
1888 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1890 /* SEC_ALLOC is for the .bss section. */
1891 offset -= nlm_get_data_low (abfd);
1893 else
1895 /* We can't handle an exported symbol that is not in
1896 the code or data segment. */
1897 bfd_set_error (bfd_error_invalid_operation);
1898 goto error_return;
1902 if (write_export_func)
1904 if ((*write_export_func) (abfd, sym, offset) == false)
1905 goto error_return;
1907 else
1909 len = strlen (sym->name);
1910 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1911 != sizeof (bfd_byte))
1912 || bfd_write (sym->name, len, 1, abfd) != len)
1913 goto error_return;
1915 put_word (abfd, offset, temp);
1916 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1917 goto error_return;
1920 nlm_fixed_header (abfd)->numberOfPublics = c;
1922 /* Write out the debugging records. The NLM conversion program
1923 wants to be able to inhibit this, so as a special hack if
1924 debugInfoOffset is set to -1 we don't write any debugging
1925 information. This can not be handled by fiddling with the
1926 symbol table, because exported symbols appear in both the
1927 exported symbol list and the debugging information. */
1928 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1930 nlm_fixed_header (abfd)->debugInfoOffset = 0;
1931 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1933 else
1935 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1936 c = 0;
1937 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1938 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1939 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1941 asymbol *sym;
1942 bfd_byte type, len;
1943 bfd_vma offset;
1944 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1946 sym = *sym_ptr_ptr;
1948 /* The NLM notion of a debugging symbol is actually what
1949 BFD calls a local or global symbol. What BFD calls a
1950 debugging symbol NLM does not understand at all. */
1951 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1952 || (sym->flags & BSF_DEBUGGING) != 0
1953 || bfd_is_und_section (bfd_get_section (sym)))
1954 continue;
1956 ++c;
1958 offset = bfd_asymbol_value (sym);
1959 sec = sym->section;
1960 if (sec->flags & SEC_CODE)
1962 offset -= nlm_get_text_low (abfd);
1963 type = 1;
1965 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1967 /* SEC_ALLOC is for the .bss section. */
1968 offset -= nlm_get_data_low (abfd);
1969 type = 0;
1971 else
1972 type = 2;
1974 /* The type is 0 for data, 1 for code, 2 for absolute. */
1975 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1976 != sizeof (bfd_byte))
1977 goto error_return;
1979 put_word (abfd, offset, temp);
1980 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1981 goto error_return;
1983 len = strlen (sym->name);
1984 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1985 != sizeof (bfd_byte))
1986 || bfd_write (sym->name, len, 1, abfd) != len)
1987 goto error_return;
1989 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1993 /* NLMLINK fills in offset values even if there is no data, so we do
1994 the same. */
1995 last = bfd_tell (abfd);
1996 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1997 nlm_fixed_header (abfd)->codeImageOffset = last;
1998 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
1999 nlm_fixed_header (abfd)->dataImageOffset = last;
2000 if (nlm_fixed_header (abfd)->customDataOffset == 0)
2001 nlm_fixed_header (abfd)->customDataOffset = last;
2002 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
2003 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
2004 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
2005 nlm_fixed_header (abfd)->relocationFixupOffset = last;
2006 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
2007 nlm_fixed_header (abfd)->externalReferencesOffset = last;
2008 if (nlm_fixed_header (abfd)->publicsOffset == 0)
2009 nlm_fixed_header (abfd)->publicsOffset = last;
2010 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
2011 nlm_fixed_header (abfd)->debugInfoOffset = last;
2013 /* At this point everything has been written out except the fixed
2014 header. */
2015 memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
2016 NLM_SIGNATURE_SIZE);
2017 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2018 nlm_fixed_header (abfd)->codeStartOffset =
2019 (bfd_get_start_address (abfd)
2020 - nlm_get_text_low (abfd));
2022 /* We have no convenient way for the caller to pass in the exit
2023 procedure or the check unload procedure, so the caller must set
2024 the values in the header to the values of the symbols. */
2025 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2026 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2027 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2028 nlm_get_text_low (abfd);
2030 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
2031 goto error_return;
2033 write_prefix_func = nlm_write_prefix_func (abfd);
2034 if (write_prefix_func)
2036 if ((*write_prefix_func) (abfd) == false)
2037 goto error_return;
2040 BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
2041 == nlm_optional_prefix_size (abfd));
2043 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
2044 if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
2045 != nlm_fixed_header_size (abfd))
2046 goto error_return;
2048 if (fixed_header != NULL)
2049 free (fixed_header);
2050 return true;
2052 error_return:
2053 if (fixed_header != NULL)
2054 free (fixed_header);
2055 return false;