xref: /openbsd/gnu/usr.bin/binutils/bfd/nlmcode.h (revision db3296cf)
1 /* NLM (NetWare Loadable Module) executable support for BFD.
2    Copyright 1993, 1994, 1995, 1998, 2000 Free Software Foundation, Inc.
3 
4    Written by Fred Fish @ Cygnus Support, using ELF support as the
5    template.
6 
7 This file is part of BFD, the Binary File Descriptor library.
8 
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.
13 
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.
18 
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.  */
22 
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26 #include "libnlm.h"
27 
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.  */
34 
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)
41 
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)
53 
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)
58 
59 /* Forward declarations of static functions */
60 
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 *));
81 
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
92 
93 const bfd_target *
94 nlm_object_p (abfd)
95      bfd *abfd;
96 {
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;
104 
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)
109     {
110       if (!(*backend_object_p) (abfd))
111 	goto got_wrong_format_error;
112     }
113 
114   /* Read in the fixed length portion of the NLM header in external format.  */
115 
116   x_fxdhdr = (PTR) bfd_malloc ((size_t) nlm_fixed_header_size (abfd));
117   if (x_fxdhdr == NULL)
118     goto got_no_match;
119 
120   if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=
121       nlm_fixed_header_size (abfd))
122     {
123       if (bfd_get_error () != bfd_error_system_call)
124 	goto got_wrong_format_error;
125       else
126 	goto got_no_match;
127     }
128 
129   /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
130      the tdata pointer in the bfd.  */
131 
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;
136 
137   nlm_tdata (abfd) = new_tdata;
138 
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;
143 
144   /* Check to see if we have an NLM file for this backend by matching
145      the NLM signature.  */
146 
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;
153 
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!) */
157 
158   if (i_fxdhdrp->version > 0xFFFF)
159     goto got_wrong_format_error;
160 
161   /* There's no supported way to check for 32 bit versus 64 bit addresses,
162      so ignore this distinction for now.  (FIXME) */
163 
164   /* Swap in the rest of the required header.  */
165   if (!nlm_swap_variable_header_in (abfd))
166     {
167       if (bfd_get_error () != bfd_error_system_call)
168 	goto got_wrong_format_error;
169       else
170 	goto got_no_match;
171     }
172 
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.  */
178 
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;
194 
195   if (!nlm_swap_auxiliary_headers_in (abfd))
196     goto got_no_match;
197 
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;
205 
206   arch = nlm_architecture (abfd);
207   if (arch != bfd_arch_unknown)
208     bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
209 
210   abfd->flags |= EXEC_P;
211   bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
212 
213   return (abfd->xvec);
214 
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);
224 }
225 
226 /* Add a section to the bfd.  */
227 
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;
235 {
236   asection *newsect;
237 
238   newsect = bfd_make_section (abfd, name);
239   if (newsect == NULL)
240     {
241       return (false);
242     }
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);
249 }
250 
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.  */
253 
254 static boolean
255 nlm_swap_variable_header_in (abfd)
256      bfd *abfd;
257 {
258   unsigned char temp[NLM_TARGET_LONG_SIZE];
259 
260   /* Read the description length and text members.  */
261 
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);
272 
273   /* Read and convert the stackSize field.  */
274 
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);
278 
279   /* Read and convert the reserved field.  */
280 
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);
284 
285   /* Read the oldThreadName field.  This field is a fixed length string.  */
286 
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);
292 
293   /* Read the screen name length and text members.  */
294 
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);
305 
306   /* Read the thread name length and text members.  */
307 
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);
319 }
320 
321 /* Swap and write out the variable length header.  All the fields must
322    exist in the NLM, and must exist in this order.  */
323 
324 static boolean
325 nlm_swap_variable_header_out (abfd)
326      bfd *abfd;
327 {
328   unsigned char temp[NLM_TARGET_LONG_SIZE];
329 
330   /* Write the description length and text members.  */
331 
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);
342 
343   /* Convert and write the stackSize field.  */
344 
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);
349 
350   /* Convert and write the reserved field.  */
351 
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);
356 
357   /* Write the oldThreadName field.  This field is a fixed length string.  */
358 
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);
364 
365   /* Write the screen name length and text members.  */
366 
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);
377 
378   /* Write the thread name length and text members.  */
379 
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);
391 }
392 
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.  */
401 
402 static boolean
403 nlm_swap_auxiliary_headers_in (abfd)
404      bfd *abfd;
405 {
406   char tempstr[16];
407   long position;
408 
409   for (;;)
410     {
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)
418 	{
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);
436 	}
437       else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
438 	{
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);
502 	}
503       else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
504 	{
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);
521 	}
522       else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
523 	{
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;
530 
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
544 	    {
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);
550 	    }
551 	  if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
552 	    dataLength = 0;
553 	  else
554 	    {
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);
560 	    }
561 	  if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
562 	    memset (dataStamp, 0, sizeof (dataStamp));
563 	  else
564 	    {
565 	      if (bfd_read ((PTR) dataStamp, 1, sizeof (dataStamp), abfd)
566 		  != sizeof (dataStamp))
567 		return false;
568 	    }
569 
570 	  /* Read the rest of the header, if any.  */
571 	  if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
572 	    {
573 	      hdr = NULL;
574 	      hdrLength = 0;
575 	    }
576 	  else
577 	    {
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;
584 	    }
585 
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)
590 	    {
591 	      file_ptr pos;
592 	      bfd_byte *contents;
593 	      bfd_byte *p, *pend;
594 
595 	      BFD_ASSERT (hdrLength == 0 && hdr == NULL);
596 
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;
607 
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;
611 
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)
625 		{
626 		  char *name;
627 		  size_t l;
628 		  file_ptr filepos;
629 		  bfd_size_type size;
630 		  asection *newsec;
631 
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
637 		     */
638 
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;
647 
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)
653 		    {
654 		      newsec->filepos = filepos;
655 		      newsec->flags |= SEC_HAS_CONTENTS;
656 		    }
657 		}
658 	    }
659 	  else
660 	    {
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;
669 	    }
670 	}
671       else
672 	{
673 	  break;
674 	}
675     }
676   return (true);
677 }
678 
679 /* Return whether there is a non-zero byte in a memory block.  */
680 
681 static boolean
682 find_nonzero (buf, size)
683      PTR buf;
684      size_t size;
685 {
686   char *p = (char *) buf;
687 
688   while (size-- != 0)
689     if (*p++ != 0)
690       return true;
691   return false;
692 }
693 
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.  */
697 
698 static boolean
699 nlm_swap_auxiliary_headers_out (abfd)
700      bfd *abfd;
701 {
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)))
705     {
706       Nlm_External_Version_Header thdr;
707 
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;
723     }
724 
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)))
728     {
729       Nlm_External_Extended_Header thdr;
730 
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;
821     }
822 
823   /* Write out the copyright header if there is one.  */
824   if (find_nonzero ((PTR) nlm_copyright_header (abfd),
825 		    sizeof (Nlm_Internal_Copyright_Header)))
826     {
827       Nlm_External_Copyright_Header thdr;
828 
829       memcpy (thdr.stamp, "CoPyRiGhT=", 10);
830       if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd)
831 	  != sizeof (thdr.stamp))
832 	return false;
833       thdr.copyrightMessageLength[0] =
834 	nlm_copyright_header (abfd)->copyrightMessageLength;
835       if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1)
836 	return false;
837       /* The copyright message is a variable length string.  */
838       if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
839 		     nlm_copyright_header (abfd)->copyrightMessageLength + 1,
840 		     1, abfd) !=
841 	  ((bfd_size_type)
842 	   nlm_copyright_header (abfd)->copyrightMessageLength + 1))
843 	return false;
844     }
845 
846   /* Write out the custom header if there is one.   */
847   if (find_nonzero ((PTR) nlm_custom_header (abfd),
848 		    sizeof (Nlm_Internal_Custom_Header)))
849     {
850       Nlm_External_Custom_Header thdr;
851       boolean ds;
852       bfd_size_type hdrLength;
853 
854       ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
855 			 sizeof (nlm_custom_header (abfd)->dataStamp));
856       memcpy (thdr.stamp, "CuStHeAd", 8);
857       hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
858 		   + nlm_custom_header (abfd)->hdrLength);
859       put_word (abfd, hdrLength, thdr.length);
860       put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
861 		thdr.dataOffset);
862       put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
863 		thdr.dataLength);
864       if (! ds)
865 	{
866 	  BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
867 	  if (bfd_write ((PTR) &thdr, 1,
868 			 sizeof (thdr) - sizeof (thdr.dataStamp), abfd)
869 	      != sizeof (thdr) - sizeof (thdr.dataStamp))
870 	    return false;
871 	}
872       else
873 	{
874 	  memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
875 		  sizeof (thdr.dataStamp));
876 	  if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
877 	    return false;
878 	  if (bfd_write (nlm_custom_header (abfd)->hdr, 1,
879 			 nlm_custom_header (abfd)->hdrLength, abfd)
880 	      != nlm_custom_header (abfd)->hdrLength)
881 	    return false;
882 	}
883     }
884 
885   /* Write out the Cygnus debugging header if there is one.  */
886   if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
887 		    sizeof (Nlm_Internal_Cygnus_Ext_Header)))
888     {
889       Nlm_External_Custom_Header thdr;
890 
891       memcpy (thdr.stamp, "CuStHeAd", 8);
892       put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
893 		(bfd_byte *) thdr.length);
894       put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
895 		(bfd_byte *) thdr.dataOffset);
896       put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
897 		(bfd_byte *) thdr.dataLength);
898       memcpy (thdr.dataStamp, "CyGnUsEx", 8);
899       if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
900 	return false;
901     }
902 
903   return true;
904 }
905 
906 /* We read the NLM's public symbols and use it to generate a bfd symbol
907    table (hey, it's better than nothing) on a one-for-one basis.  Thus
908    use the number of public symbols as the number of bfd symbols we will
909    have once we actually get around to reading them in.
910 
911    Return the number of bytes required to hold the symtab vector, based on
912    the count plus 1, since we will NULL terminate the vector allocated based
913    on this size.  */
914 
915 long
916 nlm_get_symtab_upper_bound (abfd)
917      bfd *abfd;
918 {
919   Nlm_Internal_Fixed_Header *i_fxdhdrp;	/* Nlm file header, internal form */
920   long symcount;
921   long symtab_size = 0;
922 
923   i_fxdhdrp = nlm_fixed_header (abfd);
924   symcount = (i_fxdhdrp->numberOfPublics
925 	      + i_fxdhdrp->numberOfDebugRecords
926 	      + i_fxdhdrp->numberOfExternalReferences);
927   symtab_size = (symcount + 1) * (sizeof (asymbol));
928   return (symtab_size);
929 }
930 
931 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
932    symbol table fails.  */
933 
934 long
935 nlm_get_symtab (abfd, alocation)
936      bfd *abfd;
937      asymbol **alocation;
938 {
939   nlm_symbol_type *symbase;
940   bfd_size_type counter = 0;
941 
942   if (nlm_slurp_symbol_table (abfd) == false)
943     return -1;
944   symbase = nlm_get_symbols (abfd);
945   while (counter < bfd_get_symcount (abfd))
946     {
947       *alocation++ = &symbase->symbol;
948       symbase++;
949       counter++;
950     }
951   *alocation = (asymbol *) NULL;
952   return bfd_get_symcount (abfd);
953 }
954 
955 /* Make an NLM symbol.  There is nothing special to do here.  */
956 
957 asymbol *
958 nlm_make_empty_symbol (abfd)
959      bfd *abfd;
960 {
961   nlm_symbol_type *new;
962 
963   new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
964   if (new)
965     new->symbol.the_bfd = abfd;
966   return &new->symbol;
967 }
968 
969 /* Get symbol information.  */
970 
971 void
972 nlm_get_symbol_info (ignore_abfd, symbol, ret)
973      bfd *ignore_abfd ATTRIBUTE_UNUSED;
974      asymbol *symbol;
975      symbol_info *ret;
976 {
977   bfd_symbol_info (symbol, ret);
978 }
979 
980 /* Print symbol information.  */
981 
982 void
983 nlm_print_symbol (abfd, afile, symbol, how)
984      bfd *abfd ATTRIBUTE_UNUSED;
985      PTR afile;
986      asymbol *symbol;
987      bfd_print_symbol_type how;
988 {
989   FILE *file = (FILE *) afile;
990 
991   switch (how)
992     {
993     case bfd_print_symbol_name:
994     case bfd_print_symbol_more:
995       if (symbol->name)
996 	fprintf (file, "%s", symbol->name);
997       break;
998     case bfd_print_symbol_all:
999       bfd_print_symbol_vandf ((PTR) file, symbol);
1000       fprintf (file, " %-5s", symbol->section->name);
1001       if (symbol->name)
1002 	fprintf (file, " %s", symbol->name);
1003       break;
1004     }
1005 }
1006 
1007 /* Slurp in nlm symbol table.
1008 
1009    In the external (in-file) form, NLM export records are variable length,
1010    with the following form:
1011 
1012 	1 byte		length of the symbol name (N)
1013 	N bytes		the symbol name
1014 	4 bytes		the symbol offset from start of it's section
1015 
1016    We also read in the debugging symbols and import records.  Import
1017    records are treated as undefined symbols.  As we read the import
1018    records we also read in the associated reloc information, which is
1019    attached to the symbol.
1020 
1021    The bfd symbols are copied to SYMPTRS.
1022 
1023    When we return, the bfd symcount is either zero or contains the correct
1024    number of symbols.
1025 */
1026 
1027 static boolean
1028 nlm_slurp_symbol_table (abfd)
1029      bfd *abfd;
1030 {
1031   Nlm_Internal_Fixed_Header *i_fxdhdrp;	/* Nlm file header, internal form */
1032   bfd_size_type totsymcount;	/* Number of NLM symbols */
1033   bfd_size_type symcount;	/* Counter of NLM symbols */
1034   nlm_symbol_type *sym;		/* Pointer to current bfd symbol */
1035   unsigned char symlength;	/* Symbol length read into here */
1036   unsigned char symtype;	/* Type of debugging symbol */
1037   bfd_byte temp[NLM_TARGET_LONG_SIZE];	/* Symbol offsets read into here */
1038   boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
1039   boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
1040 
1041   if (nlm_get_symbols (abfd) != NULL)
1042     return (true);
1043 
1044   /* Read each raw NLM symbol, using the information to create a canonical bfd
1045      symbol table entry.
1046 
1047      Note that we allocate the initial bfd canonical symbol buffer based on a
1048      one-to-one mapping of the NLM symbols to canonical symbols.  We actually
1049      use all the NLM symbols, so there will be no space left over at the end.
1050      When we have all the symbols, we build the caller's pointer vector.  */
1051 
1052   abfd->symcount = 0;
1053   i_fxdhdrp = nlm_fixed_header (abfd);
1054   totsymcount = (i_fxdhdrp->numberOfPublics
1055 		 + i_fxdhdrp->numberOfDebugRecords
1056 		 + i_fxdhdrp->numberOfExternalReferences);
1057   if (totsymcount == 0)
1058     {
1059       return (true);
1060     }
1061 
1062   if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1)
1063     return (false);
1064 
1065   sym = ((nlm_symbol_type *)
1066 	 bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
1067   if (!sym)
1068     return false;
1069   nlm_set_symbols (abfd, sym);
1070 
1071   /* We use the bfd's symcount directly as the control count, so that early
1072      termination of the loop leaves the symcount correct for the symbols that
1073      were read.  */
1074 
1075   set_public_section_func = nlm_set_public_section_func (abfd);
1076   symcount = i_fxdhdrp->numberOfPublics;
1077   while (abfd->symcount < symcount)
1078     {
1079       if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
1080 	  != sizeof (symlength))
1081 	return (false);
1082       sym->symbol.the_bfd = abfd;
1083       sym->symbol.name = bfd_alloc (abfd, symlength + 1);
1084       if (!sym->symbol.name)
1085 	return false;
1086       if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
1087 	  != symlength)
1088 	return (false);
1089       /* Cast away const.  */
1090       ((char *) (sym->symbol.name))[symlength] = '\0';
1091       if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
1092 	return (false);
1093       sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1094       sym->symbol.value = get_word (abfd, temp);
1095       if (set_public_section_func)
1096 	{
1097 	  /* Most backends can use the code below, but unfortunately
1098 	     some use a different scheme.  */
1099 	  if ((*set_public_section_func) (abfd, sym) == false)
1100 	    return false;
1101 	}
1102       else
1103 	{
1104 	  if (sym->symbol.value & NLM_HIBIT)
1105 	    {
1106 	      sym->symbol.value &= ~NLM_HIBIT;
1107 	      sym->symbol.flags |= BSF_FUNCTION;
1108 	      sym->symbol.section =
1109 		bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1110 	    }
1111 	  else
1112 	    {
1113 	      sym->symbol.section =
1114 		bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1115 	    }
1116 	}
1117       sym->rcnt = 0;
1118       abfd->symcount++;
1119       sym++;
1120     }
1121 
1122   /* Read the debugging records.  */
1123 
1124   if (i_fxdhdrp->numberOfDebugRecords > 0)
1125     {
1126       if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1)
1127 	return (false);
1128 
1129       symcount += i_fxdhdrp->numberOfDebugRecords;
1130       while (abfd->symcount < symcount)
1131 	{
1132 	  if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd)
1133 	       != sizeof (symtype))
1134 	   || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)
1135 	      || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
1136 		  != sizeof (symlength)))
1137 	    return false;
1138 	  sym->symbol.the_bfd = abfd;
1139 	  sym->symbol.name = bfd_alloc (abfd, symlength + 1);
1140 	  if (!sym->symbol.name)
1141 	    return false;
1142 	  if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
1143 	      != symlength)
1144 	    return (false);
1145 	  /* Cast away const.  */
1146 	  ((char *) (sym->symbol.name))[symlength] = '\0';
1147 	  sym->symbol.flags = BSF_LOCAL;
1148 	  sym->symbol.value = get_word (abfd, temp);
1149 	  if (symtype == 0)
1150 	    {
1151 	      sym->symbol.section =
1152 		bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1153 	    }
1154 	  else if (symtype == 1)
1155 	    {
1156 	      sym->symbol.flags |= BSF_FUNCTION;
1157 	      sym->symbol.section =
1158 		bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1159 	    }
1160 	  else
1161 	    {
1162 	      sym->symbol.section = bfd_abs_section_ptr;
1163 	    }
1164 	  sym->rcnt = 0;
1165 	  abfd->symcount++;
1166 	  sym++;
1167 	}
1168     }
1169 
1170   /* Read in the import records.  We can only do this if we know how
1171      to read relocs for this target.  */
1172 
1173   read_import_func = nlm_read_import_func (abfd);
1174   if (read_import_func != NULL)
1175     {
1176       if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET)
1177 	  == -1)
1178 	return (false);
1179 
1180       symcount += i_fxdhdrp->numberOfExternalReferences;
1181       while (abfd->symcount < symcount)
1182 	{
1183 	  if ((*read_import_func) (abfd, sym) == false)
1184 	    return false;
1185 	  sym++;
1186 	  abfd->symcount++;
1187 	}
1188     }
1189 
1190   return (true);
1191 }
1192 
1193 /* Get the relocs for an NLM file.  There are two types of relocs.
1194    Imports are relocs against symbols defined in other NLM files.  We
1195    treat these as relocs against global symbols.  Relocation fixups
1196    are internal relocs.
1197 
1198    The actual format used to store the relocs is machine specific.  */
1199 
1200 /* Read in the relocation fixup information.  This is stored in
1201    nlm_relocation_fixups, an array of arelent structures, and
1202    nlm_relocation_fixup_secs, an array of section pointers.  The
1203    section pointers are needed because the relocs are not sorted by
1204    section.  */
1205 
1206 static boolean
1207 nlm_slurp_reloc_fixups (abfd)
1208      bfd *abfd;
1209 {
1210   boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1211 				arelent *));
1212   bfd_size_type count;
1213   arelent *rels;
1214   asection **secs;
1215 
1216   if (nlm_relocation_fixups (abfd) != NULL)
1217     return true;
1218   read_func = nlm_read_reloc_func (abfd);
1219   if (read_func == NULL)
1220     return true;
1221 
1222   if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1223 		SEEK_SET) != 0)
1224     return false;
1225 
1226   count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1227   rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
1228   secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
1229   if ((rels == NULL || secs == NULL) && count != 0)
1230     return false;
1231   nlm_relocation_fixups (abfd) = rels;
1232   nlm_relocation_fixup_secs (abfd) = secs;
1233 
1234   /* We have to read piece by piece, because we don't know how large
1235      the machine specific reloc information is.  */
1236   while (count-- != 0)
1237     {
1238       if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
1239 	{
1240 	  nlm_relocation_fixups (abfd) = NULL;
1241 	  nlm_relocation_fixup_secs (abfd) = NULL;
1242 	  return false;
1243 	}
1244       ++secs;
1245       ++rels;
1246     }
1247 
1248   return true;
1249 }
1250 
1251 /* Get the number of relocs.  This really just returns an upper bound,
1252    since it does not attempt to distinguish them based on the section.
1253    That will be handled when they are actually read.  */
1254 
1255 long
1256 nlm_get_reloc_upper_bound (abfd, sec)
1257      bfd *abfd;
1258      asection *sec;
1259 {
1260   nlm_symbol_type *syms;
1261   bfd_size_type count;
1262   unsigned int ret;
1263 
1264   /* If we don't know how to read relocs, just return 0.  */
1265   if (nlm_read_reloc_func (abfd) == NULL)
1266     return -1;
1267   /* Make sure we have either the code or the data section.  */
1268   if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1269     return 0;
1270 
1271   syms = nlm_get_symbols (abfd);
1272   if (syms == NULL)
1273     {
1274       if (nlm_slurp_symbol_table (abfd) == false)
1275 	return -1;
1276       syms = nlm_get_symbols (abfd);
1277     }
1278 
1279   ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1280 
1281   count = bfd_get_symcount (abfd);
1282   while (count-- != 0)
1283     {
1284       ret += syms->rcnt;
1285       ++syms;
1286     }
1287 
1288   return (ret + 1) * sizeof (arelent *);
1289 }
1290 
1291 /* Get the relocs themselves.  */
1292 
1293 long
1294 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1295      bfd *abfd;
1296      asection *sec;
1297      arelent **relptr;
1298      asymbol **symbols;
1299 {
1300   arelent *rels;
1301   asection **secs;
1302   bfd_size_type count, i;
1303   unsigned int ret;
1304 
1305   /* Get the relocation fixups.  */
1306   rels = nlm_relocation_fixups (abfd);
1307   if (rels == NULL)
1308     {
1309       if (nlm_slurp_reloc_fixups (abfd) == false)
1310 	return -1;
1311       rels = nlm_relocation_fixups (abfd);
1312     }
1313   secs = nlm_relocation_fixup_secs (abfd);
1314 
1315   ret = 0;
1316   count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1317   for (i = 0; i < count; i++, rels++, secs++)
1318     {
1319       if (*secs == sec)
1320 	{
1321 	  *relptr++ = rels;
1322 	  ++ret;
1323 	}
1324     }
1325 
1326   /* Get the import symbols.  */
1327   count = bfd_get_symcount (abfd);
1328   for (i = 0; i < count; i++, symbols++)
1329     {
1330       asymbol *sym;
1331 
1332       sym = *symbols;
1333       if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1334 	{
1335 	  nlm_symbol_type *nlm_sym;
1336 	  bfd_size_type j;
1337 
1338 	  nlm_sym = (nlm_symbol_type *) sym;
1339 	  for (j = 0; j < nlm_sym->rcnt; j++)
1340 	    {
1341 	      if (nlm_sym->relocs[j].section == sec)
1342 		{
1343 		  *relptr = &nlm_sym->relocs[j].reloc;
1344 		  (*relptr)->sym_ptr_ptr = symbols;
1345 		  ++relptr;
1346 		  ++ret;
1347 		}
1348 	    }
1349 	}
1350     }
1351 
1352   *relptr = NULL;
1353 
1354   return ret;
1355 }
1356 
1357 /* Compute the section file positions for an NLM file.  All variable
1358    length data in the file headers must be set before this function is
1359    called.  If the variable length data is changed later, the
1360    resulting object file will be incorrect.  Unfortunately, there is
1361    no way to check this.
1362 
1363    This routine also sets the Size and Offset fields in the fixed
1364    header.
1365 
1366    It also looks over the symbols and moves any common symbols into
1367    the .bss section; NLM has no way to represent a common symbol.
1368    This approach means that either the symbols must already have been
1369    set at this point, or there must be no common symbols.  We need to
1370    move the symbols at this point so that mangle_relocs can see the
1371    final values.  */
1372 
1373 static boolean
1374 nlm_compute_section_file_positions (abfd)
1375      bfd *abfd;
1376 {
1377   file_ptr sofar;
1378   asection *sec;
1379   bfd_vma text, data, bss;
1380   bfd_vma text_low, data_low;
1381   unsigned int text_align, data_align, other_align;
1382   file_ptr text_ptr, data_ptr, other_ptr;
1383   asection *bss_sec;
1384   asymbol **sym_ptr_ptr;
1385 
1386   if (abfd->output_has_begun == true)
1387     return true;
1388 
1389   /* Make sure we have a section to hold uninitialized data.  */
1390   bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1391   if (bss_sec == NULL)
1392     {
1393       if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1394 			    (file_ptr) 0, (bfd_size_type) 0,
1395 			    SEC_ALLOC))
1396 	return false;
1397       bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1398     }
1399 
1400   abfd->output_has_begun = true;
1401 
1402   /* The fixed header.  */
1403   sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1404 
1405   /* The variable header.  */
1406   sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1407 	    + nlm_variable_header (abfd)->descriptionLength + 1
1408 	    + NLM_TARGET_LONG_SIZE	/* stackSize */
1409 	    + NLM_TARGET_LONG_SIZE	/* reserved */
1410 	    + sizeof (nlm_variable_header (abfd)->oldThreadName)
1411 	    + sizeof (nlm_variable_header (abfd)->screenNameLength)
1412 	    + nlm_variable_header (abfd)->screenNameLength + 1
1413 	    + sizeof (nlm_variable_header (abfd)->threadNameLength)
1414 	    + nlm_variable_header (abfd)->threadNameLength + 1);
1415 
1416   /* The auxiliary headers.  */
1417   if (find_nonzero ((PTR) nlm_version_header (abfd),
1418 		    sizeof (Nlm_Internal_Version_Header)))
1419     sofar += sizeof (Nlm_External_Version_Header);
1420   if (find_nonzero ((PTR) nlm_extended_header (abfd),
1421 		    sizeof (Nlm_Internal_Extended_Header)))
1422     sofar += sizeof (Nlm_External_Extended_Header);
1423   if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1424 		    sizeof (Nlm_Internal_Copyright_Header)))
1425     sofar += (sizeof (Nlm_External_Copyright_Header)
1426 	      + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1427   if (find_nonzero ((PTR) nlm_custom_header (abfd),
1428 		    sizeof (Nlm_Internal_Custom_Header)))
1429     sofar += (sizeof (Nlm_External_Custom_Header)
1430 	      + nlm_custom_header (abfd)->hdrLength);
1431   if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
1432 		    sizeof (Nlm_Internal_Cygnus_Ext_Header)))
1433     sofar += sizeof (Nlm_External_Custom_Header);
1434 
1435   /* Compute the section file positions in two passes.  First get the
1436      sizes of the text and data sections, and then set the file
1437      positions.  This code aligns the sections in the file using the
1438      same alignment restrictions that apply to the sections in memory;
1439      this may not be necessary.  */
1440   text = 0;
1441   text_low = (bfd_vma) - 1;
1442   text_align = 0;
1443   data = 0;
1444   data_low = (bfd_vma) - 1;
1445   data_align = 0;
1446   bss = 0;
1447   other_align = 0;
1448   for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1449     {
1450       flagword f;
1451 
1452       sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1453 
1454       f = bfd_get_section_flags (abfd, sec);
1455       if (f & SEC_CODE)
1456 	{
1457 	  text += sec->_raw_size;
1458 	  if (bfd_get_section_vma (abfd, sec) < text_low)
1459 	    text_low = bfd_get_section_vma (abfd, sec);
1460 	  if (sec->alignment_power > text_align)
1461 	    text_align = sec->alignment_power;
1462 	}
1463       else if (f & SEC_DATA)
1464 	{
1465 	  data += sec->_raw_size;
1466 	  if (bfd_get_section_vma (abfd, sec) < data_low)
1467 	    data_low = bfd_get_section_vma (abfd, sec);
1468 	  if (sec->alignment_power > data_align)
1469 	    data_align = sec->alignment_power;
1470 	}
1471       else if (f & SEC_HAS_CONTENTS)
1472 	{
1473 	  if (sec->alignment_power > other_align)
1474 	    other_align = sec->alignment_power;
1475 	}
1476       else if (f & SEC_ALLOC)
1477 	bss += sec->_raw_size;
1478     }
1479 
1480   nlm_set_text_low (abfd, text_low);
1481   nlm_set_data_low (abfd, data_low);
1482 
1483   if (nlm_no_uninitialized_data (abfd))
1484     {
1485       /* This NetWare format does not use uninitialized data.  We must
1486 	 increase the size of the data section.  We will never wind up
1487 	 writing those file locations, so they will remain zero.  */
1488       data += bss;
1489       bss = 0;
1490     }
1491 
1492   text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1493   data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1494   other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1495 
1496   /* Fill in some fields in the header for which we now have the
1497      information.  */
1498   nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1499   nlm_fixed_header (abfd)->codeImageSize = text;
1500   nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1501   nlm_fixed_header (abfd)->dataImageSize = data;
1502   nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1503 
1504   for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1505     {
1506       flagword f;
1507 
1508       f = bfd_get_section_flags (abfd, sec);
1509 
1510       if (f & SEC_CODE)
1511 	{
1512 	  sec->filepos = text_ptr;
1513 	  text_ptr += sec->_raw_size;
1514 	}
1515       else if (f & SEC_DATA)
1516 	{
1517 	  sec->filepos = data_ptr;
1518 	  data_ptr += sec->_raw_size;
1519 	}
1520       else if (f & SEC_HAS_CONTENTS)
1521 	{
1522 	  sec->filepos = other_ptr;
1523 	  other_ptr += sec->_raw_size;
1524 	}
1525     }
1526 
1527   nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1528 
1529   /* Move all common symbols into the .bss section.  */
1530 
1531   sym_ptr_ptr = bfd_get_outsymbols (abfd);
1532   if (sym_ptr_ptr != NULL)
1533     {
1534       asymbol **sym_end;
1535       bfd_vma add;
1536 
1537       sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1538       add = 0;
1539       for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1540 	{
1541 	  asymbol *sym;
1542 	  bfd_vma size;
1543 
1544 	  sym = *sym_ptr_ptr;
1545 
1546 	  if (!bfd_is_com_section (bfd_get_section (sym)))
1547 	    continue;
1548 
1549 	  /* Put the common symbol in the .bss section, and increase
1550 	     the size of the .bss section by the size of the common
1551 	     symbol (which is the old value of the symbol).  */
1552 	  sym->section = bss_sec;
1553 	  size = sym->value;
1554 	  sym->value = bss_sec->_raw_size + add;
1555 	  add += size;
1556 	  add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1557 	}
1558       if (add != 0)
1559 	{
1560 	  if (nlm_no_uninitialized_data (abfd))
1561 	    {
1562 	      /* We could handle this case, but so far it hasn't been
1563 		 necessary.  */
1564 	      abort ();
1565 	    }
1566 	  nlm_fixed_header (abfd)->uninitializedDataSize += add;
1567 	  bss_sec->_raw_size += add;
1568 	}
1569     }
1570 
1571   return true;
1572 }
1573 
1574 /* Set the contents of a section.  To do this we need to know where
1575    the section is going to be located in the output file.  That means
1576    that the sizes of all the sections must be set, and all the
1577    variable size header information must be known.  */
1578 
1579 boolean
1580 nlm_set_section_contents (abfd, section, location, offset, count)
1581      bfd *abfd;
1582      asection *section;
1583      PTR location;
1584      file_ptr offset;
1585      bfd_size_type count;
1586 {
1587   if (abfd->output_has_begun == false
1588       && nlm_compute_section_file_positions (abfd) == false)
1589     return false;
1590 
1591   if (count == 0)
1592     return true;
1593 
1594   /* i386 NetWare has a very restricted set of relocs.  In order for
1595      objcopy to work, the NLM i386 backend needs a chance to rework
1596      the section contents so that its set of relocs will work.  If all
1597      the relocs are already acceptable, this will not do anything.  */
1598   if (section->reloc_count != 0)
1599     {
1600       boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1601 					     bfd_vma, bfd_size_type));
1602 
1603       mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1604       if (mangle_relocs_func != NULL)
1605 	{
1606 	  if (!(*mangle_relocs_func) (abfd, section, location,
1607 				      (bfd_vma) offset, count))
1608 	    return false;
1609 	}
1610     }
1611 
1612   if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1613       || bfd_write (location, 1, count, abfd) != count)
1614     return false;
1615 
1616   return true;
1617 }
1618 
1619 /* We need to sort a list of relocs associated with sections when we
1620    write out the external relocs.  */
1621 
1622 static int
1623 nlm_external_reloc_compare (p1, p2)
1624      const void *p1;
1625      const void *p2;
1626 {
1627   const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1628   const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1629   int cmp;
1630 
1631   cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1632 		(*r2->rel->sym_ptr_ptr)->name);
1633   if (cmp != 0)
1634     return cmp;
1635 
1636   /* We sort by address within symbol to make the sort more stable and
1637      increase the chances that different hosts will generate bit for
1638      bit equivalent results.  */
1639   return (int) (r1->rel->address - r2->rel->address);
1640 }
1641 
1642 /* Write out an NLM file.  We write out the information in this order:
1643      fixed header
1644      variable header
1645      auxiliary headers
1646      code sections
1647      data sections
1648      other sections (custom data, messages, help, shared NLM, RPC,
1649      		     module dependencies)
1650      relocation fixups
1651      external references (imports)
1652      public symbols (exports)
1653      debugging records
1654    This is similar to the order used by the NetWare tools; the
1655    difference is that NetWare puts the sections other than code, data
1656    and custom data at the end of the NLM.  It is convenient for us to
1657    know where the sections are going to be before worrying about the
1658    size of the other information.
1659 
1660    By the time this function is called, all the section data should
1661    have been output using set_section_contents.  Note that custom
1662    data, the message file, the help file, the shared NLM file, the RPC
1663    data, and the module dependencies are all considered to be
1664    sections; the caller is responsible for filling in the offset and
1665    length fields in the NLM headers.  The relocation fixups and
1666    imports are both obtained from the list of relocs attached to each
1667    section.  The exports and debugging records are obtained from the
1668    list of outsymbols.  */
1669 
1670 boolean
1671 nlm_write_object_contents (abfd)
1672      bfd *abfd;
1673 {
1674   asection *sec;
1675   boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1676   bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1677   struct reloc_and_sec *external_relocs;
1678   asymbol **sym_ptr_ptr;
1679   file_ptr last;
1680   boolean (*write_prefix_func) PARAMS ((bfd *));
1681   unsigned char *fixed_header = NULL;
1682 
1683   fixed_header = ((unsigned char *)
1684 		  bfd_malloc ((size_t) nlm_fixed_header_size (abfd)));
1685   if (fixed_header == NULL)
1686     goto error_return;
1687 
1688   if (abfd->output_has_begun == false
1689       && nlm_compute_section_file_positions (abfd) == false)
1690     goto error_return;
1691 
1692   /* Write out the variable length headers.  */
1693   if (bfd_seek (abfd,
1694 	     nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
1695 		SEEK_SET) != 0)
1696     goto error_return;
1697   if (nlm_swap_variable_header_out (abfd) == false
1698       || nlm_swap_auxiliary_headers_out (abfd) == false)
1699     {
1700       bfd_set_error (bfd_error_system_call);
1701       goto error_return;
1702     }
1703 
1704   /* A weak check on whether the section file positions were
1705      reasonable.  */
1706   if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1707     {
1708       bfd_set_error (bfd_error_invalid_operation);
1709       goto error_return;
1710     }
1711 
1712   /* Advance to the relocs.  */
1713   if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1714 		SEEK_SET) != 0)
1715     goto error_return;
1716 
1717   /* The format of the relocation entries is dependent upon the
1718      particular target.  We use an external routine to write the reloc
1719      out.  */
1720   write_import_func = nlm_write_import_func (abfd);
1721 
1722   /* Write out the internal relocation fixups.  While we're looping
1723      over the relocs, we also count the external relocs, which is
1724      needed when they are written out below.  */
1725   internal_reloc_count = 0;
1726   external_reloc_count = 0;
1727   for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1728     {
1729       arelent **rel_ptr_ptr, **rel_end;
1730 
1731       if (sec->reloc_count == 0)
1732 	continue;
1733 
1734       /* We can only represent relocs within a code or data
1735 	 section.  We ignore them for a debugging section.  */
1736       if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1737 	continue;
1738 
1739       /* We need to know how to write out imports */
1740       if (write_import_func == NULL)
1741 	{
1742 	  bfd_set_error (bfd_error_invalid_operation);
1743 	  goto error_return;
1744 	}
1745 
1746       rel_ptr_ptr = sec->orelocation;
1747       rel_end = rel_ptr_ptr + sec->reloc_count;
1748       for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1749 	{
1750 	  arelent *rel;
1751 	  asymbol *sym;
1752 
1753 	  rel = *rel_ptr_ptr;
1754 	  sym = *rel->sym_ptr_ptr;
1755 
1756 	  if (! bfd_is_und_section (bfd_get_section (sym)))
1757 	    {
1758 	      ++internal_reloc_count;
1759 	      if ((*write_import_func) (abfd, sec, rel) == false)
1760 		goto error_return;
1761 	    }
1762 	  else
1763 	    ++external_reloc_count;
1764 	}
1765     }
1766   nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1767 
1768   /* Write out the imports (relocs against external symbols).  These
1769      are output as a symbol name followed by all the relocs for that
1770      symbol, so we must first gather together all the relocs against
1771      external symbols and sort them.  */
1772   external_relocs =
1773     (struct reloc_and_sec *) bfd_alloc (abfd,
1774 					(external_reloc_count
1775 					 * sizeof (struct reloc_and_sec)));
1776   if (external_relocs == (struct reloc_and_sec *) NULL)
1777     goto error_return;
1778   i = 0;
1779   for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1780     {
1781       arelent **rel_ptr_ptr, **rel_end;
1782 
1783       if (sec->reloc_count == 0)
1784 	continue;
1785 
1786       rel_ptr_ptr = sec->orelocation;
1787       rel_end = rel_ptr_ptr + sec->reloc_count;
1788       for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1789 	{
1790 	  arelent *rel;
1791 	  asymbol *sym;
1792 
1793 	  rel = *rel_ptr_ptr;
1794 	  sym = *rel->sym_ptr_ptr;
1795 
1796 	  if (! bfd_is_und_section (bfd_get_section (sym)))
1797 	    continue;
1798 
1799 	  external_relocs[i].rel = rel;
1800 	  external_relocs[i].sec = sec;
1801 	  ++i;
1802 	}
1803     }
1804 
1805   BFD_ASSERT (i == external_reloc_count);
1806 
1807   /* Sort the external relocs by name.  */
1808   qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1809 	 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1810 
1811   /* Write out the external relocs.  */
1812   nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1813   c = 0;
1814   i = 0;
1815   while (i < external_reloc_count)
1816     {
1817       arelent *rel;
1818       asymbol *sym;
1819       bfd_size_type j, cnt;
1820 
1821       ++c;
1822 
1823       rel = external_relocs[i].rel;
1824       sym = *rel->sym_ptr_ptr;
1825 
1826       cnt = 0;
1827       for (j = i;
1828 	   (j < external_reloc_count
1829 	    && *external_relocs[j].rel->sym_ptr_ptr == sym);
1830 	   j++)
1831 	++cnt;
1832 
1833       if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1834 					     &external_relocs[i])
1835 	  == false)
1836 	goto error_return;
1837 
1838       i += cnt;
1839     }
1840 
1841   nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1842 
1843   /* Write out the public symbols (exports).  */
1844   sym_ptr_ptr = bfd_get_outsymbols (abfd);
1845   if (sym_ptr_ptr != (asymbol **) NULL)
1846     {
1847       bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1848       boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1849 
1850       asymbol **sym_end;
1851 
1852       nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1853       get_public_offset_func = nlm_get_public_offset_func (abfd);
1854       write_export_func = nlm_write_export_func (abfd);
1855       c = 0;
1856       sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1857       for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1858 	{
1859 	  asymbol *sym;
1860 	  bfd_byte len;
1861 	  bfd_vma offset;
1862 	  bfd_byte temp[NLM_TARGET_LONG_SIZE];
1863 
1864 	  sym = *sym_ptr_ptr;
1865 
1866 	  if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1867 	      || bfd_is_und_section (bfd_get_section (sym)))
1868 	    continue;
1869 
1870 	  ++c;
1871 
1872 	  if (get_public_offset_func)
1873 	    {
1874 	      /* Most backends can use the code below, but
1875 		 unfortunately some use a different scheme.  */
1876 	      offset = (*get_public_offset_func) (abfd, sym);
1877 	    }
1878 	  else
1879 	    {
1880 	      offset = bfd_asymbol_value (sym);
1881 	      sec = sym->section;
1882 	      if (sec->flags & SEC_CODE)
1883 		{
1884 		  offset -= nlm_get_text_low (abfd);
1885 		  offset |= NLM_HIBIT;
1886 		}
1887 	      else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1888 		{
1889 		  /* SEC_ALLOC is for the .bss section.  */
1890 		  offset -= nlm_get_data_low (abfd);
1891 		}
1892 	      else
1893 		{
1894 		  /* We can't handle an exported symbol that is not in
1895 		     the code or data segment.  */
1896 		  bfd_set_error (bfd_error_invalid_operation);
1897 		  goto error_return;
1898 		}
1899 	    }
1900 
1901 	  if (write_export_func)
1902 	    {
1903 	      if ((*write_export_func) (abfd, sym, offset) == false)
1904 		goto error_return;
1905 	    }
1906 	  else
1907 	    {
1908 	      len = strlen (sym->name);
1909 	      if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1910 		   != sizeof (bfd_byte))
1911 		  || bfd_write (sym->name, len, 1, abfd) != len)
1912 		goto error_return;
1913 
1914 	      put_word (abfd, offset, temp);
1915 	      if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1916 		goto error_return;
1917 	    }
1918 	}
1919       nlm_fixed_header (abfd)->numberOfPublics = c;
1920 
1921       /* Write out the debugging records.  The NLM conversion program
1922 	 wants to be able to inhibit this, so as a special hack if
1923 	 debugInfoOffset is set to -1 we don't write any debugging
1924 	 information.  This can not be handled by fiddling with the
1925 	 symbol table, because exported symbols appear in both the
1926 	 exported symbol list and the debugging information.  */
1927       if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1928 	{
1929 	  nlm_fixed_header (abfd)->debugInfoOffset = 0;
1930 	  nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1931 	}
1932       else
1933 	{
1934 	  nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1935 	  c = 0;
1936 	  sym_ptr_ptr = bfd_get_outsymbols (abfd);
1937 	  sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1938 	  for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1939 	    {
1940 	      asymbol *sym;
1941 	      bfd_byte type, len;
1942 	      bfd_vma offset;
1943 	      bfd_byte temp[NLM_TARGET_LONG_SIZE];
1944 
1945 	      sym = *sym_ptr_ptr;
1946 
1947 	      /* The NLM notion of a debugging symbol is actually what
1948 		 BFD calls a local or global symbol.  What BFD calls a
1949 		 debugging symbol NLM does not understand at all.  */
1950 	      if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1951 		  || (sym->flags & BSF_DEBUGGING) != 0
1952 		  || bfd_is_und_section (bfd_get_section (sym)))
1953 		continue;
1954 
1955 	      ++c;
1956 
1957 	      offset = bfd_asymbol_value (sym);
1958 	      sec = sym->section;
1959 	      if (sec->flags & SEC_CODE)
1960 		{
1961 		  offset -= nlm_get_text_low (abfd);
1962 		  type = 1;
1963 		}
1964 	      else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1965 		{
1966 		  /* SEC_ALLOC is for the .bss section.  */
1967 		  offset -= nlm_get_data_low (abfd);
1968 		  type = 0;
1969 		}
1970 	      else
1971 		type = 2;
1972 
1973 	      /* The type is 0 for data, 1 for code, 2 for absolute.  */
1974 	      if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1975 		  != sizeof (bfd_byte))
1976 		goto error_return;
1977 
1978 	      put_word (abfd, offset, temp);
1979 	      if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1980 		goto error_return;
1981 
1982 	      len = strlen (sym->name);
1983 	      if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1984 		   != sizeof (bfd_byte))
1985 		  || bfd_write (sym->name, len, 1, abfd) != len)
1986 		goto error_return;
1987 	    }
1988 	  nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1989 	}
1990     }
1991 
1992   /* NLMLINK fills in offset values even if there is no data, so we do
1993      the same.  */
1994   last = bfd_tell (abfd);
1995   if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1996     nlm_fixed_header (abfd)->codeImageOffset = last;
1997   if (nlm_fixed_header (abfd)->dataImageOffset == 0)
1998     nlm_fixed_header (abfd)->dataImageOffset = last;
1999   if (nlm_fixed_header (abfd)->customDataOffset == 0)
2000     nlm_fixed_header (abfd)->customDataOffset = last;
2001   if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
2002     nlm_fixed_header (abfd)->moduleDependencyOffset = last;
2003   if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
2004     nlm_fixed_header (abfd)->relocationFixupOffset = last;
2005   if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
2006     nlm_fixed_header (abfd)->externalReferencesOffset = last;
2007   if (nlm_fixed_header (abfd)->publicsOffset == 0)
2008     nlm_fixed_header (abfd)->publicsOffset = last;
2009   if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
2010     nlm_fixed_header (abfd)->debugInfoOffset = last;
2011 
2012   /* At this point everything has been written out except the fixed
2013      header.  */
2014   memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
2015 	  NLM_SIGNATURE_SIZE);
2016   nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
2017   nlm_fixed_header (abfd)->codeStartOffset =
2018     (bfd_get_start_address (abfd)
2019      - nlm_get_text_low (abfd));
2020 
2021   /* We have no convenient way for the caller to pass in the exit
2022      procedure or the check unload procedure, so the caller must set
2023      the values in the header to the values of the symbols.  */
2024   nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
2025   if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
2026     nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
2027       nlm_get_text_low (abfd);
2028 
2029   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
2030     goto error_return;
2031 
2032   write_prefix_func = nlm_write_prefix_func (abfd);
2033   if (write_prefix_func)
2034     {
2035       if ((*write_prefix_func) (abfd) == false)
2036 	goto error_return;
2037     }
2038 
2039   BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
2040 	      == nlm_optional_prefix_size (abfd));
2041 
2042   nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
2043   if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
2044       != nlm_fixed_header_size (abfd))
2045     goto error_return;
2046 
2047   if (fixed_header != NULL)
2048     free (fixed_header);
2049   return true;
2050 
2051 error_return:
2052   if (fixed_header != NULL)
2053     free (fixed_header);
2054   return false;
2055 }
2056