~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/nlmcode.h

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

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