merge from gcc
[binutils.git] / bfd / nlmcode.h
blob68e4a2a8723efff8a4a0929d91c3c3a7df278ac6
1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright 1993, 1994, 1995, 1998, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
5 Written by Fred Fish @ Cygnus Support, using ELF support as the
6 template.
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "libbfd.h"
27 #include "libnlm.h"
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)
41 #define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header)
43 #define nlm_symbol_type nlmNAME(symbol_type)
44 #define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
45 #define nlm_canonicalize_symtab nlmNAME(canonicalize_symtab)
46 #define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
47 #define nlm_print_symbol nlmNAME(print_symbol)
48 #define nlm_get_symbol_info nlmNAME(get_symbol_info)
49 #define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
50 #define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
51 #define nlm_object_p nlmNAME(object_p)
52 #define nlm_set_section_contents nlmNAME(set_section_contents)
53 #define nlm_write_object_contents nlmNAME(write_object_contents)
55 #define nlm_swap_fixed_header_in(abfd,src,dst) \
56 (nlm_swap_fixed_header_in_func(abfd)) (abfd,src,dst)
57 #define nlm_swap_fixed_header_out(abfd,src,dst) \
58 (nlm_swap_fixed_header_out_func(abfd)) (abfd,src,dst)
60 /* Forward declarations of static functions. */
62 static bfd_boolean add_bfd_section
63 PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
64 static bfd_boolean nlm_swap_variable_header_in
65 PARAMS ((bfd *));
66 static bfd_boolean nlm_swap_variable_header_out
67 PARAMS ((bfd *));
68 static bfd_boolean find_nonzero
69 PARAMS ((PTR, size_t));
70 static bfd_boolean nlm_swap_auxiliary_headers_in
71 PARAMS ((bfd *));
72 static bfd_boolean nlm_swap_auxiliary_headers_out
73 PARAMS ((bfd *));
74 static bfd_boolean nlm_slurp_symbol_table
75 PARAMS ((bfd *));
76 static bfd_boolean nlm_slurp_reloc_fixups
77 PARAMS ((bfd *));
78 static bfd_boolean nlm_compute_section_file_positions
79 PARAMS ((bfd *));
80 static int nlm_external_reloc_compare
81 PARAMS ((const void *, const void *));
83 /* Should perhaps use put_offset, put_word, etc. For now, the two versions
84 can be handled by explicitly specifying 32 bits or "the long type". */
85 #if ARCH_SIZE == 64
86 #define put_word H_PUT_64
87 #define get_word H_GET_64
88 #endif
89 #if ARCH_SIZE == 32
90 #define put_word H_PUT_32
91 #define get_word H_GET_32
92 #endif
94 const bfd_target *
95 nlm_object_p (abfd)
96 bfd *abfd;
98 struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
99 bfd_boolean (*backend_object_p) PARAMS ((bfd *));
100 PTR x_fxdhdr = NULL;
101 Nlm_Internal_Fixed_Header *i_fxdhdrp;
102 struct nlm_obj_tdata *new_tdata = NULL;
103 const char *signature;
104 enum bfd_architecture arch;
105 bfd_size_type amt;
107 /* Some NLM formats have a prefix before the standard NLM fixed
108 header. */
109 backend_object_p = nlm_backend_object_p_func (abfd);
110 if (backend_object_p)
112 if (!(*backend_object_p) (abfd))
113 goto got_wrong_format_error;
116 /* Read in the fixed length portion of the NLM header in external format. */
117 amt = nlm_fixed_header_size (abfd);
118 x_fxdhdr = (PTR) bfd_malloc (amt);
119 if (x_fxdhdr == NULL)
120 goto got_no_match;
122 if (bfd_bread ((PTR) x_fxdhdr, amt, abfd) != amt)
124 if (bfd_get_error () != bfd_error_system_call)
125 goto got_wrong_format_error;
126 else
127 goto got_no_match;
130 /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
131 the tdata pointer in the bfd. */
132 amt = sizeof (struct nlm_obj_tdata);
133 new_tdata = (struct nlm_obj_tdata *) bfd_zalloc (abfd, amt);
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. */
146 signature = nlm_signature (abfd);
147 if (signature != NULL
148 && *signature != '\0'
149 && strncmp ((char *) i_fxdhdrp->signature, signature,
150 NLM_SIGNATURE_SIZE) != 0)
151 goto got_wrong_format_error;
153 /* There's no supported way to discover the endianess of an NLM, so test for
154 a sane version number after doing byte swapping appropriate for this
155 XVEC. (Hack alert!) */
156 if (i_fxdhdrp->version > 0xFFFF)
157 goto got_wrong_format_error;
159 /* There's no supported way to check for 32 bit versus 64 bit addresses,
160 so ignore this distinction for now. (FIXME) */
161 /* Swap in the rest of the required header. */
162 if (!nlm_swap_variable_header_in (abfd))
164 if (bfd_get_error () != bfd_error_system_call)
165 goto got_wrong_format_error;
166 else
167 goto got_no_match;
170 /* Add the sections supplied by all NLM's, and then read in the
171 auxiliary headers. Reading the auxiliary headers may create
172 additional sections described in the cygnus_ext header.
173 From this point on we assume that we have an NLM, and do not
174 treat errors as indicating the wrong format. */
175 if (!add_bfd_section (abfd, NLM_CODE_NAME,
176 i_fxdhdrp->codeImageOffset,
177 i_fxdhdrp->codeImageSize,
178 (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
179 | SEC_RELOC))
180 || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
181 i_fxdhdrp->dataImageOffset,
182 i_fxdhdrp->dataImageSize,
183 (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
184 | SEC_RELOC))
185 || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
186 (file_ptr) 0,
187 i_fxdhdrp->uninitializedDataSize,
188 SEC_ALLOC))
189 goto got_no_match;
191 if (!nlm_swap_auxiliary_headers_in (abfd))
192 goto got_no_match;
194 if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
195 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
196 abfd->flags |= HAS_RELOC;
197 if (nlm_fixed_header (abfd)->numberOfPublics != 0
198 || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
199 || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
200 abfd->flags |= HAS_SYMS;
202 arch = nlm_architecture (abfd);
203 if (arch != bfd_arch_unknown)
204 bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
206 abfd->flags |= EXEC_P;
207 bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
209 return (abfd->xvec);
211 got_wrong_format_error:
212 bfd_set_error (bfd_error_wrong_format);
213 got_no_match:
214 nlm_tdata (abfd) = preserved_tdata;
215 if (new_tdata != NULL)
216 bfd_release (abfd, new_tdata);
217 if (x_fxdhdr != NULL)
218 free (x_fxdhdr);
219 return (NULL);
222 /* Add a section to the bfd. */
224 static bfd_boolean
225 add_bfd_section (abfd, name, offset, size, flags)
226 bfd *abfd;
227 char *name;
228 file_ptr offset;
229 bfd_size_type size;
230 flagword flags;
232 asection *newsect;
234 newsect = bfd_make_section (abfd, name);
235 if (newsect == NULL)
236 return FALSE;
238 newsect->vma = 0; /* NLM's are relocatable. */
239 newsect->_raw_size = size;
240 newsect->filepos = offset;
241 newsect->flags = flags;
242 newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */
244 return TRUE;
247 /* Read and swap in the variable length header. All the fields must
248 exist in the NLM, and must exist in the order they are read here. */
250 static bfd_boolean
251 nlm_swap_variable_header_in (abfd)
252 bfd *abfd;
254 unsigned char temp[NLM_TARGET_LONG_SIZE];
255 bfd_size_type amt;
257 /* Read the description length and text members. */
259 amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
260 if (bfd_bread ((PTR) &nlm_variable_header (abfd)->descriptionLength,
261 amt, abfd) != amt)
262 return FALSE;
263 amt = nlm_variable_header (abfd)->descriptionLength + 1;
264 if (bfd_bread ((PTR) nlm_variable_header (abfd)->descriptionText,
265 amt, abfd) != amt)
266 return FALSE;
268 /* Read and convert the stackSize field. */
270 amt = sizeof (temp);
271 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
272 return FALSE;
273 nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
275 /* Read and convert the reserved field. */
277 amt = sizeof (temp);
278 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
279 return FALSE;
280 nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
282 /* Read the oldThreadName field. This field is a fixed length string. */
284 amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
285 if (bfd_bread ((PTR) nlm_variable_header (abfd)->oldThreadName,
286 amt, abfd) != amt)
287 return FALSE;
289 /* Read the screen name length and text members. */
291 amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
292 if (bfd_bread ((PTR) & nlm_variable_header (abfd)->screenNameLength,
293 amt, abfd) != amt)
294 return FALSE;
295 amt = nlm_variable_header (abfd)->screenNameLength + 1;
296 if (bfd_bread ((PTR) nlm_variable_header (abfd)->screenName,
297 amt, abfd) != amt)
298 return FALSE;
300 /* Read the thread name length and text members. */
302 amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
303 if (bfd_bread ((PTR) & nlm_variable_header (abfd)->threadNameLength,
304 amt, abfd) != amt)
305 return FALSE;
306 amt = nlm_variable_header (abfd)->threadNameLength + 1;
307 if (bfd_bread ((PTR) nlm_variable_header (abfd)->threadName,
308 amt, abfd) != amt)
309 return FALSE;
310 return TRUE;
313 /* Swap and write out the variable length header. All the fields must
314 exist in the NLM, and must exist in this order. */
316 static bfd_boolean
317 nlm_swap_variable_header_out (abfd)
318 bfd *abfd;
320 unsigned char temp[NLM_TARGET_LONG_SIZE];
321 bfd_size_type amt;
323 /* Write the description length and text members. */
324 amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
325 if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->descriptionLength, amt,
326 abfd) != amt)
327 return FALSE;
328 amt = nlm_variable_header (abfd)->descriptionLength + 1;
329 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->descriptionText, amt,
330 abfd) != amt)
331 return FALSE;
333 /* Convert and write the stackSize field. */
334 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
335 (bfd_byte *) temp);
336 amt = sizeof (temp);
337 if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
338 return FALSE;
340 /* Convert and write the reserved field. */
341 put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
342 (bfd_byte *) temp);
343 amt = sizeof (temp);
344 if (bfd_bwrite ((PTR) temp, amt, abfd) != amt)
345 return FALSE;
347 /* Write the oldThreadName field. This field is a fixed length string. */
348 amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
349 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->oldThreadName, amt,
350 abfd) != amt)
351 return FALSE;
353 /* Write the screen name length and text members. */
354 amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
355 if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->screenNameLength, amt,
356 abfd) != amt)
357 return FALSE;
358 amt = nlm_variable_header (abfd)->screenNameLength + 1;
359 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->screenName, amt,
360 abfd) != amt)
361 return FALSE;
363 /* Write the thread name length and text members. */
364 amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
365 if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->threadNameLength, amt,
366 abfd) != amt)
367 return FALSE;
368 amt = nlm_variable_header (abfd)->threadNameLength + 1;
369 if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->threadName, amt,
370 abfd) != amt)
371 return FALSE;
372 return TRUE;
375 /* Read and swap in the contents of all the auxiliary headers. Because of
376 the braindead design, we have to do strcmps on strings of indeterminate
377 length to figure out what each auxiliary header is. Even worse, we have
378 no way of knowing how many auxiliary headers there are or where the end
379 of the auxiliary headers are, except by finding something that doesn't
380 look like a known auxiliary header. This means that the first new type
381 of auxiliary header added will break all existing tools that don't
382 recognize it. */
384 static bfd_boolean
385 nlm_swap_auxiliary_headers_in (abfd)
386 bfd *abfd;
388 char tempstr[16];
389 file_ptr position;
390 bfd_size_type amt;
392 for (;;)
394 position = bfd_tell (abfd);
395 amt = sizeof (tempstr);
396 if (bfd_bread ((PTR) tempstr, amt, abfd) != amt)
397 return FALSE;
398 if (bfd_seek (abfd, position, SEEK_SET) != 0)
399 return FALSE;
400 if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
402 Nlm_External_Version_Header thdr;
404 amt = sizeof (thdr);
405 if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
406 return FALSE;
407 memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
408 sizeof (thdr.stamp));
409 nlm_version_header (abfd)->majorVersion =
410 get_word (abfd, (bfd_byte *) thdr.majorVersion);
411 nlm_version_header (abfd)->minorVersion =
412 get_word (abfd, (bfd_byte *) thdr.minorVersion);
413 nlm_version_header (abfd)->revision =
414 get_word (abfd, (bfd_byte *) thdr.revision);
415 nlm_version_header (abfd)->year =
416 get_word (abfd, (bfd_byte *) thdr.year);
417 nlm_version_header (abfd)->month =
418 get_word (abfd, (bfd_byte *) thdr.month);
419 nlm_version_header (abfd)->day =
420 get_word (abfd, (bfd_byte *) thdr.day);
422 else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
424 Nlm_External_Extended_Header thdr;
426 amt = sizeof (thdr);
427 if (bfd_bread ((PTR) &thdr, amt, abfd) != amt)
428 return FALSE;
429 memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
430 sizeof (thdr.stamp));
431 nlm_extended_header (abfd)->languageID =
432 get_word (abfd, (bfd_byte *) thdr.languageID);
433 nlm_extended_header (abfd)->messageFileOffset =
434 get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
435 nlm_extended_header (abfd)->messageFileLength =
436 get_word (abfd, (bfd_byte *) thdr.messageFileLength);
437 nlm_extended_header (abfd)->messageCount =
438 get_word (abfd, (bfd_byte *) thdr.messageCount);
439 nlm_extended_header (abfd)->helpFileOffset =
440 get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
441 nlm_extended_header (abfd)->helpFileLength =
442 get_word (abfd, (bfd_byte *) thdr.helpFileLength);
443 nlm_extended_header (abfd)->RPCDataOffset =
444 get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
445 nlm_extended_header (abfd)->RPCDataLength =
446 get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
447 nlm_extended_header (abfd)->sharedCodeOffset =
448 get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
449 nlm_extended_header (abfd)->sharedCodeLength =
450 get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
451 nlm_extended_header (abfd)->sharedDataOffset =
452 get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
453 nlm_extended_header (abfd)->sharedDataLength =
454 get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
455 nlm_extended_header (abfd)->sharedRelocationFixupOffset =
456 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
457 nlm_extended_header (abfd)->sharedRelocationFixupCount =
458 get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
459 nlm_extended_header (abfd)->sharedExternalReferenceOffset =
460 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
461 nlm_extended_header (abfd)->sharedExternalReferenceCount =
462 get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
463 nlm_extended_header (abfd)->sharedPublicsOffset =
464 get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
465 nlm_extended_header (abfd)->sharedPublicsCount =
466 get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
467 nlm_extended_header (abfd)->sharedDebugRecordOffset =
468 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
469 nlm_extended_header (abfd)->sharedDebugRecordCount =
470 get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
471 nlm_extended_header (abfd)->SharedInitializationOffset =
472 get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
473 nlm_extended_header (abfd)->SharedExitProcedureOffset =
474 get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
475 nlm_extended_header (abfd)->productID =
476 get_word (abfd, (bfd_byte *) thdr.productID);
477 nlm_extended_header (abfd)->reserved0 =
478 get_word (abfd, (bfd_byte *) thdr.reserved0);
479 nlm_extended_header (abfd)->reserved1 =
480 get_word (abfd, (bfd_byte *) thdr.reserved1);
481 nlm_extended_header (abfd)->reserved2 =
482 get_word (abfd, (bfd_byte *) thdr.reserved2);
483 nlm_extended_header (abfd)->reserved3 =
484 get_word (abfd, (bfd_byte *) thdr.reserved3);
485 nlm_extended_header (abfd)->reserved4 =
486 get_word (abfd, (bfd_byte *) thdr.reserved4);
487 nlm_extended_header (abfd)->reserved5 =
488 get_word (abfd, (bfd_byte *) thdr.reserved5);
490 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
492 amt = sizeof (nlm_copyright_header (abfd)->stamp);
493 if (bfd_bread ((PTR) nlm_copyright_header (abfd)->stamp,
494 amt, abfd) != amt)
495 return FALSE;
496 if (bfd_bread ((PTR) &(nlm_copyright_header (abfd)
497 ->copyrightMessageLength),
498 (bfd_size_type) 1, abfd) != 1)
499 return FALSE;
500 /* The copyright message is a variable length string. */
501 amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
502 if (bfd_bread ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
503 amt, abfd) != amt)
504 return FALSE;
506 else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
508 Nlm_External_Custom_Header thdr;
509 bfd_size_type hdrLength;
510 file_ptr dataOffset;
511 bfd_size_type dataLength;
512 char dataStamp[8];
513 PTR hdr;
515 /* Read the stamp ("CuStHeAd"). */
516 amt = sizeof (thdr.stamp);
517 if (bfd_bread ((PTR) thdr.stamp, amt, abfd) != amt)
518 return FALSE;
519 /* Read the length of this custom header. */
520 amt = sizeof (thdr.length);
521 if (bfd_bread ((PTR) thdr.length, amt, abfd) != amt)
522 return FALSE;
523 hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
524 /* Read further fields if we have them. */
525 if (hdrLength < NLM_TARGET_LONG_SIZE)
526 dataOffset = 0;
527 else
529 amt = sizeof (thdr.dataOffset);
530 if (bfd_bread ((PTR) thdr.dataOffset, amt, abfd) != amt)
531 return FALSE;
532 dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
534 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
535 dataLength = 0;
536 else
538 amt = sizeof (thdr.dataLength);
539 if (bfd_bread ((PTR) thdr.dataLength, amt, abfd) != amt)
540 return FALSE;
541 dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
543 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
544 memset (dataStamp, 0, sizeof (dataStamp));
545 else
547 amt = sizeof (dataStamp);
548 if (bfd_bread ((PTR) dataStamp, amt, abfd) != amt)
549 return FALSE;
552 /* Read the rest of the header, if any. */
553 if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
555 hdr = NULL;
556 hdrLength = 0;
558 else
560 hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
561 hdr = bfd_alloc (abfd, hdrLength);
562 if (hdr == NULL)
563 return FALSE;
564 if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
565 return FALSE;
568 /* If we have found a Cygnus header, process it. Otherwise,
569 just save the associated data without trying to interpret
570 it. */
571 if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
573 file_ptr pos;
574 bfd_byte *contents;
575 bfd_byte *p, *pend;
577 BFD_ASSERT (hdrLength == 0 && hdr == NULL);
579 pos = bfd_tell (abfd);
580 if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
581 return FALSE;
582 contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
583 if (contents == NULL)
584 return FALSE;
585 if (bfd_bread (contents, dataLength, abfd) != dataLength)
586 return FALSE;
587 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
588 return FALSE;
590 memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
591 nlm_cygnus_ext_header (abfd)->offset = dataOffset;
592 nlm_cygnus_ext_header (abfd)->length = dataLength;
594 /* This data this header points to provides a list of
595 the sections which were in the original object file
596 which was converted to become an NLM. We locate
597 those sections and add them to the BFD. Note that
598 this is likely to create a second .text, .data and
599 .bss section; retrieving the sections by name will
600 get the actual NLM sections, which is what we want to
601 happen. The sections from the original file, which
602 may be subsets of the NLM section, can only be found
603 using bfd_map_over_sections. */
604 p = contents;
605 pend = p + dataLength;
606 while (p < pend)
608 char *name;
609 size_t l;
610 file_ptr filepos;
611 bfd_size_type size;
612 asection *newsec;
614 /* The format of this information is
615 null terminated section name
616 zeroes to adjust to 4 byte boundary
617 4 byte section data file pointer
618 4 byte section size
621 name = (char *) p;
622 l = strlen (name) + 1;
623 l = (l + 3) &~ (size_t) 3;
624 p += l;
625 filepos = H_GET_32 (abfd, p);
626 p += 4;
627 size = H_GET_32 (abfd, p);
628 p += 4;
630 newsec = bfd_make_section_anyway (abfd, name);
631 if (newsec == (asection *) NULL)
632 return FALSE;
633 newsec->_raw_size = size;
634 if (filepos != 0)
636 newsec->filepos = filepos;
637 newsec->flags |= SEC_HAS_CONTENTS;
641 else
643 memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
644 sizeof (thdr.stamp));
645 nlm_custom_header (abfd)->hdrLength = hdrLength;
646 nlm_custom_header (abfd)->dataOffset = dataOffset;
647 nlm_custom_header (abfd)->dataLength = dataLength;
648 memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
649 sizeof (dataStamp));
650 nlm_custom_header (abfd)->hdr = hdr;
653 else
654 break;
656 return TRUE;
659 /* Return whether there is a non-zero byte in a memory block. */
661 static bfd_boolean
662 find_nonzero (buf, size)
663 PTR buf;
664 size_t size;
666 char *p = (char *) buf;
668 while (size-- != 0)
669 if (*p++ != 0)
670 return TRUE;
671 return FALSE;
674 /* Swap out the contents of the auxiliary headers. We create those
675 auxiliary headers which have been set non-zero. We do not require
676 the caller to set up the stamp fields. */
678 static bfd_boolean
679 nlm_swap_auxiliary_headers_out (abfd)
680 bfd *abfd;
682 bfd_size_type amt;
684 /* Write out the version header if there is one. */
685 if (find_nonzero ((PTR) nlm_version_header (abfd),
686 sizeof (Nlm_Internal_Version_Header)))
688 Nlm_External_Version_Header thdr;
690 memcpy (thdr.stamp, "VeRsIoN#", 8);
691 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
692 (bfd_byte *) thdr.majorVersion);
693 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
694 (bfd_byte *) thdr.minorVersion);
695 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
696 (bfd_byte *) thdr.revision);
697 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
698 (bfd_byte *) thdr.year);
699 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
700 (bfd_byte *) thdr.month);
701 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
702 (bfd_byte *) thdr.day);
703 if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
704 != sizeof (thdr))
705 return FALSE;
708 /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
709 tag in order to make the NW4.x and NW5.x loaders happy. */
711 /* Write out the copyright header if there is one. */
712 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
713 sizeof (Nlm_Internal_Copyright_Header)))
715 Nlm_External_Copyright_Header thdr;
717 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
718 amt = sizeof (thdr.stamp);
719 if (bfd_bwrite ((PTR) thdr.stamp, amt, abfd) != amt)
720 return FALSE;
721 thdr.copyrightMessageLength[0] =
722 nlm_copyright_header (abfd)->copyrightMessageLength;
723 amt = 1;
724 if (bfd_bwrite ((PTR) thdr.copyrightMessageLength, amt, abfd) != amt)
725 return FALSE;
726 /* The copyright message is a variable length string. */
727 amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
728 if (bfd_bwrite ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
729 amt, abfd) != amt)
730 return FALSE;
733 /* Write out the extended header if there is one. */
734 if (find_nonzero ((PTR) nlm_extended_header (abfd),
735 sizeof (Nlm_Internal_Extended_Header)))
737 Nlm_External_Extended_Header thdr;
739 memcpy (thdr.stamp, "MeSsAgEs", 8);
740 put_word (abfd,
741 (bfd_vma) nlm_extended_header (abfd)->languageID,
742 (bfd_byte *) thdr.languageID);
743 put_word (abfd,
744 (bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
745 (bfd_byte *) thdr.messageFileOffset);
746 put_word (abfd,
747 (bfd_vma) nlm_extended_header (abfd)->messageFileLength,
748 (bfd_byte *) thdr.messageFileLength);
749 put_word (abfd,
750 (bfd_vma) nlm_extended_header (abfd)->messageCount,
751 (bfd_byte *) thdr.messageCount);
752 put_word (abfd,
753 (bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
754 (bfd_byte *) thdr.helpFileOffset);
755 put_word (abfd,
756 (bfd_vma) nlm_extended_header (abfd)->helpFileLength,
757 (bfd_byte *) thdr.helpFileLength);
758 put_word (abfd,
759 (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
760 (bfd_byte *) thdr.RPCDataOffset);
761 put_word (abfd,
762 (bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
763 (bfd_byte *) thdr.RPCDataLength);
764 put_word (abfd,
765 (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
766 (bfd_byte *) thdr.sharedCodeOffset);
767 put_word (abfd,
768 (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
769 (bfd_byte *) thdr.sharedCodeLength);
770 put_word (abfd,
771 (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
772 (bfd_byte *) thdr.sharedDataOffset);
773 put_word (abfd,
774 (bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
775 (bfd_byte *) thdr.sharedDataLength);
776 put_word (abfd,
777 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
778 (bfd_byte *) thdr.sharedRelocationFixupOffset);
779 put_word (abfd,
780 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
781 (bfd_byte *) thdr.sharedRelocationFixupCount);
782 put_word (abfd,
783 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
784 (bfd_byte *) thdr.sharedExternalReferenceOffset);
785 put_word (abfd,
786 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
787 (bfd_byte *) thdr.sharedExternalReferenceCount);
788 put_word (abfd,
789 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
790 (bfd_byte *) thdr.sharedPublicsOffset);
791 put_word (abfd,
792 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
793 (bfd_byte *) thdr.sharedPublicsCount);
794 put_word (abfd,
795 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
796 (bfd_byte *) thdr.sharedDebugRecordOffset);
797 put_word (abfd,
798 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
799 (bfd_byte *) thdr.sharedDebugRecordCount);
800 put_word (abfd,
801 (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
802 (bfd_byte *) thdr.sharedInitializationOffset);
803 put_word (abfd,
804 (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
805 (bfd_byte *) thdr.SharedExitProcedureOffset);
806 put_word (abfd,
807 (bfd_vma) nlm_extended_header (abfd)->productID,
808 (bfd_byte *) thdr.productID);
809 put_word (abfd,
810 (bfd_vma) nlm_extended_header (abfd)->reserved0,
811 (bfd_byte *) thdr.reserved0);
812 put_word (abfd,
813 (bfd_vma) nlm_extended_header (abfd)->reserved1,
814 (bfd_byte *) thdr.reserved1);
815 put_word (abfd,
816 (bfd_vma) nlm_extended_header (abfd)->reserved2,
817 (bfd_byte *) thdr.reserved2);
818 put_word (abfd,
819 (bfd_vma) nlm_extended_header (abfd)->reserved3,
820 (bfd_byte *) thdr.reserved3);
821 put_word (abfd,
822 (bfd_vma) nlm_extended_header (abfd)->reserved4,
823 (bfd_byte *) thdr.reserved4);
824 put_word (abfd,
825 (bfd_vma) nlm_extended_header (abfd)->reserved5,
826 (bfd_byte *) thdr.reserved5);
827 if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd)
828 != sizeof (thdr))
829 return FALSE;
832 /* Write out the custom header if there is one. */
833 if (find_nonzero ((PTR) nlm_custom_header (abfd),
834 sizeof (Nlm_Internal_Custom_Header)))
836 Nlm_External_Custom_Header thdr;
837 bfd_boolean ds;
838 bfd_size_type hdrLength;
840 ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
841 sizeof (nlm_custom_header (abfd)->dataStamp));
842 memcpy (thdr.stamp, "CuStHeAd", 8);
843 hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
844 + nlm_custom_header (abfd)->hdrLength);
845 put_word (abfd, hdrLength, thdr.length);
846 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
847 thdr.dataOffset);
848 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
849 thdr.dataLength);
850 if (! ds)
852 BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
853 amt = sizeof (thdr) - sizeof (thdr.dataStamp);
854 if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
855 return FALSE;
857 else
859 memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
860 sizeof (thdr.dataStamp));
861 amt = sizeof (thdr);
862 if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
863 return FALSE;
864 amt = nlm_custom_header (abfd)->hdrLength;
865 if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
866 return FALSE;
870 /* Write out the Cygnus debugging header if there is one. */
871 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
872 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
874 Nlm_External_Custom_Header thdr;
876 memcpy (thdr.stamp, "CuStHeAd", 8);
877 put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
878 (bfd_byte *) thdr.length);
879 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
880 (bfd_byte *) thdr.dataOffset);
881 put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
882 (bfd_byte *) thdr.dataLength);
883 memcpy (thdr.dataStamp, "CyGnUsEx", 8);
884 amt = sizeof (thdr);
885 if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt)
886 return FALSE;
889 return TRUE;
892 /* We read the NLM's public symbols and use it to generate a bfd symbol
893 table (hey, it's better than nothing) on a one-for-one basis. Thus
894 use the number of public symbols as the number of bfd symbols we will
895 have once we actually get around to reading them in.
897 Return the number of bytes required to hold the symtab vector, based on
898 the count plus 1, since we will NULL terminate the vector allocated based
899 on this size. */
901 long
902 nlm_get_symtab_upper_bound (abfd)
903 bfd *abfd;
905 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */
906 long symcount;
907 long symtab_size = 0;
909 i_fxdhdrp = nlm_fixed_header (abfd);
910 symcount = (i_fxdhdrp->numberOfPublics
911 + i_fxdhdrp->numberOfDebugRecords
912 + i_fxdhdrp->numberOfExternalReferences);
913 symtab_size = (symcount + 1) * (sizeof (asymbol));
914 return (symtab_size);
917 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
918 symbol table fails. */
920 long
921 nlm_canonicalize_symtab (abfd, alocation)
922 bfd *abfd;
923 asymbol **alocation;
925 nlm_symbol_type *symbase;
926 bfd_size_type counter = 0;
928 if (! nlm_slurp_symbol_table (abfd))
929 return -1;
930 symbase = nlm_get_symbols (abfd);
931 while (counter < bfd_get_symcount (abfd))
933 *alocation++ = &symbase->symbol;
934 symbase++;
935 counter++;
937 *alocation = (asymbol *) NULL;
938 return bfd_get_symcount (abfd);
941 /* Make an NLM symbol. There is nothing special to do here. */
943 asymbol *
944 nlm_make_empty_symbol (abfd)
945 bfd *abfd;
947 bfd_size_type amt = sizeof (nlm_symbol_type);
948 nlm_symbol_type *new = (nlm_symbol_type *) bfd_zalloc (abfd, amt);
950 if (new)
951 new->symbol.the_bfd = abfd;
952 return &new->symbol;
955 /* Get symbol information. */
957 void
958 nlm_get_symbol_info (ignore_abfd, symbol, ret)
959 bfd *ignore_abfd ATTRIBUTE_UNUSED;
960 asymbol *symbol;
961 symbol_info *ret;
963 bfd_symbol_info (symbol, ret);
966 /* Print symbol information. */
968 void
969 nlm_print_symbol (abfd, afile, symbol, how)
970 bfd *abfd;
971 PTR afile;
972 asymbol *symbol;
973 bfd_print_symbol_type how;
975 FILE *file = (FILE *) afile;
977 switch (how)
979 case bfd_print_symbol_name:
980 case bfd_print_symbol_more:
981 if (symbol->name)
982 fprintf (file, "%s", symbol->name);
983 break;
984 case bfd_print_symbol_all:
985 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
986 fprintf (file, " %-5s", symbol->section->name);
987 if (symbol->name)
988 fprintf (file, " %s", symbol->name);
989 break;
993 /* Slurp in nlm symbol table.
995 In the external (in-file) form, NLM export records are variable length,
996 with the following form:
998 1 byte length of the symbol name (N)
999 N bytes the symbol name
1000 4 bytes the symbol offset from start of it's section
1002 We also read in the debugging symbols and import records. Import
1003 records are treated as undefined symbols. As we read the import
1004 records we also read in the associated reloc information, which is
1005 attached to the symbol.
1007 The bfd symbols are copied to SYMPTRS.
1009 When we return, the bfd symcount is either zero or contains the correct
1010 number of symbols. */
1012 static bfd_boolean
1013 nlm_slurp_symbol_table (abfd)
1014 bfd *abfd;
1016 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */
1017 bfd_size_type totsymcount; /* Number of NLM symbols. */
1018 bfd_size_type symcount; /* Counter of NLM symbols. */
1019 nlm_symbol_type *sym; /* Pointer to current bfd symbol. */
1020 unsigned char symlength; /* Symbol length read into here. */
1021 unsigned char symtype; /* Type of debugging symbol. */
1022 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here. */
1023 bfd_boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
1024 bfd_boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
1025 bfd_size_type amt;
1027 if (nlm_get_symbols (abfd) != NULL)
1028 return TRUE;
1030 /* Read each raw NLM symbol, using the information to create a canonical bfd
1031 symbol table entry.
1033 Note that we allocate the initial bfd canonical symbol buffer based on a
1034 one-to-one mapping of the NLM symbols to canonical symbols. We actually
1035 use all the NLM symbols, so there will be no space left over at the end.
1036 When we have all the symbols, we build the caller's pointer vector. */
1038 abfd->symcount = 0;
1039 i_fxdhdrp = nlm_fixed_header (abfd);
1040 totsymcount = (i_fxdhdrp->numberOfPublics
1041 + i_fxdhdrp->numberOfDebugRecords
1042 + i_fxdhdrp->numberOfExternalReferences);
1043 if (totsymcount == 0)
1044 return TRUE;
1046 if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
1047 return FALSE;
1049 amt = totsymcount * sizeof (nlm_symbol_type);
1050 sym = ((nlm_symbol_type *) bfd_zalloc (abfd, amt));
1051 if (!sym)
1052 return FALSE;
1053 nlm_set_symbols (abfd, sym);
1055 /* We use the bfd's symcount directly as the control count, so that early
1056 termination of the loop leaves the symcount correct for the symbols that
1057 were read. */
1059 set_public_section_func = nlm_set_public_section_func (abfd);
1060 symcount = i_fxdhdrp->numberOfPublics;
1061 while (abfd->symcount < symcount)
1063 amt = sizeof (symlength);
1064 if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
1065 return FALSE;
1066 amt = symlength;
1067 sym->symbol.the_bfd = abfd;
1068 sym->symbol.name = bfd_alloc (abfd, amt + 1);
1069 if (!sym->symbol.name)
1070 return FALSE;
1071 if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
1072 return FALSE;
1073 /* Cast away const. */
1074 ((char *) (sym->symbol.name))[symlength] = '\0';
1075 amt = sizeof (temp);
1076 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
1077 return FALSE;
1078 sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1079 sym->symbol.value = get_word (abfd, temp);
1080 if (set_public_section_func)
1082 /* Most backends can use the code below, but unfortunately
1083 some use a different scheme. */
1084 if (! (*set_public_section_func) (abfd, sym))
1085 return FALSE;
1087 else
1089 if (sym->symbol.value & NLM_HIBIT)
1091 sym->symbol.value &= ~NLM_HIBIT;
1092 sym->symbol.flags |= BSF_FUNCTION;
1093 sym->symbol.section =
1094 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1096 else
1098 sym->symbol.section =
1099 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1102 sym->rcnt = 0;
1103 abfd->symcount++;
1104 sym++;
1107 /* Read the debugging records. */
1109 if (i_fxdhdrp->numberOfDebugRecords > 0)
1111 if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
1112 return FALSE;
1114 symcount += i_fxdhdrp->numberOfDebugRecords;
1115 while (abfd->symcount < symcount)
1117 amt = sizeof (symtype);
1118 if (bfd_bread ((PTR) &symtype, amt, abfd) != amt)
1119 return FALSE;
1120 amt = sizeof (temp);
1121 if (bfd_bread ((PTR) temp, amt, abfd) != amt)
1122 return FALSE;
1123 amt = sizeof (symlength);
1124 if (bfd_bread ((PTR) &symlength, amt, abfd) != amt)
1125 return FALSE;
1126 amt = symlength;
1127 sym->symbol.the_bfd = abfd;
1128 sym->symbol.name = bfd_alloc (abfd, amt + 1);
1129 if (!sym->symbol.name)
1130 return FALSE;
1131 if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt)
1132 return FALSE;
1133 /* Cast away const. */
1134 ((char *) (sym->symbol.name))[symlength] = '\0';
1135 sym->symbol.flags = BSF_LOCAL;
1136 sym->symbol.value = get_word (abfd, temp);
1137 if (symtype == 0)
1139 sym->symbol.section =
1140 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1142 else if (symtype == 1)
1144 sym->symbol.flags |= BSF_FUNCTION;
1145 sym->symbol.section =
1146 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1148 else
1150 sym->symbol.section = bfd_abs_section_ptr;
1152 sym->rcnt = 0;
1153 abfd->symcount++;
1154 sym++;
1158 /* Read in the import records. We can only do this if we know how
1159 to read relocs for this target. */
1160 read_import_func = nlm_read_import_func (abfd);
1161 if (read_import_func != NULL)
1163 if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
1164 return FALSE;
1166 symcount += i_fxdhdrp->numberOfExternalReferences;
1167 while (abfd->symcount < symcount)
1169 if (! (*read_import_func) (abfd, sym))
1170 return FALSE;
1171 sym++;
1172 abfd->symcount++;
1176 return TRUE;
1179 /* Get the relocs for an NLM file. There are two types of relocs.
1180 Imports are relocs against symbols defined in other NLM files. We
1181 treat these as relocs against global symbols. Relocation fixups
1182 are internal relocs.
1184 The actual format used to store the relocs is machine specific. */
1186 /* Read in the relocation fixup information. This is stored in
1187 nlm_relocation_fixups, an array of arelent structures, and
1188 nlm_relocation_fixup_secs, an array of section pointers. The
1189 section pointers are needed because the relocs are not sorted by
1190 section. */
1192 static bfd_boolean
1193 nlm_slurp_reloc_fixups (abfd)
1194 bfd *abfd;
1196 bfd_boolean (*read_func)
1197 PARAMS ((bfd *, nlm_symbol_type *, asection **, arelent *));
1198 bfd_size_type count, amt;
1199 arelent *rels;
1200 asection **secs;
1202 if (nlm_relocation_fixups (abfd) != NULL)
1203 return TRUE;
1204 read_func = nlm_read_reloc_func (abfd);
1205 if (read_func == NULL)
1206 return TRUE;
1208 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1209 SEEK_SET) != 0)
1210 return FALSE;
1212 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1213 amt = count * sizeof (arelent);
1214 rels = (arelent *) bfd_alloc (abfd, amt);
1215 amt = count * sizeof (asection *);
1216 secs = (asection **) bfd_alloc (abfd, amt);
1217 if ((rels == NULL || secs == NULL) && count != 0)
1218 return FALSE;
1219 nlm_relocation_fixups (abfd) = rels;
1220 nlm_relocation_fixup_secs (abfd) = secs;
1222 /* We have to read piece by piece, because we don't know how large
1223 the machine specific reloc information is. */
1224 while (count-- != 0)
1226 if (! (*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels))
1228 nlm_relocation_fixups (abfd) = NULL;
1229 nlm_relocation_fixup_secs (abfd) = NULL;
1230 return FALSE;
1232 ++secs;
1233 ++rels;
1236 return TRUE;
1239 /* Get the number of relocs. This really just returns an upper bound,
1240 since it does not attempt to distinguish them based on the section.
1241 That will be handled when they are actually read. */
1243 long
1244 nlm_get_reloc_upper_bound (abfd, sec)
1245 bfd *abfd;
1246 asection *sec;
1248 nlm_symbol_type *syms;
1249 bfd_size_type count;
1250 unsigned int ret;
1252 /* If we don't know how to read relocs, just return 0. */
1253 if (nlm_read_reloc_func (abfd) == NULL)
1254 return -1;
1255 /* Make sure we have either the code or the data section. */
1256 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1257 return 0;
1259 syms = nlm_get_symbols (abfd);
1260 if (syms == NULL)
1262 if (! nlm_slurp_symbol_table (abfd))
1263 return -1;
1264 syms = nlm_get_symbols (abfd);
1267 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1269 count = bfd_get_symcount (abfd);
1270 while (count-- != 0)
1272 ret += syms->rcnt;
1273 ++syms;
1276 return (ret + 1) * sizeof (arelent *);
1279 /* Get the relocs themselves. */
1281 long
1282 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1283 bfd *abfd;
1284 asection *sec;
1285 arelent **relptr;
1286 asymbol **symbols;
1288 arelent *rels;
1289 asection **secs;
1290 bfd_size_type count, i;
1291 unsigned int ret;
1293 /* Get the relocation fixups. */
1294 rels = nlm_relocation_fixups (abfd);
1295 if (rels == NULL)
1297 if (! nlm_slurp_reloc_fixups (abfd))
1298 return -1;
1299 rels = nlm_relocation_fixups (abfd);
1301 secs = nlm_relocation_fixup_secs (abfd);
1303 ret = 0;
1304 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1305 for (i = 0; i < count; i++, rels++, secs++)
1307 if (*secs == sec)
1309 *relptr++ = rels;
1310 ++ret;
1314 /* Get the import symbols. */
1315 count = bfd_get_symcount (abfd);
1316 for (i = 0; i < count; i++, symbols++)
1318 asymbol *sym;
1320 sym = *symbols;
1321 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1323 nlm_symbol_type *nlm_sym;
1324 bfd_size_type j;
1326 nlm_sym = (nlm_symbol_type *) sym;
1327 for (j = 0; j < nlm_sym->rcnt; j++)
1329 if (nlm_sym->relocs[j].section == sec)
1331 *relptr = &nlm_sym->relocs[j].reloc;
1332 (*relptr)->sym_ptr_ptr = symbols;
1333 ++relptr;
1334 ++ret;
1340 *relptr = NULL;
1342 return ret;
1345 /* Compute the section file positions for an NLM file. All variable
1346 length data in the file headers must be set before this function is
1347 called. If the variable length data is changed later, the
1348 resulting object file will be incorrect. Unfortunately, there is
1349 no way to check this.
1351 This routine also sets the Size and Offset fields in the fixed
1352 header.
1354 It also looks over the symbols and moves any common symbols into
1355 the .bss section; NLM has no way to represent a common symbol.
1356 This approach means that either the symbols must already have been
1357 set at this point, or there must be no common symbols. We need to
1358 move the symbols at this point so that mangle_relocs can see the
1359 final values. */
1361 static bfd_boolean
1362 nlm_compute_section_file_positions (abfd)
1363 bfd *abfd;
1365 file_ptr sofar;
1366 asection *sec;
1367 bfd_vma text, data, bss;
1368 bfd_vma text_low, data_low;
1369 unsigned int text_align, data_align, other_align;
1370 file_ptr text_ptr, data_ptr, other_ptr;
1371 asection *bss_sec;
1372 asymbol **sym_ptr_ptr;
1374 if (abfd->output_has_begun)
1375 return TRUE;
1377 /* Make sure we have a section to hold uninitialized data. */
1378 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1379 if (bss_sec == NULL)
1381 if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1382 (file_ptr) 0, (bfd_size_type) 0,
1383 SEC_ALLOC))
1384 return FALSE;
1385 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1388 abfd->output_has_begun = TRUE;
1390 /* The fixed header. */
1391 sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1393 /* The variable header. */
1394 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1395 + nlm_variable_header (abfd)->descriptionLength + 1
1396 + NLM_TARGET_LONG_SIZE /* stackSize */
1397 + NLM_TARGET_LONG_SIZE /* reserved */
1398 + sizeof (nlm_variable_header (abfd)->oldThreadName)
1399 + sizeof (nlm_variable_header (abfd)->screenNameLength)
1400 + nlm_variable_header (abfd)->screenNameLength + 1
1401 + sizeof (nlm_variable_header (abfd)->threadNameLength)
1402 + nlm_variable_header (abfd)->threadNameLength + 1);
1404 /* The auxiliary headers. */
1405 if (find_nonzero ((PTR) nlm_version_header (abfd),
1406 sizeof (Nlm_Internal_Version_Header)))
1407 sofar += sizeof (Nlm_External_Version_Header);
1408 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1409 sizeof (Nlm_Internal_Extended_Header)))
1410 sofar += sizeof (Nlm_External_Extended_Header);
1411 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1412 sizeof (Nlm_Internal_Copyright_Header)))
1413 sofar += (sizeof (Nlm_External_Copyright_Header)
1414 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1415 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1416 sizeof (Nlm_Internal_Custom_Header)))
1417 sofar += (sizeof (Nlm_External_Custom_Header)
1418 + nlm_custom_header (abfd)->hdrLength);
1419 if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
1420 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
1421 sofar += sizeof (Nlm_External_Custom_Header);
1423 /* Compute the section file positions in two passes. First get the
1424 sizes of the text and data sections, and then set the file
1425 positions. This code aligns the sections in the file using the
1426 same alignment restrictions that apply to the sections in memory;
1427 this may not be necessary. */
1428 text = 0;
1429 text_low = (bfd_vma) - 1;
1430 text_align = 0;
1431 data = 0;
1432 data_low = (bfd_vma) - 1;
1433 data_align = 0;
1434 bss = 0;
1435 other_align = 0;
1436 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1438 flagword f;
1440 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1442 f = bfd_get_section_flags (abfd, sec);
1443 if (f & SEC_CODE)
1445 text += sec->_raw_size;
1446 if (bfd_get_section_vma (abfd, sec) < text_low)
1447 text_low = bfd_get_section_vma (abfd, sec);
1448 if (sec->alignment_power > text_align)
1449 text_align = sec->alignment_power;
1451 else if (f & SEC_DATA)
1453 data += sec->_raw_size;
1454 if (bfd_get_section_vma (abfd, sec) < data_low)
1455 data_low = bfd_get_section_vma (abfd, sec);
1456 if (sec->alignment_power > data_align)
1457 data_align = sec->alignment_power;
1459 else if (f & SEC_HAS_CONTENTS)
1461 if (sec->alignment_power > other_align)
1462 other_align = sec->alignment_power;
1464 else if (f & SEC_ALLOC)
1465 bss += sec->_raw_size;
1468 nlm_set_text_low (abfd, text_low);
1469 nlm_set_data_low (abfd, data_low);
1471 if (nlm_no_uninitialized_data (abfd))
1473 /* This NetWare format does not use uninitialized data. We must
1474 increase the size of the data section. We will never wind up
1475 writing those file locations, so they will remain zero. */
1476 data += bss;
1477 bss = 0;
1480 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1481 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1482 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1484 /* Fill in some fields in the header for which we now have the
1485 information. */
1486 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1487 nlm_fixed_header (abfd)->codeImageSize = text;
1488 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1489 nlm_fixed_header (abfd)->dataImageSize = data;
1490 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1492 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1494 flagword f;
1496 f = bfd_get_section_flags (abfd, sec);
1498 if (f & SEC_CODE)
1500 sec->filepos = text_ptr;
1501 text_ptr += sec->_raw_size;
1503 else if (f & SEC_DATA)
1505 sec->filepos = data_ptr;
1506 data_ptr += sec->_raw_size;
1508 else if (f & SEC_HAS_CONTENTS)
1510 sec->filepos = other_ptr;
1511 other_ptr += sec->_raw_size;
1515 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1517 /* Move all common symbols into the .bss section. */
1519 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1520 if (sym_ptr_ptr != NULL)
1522 asymbol **sym_end;
1523 bfd_vma add;
1525 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1526 add = 0;
1527 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1529 asymbol *sym;
1530 bfd_vma size;
1532 sym = *sym_ptr_ptr;
1534 if (!bfd_is_com_section (bfd_get_section (sym)))
1535 continue;
1537 /* Put the common symbol in the .bss section, and increase
1538 the size of the .bss section by the size of the common
1539 symbol (which is the old value of the symbol). */
1540 sym->section = bss_sec;
1541 size = sym->value;
1542 sym->value = bss_sec->_raw_size + add;
1543 add += size;
1544 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1546 if (add != 0)
1548 if (nlm_no_uninitialized_data (abfd))
1550 /* We could handle this case, but so far it hasn't been
1551 necessary. */
1552 abort ();
1554 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1555 bss_sec->_raw_size += add;
1559 return TRUE;
1562 /* Set the contents of a section. To do this we need to know where
1563 the section is going to be located in the output file. That means
1564 that the sizes of all the sections must be set, and all the
1565 variable size header information must be known. */
1567 bfd_boolean
1568 nlm_set_section_contents (abfd, section, location, offset, count)
1569 bfd *abfd;
1570 asection *section;
1571 const PTR location;
1572 file_ptr offset;
1573 bfd_size_type count;
1575 if (! abfd->output_has_begun
1576 && ! nlm_compute_section_file_positions (abfd))
1577 return FALSE;
1579 if (count == 0)
1580 return TRUE;
1582 /* i386 NetWare has a very restricted set of relocs. In order for
1583 objcopy to work, the NLM i386 backend needs a chance to rework
1584 the section contents so that its set of relocs will work. If all
1585 the relocs are already acceptable, this will not do anything. */
1586 if (section->reloc_count != 0)
1588 bfd_boolean (*mangle_relocs_func)
1589 PARAMS ((bfd *, asection *, const PTR, bfd_vma, bfd_size_type));
1591 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1592 if (mangle_relocs_func != NULL)
1594 if (!(*mangle_relocs_func) (abfd, section, location,
1595 (bfd_vma) offset, count))
1596 return FALSE;
1600 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1601 || bfd_bwrite (location, count, abfd) != count)
1602 return FALSE;
1604 return TRUE;
1607 /* We need to sort a list of relocs associated with sections when we
1608 write out the external relocs. */
1610 static int
1611 nlm_external_reloc_compare (p1, p2)
1612 const void *p1;
1613 const void *p2;
1615 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1616 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1617 int cmp;
1619 cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1620 (*r2->rel->sym_ptr_ptr)->name);
1621 if (cmp != 0)
1622 return cmp;
1624 /* We sort by address within symbol to make the sort more stable and
1625 increase the chances that different hosts will generate bit for
1626 bit equivalent results. */
1627 return (int) (r1->rel->address - r2->rel->address);
1630 /* Write out an NLM file. We write out the information in this order:
1631 fixed header
1632 variable header
1633 auxiliary headers
1634 code sections
1635 data sections
1636 other sections (custom data, messages, help, shared NLM, RPC,
1637 module dependencies)
1638 relocation fixups
1639 external references (imports)
1640 public symbols (exports)
1641 debugging records
1642 This is similar to the order used by the NetWare tools; the
1643 difference is that NetWare puts the sections other than code, data
1644 and custom data at the end of the NLM. It is convenient for us to
1645 know where the sections are going to be before worrying about the
1646 size of the other information.
1648 By the time this function is called, all the section data should
1649 have been output using set_section_contents. Note that custom
1650 data, the message file, the help file, the shared NLM file, the RPC
1651 data, and the module dependencies are all considered to be
1652 sections; the caller is responsible for filling in the offset and
1653 length fields in the NLM headers. The relocation fixups and
1654 imports are both obtained from the list of relocs attached to each
1655 section. The exports and debugging records are obtained from the
1656 list of outsymbols. */
1658 bfd_boolean
1659 nlm_write_object_contents (abfd)
1660 bfd *abfd;
1662 asection *sec;
1663 bfd_boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1664 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1665 struct reloc_and_sec *external_relocs;
1666 asymbol **sym_ptr_ptr;
1667 file_ptr last;
1668 bfd_boolean (*write_prefix_func) PARAMS ((bfd *));
1669 unsigned char *fixed_header = NULL;
1670 file_ptr pos;
1671 bfd_size_type amt;
1673 fixed_header = ((unsigned char *)
1674 bfd_malloc (nlm_fixed_header_size (abfd)));
1675 if (fixed_header == NULL)
1676 goto error_return;
1678 if (! abfd->output_has_begun
1679 && ! nlm_compute_section_file_positions (abfd))
1680 goto error_return;
1682 /* Write out the variable length headers. */
1683 pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1684 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
1685 goto error_return;
1686 if (! nlm_swap_variable_header_out (abfd)
1687 || ! nlm_swap_auxiliary_headers_out (abfd))
1689 bfd_set_error (bfd_error_system_call);
1690 goto error_return;
1693 /* A weak check on whether the section file positions were
1694 reasonable. */
1695 if (bfd_tell (abfd) > (ufile_ptr) nlm_fixed_header (abfd)->codeImageOffset)
1697 bfd_set_error (bfd_error_invalid_operation);
1698 goto error_return;
1701 /* Advance to the relocs. */
1702 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1703 SEEK_SET) != 0)
1704 goto error_return;
1706 /* The format of the relocation entries is dependent upon the
1707 particular target. We use an external routine to write the reloc
1708 out. */
1709 write_import_func = nlm_write_import_func (abfd);
1711 /* Write out the internal relocation fixups. While we're looping
1712 over the relocs, we also count the external relocs, which is
1713 needed when they are written out below. */
1714 internal_reloc_count = 0;
1715 external_reloc_count = 0;
1716 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1718 arelent **rel_ptr_ptr, **rel_end;
1720 if (sec->reloc_count == 0)
1721 continue;
1723 /* We can only represent relocs within a code or data
1724 section. We ignore them for a debugging section. */
1725 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1726 continue;
1728 /* We need to know how to write out imports */
1729 if (write_import_func == NULL)
1731 bfd_set_error (bfd_error_invalid_operation);
1732 goto error_return;
1735 rel_ptr_ptr = sec->orelocation;
1736 rel_end = rel_ptr_ptr + sec->reloc_count;
1737 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1739 arelent *rel;
1740 asymbol *sym;
1742 rel = *rel_ptr_ptr;
1743 sym = *rel->sym_ptr_ptr;
1745 if (! bfd_is_und_section (bfd_get_section (sym)))
1747 ++internal_reloc_count;
1748 if (! (*write_import_func) (abfd, sec, rel))
1749 goto error_return;
1751 else
1752 ++external_reloc_count;
1755 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1757 /* Write out the imports (relocs against external symbols). These
1758 are output as a symbol name followed by all the relocs for that
1759 symbol, so we must first gather together all the relocs against
1760 external symbols and sort them. */
1761 amt = external_reloc_count * sizeof (struct reloc_and_sec);
1762 external_relocs = (struct reloc_and_sec *) bfd_alloc (abfd, amt);
1763 if (external_relocs == (struct reloc_and_sec *) NULL)
1764 goto error_return;
1765 i = 0;
1766 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1768 arelent **rel_ptr_ptr, **rel_end;
1770 if (sec->reloc_count == 0)
1771 continue;
1773 rel_ptr_ptr = sec->orelocation;
1774 rel_end = rel_ptr_ptr + sec->reloc_count;
1775 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1777 arelent *rel;
1778 asymbol *sym;
1780 rel = *rel_ptr_ptr;
1781 sym = *rel->sym_ptr_ptr;
1783 if (! bfd_is_und_section (bfd_get_section (sym)))
1784 continue;
1786 external_relocs[i].rel = rel;
1787 external_relocs[i].sec = sec;
1788 ++i;
1792 BFD_ASSERT (i == external_reloc_count);
1794 /* Sort the external relocs by name. */
1795 qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1796 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1798 /* Write out the external relocs. */
1799 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1800 c = 0;
1801 i = 0;
1802 while (i < external_reloc_count)
1804 arelent *rel;
1805 asymbol *sym;
1806 bfd_size_type j, cnt;
1808 ++c;
1810 rel = external_relocs[i].rel;
1811 sym = *rel->sym_ptr_ptr;
1813 cnt = 0;
1814 for (j = i;
1815 (j < external_reloc_count
1816 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1817 j++)
1818 ++cnt;
1820 if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1821 &external_relocs[i]))
1822 goto error_return;
1824 i += cnt;
1827 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1829 /* Write out the public symbols (exports). */
1830 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1831 if (sym_ptr_ptr != (asymbol **) NULL)
1833 bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1834 bfd_boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1836 asymbol **sym_end;
1838 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1839 get_public_offset_func = nlm_get_public_offset_func (abfd);
1840 write_export_func = nlm_write_export_func (abfd);
1841 c = 0;
1842 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1843 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1845 asymbol *sym;
1846 bfd_byte len;
1847 bfd_vma offset;
1848 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1850 sym = *sym_ptr_ptr;
1852 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1853 || bfd_is_und_section (bfd_get_section (sym)))
1854 continue;
1856 ++c;
1858 if (get_public_offset_func)
1860 /* Most backends can use the code below, but
1861 unfortunately some use a different scheme. */
1862 offset = (*get_public_offset_func) (abfd, sym);
1864 else
1866 offset = bfd_asymbol_value (sym);
1867 sec = sym->section;
1868 if (sec->flags & SEC_CODE)
1870 offset -= nlm_get_text_low (abfd);
1871 offset |= NLM_HIBIT;
1873 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1875 /* SEC_ALLOC is for the .bss section. */
1876 offset -= nlm_get_data_low (abfd);
1878 else
1880 /* We can't handle an exported symbol that is not in
1881 the code or data segment. */
1882 bfd_set_error (bfd_error_invalid_operation);
1883 goto error_return;
1887 if (write_export_func)
1889 if (! (*write_export_func) (abfd, sym, offset))
1890 goto error_return;
1892 else
1894 len = strlen (sym->name);
1895 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1896 != sizeof (bfd_byte))
1897 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1898 goto error_return;
1900 put_word (abfd, offset, temp);
1901 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1902 != sizeof (temp))
1903 goto error_return;
1906 nlm_fixed_header (abfd)->numberOfPublics = c;
1908 /* Write out the debugging records. The NLM conversion program
1909 wants to be able to inhibit this, so as a special hack if
1910 debugInfoOffset is set to -1 we don't write any debugging
1911 information. This can not be handled by fiddling with the
1912 symbol table, because exported symbols appear in both the
1913 exported symbol list and the debugging information. */
1914 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1916 nlm_fixed_header (abfd)->debugInfoOffset = 0;
1917 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1919 else
1921 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1922 c = 0;
1923 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1924 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1925 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1927 asymbol *sym;
1928 bfd_byte type, len;
1929 bfd_vma offset;
1930 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1932 sym = *sym_ptr_ptr;
1934 /* The NLM notion of a debugging symbol is actually what
1935 BFD calls a local or global symbol. What BFD calls a
1936 debugging symbol NLM does not understand at all. */
1937 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1938 || (sym->flags & BSF_DEBUGGING) != 0
1939 || bfd_is_und_section (bfd_get_section (sym)))
1940 continue;
1942 ++c;
1944 offset = bfd_asymbol_value (sym);
1945 sec = sym->section;
1946 if (sec->flags & SEC_CODE)
1948 offset -= nlm_get_text_low (abfd);
1949 type = 1;
1951 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1953 /* SEC_ALLOC is for the .bss section. */
1954 offset -= nlm_get_data_low (abfd);
1955 type = 0;
1957 else
1958 type = 2;
1960 /* The type is 0 for data, 1 for code, 2 for absolute. */
1961 if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
1962 != sizeof (bfd_byte))
1963 goto error_return;
1965 put_word (abfd, offset, temp);
1966 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1967 != sizeof (temp))
1968 goto error_return;
1970 len = strlen (sym->name);
1971 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1972 != sizeof (bfd_byte))
1973 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1974 goto error_return;
1976 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1980 /* NLMLINK fills in offset values even if there is no data, so we do
1981 the same. */
1982 last = bfd_tell (abfd);
1983 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1984 nlm_fixed_header (abfd)->codeImageOffset = last;
1985 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
1986 nlm_fixed_header (abfd)->dataImageOffset = last;
1987 if (nlm_fixed_header (abfd)->customDataOffset == 0)
1988 nlm_fixed_header (abfd)->customDataOffset = last;
1989 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
1990 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
1991 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
1992 nlm_fixed_header (abfd)->relocationFixupOffset = last;
1993 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
1994 nlm_fixed_header (abfd)->externalReferencesOffset = last;
1995 if (nlm_fixed_header (abfd)->publicsOffset == 0)
1996 nlm_fixed_header (abfd)->publicsOffset = last;
1997 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
1998 nlm_fixed_header (abfd)->debugInfoOffset = last;
2000 /* At this point everything has been written out except the fixed
2001 header. */
2002 memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
2003 NLM_SIGNATURE_SIZE);
2004 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2005 nlm_fixed_header (abfd)->codeStartOffset =
2006 (bfd_get_start_address (abfd)
2007 - nlm_get_text_low (abfd));
2009 /* We have no convenient way for the caller to pass in the exit
2010 procedure or the check unload procedure, so the caller must set
2011 the values in the header to the values of the symbols. */
2012 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2013 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2014 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2015 nlm_get_text_low (abfd);
2017 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
2018 goto error_return;
2020 write_prefix_func = nlm_write_prefix_func (abfd);
2021 if (write_prefix_func)
2023 if (! (*write_prefix_func) (abfd))
2024 goto error_return;
2027 BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
2028 == nlm_optional_prefix_size (abfd));
2030 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
2031 if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
2032 != nlm_fixed_header_size (abfd))
2033 goto error_return;
2035 if (fixed_header != NULL)
2036 free (fixed_header);
2037 return TRUE;
2039 error_return:
2040 if (fixed_header != NULL)
2041 free (fixed_header);
2042 return FALSE;