Upload Tizen:Base source
[external/binutils.git] / bfd / nlmcode.h
1 /* NLM (NetWare Loadable Module) executable support for BFD.
2    Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005, 2006, 2007 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 3 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,
23    MA 02110-1301, USA.  */
24
25 #include "sysdep.h"
26 #include "bfd.h"
27 #include "libbfd.h"
28 #include "libnlm.h"
29
30 /* The functions in this file do not use the names they appear to use.
31    This file is actually compiled multiple times, once for each size
32    of NLM target we are using.  At each size we use a different name,
33    constructed by the macro nlmNAME.  For example, the function which
34    is named nlm_symbol_type below is actually named nlm32_symbol_type
35    in the final executable.  */
36
37 #define Nlm_External_Fixed_Header       NlmNAME (External_Fixed_Header)
38 #define Nlm_External_Version_Header     NlmNAME (External_Version_Header)
39 #define Nlm_External_Copyright_Header   NlmNAME (External_Copyright_Header)
40 #define Nlm_External_Extended_Header    NlmNAME (External_Extended_Header)
41 #define Nlm_External_Custom_Header      NlmNAME (External_Custom_Header)
42 #define Nlm_External_Cygnus_Ext_Header  NlmNAME (External_Cygnus_Ext_Header)
43
44 #define nlm_symbol_type                 nlmNAME (symbol_type)
45 #define nlm_get_symtab_upper_bound      nlmNAME (get_symtab_upper_bound)
46 #define nlm_canonicalize_symtab         nlmNAME (canonicalize_symtab)
47 #define nlm_make_empty_symbol           nlmNAME (make_empty_symbol)
48 #define nlm_print_symbol                nlmNAME (print_symbol)
49 #define nlm_get_symbol_info             nlmNAME (get_symbol_info)
50 #define nlm_get_reloc_upper_bound       nlmNAME (get_reloc_upper_bound)
51 #define nlm_canonicalize_reloc          nlmNAME (canonicalize_reloc)
52 #define nlm_object_p                    nlmNAME (object_p)
53 #define nlm_set_section_contents        nlmNAME (set_section_contents)
54 #define nlm_write_object_contents       nlmNAME (write_object_contents)
55
56 #define nlm_swap_fixed_header_in(abfd,src,dst) \
57   (nlm_swap_fixed_header_in_func (abfd)) (abfd, src, dst)
58 #define nlm_swap_fixed_header_out(abfd,src,dst) \
59   (nlm_swap_fixed_header_out_func (abfd)) (abfd, src, dst)
60
61 /* Should perhaps use put_offset, put_word, etc.  For now, the two versions
62    can be handled by explicitly specifying 32 bits or "the long type".  */
63 #if ARCH_SIZE == 64
64 #define put_word        H_PUT_64
65 #define get_word        H_GET_64
66 #endif
67 #if ARCH_SIZE == 32
68 #define put_word        H_PUT_32
69 #define get_word        H_GET_32
70 #endif
71
72 /* Read and swap in the variable length header.  All the fields must
73    exist in the NLM, and must exist in the order they are read here.  */
74
75 static bfd_boolean
76 nlm_swap_variable_header_in (bfd *abfd)
77 {
78   unsigned char temp[NLM_TARGET_LONG_SIZE];
79   bfd_size_type amt;
80
81   /* Read the description length and text members.  */
82   amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
83   if (bfd_bread ((void *) &nlm_variable_header (abfd)->descriptionLength,
84                 amt, abfd) != amt)
85     return FALSE;
86   amt = nlm_variable_header (abfd)->descriptionLength + 1;
87   if (bfd_bread ((void *) nlm_variable_header (abfd)->descriptionText,
88                 amt, abfd) != amt)
89     return FALSE;
90
91   /* Read and convert the stackSize field.  */
92   amt = sizeof (temp);
93   if (bfd_bread ((void *) temp, amt, abfd) != amt)
94     return FALSE;
95   nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
96
97   /* Read and convert the reserved field.  */
98   amt = sizeof (temp);
99   if (bfd_bread ((void *) temp, amt, abfd) != amt)
100     return FALSE;
101   nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
102
103   /* Read the oldThreadName field.  This field is a fixed length string.  */
104   amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
105   if (bfd_bread ((void *) nlm_variable_header (abfd)->oldThreadName,
106                 amt, abfd) != amt)
107     return FALSE;
108
109   /* Read the screen name length and text members.  */
110   amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
111   if (bfd_bread ((void *) & nlm_variable_header (abfd)->screenNameLength,
112                 amt, abfd) != amt)
113     return FALSE;
114   amt = nlm_variable_header (abfd)->screenNameLength + 1;
115   if (bfd_bread ((void *) nlm_variable_header (abfd)->screenName,
116                 amt, abfd) != amt)
117     return FALSE;
118
119   /* Read the thread name length and text members.  */
120   amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
121   if (bfd_bread ((void *) & nlm_variable_header (abfd)->threadNameLength,
122                 amt, abfd) != amt)
123     return FALSE;
124   amt = nlm_variable_header (abfd)->threadNameLength + 1;
125   if (bfd_bread ((void *) nlm_variable_header (abfd)->threadName,
126                 amt, abfd) != amt)
127     return FALSE;
128   return TRUE;
129 }
130
131 /* Add a section to the bfd.  */
132
133 static bfd_boolean
134 add_bfd_section (bfd *abfd,
135                  char *name,
136                  file_ptr offset,
137                  bfd_size_type size,
138                  flagword flags)
139 {
140   asection *newsect;
141
142   newsect = bfd_make_section_with_flags (abfd, name, flags);
143   if (newsect == NULL)
144     return FALSE;
145
146   newsect->vma = 0;             /* NLM's are relocatable.  */
147   newsect->size = size;
148   newsect->filepos = offset;
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 (CONST_STRNEQ (tempstr, "VeRsIoN#"))
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 (CONST_STRNEQ (tempstr, "MeSsAgEs"))
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 (CONST_STRNEQ (tempstr, "CoPyRiGhT="))
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 (CONST_STRNEQ (tempstr, "CuStHeAd"))
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 (CONST_STRNEQ (dataStamp, "CyGnUsEx"))
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               LITMEMCPY (nlm_cygnus_ext_header (abfd), "CyGnUsEx");
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       LITMEMCPY (thdr.stamp, "VeRsIoN#");
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       LITMEMCPY (thdr.stamp, "CoPyRiGhT=");
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       LITMEMCPY (thdr.stamp, "MeSsAgEs");
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       LITMEMCPY (thdr.stamp, "CuStHeAd");
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       LITMEMCPY (thdr.stamp, "CuStHeAd");
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       LITMEMCPY (thdr.dataStamp, "CyGnUsEx");
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 \f
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 \f
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 }