Update year range in copyright notice of binutils files
[deliverable/binutils-gdb.git] / bfd / nlmcode.h
1 /* NLM (NetWare Loadable Module) executable support for BFD.
2 Copyright (C) 1993-2018 Free Software Foundation, Inc.
3
4 Written by Fred Fish @ Cygnus Support, using ELF support as the
5 template.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 #include "sysdep.h"
25 #include "bfd.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_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)
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 /* 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
63 #define put_word H_PUT_64
64 #define get_word H_GET_64
65 #endif
66 #if ARCH_SIZE == 32
67 #define put_word H_PUT_32
68 #define get_word H_GET_32
69 #endif
70
71 /* Read and swap in the variable length header. All the fields must
72 exist in the NLM, and must exist in the order they are read here. */
73
74 static bfd_boolean
75 nlm_swap_variable_header_in (bfd *abfd)
76 {
77 unsigned char temp[NLM_TARGET_LONG_SIZE];
78 bfd_size_type amt;
79
80 /* Read the description length and text members. */
81 amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
82 if (bfd_bread ((void *) &nlm_variable_header (abfd)->descriptionLength,
83 amt, abfd) != amt)
84 return FALSE;
85 amt = nlm_variable_header (abfd)->descriptionLength + 1;
86 if (bfd_bread ((void *) nlm_variable_header (abfd)->descriptionText,
87 amt, abfd) != amt)
88 return FALSE;
89
90 /* Read and convert the stackSize field. */
91 amt = sizeof (temp);
92 if (bfd_bread ((void *) temp, amt, abfd) != amt)
93 return FALSE;
94 nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
95
96 /* Read and convert the reserved field. */
97 amt = sizeof (temp);
98 if (bfd_bread ((void *) temp, amt, abfd) != amt)
99 return FALSE;
100 nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
101
102 /* Read the oldThreadName field. This field is a fixed length string. */
103 amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
104 if (bfd_bread ((void *) nlm_variable_header (abfd)->oldThreadName,
105 amt, abfd) != amt)
106 return FALSE;
107
108 /* Read the screen name length and text members. */
109 amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
110 if (bfd_bread ((void *) & nlm_variable_header (abfd)->screenNameLength,
111 amt, abfd) != amt)
112 return FALSE;
113 amt = nlm_variable_header (abfd)->screenNameLength + 1;
114 if (bfd_bread ((void *) nlm_variable_header (abfd)->screenName,
115 amt, abfd) != amt)
116 return FALSE;
117
118 /* Read the thread name length and text members. */
119 amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
120 if (bfd_bread ((void *) & nlm_variable_header (abfd)->threadNameLength,
121 amt, abfd) != amt)
122 return FALSE;
123 amt = nlm_variable_header (abfd)->threadNameLength + 1;
124 if (bfd_bread ((void *) nlm_variable_header (abfd)->threadName,
125 amt, abfd) != amt)
126 return FALSE;
127 return TRUE;
128 }
129
130 /* Add a section to the bfd. */
131
132 static bfd_boolean
133 add_bfd_section (bfd *abfd,
134 char *name,
135 file_ptr offset,
136 bfd_size_type size,
137 flagword flags)
138 {
139 asection *newsect;
140
141 newsect = bfd_make_section_with_flags (abfd, name, flags);
142 if (newsect == NULL)
143 return FALSE;
144
145 newsect->vma = 0; /* NLM's are relocatable. */
146 newsect->size = size;
147 newsect->filepos = offset;
148 newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */
149
150 return TRUE;
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
160 recognize it. */
161
162 static bfd_boolean
163 nlm_swap_auxiliary_headers_in (bfd *abfd)
164 {
165 char tempstr[16];
166 file_ptr position;
167 bfd_size_type amt;
168
169 for (;;)
170 {
171 position = bfd_tell (abfd);
172 amt = sizeof (tempstr);
173 if (bfd_bread ((void *) tempstr, amt, abfd) != amt)
174 return FALSE;
175 if (bfd_seek (abfd, position, SEEK_SET) != 0)
176 return FALSE;
177 if (CONST_STRNEQ (tempstr, "VeRsIoN#"))
178 {
179 Nlm_External_Version_Header thdr;
180
181 amt = sizeof (thdr);
182 if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
183 return FALSE;
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 }
199 else if (CONST_STRNEQ (tempstr, "MeSsAgEs"))
200 {
201 Nlm_External_Extended_Header thdr;
202
203 amt = sizeof (thdr);
204 if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
205 return FALSE;
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 }
267 else if (CONST_STRNEQ (tempstr, "CoPyRiGhT="))
268 {
269 amt = sizeof (nlm_copyright_header (abfd)->stamp);
270 if (bfd_bread ((void *) nlm_copyright_header (abfd)->stamp,
271 amt, abfd) != amt)
272 return FALSE;
273 if (bfd_bread ((void *) &(nlm_copyright_header (abfd)
274 ->copyrightMessageLength),
275 (bfd_size_type) 1, abfd) != 1)
276 return FALSE;
277 /* The copyright message is a variable length string. */
278 amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
279 if (bfd_bread ((void *) nlm_copyright_header (abfd)->copyrightMessage,
280 amt, abfd) != amt)
281 return FALSE;
282 }
283 else if (CONST_STRNEQ (tempstr, "CuStHeAd"))
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];
290 void * hdr;
291
292 /* Read the stamp ("CuStHeAd"). */
293 amt = sizeof (thdr.stamp);
294 if (bfd_bread ((void *) thdr.stamp, amt, abfd) != amt)
295 return FALSE;
296 /* Read the length of this custom header. */
297 amt = sizeof (thdr.length);
298 if (bfd_bread ((void *) thdr.length, amt, abfd) != amt)
299 return FALSE;
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 {
306 amt = sizeof (thdr.dataOffset);
307 if (bfd_bread ((void *) thdr.dataOffset, amt, abfd) != amt)
308 return FALSE;
309 dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
310 }
311 if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
312 dataLength = 0;
313 else
314 {
315 amt = sizeof (thdr.dataLength);
316 if (bfd_bread ((void *) thdr.dataLength, amt, abfd) != amt)
317 return FALSE;
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 {
324 amt = sizeof (dataStamp);
325 if (bfd_bread ((void *) dataStamp, amt, abfd) != amt)
326 return FALSE;
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)
340 return FALSE;
341 if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
342 return FALSE;
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. */
348 if (CONST_STRNEQ (dataStamp, "CyGnUsEx"))
349 {
350 file_ptr pos;
351 bfd_byte *contents;
352 bfd_byte *p, *pend;
353
354 /* See PR 21840 for a reproducer. */
355 if (hdrLength != 0 || hdr != NULL)
356 return FALSE;
357
358 pos = bfd_tell (abfd);
359 if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
360 return FALSE;
361 contents = bfd_alloc (abfd, dataLength);
362 if (contents == NULL)
363 return FALSE;
364 if (bfd_bread (contents, dataLength, abfd) != dataLength)
365 return FALSE;
366 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
367 return FALSE;
368
369 LITMEMCPY (nlm_cygnus_ext_header (abfd), "CyGnUsEx");
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
397 4 byte section size. */
398
399 name = (char *) p;
400 l = strlen (name) + 1;
401 l = (l + 3) &~ (size_t) 3;
402 p += l;
403 filepos = H_GET_32 (abfd, p);
404 p += 4;
405 size = H_GET_32 (abfd, p);
406 p += 4;
407
408 newsec = bfd_make_section_anyway (abfd, name);
409 if (newsec == NULL)
410 return FALSE;
411 newsec->size = size;
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
432 break;
433 }
434 return TRUE;
435 }
436
437 const bfd_target *
438 nlm_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
495 /* There's no supported way to discover the endianness of an NLM, so test for
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
553 got_wrong_format_error:
554 bfd_set_error (bfd_error_wrong_format);
555 got_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
568 static bfd_boolean
569 nlm_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
622 /* Return whether there is a non-zero byte in a memory block. */
623
624 static bfd_boolean
625 find_nonzero (void * buf, size_t size)
626 {
627 char *p = (char *) buf;
628
629 while (size-- != 0)
630 if (*p++ != 0)
631 return TRUE;
632 return FALSE;
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
639 static bfd_boolean
640 nlm_swap_auxiliary_headers_out (bfd *abfd)
641 {
642 bfd_size_type amt;
643
644 /* Write out the version header if there is one. */
645 if (find_nonzero (nlm_version_header (abfd),
646 sizeof (Nlm_Internal_Version_Header)))
647 {
648 Nlm_External_Version_Header thdr;
649
650 LITMEMCPY (thdr.stamp, "VeRsIoN#");
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);
663 if (bfd_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
664 != sizeof (thdr))
665 return FALSE;
666 }
667
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. */
672 if (find_nonzero (nlm_copyright_header (abfd),
673 sizeof (Nlm_Internal_Copyright_Header)))
674 {
675 Nlm_External_Copyright_Header thdr;
676
677 LITMEMCPY (thdr.stamp, "CoPyRiGhT=");
678 amt = sizeof (thdr.stamp);
679 if (bfd_bwrite ((void *) thdr.stamp, amt, abfd) != amt)
680 return FALSE;
681 thdr.copyrightMessageLength[0] =
682 nlm_copyright_header (abfd)->copyrightMessageLength;
683 amt = 1;
684 if (bfd_bwrite ((void *) thdr.copyrightMessageLength, amt, abfd) != amt)
685 return FALSE;
686 /* The copyright message is a variable length string. */
687 amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
688 if (bfd_bwrite ((void *) nlm_copyright_header (abfd)->copyrightMessage,
689 amt, abfd) != amt)
690 return FALSE;
691 }
692
693 /* Write out the extended header if there is one. */
694 if (find_nonzero (nlm_extended_header (abfd),
695 sizeof (Nlm_Internal_Extended_Header)))
696 {
697 Nlm_External_Extended_Header thdr;
698
699 LITMEMCPY (thdr.stamp, "MeSsAgEs");
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);
787 if (bfd_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
788 != sizeof (thdr))
789 return FALSE;
790 }
791
792 /* Write out the custom header if there is one. */
793 if (find_nonzero (nlm_custom_header (abfd),
794 sizeof (Nlm_Internal_Custom_Header)))
795 {
796 Nlm_External_Custom_Header thdr;
797 bfd_boolean ds;
798 bfd_size_type hdrLength;
799
800 ds = find_nonzero (nlm_custom_header (abfd)->dataStamp,
801 sizeof (nlm_custom_header (abfd)->dataStamp));
802 LITMEMCPY (thdr.stamp, "CuStHeAd");
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);
813 amt = sizeof (thdr) - sizeof (thdr.dataStamp);
814 if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
815 return FALSE;
816 }
817 else
818 {
819 memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
820 sizeof (thdr.dataStamp));
821 amt = sizeof (thdr);
822 if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
823 return FALSE;
824 amt = nlm_custom_header (abfd)->hdrLength;
825 if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
826 return FALSE;
827 }
828 }
829
830 /* Write out the Cygnus debugging header if there is one. */
831 if (find_nonzero (nlm_cygnus_ext_header (abfd),
832 sizeof (Nlm_Internal_Cygnus_Ext_Header)))
833 {
834 Nlm_External_Custom_Header thdr;
835
836 LITMEMCPY (thdr.stamp, "CuStHeAd");
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);
843 LITMEMCPY (thdr.dataStamp, "CyGnUsEx");
844 amt = sizeof (thdr);
845 if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
846 return FALSE;
847 }
848
849 return TRUE;
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
859 on this size. */
860
861 long
862 nlm_get_symtab_upper_bound (bfd *abfd)
863 {
864 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */
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));
873 return symtab_size;
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
890 The bfd symbols are copied to SYMvoid *S.
891
892 When we return, the bfd symcount is either zero or contains the correct
893 number of symbols. */
894
895 static bfd_boolean
896 nlm_slurp_symbol_table (bfd *abfd)
897 {
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. */
905 bfd_boolean (*read_import_func) (bfd *, nlm_symbol_type *);
906 bfd_boolean (*set_public_section_func) (bfd *, nlm_symbol_type *);
907 bfd_size_type amt;
908
909 if (nlm_get_symbols (abfd) != NULL)
910 return TRUE;
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.
918 When we have all the symbols, we build the caller's pointer vector. */
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)
926 return TRUE;
927
928 if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
929 return FALSE;
930
931 amt = totsymcount * sizeof (nlm_symbol_type);
932 sym = bfd_zalloc (abfd, amt);
933 if (!sym)
934 return FALSE;
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
939 were read. */
940
941 set_public_section_func = nlm_set_public_section_func (abfd);
942 symcount = i_fxdhdrp->numberOfPublics;
943 while (abfd->symcount < symcount)
944 {
945 amt = sizeof (symlength);
946 if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
947 return FALSE;
948 amt = symlength;
949 sym->symbol.the_bfd = abfd;
950 sym->symbol.name = bfd_alloc (abfd, amt + 1);
951 if (!sym->symbol.name)
952 return FALSE;
953 if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
954 return FALSE;
955 /* Cast away const. */
956 ((char *) (sym->symbol.name))[symlength] = '\0';
957 amt = sizeof (temp);
958 if (bfd_bread ((void *) temp, amt, abfd) != amt)
959 return FALSE;
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. */
966 if (! (*set_public_section_func) (abfd, sym))
967 return FALSE;
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
979 sym->symbol.section =
980 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
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 {
991 if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
992 return FALSE;
993
994 symcount += i_fxdhdrp->numberOfDebugRecords;
995 while (abfd->symcount < symcount)
996 {
997 amt = sizeof (symtype);
998 if (bfd_bread ((void *) &symtype, amt, abfd) != amt)
999 return FALSE;
1000 amt = sizeof (temp);
1001 if (bfd_bread ((void *) temp, amt, abfd) != amt)
1002 return FALSE;
1003 amt = sizeof (symlength);
1004 if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
1005 return FALSE;
1006 amt = symlength;
1007 sym->symbol.the_bfd = abfd;
1008 sym->symbol.name = bfd_alloc (abfd, amt + 1);
1009 if (!sym->symbol.name)
1010 return FALSE;
1011 if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
1012 return FALSE;
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);
1017
1018 if (symtype == 0)
1019 sym->symbol.section =
1020 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
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
1028 sym->symbol.section = bfd_abs_section_ptr;
1029
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. */
1038 read_import_func = nlm_read_import_func (abfd);
1039 if (read_import_func != NULL)
1040 {
1041 if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
1042 return FALSE;
1043
1044 symcount += i_fxdhdrp->numberOfExternalReferences;
1045 while (abfd->symcount < symcount)
1046 {
1047 if (! (*read_import_func) (abfd, sym))
1048 return FALSE;
1049 sym++;
1050 abfd->symcount++;
1051 }
1052 }
1053
1054 return TRUE;
1055 }
1056
1057 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
1058 symbol table fails. */
1059
1060 long
1061 nlm_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
1081 asymbol *
1082 nlm_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
1095 void
1096 nlm_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
1105 void
1106 nlm_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 }
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
1142 static bfd_boolean
1143 nlm_slurp_reloc_fixups (bfd *abfd)
1144 {
1145 bfd_boolean (*read_func) (bfd *, nlm_symbol_type *, asection **, arelent *);
1146 bfd_size_type count, amt;
1147 arelent *rels;
1148 asection **secs;
1149
1150 if (nlm_relocation_fixups (abfd) != NULL)
1151 return TRUE;
1152 read_func = nlm_read_reloc_func (abfd);
1153 if (read_func == NULL)
1154 return TRUE;
1155
1156 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1157 SEEK_SET) != 0)
1158 return FALSE;
1159
1160 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1161 amt = count * sizeof (arelent);
1162 rels = bfd_alloc (abfd, amt);
1163 amt = count * sizeof (asection *);
1164 secs = bfd_alloc (abfd, amt);
1165 if ((rels == NULL || secs == NULL) && count != 0)
1166 return FALSE;
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 {
1174 if (! (*read_func) (abfd, NULL, secs, rels))
1175 {
1176 nlm_relocation_fixups (abfd) = NULL;
1177 nlm_relocation_fixup_secs (abfd) = NULL;
1178 return FALSE;
1179 }
1180 ++secs;
1181 ++rels;
1182 }
1183
1184 return TRUE;
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
1191 long
1192 nlm_get_reloc_upper_bound (bfd *abfd, asection *sec)
1193 {
1194 nlm_symbol_type *syms;
1195 bfd_size_type count;
1196 unsigned int ret;
1197
1198 /* If we don't know how to read relocs, just return 0. */
1199 if (nlm_read_reloc_func (abfd) == NULL)
1200 return -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 {
1208 if (! nlm_slurp_symbol_table (abfd))
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
1227 long
1228 nlm_canonicalize_reloc (bfd *abfd,
1229 asection *sec,
1230 arelent **relptr,
1231 asymbol **symbols)
1232 {
1233 arelent *rels;
1234 asection **secs;
1235 bfd_size_type count, i;
1236 long ret;
1237
1238 /* Get the relocation fixups. */
1239 rels = nlm_relocation_fixups (abfd);
1240 if (rels == NULL)
1241 {
1242 if (! nlm_slurp_reloc_fixups (abfd))
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
1306 static bfd_boolean
1307 nlm_compute_section_file_positions (bfd *abfd)
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
1318 if (abfd->output_has_begun)
1319 return TRUE;
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))
1328 return FALSE;
1329 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1330 }
1331
1332 abfd->output_has_begun = TRUE;
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. */
1349 if (find_nonzero (nlm_version_header (abfd),
1350 sizeof (Nlm_Internal_Version_Header)))
1351 sofar += sizeof (Nlm_External_Version_Header);
1352 if (find_nonzero (nlm_extended_header (abfd),
1353 sizeof (Nlm_Internal_Extended_Header)))
1354 sofar += sizeof (Nlm_External_Extended_Header);
1355 if (find_nonzero (nlm_copyright_header (abfd),
1356 sizeof (Nlm_Internal_Copyright_Header)))
1357 sofar += (sizeof (Nlm_External_Copyright_Header)
1358 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1359 if (find_nonzero (nlm_custom_header (abfd),
1360 sizeof (Nlm_Internal_Custom_Header)))
1361 sofar += (sizeof (Nlm_External_Custom_Header)
1362 + nlm_custom_header (abfd)->hdrLength);
1363 if (find_nonzero (nlm_cygnus_ext_header (abfd),
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;
1380 for (sec = abfd->sections; sec != NULL; sec = sec->next)
1381 {
1382 flagword f;
1383
1384 sec->size = BFD_ALIGN (sec->size, 1 << sec->alignment_power);
1385
1386 f = bfd_get_section_flags (abfd, sec);
1387 if (f & SEC_CODE)
1388 {
1389 text += sec->size;
1390 if (bfd_get_section_vma (abfd, sec) < text_low)
1391 text_low = bfd_get_section_vma (abfd, sec);
1392 if (sec->alignment_power > text_align)
1393 text_align = sec->alignment_power;
1394 }
1395 else if (f & SEC_DATA)
1396 {
1397 data += sec->size;
1398 if (bfd_get_section_vma (abfd, sec) < data_low)
1399 data_low = bfd_get_section_vma (abfd, sec);
1400 if (sec->alignment_power > data_align)
1401 data_align = sec->alignment_power;
1402 }
1403 else if (f & SEC_HAS_CONTENTS)
1404 {
1405 if (sec->alignment_power > other_align)
1406 other_align = sec->alignment_power;
1407 }
1408 else if (f & SEC_ALLOC)
1409 bss += sec->size;
1410 }
1411
1412 nlm_set_text_low (abfd, text_low);
1413 nlm_set_data_low (abfd, data_low);
1414
1415 if (nlm_no_uninitialized_data (abfd))
1416 {
1417 /* This NetWare format does not use uninitialized data. We must
1418 increase the size of the data section. We will never wind up
1419 writing those file locations, so they will remain zero. */
1420 data += bss;
1421 bss = 0;
1422 }
1423
1424 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1425 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1426 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1427
1428 /* Fill in some fields in the header for which we now have the
1429 information. */
1430 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1431 nlm_fixed_header (abfd)->codeImageSize = text;
1432 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1433 nlm_fixed_header (abfd)->dataImageSize = data;
1434 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1435
1436 for (sec = abfd->sections; sec != NULL; sec = sec->next)
1437 {
1438 flagword f;
1439
1440 f = bfd_get_section_flags (abfd, sec);
1441
1442 if (f & SEC_CODE)
1443 {
1444 sec->filepos = text_ptr;
1445 text_ptr += sec->size;
1446 }
1447 else if (f & SEC_DATA)
1448 {
1449 sec->filepos = data_ptr;
1450 data_ptr += sec->size;
1451 }
1452 else if (f & SEC_HAS_CONTENTS)
1453 {
1454 sec->filepos = other_ptr;
1455 other_ptr += sec->size;
1456 }
1457 }
1458
1459 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1460
1461 /* Move all common symbols into the .bss section. */
1462
1463 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1464 if (sym_ptr_ptr != NULL)
1465 {
1466 asymbol **sym_end;
1467 bfd_vma add;
1468
1469 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1470 add = 0;
1471 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1472 {
1473 asymbol *sym;
1474 bfd_vma size;
1475
1476 sym = *sym_ptr_ptr;
1477
1478 if (!bfd_is_com_section (bfd_get_section (sym)))
1479 continue;
1480
1481 /* Put the common symbol in the .bss section, and increase
1482 the size of the .bss section by the size of the common
1483 symbol (which is the old value of the symbol). */
1484 sym->section = bss_sec;
1485 size = sym->value;
1486 sym->value = bss_sec->size + add;
1487 add += size;
1488 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1489 }
1490 if (add != 0)
1491 {
1492 if (nlm_no_uninitialized_data (abfd))
1493 {
1494 /* We could handle this case, but so far it hasn't been
1495 necessary. */
1496 abort ();
1497 }
1498 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1499 bss_sec->size += add;
1500 }
1501 }
1502
1503 return TRUE;
1504 }
1505
1506 /* Set the contents of a section. To do this we need to know where
1507 the section is going to be located in the output file. That means
1508 that the sizes of all the sections must be set, and all the
1509 variable size header information must be known. */
1510
1511 bfd_boolean
1512 nlm_set_section_contents (bfd *abfd,
1513 asection *section,
1514 const void * location,
1515 file_ptr offset,
1516 bfd_size_type count)
1517 {
1518 if (! abfd->output_has_begun
1519 && ! nlm_compute_section_file_positions (abfd))
1520 return FALSE;
1521
1522 if (count == 0)
1523 return TRUE;
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 {
1531 bfd_boolean (*mangle_relocs_func)
1532 (bfd *, asection *, const void *, bfd_vma, bfd_size_type);
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))
1539 return FALSE;
1540 }
1541 }
1542
1543 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1544 || bfd_bwrite (location, count, abfd) != count)
1545 return FALSE;
1546
1547 return TRUE;
1548 }
1549
1550 /* We need to sort a list of relocs associated with sections when we
1551 write out the external relocs. */
1552
1553 static int
1554 nlm_external_reloc_compare (const void *p1, const void *p2)
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,
1578 module dependencies)
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
1599 bfd_boolean
1600 nlm_write_object_contents (bfd *abfd)
1601 {
1602 asection *sec;
1603 bfd_boolean (*write_import_func) (bfd *, asection *, arelent *);
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;
1608 bfd_boolean (*write_prefix_func) (bfd *);
1609 unsigned char *fixed_header = NULL;
1610 file_ptr pos;
1611 bfd_size_type amt;
1612
1613 fixed_header = bfd_malloc (nlm_fixed_header_size (abfd));
1614 if (fixed_header == NULL)
1615 goto error_return;
1616
1617 if (! abfd->output_has_begun
1618 && ! nlm_compute_section_file_positions (abfd))
1619 goto error_return;
1620
1621 /* Write out the variable length headers. */
1622 pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1623 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
1624 goto error_return;
1625 if (! nlm_swap_variable_header_out (abfd)
1626 || ! nlm_swap_auxiliary_headers_out (abfd))
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. */
1634 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
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;
1655 for (sec = abfd->sections; sec != NULL; sec = sec->next)
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;
1687 if (! (*write_import_func) (abfd, sec, rel))
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. */
1700 amt = external_reloc_count * sizeof (struct reloc_and_sec);
1701 external_relocs = bfd_alloc (abfd, amt);
1702 if (external_relocs == NULL)
1703 goto error_return;
1704 i = 0;
1705 for (sec = abfd->sections; sec != NULL; sec = sec->next)
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. */
1734 qsort (external_relocs, (size_t) external_reloc_count,
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
1759 if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1760 &external_relocs[i]))
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);
1770 if (sym_ptr_ptr != NULL)
1771 {
1772 bfd_vma (*get_public_offset_func) (bfd *, asymbol *);
1773 bfd_boolean (*write_export_func) (bfd *, asymbol *, bfd_vma);
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 {
1828 if (! (*write_export_func) (abfd, sym, offset))
1829 goto error_return;
1830 }
1831 else
1832 {
1833 len = strlen (sym->name);
1834 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
1835 != sizeof (bfd_byte))
1836 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
1837 goto error_return;
1838
1839 put_word (abfd, offset, temp);
1840 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1841 != sizeof (temp))
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. */
1900 if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
1901 != sizeof (bfd_byte))
1902 goto error_return;
1903
1904 put_word (abfd, offset, temp);
1905 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
1906 != sizeof (temp))
1907 goto error_return;
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 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
1956 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
1957 goto error_return;
1958
1959 write_prefix_func = nlm_write_prefix_func (abfd);
1960 if (write_prefix_func)
1961 {
1962 if (! (*write_prefix_func) (abfd))
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);
1970 if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
1971 != nlm_fixed_header_size (abfd))
1972 goto error_return;
1973
1974 if (fixed_header != NULL)
1975 free (fixed_header);
1976 return TRUE;
1977
1978 error_return:
1979 if (fixed_header != NULL)
1980 free (fixed_header);
1981 return FALSE;
1982 }
This page took 0.074245 seconds and 5 git commands to generate.