OSDN Git Service

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