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