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