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