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