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