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