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