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