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