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