Made sure that every call to bfd_read, bfd_write, and bfd_seek
[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)->debugRecOffset =
501 get_word (abfd, (bfd_byte *) thdr.debugRecOffset);
502 nlm_custom_header (abfd)->debugRecLength =
503 get_word (abfd, (bfd_byte *) thdr.debugRecLength);
504 }
505 else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
506 {
507 if (bfd_read ((PTR) nlm_copyright_header (abfd)->stamp,
508 sizeof (nlm_copyright_header (abfd)->stamp),
509 1, abfd)
510 != sizeof (nlm_copyright_header (abfd)->stamp))
511 return (false);
512 if (bfd_read ((PTR) & (nlm_copyright_header (abfd)
513 ->copyrightMessageLength),
514 1, 1, abfd) != 1)
515 return (false);
516 /* The copyright message is a variable length string. */
517 if (bfd_read ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
518 nlm_copyright_header (abfd)->copyrightMessageLength + 1,
519 1, abfd) !=
520 nlm_copyright_header (abfd)->copyrightMessageLength + 1)
521 return (false);
522 }
523 else
524 {
525 break;
526 }
527 }
528 return (true);
529 }
530
531 /* Return whether there is a non-zero byte in a memory block. */
532
533 static boolean
534 find_nonzero (buf, size)
535 PTR buf;
536 size_t size;
537 {
538 char *p = (char *) buf;
539
540 while (size-- != 0)
541 if (*p++ != 0)
542 return true;
543 return false;
544 }
545
546 /* Swap out the contents of the auxiliary headers. We create those
547 auxiliary headers which have been set non-zero. We do not require
548 the caller to set up the stamp fields. */
549
550 static boolean
551 nlm_swap_auxiliary_headers_out (abfd)
552 bfd *abfd;
553 {
554 /* Write out the version header if there is one. */
555 if (find_nonzero ((PTR) nlm_version_header (abfd),
556 sizeof (Nlm_Internal_Version_Header)))
557 {
558 Nlm_External_Version_Header thdr;
559
560 memcpy (thdr.stamp, "VeRsIoN#", 8);
561 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
562 (bfd_byte *) thdr.majorVersion);
563 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
564 (bfd_byte *) thdr.minorVersion);
565 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
566 (bfd_byte *) thdr.revision);
567 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
568 (bfd_byte *) thdr.year);
569 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
570 (bfd_byte *) thdr.month);
571 put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
572 (bfd_byte *) thdr.day);
573 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
574 return false;
575 }
576
577 /* Write out the extended header if there is one. */
578 if (find_nonzero ((PTR) nlm_extended_header (abfd),
579 sizeof (Nlm_Internal_Extended_Header)))
580 {
581 Nlm_External_Extended_Header thdr;
582
583 memcpy (thdr.stamp, "MeSsAgEs", 8);
584 put_word (abfd,
585 (bfd_vma) nlm_extended_header (abfd)->languageID,
586 (bfd_byte *) thdr.languageID);
587 put_word (abfd,
588 (bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
589 (bfd_byte *) thdr.messageFileOffset);
590 put_word (abfd,
591 (bfd_vma) nlm_extended_header (abfd)->messageFileLength,
592 (bfd_byte *) thdr.messageFileLength);
593 put_word (abfd,
594 (bfd_vma) nlm_extended_header (abfd)->messageCount,
595 (bfd_byte *) thdr.messageCount);
596 put_word (abfd,
597 (bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
598 (bfd_byte *) thdr.helpFileOffset);
599 put_word (abfd,
600 (bfd_vma) nlm_extended_header (abfd)->helpFileLength,
601 (bfd_byte *) thdr.helpFileLength);
602 put_word (abfd,
603 (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
604 (bfd_byte *) thdr.RPCDataOffset);
605 put_word (abfd,
606 (bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
607 (bfd_byte *) thdr.RPCDataLength);
608 put_word (abfd,
609 (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
610 (bfd_byte *) thdr.sharedCodeOffset);
611 put_word (abfd,
612 (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
613 (bfd_byte *) thdr.sharedCodeLength);
614 put_word (abfd,
615 (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
616 (bfd_byte *) thdr.sharedDataOffset);
617 put_word (abfd,
618 (bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
619 (bfd_byte *) thdr.sharedDataLength);
620 put_word (abfd,
621 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
622 (bfd_byte *) thdr.sharedRelocationFixupOffset);
623 put_word (abfd,
624 (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
625 (bfd_byte *) thdr.sharedRelocationFixupCount);
626 put_word (abfd,
627 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
628 (bfd_byte *) thdr.sharedExternalReferenceOffset);
629 put_word (abfd,
630 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
631 (bfd_byte *) thdr.sharedExternalReferenceCount);
632 put_word (abfd,
633 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
634 (bfd_byte *) thdr.sharedPublicsOffset);
635 put_word (abfd,
636 (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
637 (bfd_byte *) thdr.sharedPublicsCount);
638 put_word (abfd,
639 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
640 (bfd_byte *) thdr.sharedDebugRecordOffset);
641 put_word (abfd,
642 (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
643 (bfd_byte *) thdr.sharedDebugRecordCount);
644 put_word (abfd,
645 (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
646 (bfd_byte *) thdr.sharedInitializationOffset);
647 put_word (abfd,
648 (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
649 (bfd_byte *) thdr.SharedExitProcedureOffset);
650 put_word (abfd,
651 (bfd_vma) nlm_extended_header (abfd)->productID,
652 (bfd_byte *) thdr.productID);
653 put_word (abfd,
654 (bfd_vma) nlm_extended_header (abfd)->reserved0,
655 (bfd_byte *) thdr.reserved0);
656 put_word (abfd,
657 (bfd_vma) nlm_extended_header (abfd)->reserved1,
658 (bfd_byte *) thdr.reserved1);
659 put_word (abfd,
660 (bfd_vma) nlm_extended_header (abfd)->reserved2,
661 (bfd_byte *) thdr.reserved2);
662 put_word (abfd,
663 (bfd_vma) nlm_extended_header (abfd)->reserved3,
664 (bfd_byte *) thdr.reserved3);
665 put_word (abfd,
666 (bfd_vma) nlm_extended_header (abfd)->reserved4,
667 (bfd_byte *) thdr.reserved4);
668 put_word (abfd,
669 (bfd_vma) nlm_extended_header (abfd)->reserved5,
670 (bfd_byte *) thdr.reserved5);
671 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
672 return false;
673 }
674
675 /* Write out the custom header if there is one. */
676 if (find_nonzero ((PTR) nlm_custom_header (abfd),
677 sizeof (Nlm_Internal_Custom_Header)))
678 {
679 Nlm_External_Custom_Header thdr;
680
681 /* Right now we assume the custom header is always the suggested
682 format for alternate debugging records. */
683 BFD_ASSERT (nlm_custom_header (abfd)->dataLength == 8);
684
685 memcpy (thdr.stamp, "CuStHeAd", 8);
686 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
687 (bfd_byte *) thdr.dataLength);
688 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->debugRecOffset,
689 (bfd_byte *) thdr.debugRecOffset);
690 put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->debugRecLength,
691 (bfd_byte *) thdr.debugRecLength);
692 if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
693 return false;
694 }
695
696 /* Write out the copyright header if there is one. */
697 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
698 sizeof (Nlm_Internal_Copyright_Header)))
699 {
700 Nlm_External_Copyright_Header thdr;
701
702 memcpy (thdr.stamp, "CoPyRiGhT=", 10);
703 if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd)
704 != sizeof (thdr.stamp))
705 return false;
706 thdr.copyrightMessageLength[0] =
707 nlm_copyright_header (abfd)->copyrightMessageLength;
708 if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1)
709 return false;
710 /* The copyright message is a variable length string. */
711 if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
712 nlm_copyright_header (abfd)->copyrightMessageLength + 1,
713 1, abfd) !=
714 nlm_copyright_header (abfd)->copyrightMessageLength + 1)
715 return false;
716 }
717
718 return true;
719 }
720
721 /* We read the NLM's public symbols and use it to generate a bfd symbol
722 table (hey, it's better than nothing) on a one-for-one basis. Thus
723 use the number of public symbols as the number of bfd symbols we will
724 have once we actually get around to reading them in.
725
726 Return the number of bytes required to hold the symtab vector, based on
727 the count plus 1, since we will NULL terminate the vector allocated based
728 on this size. */
729
730 long
731 nlm_get_symtab_upper_bound (abfd)
732 bfd *abfd;
733 {
734 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
735 long symcount;
736 long symtab_size = 0;
737
738 i_fxdhdrp = nlm_fixed_header (abfd);
739 symcount = (i_fxdhdrp->numberOfPublics
740 + i_fxdhdrp->numberOfDebugRecords
741 + i_fxdhdrp->numberOfExternalReferences);
742 symtab_size = (symcount + 1) * (sizeof (asymbol));
743 return (symtab_size);
744 }
745
746 /* Note that bfd_get_symcount is guaranteed to be zero if slurping the
747 symbol table fails. */
748
749 long
750 nlm_get_symtab (abfd, alocation)
751 bfd *abfd;
752 asymbol **alocation;
753 {
754 nlm_symbol_type *symbase;
755 bfd_size_type counter = 0;
756
757 if (nlm_slurp_symbol_table (abfd) == false)
758 return -1;
759 symbase = nlm_get_symbols (abfd);
760 while (counter < bfd_get_symcount (abfd))
761 {
762 *alocation++ = &symbase->symbol;
763 symbase++;
764 counter++;
765 }
766 *alocation = (asymbol *) NULL;
767 return bfd_get_symcount (abfd);
768 }
769
770 /* Make an NLM symbol. There is nothing special to do here. */
771
772 asymbol *
773 nlm_make_empty_symbol (abfd)
774 bfd *abfd;
775 {
776 nlm_symbol_type *new;
777
778 new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
779 if (new)
780 new->symbol.the_bfd = abfd;
781 return &new->symbol;
782 }
783
784 /* Get symbol information. */
785
786 void
787 nlm_get_symbol_info (ignore_abfd, symbol, ret)
788 bfd *ignore_abfd;
789 asymbol *symbol;
790 symbol_info *ret;
791 {
792 bfd_symbol_info (symbol, ret);
793 }
794
795 /* Print symbol information. */
796
797 void
798 nlm_print_symbol (abfd, afile, symbol, how)
799 bfd *abfd;
800 PTR afile;
801 asymbol *symbol;
802 bfd_print_symbol_type how;
803 {
804 FILE *file = (FILE *) afile;
805
806 switch (how)
807 {
808 case bfd_print_symbol_name:
809 case bfd_print_symbol_more:
810 if (symbol->name)
811 fprintf (file, "%s", symbol->name);
812 break;
813 case bfd_print_symbol_all:
814 bfd_print_symbol_vandf ((PTR) file, symbol);
815 fprintf (file, " %-5s", symbol->section->name);
816 if (symbol->name)
817 fprintf (file, " %s", symbol->name);
818 break;
819 }
820 }
821
822 /* Slurp in nlm symbol table.
823
824 In the external (in-file) form, NLM export records are variable length,
825 with the following form:
826
827 1 byte length of the symbol name (N)
828 N bytes the symbol name
829 4 bytes the symbol offset from start of it's section
830
831 We also read in the debugging symbols and import records. Import
832 records are treated as undefined symbols. As we read the import
833 records we also read in the associated reloc information, which is
834 attached to the symbol.
835
836 The bfd symbols are copied to SYMPTRS.
837
838 When we return, the bfd symcount is either zero or contains the correct
839 number of symbols.
840 */
841
842 static boolean
843 nlm_slurp_symbol_table (abfd)
844 bfd *abfd;
845 {
846 Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
847 bfd_size_type totsymcount; /* Number of NLM symbols */
848 bfd_size_type symcount; /* Counter of NLM symbols */
849 nlm_symbol_type *sym; /* Pointer to current bfd symbol */
850 unsigned char symlength; /* Symbol length read into here */
851 unsigned char symtype; /* Type of debugging symbol */
852 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
853 boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
854 boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
855
856 if (nlm_get_symbols (abfd) != NULL)
857 return (true);
858
859 /* Read each raw NLM symbol, using the information to create a canonical bfd
860 symbol table entry.
861
862 Note that we allocate the initial bfd canonical symbol buffer based on a
863 one-to-one mapping of the NLM symbols to canonical symbols. We actually
864 use all the NLM symbols, so there will be no space left over at the end.
865 When we have all the symbols, we build the caller's pointer vector. */
866
867 abfd->symcount = 0;
868 i_fxdhdrp = nlm_fixed_header (abfd);
869 totsymcount = (i_fxdhdrp->numberOfPublics
870 + i_fxdhdrp->numberOfDebugRecords
871 + i_fxdhdrp->numberOfExternalReferences);
872 if (totsymcount == 0)
873 {
874 return (true);
875 }
876
877 if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1)
878 return (false);
879
880 sym = ((nlm_symbol_type *)
881 bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
882 if (!sym)
883 {
884 bfd_set_error (bfd_error_no_memory);
885 return false;
886 }
887 nlm_set_symbols (abfd, sym);
888
889 /* We use the bfd's symcount directly as the control count, so that early
890 termination of the loop leaves the symcount correct for the symbols that
891 were read. */
892
893 set_public_section_func = nlm_set_public_section_func (abfd);
894 symcount = i_fxdhdrp->numberOfPublics;
895 while (abfd->symcount < symcount)
896 {
897 if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
898 != sizeof (symlength))
899 return (false);
900 sym->symbol.the_bfd = abfd;
901 sym->symbol.name = bfd_alloc (abfd, symlength + 1);
902 if (!sym->symbol.name)
903 {
904 bfd_set_error (bfd_error_no_memory);
905 return false;
906 }
907 if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
908 != symlength)
909 return (false);
910 /* Cast away const. */
911 ((char *) (sym->symbol.name))[symlength] = '\0';
912 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
913 return (false);
914 sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
915 sym->symbol.value = get_word (abfd, temp);
916 if (set_public_section_func)
917 {
918 /* Most backends can use the code below, but unfortunately
919 some use a different scheme. */
920 if ((*set_public_section_func) (abfd, sym) == false)
921 return false;
922 }
923 else
924 {
925 if (sym->symbol.value & NLM_HIBIT)
926 {
927 sym->symbol.value &= ~NLM_HIBIT;
928 sym->symbol.flags |= BSF_FUNCTION;
929 sym->symbol.section =
930 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
931 }
932 else
933 {
934 sym->symbol.section =
935 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
936 }
937 }
938 sym->rcnt = 0;
939 abfd->symcount++;
940 sym++;
941 }
942
943 /* Read the debugging records. */
944
945 if (i_fxdhdrp->numberOfDebugRecords > 0)
946 {
947 if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1)
948 return (false);
949
950 symcount += i_fxdhdrp->numberOfDebugRecords;
951 while (abfd->symcount < symcount)
952 {
953 if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd)
954 != sizeof (symtype))
955 || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)
956 || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
957 != sizeof (symlength)))
958 return false;
959 sym->symbol.the_bfd = abfd;
960 sym->symbol.name = bfd_alloc (abfd, symlength + 1);
961 if (!sym->symbol.name)
962 {
963 bfd_set_error (bfd_error_no_memory);
964 return false;
965 }
966 if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
967 != symlength)
968 return (false);
969 /* Cast away const. */
970 ((char *) (sym->symbol.name))[symlength] = '\0';
971 sym->symbol.flags = BSF_LOCAL;
972 sym->symbol.value = get_word (abfd, temp);
973 if (symtype == 0)
974 {
975 sym->symbol.section =
976 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
977 }
978 else if (symtype == 1)
979 {
980 sym->symbol.flags |= BSF_FUNCTION;
981 sym->symbol.section =
982 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
983 }
984 else
985 {
986 sym->symbol.section = &bfd_abs_section;
987 }
988 sym->rcnt = 0;
989 abfd->symcount++;
990 sym++;
991 }
992 }
993
994 /* Read in the import records. We can only do this if we know how
995 to read relocs for this target. */
996
997 read_import_func = nlm_read_import_func (abfd);
998 if (read_import_func != NULL)
999 {
1000 if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET)
1001 == -1)
1002 return (false);
1003
1004 symcount += i_fxdhdrp->numberOfExternalReferences;
1005 while (abfd->symcount < symcount)
1006 {
1007 if ((*read_import_func) (abfd, sym) == false)
1008 return false;
1009 sym++;
1010 abfd->symcount++;
1011 }
1012 }
1013
1014 return (true);
1015 }
1016 \f
1017 /* Get the relocs for an NLM file. There are two types of relocs.
1018 Imports are relocs against symbols defined in other NLM files. We
1019 treat these as relocs against global symbols. Relocation fixups
1020 are internal relocs.
1021
1022 The actual format used to store the relocs is machine specific. */
1023
1024 /* Read in the relocation fixup information. This is stored in
1025 nlm_relocation_fixups, an array of arelent structures, and
1026 nlm_relocation_fixup_secs, an array of section pointers. The
1027 section pointers are needed because the relocs are not sorted by
1028 section. */
1029
1030 static boolean
1031 nlm_slurp_reloc_fixups (abfd)
1032 bfd *abfd;
1033 {
1034 boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
1035 arelent *));
1036 bfd_size_type count;
1037 arelent *rels;
1038 asection **secs;
1039
1040 if (nlm_relocation_fixups (abfd) != NULL)
1041 return true;
1042 read_func = nlm_read_reloc_func (abfd);
1043 if (read_func == NULL)
1044 return true;
1045
1046 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1047 SEEK_SET) != 0)
1048 return false;
1049
1050 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1051 rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
1052 secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
1053 if (rels == NULL || secs == NULL)
1054 {
1055 bfd_set_error (bfd_error_no_memory);
1056 return false;
1057 }
1058 nlm_relocation_fixups (abfd) = rels;
1059 nlm_relocation_fixup_secs (abfd) = secs;
1060
1061 /* We have to read piece by piece, because we don't know how large
1062 the machine specific reloc information is. */
1063 while (count-- != 0)
1064 {
1065 if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
1066 {
1067 nlm_relocation_fixups (abfd) = NULL;
1068 nlm_relocation_fixup_secs (abfd) = NULL;
1069 return false;
1070 }
1071 ++secs;
1072 ++rels;
1073 }
1074
1075 return true;
1076 }
1077
1078 /* Get the number of relocs. This really just returns an upper bound,
1079 since it does not attempt to distinguish them based on the section.
1080 That will be handled when they are actually read. */
1081
1082 long
1083 nlm_get_reloc_upper_bound (abfd, sec)
1084 bfd *abfd;
1085 asection *sec;
1086 {
1087 nlm_symbol_type *syms;
1088 bfd_size_type count;
1089 unsigned int ret;
1090
1091 /* If we don't know how to read relocs, just return 0. */
1092 if (nlm_read_reloc_func (abfd) == NULL)
1093 return -1;
1094 /* Make sure we have either the code or the data section. */
1095 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1096 return 0;
1097
1098 syms = nlm_get_symbols (abfd);
1099 if (syms == NULL)
1100 {
1101 if (nlm_slurp_symbol_table (abfd) == false)
1102 return -1;
1103 syms = nlm_get_symbols (abfd);
1104 }
1105
1106 ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1107
1108 count = bfd_get_symcount (abfd);
1109 while (count-- != 0)
1110 {
1111 ret += syms->rcnt;
1112 ++syms;
1113 }
1114
1115 return (ret + 1) * sizeof (arelent *);
1116 }
1117
1118 /* Get the relocs themselves. */
1119
1120 long
1121 nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
1122 bfd *abfd;
1123 asection *sec;
1124 arelent **relptr;
1125 asymbol **symbols;
1126 {
1127 arelent *rels;
1128 asection **secs;
1129 bfd_size_type count, i;
1130 unsigned int ret;
1131
1132 /* Get the relocation fixups. */
1133 rels = nlm_relocation_fixups (abfd);
1134 if (rels == NULL)
1135 {
1136 if (nlm_slurp_reloc_fixups (abfd) == false)
1137 return -1;
1138 rels = nlm_relocation_fixups (abfd);
1139 if (rels == NULL)
1140 return -1;
1141 }
1142 secs = nlm_relocation_fixup_secs (abfd);
1143
1144 ret = 0;
1145 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1146 for (i = 0; i < count; i++, rels++, secs++)
1147 {
1148 if (*secs == sec)
1149 {
1150 *relptr++ = rels;
1151 ++ret;
1152 }
1153 }
1154
1155 /* Get the import symbols. */
1156 count = bfd_get_symcount (abfd);
1157 for (i = 0; i < count; i++, symbols++)
1158 {
1159 asymbol *sym;
1160
1161 sym = *symbols;
1162 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1163 {
1164 nlm_symbol_type *nlm_sym;
1165 bfd_size_type j;
1166
1167 nlm_sym = (nlm_symbol_type *) sym;
1168 for (j = 0; j < nlm_sym->rcnt; j++)
1169 {
1170 if (nlm_sym->relocs[j].section == sec)
1171 {
1172 *relptr = &nlm_sym->relocs[j].reloc;
1173 (*relptr)->sym_ptr_ptr = symbols;
1174 ++relptr;
1175 ++ret;
1176 }
1177 }
1178 }
1179 }
1180
1181 *relptr = NULL;
1182
1183 return ret;
1184 }
1185 \f
1186 /* Compute the section file positions for an NLM file. All variable
1187 length data in the file headers must be set before this function is
1188 called. If the variable length data is changed later, the
1189 resulting object file will be incorrect. Unfortunately, there is
1190 no way to check this.
1191
1192 This routine also sets the Size and Offset fields in the fixed
1193 header.
1194
1195 It also looks over the symbols and moves any common symbols into
1196 the .bss section; NLM has no way to represent a common symbol.
1197 This approach means that either the symbols must already have been
1198 set at this point, or there must be no common symbols. We need to
1199 move the symbols at this point so that mangle_relocs can see the
1200 final values. */
1201
1202 static boolean
1203 nlm_compute_section_file_positions (abfd)
1204 bfd *abfd;
1205 {
1206 file_ptr sofar;
1207 asection *sec;
1208 bfd_vma text, data, bss;
1209 bfd_vma text_low, data_low;
1210 int text_align, data_align, other_align;
1211 file_ptr text_ptr, data_ptr, other_ptr;
1212 asection *bss_sec;
1213 asymbol **sym_ptr_ptr;
1214
1215 if (abfd->output_has_begun == true)
1216 return true;
1217
1218 /* Make sure we have a section to hold uninitialized data. */
1219 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1220 if (bss_sec == NULL)
1221 {
1222 if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1223 (file_ptr) 0, (bfd_size_type) 0,
1224 SEC_ALLOC))
1225 return false;
1226 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1227 }
1228
1229 abfd->output_has_begun = true;
1230
1231 /* The fixed header. */
1232 sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1233
1234 /* The variable header. */
1235 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1236 + nlm_variable_header (abfd)->descriptionLength + 1
1237 + NLM_TARGET_LONG_SIZE /* stackSize */
1238 + NLM_TARGET_LONG_SIZE /* reserved */
1239 + sizeof (nlm_variable_header (abfd)->oldThreadName)
1240 + sizeof (nlm_variable_header (abfd)->screenNameLength)
1241 + nlm_variable_header (abfd)->screenNameLength + 1
1242 + sizeof (nlm_variable_header (abfd)->threadNameLength)
1243 + nlm_variable_header (abfd)->threadNameLength + 1);
1244
1245 /* The auxiliary headers. */
1246 if (find_nonzero ((PTR) nlm_version_header (abfd),
1247 sizeof (Nlm_Internal_Version_Header)))
1248 sofar += sizeof (Nlm_External_Version_Header);
1249 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1250 sizeof (Nlm_Internal_Extended_Header)))
1251 sofar += sizeof (Nlm_External_Extended_Header);
1252 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1253 sizeof (Nlm_Internal_Custom_Header)))
1254 sofar += sizeof (Nlm_External_Custom_Header);
1255 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1256 sizeof (Nlm_Internal_Copyright_Header)))
1257 sofar += (sizeof (Nlm_External_Copyright_Header)
1258 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1259
1260 /* Compute the section file positions in two passes. First get the
1261 sizes of the text and data sections, and then set the file
1262 positions. This code aligns the sections in the file using the
1263 same alignment restrictions that apply to the sections in memory;
1264 this may not be necessary. */
1265 text = 0;
1266 text_low = (bfd_vma) - 1;
1267 text_align = 0;
1268 data = 0;
1269 data_low = (bfd_vma) - 1;
1270 data_align = 0;
1271 bss = 0;
1272 other_align = 0;
1273 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1274 {
1275 flagword f;
1276
1277 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1278
1279 f = bfd_get_section_flags (abfd, sec);
1280 if (f & SEC_CODE)
1281 {
1282 text += sec->_raw_size;
1283 if (bfd_get_section_vma (abfd, sec) < text_low)
1284 text_low = bfd_get_section_vma (abfd, sec);
1285 if (sec->alignment_power > text_align)
1286 text_align = sec->alignment_power;
1287 }
1288 else if (f & SEC_DATA)
1289 {
1290 data += sec->_raw_size;
1291 if (bfd_get_section_vma (abfd, sec) < data_low)
1292 data_low = bfd_get_section_vma (abfd, sec);
1293 if (sec->alignment_power > data_align)
1294 data_align = sec->alignment_power;
1295 }
1296 else if (f & SEC_HAS_CONTENTS)
1297 {
1298 if (sec->alignment_power > other_align)
1299 other_align = sec->alignment_power;
1300 }
1301 else if (f & SEC_ALLOC)
1302 bss += sec->_raw_size;
1303 }
1304
1305 nlm_set_text_low (abfd, text_low);
1306 nlm_set_data_low (abfd, data_low);
1307
1308 if (nlm_no_uninitialized_data (abfd))
1309 {
1310 /* This NetWare format does not use uninitialized data. We must
1311 increase the size of the data section. We will never wind up
1312 writing those file locations, so they will remain zero. */
1313 data += bss;
1314 bss = 0;
1315 }
1316
1317 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1318 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1319 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1320
1321 /* Fill in some fields in the header for which we now have the
1322 information. */
1323 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1324 nlm_fixed_header (abfd)->codeImageSize = text;
1325 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1326 nlm_fixed_header (abfd)->dataImageSize = data;
1327 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1328
1329 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1330 {
1331 flagword f;
1332
1333 f = bfd_get_section_flags (abfd, sec);
1334
1335 if (f & SEC_CODE)
1336 {
1337 sec->filepos = text_ptr;
1338 text_ptr += sec->_raw_size;
1339 }
1340 else if (f & SEC_DATA)
1341 {
1342 sec->filepos = data_ptr;
1343 data_ptr += sec->_raw_size;
1344 }
1345 else if (f & SEC_HAS_CONTENTS)
1346 {
1347 sec->filepos = other_ptr;
1348 other_ptr += sec->_raw_size;
1349 }
1350 }
1351
1352 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1353
1354 /* Move all common symbols into the .bss section. */
1355
1356 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1357 if (sym_ptr_ptr != NULL)
1358 {
1359 asymbol **sym_end;
1360 bfd_vma add;
1361
1362 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1363 add = 0;
1364 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1365 {
1366 asymbol *sym;
1367 bfd_vma size;
1368
1369 sym = *sym_ptr_ptr;
1370
1371 if (!bfd_is_com_section (bfd_get_section (sym)))
1372 continue;
1373
1374 /* Put the common symbol in the .bss section, and increase
1375 the size of the .bss section by the size of the common
1376 symbol (which is the old value of the symbol). */
1377 sym->section = bss_sec;
1378 size = sym->value;
1379 sym->value = bss_sec->_raw_size + add;
1380 add += size;
1381 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1382 }
1383 if (add != 0)
1384 {
1385 if (nlm_no_uninitialized_data (abfd))
1386 {
1387 /* We could handle this case, but so far it hasn't been
1388 necessary. */
1389 abort ();
1390 }
1391 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1392 bss_sec->_raw_size += add;
1393 }
1394 }
1395
1396 return true;
1397 }
1398
1399 /* Set the contents of a section. To do this we need to know where
1400 the section is going to be located in the output file. That means
1401 that the sizes of all the sections must be set, and all the
1402 variable size header information must be known. */
1403
1404 boolean
1405 nlm_set_section_contents (abfd, section, location, offset, count)
1406 bfd *abfd;
1407 asection *section;
1408 PTR location;
1409 file_ptr offset;
1410 bfd_size_type count;
1411 {
1412 if (abfd->output_has_begun == false
1413 && nlm_compute_section_file_positions (abfd) == false)
1414 return false;
1415
1416 if (count == 0)
1417 return true;
1418
1419 /* i386 NetWare has a very restricted set of relocs. In order for
1420 objcopy to work, the NLM i386 backend needs a chance to rework
1421 the section contents so that its set of relocs will work. If all
1422 the relocs are already acceptable, this will not do anything. */
1423 if (section->reloc_count != 0)
1424 {
1425 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1426 bfd_vma, bfd_size_type));
1427
1428 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1429 if (mangle_relocs_func != NULL)
1430 {
1431 if (!(*mangle_relocs_func) (abfd, section, location,
1432 (bfd_vma) offset, count))
1433 return false;
1434 }
1435 }
1436
1437 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1438 || bfd_write (location, 1, count, abfd) != count)
1439 return false;
1440
1441 return true;
1442 }
1443
1444 /* We need to sort a list of relocs associated with sections when we
1445 write out the external relocs. */
1446
1447 static int
1448 nlm_external_reloc_compare (p1, p2)
1449 const void *p1;
1450 const void *p2;
1451 {
1452 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1453 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1454 int cmp;
1455
1456 cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1457 (*r2->rel->sym_ptr_ptr)->name);
1458 if (cmp != 0)
1459 return cmp;
1460
1461 /* We sort by address within symbol to make the sort more stable and
1462 increase the chances that different hosts will generate bit for
1463 bit equivalent results. */
1464 return (int) (r1->rel->address - r2->rel->address);
1465 }
1466
1467 /* Write out an NLM file. We write out the information in this order:
1468 fixed header
1469 variable header
1470 auxiliary headers
1471 code sections
1472 data sections
1473 other sections (custom data, messages, help, shared NLM, RPC,
1474 module dependencies)
1475 relocation fixups
1476 external references (imports)
1477 public symbols (exports)
1478 debugging records
1479 This is similar to the order used by the NetWare tools; the
1480 difference is that NetWare puts the sections other than code, data
1481 and custom data at the end of the NLM. It is convenient for us to
1482 know where the sections are going to be before worrying about the
1483 size of the other information.
1484
1485 By the time this function is called, all the section data should
1486 have been output using set_section_contents. Note that custom
1487 data, the message file, the help file, the shared NLM file, the RPC
1488 data, and the module dependencies are all considered to be
1489 sections; the caller is responsible for filling in the offset and
1490 length fields in the NLM headers. The relocation fixups and
1491 imports are both obtained from the list of relocs attached to each
1492 section. The exports and debugging records are obtained from the
1493 list of outsymbols. */
1494
1495 boolean
1496 nlm_write_object_contents (abfd)
1497 bfd *abfd;
1498 {
1499 asection *sec;
1500 boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1501 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1502 struct reloc_and_sec *external_relocs;
1503 asymbol **sym_ptr_ptr;
1504 file_ptr last;
1505 boolean (*write_prefix_func) PARAMS ((bfd *));
1506 unsigned char *fixed_header = NULL;
1507
1508 fixed_header = (unsigned char *) malloc (nlm_fixed_header_size (abfd));
1509 if (fixed_header == NULL)
1510 {
1511 bfd_set_error (bfd_error_no_memory);
1512 goto error_return;
1513 }
1514
1515 if (abfd->output_has_begun == false
1516 && nlm_compute_section_file_positions (abfd) == false)
1517 goto error_return;
1518
1519 /* Write out the variable length headers. */
1520 if (bfd_seek (abfd,
1521 nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
1522 SEEK_SET) != 0)
1523 goto error_return;
1524 if (nlm_swap_variable_header_out (abfd) == false
1525 || nlm_swap_auxiliary_headers_out (abfd) == false)
1526 {
1527 bfd_set_error (bfd_error_system_call);
1528 goto error_return;
1529 }
1530
1531 /* A weak check on whether the section file positions were
1532 reasonable. */
1533 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1534 {
1535 bfd_set_error (bfd_error_invalid_operation);
1536 goto error_return;
1537 }
1538
1539 /* Advance to the relocs. */
1540 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1541 SEEK_SET) != 0)
1542 goto error_return;
1543
1544 /* The format of the relocation entries is dependent upon the
1545 particular target. We use an external routine to write the reloc
1546 out. */
1547 write_import_func = nlm_write_import_func (abfd);
1548
1549 /* Write out the internal relocation fixups. While we're looping
1550 over the relocs, we also count the external relocs, which is
1551 needed when they are written out below. */
1552 internal_reloc_count = 0;
1553 external_reloc_count = 0;
1554 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1555 {
1556 arelent **rel_ptr_ptr, **rel_end;
1557
1558 if (sec->reloc_count == 0)
1559 continue;
1560
1561 /* We can only represent relocs within a code or data
1562 section. We ignore them for a debugging section. */
1563 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1564 continue;
1565
1566 /* We need to know how to write out imports */
1567 if (write_import_func == NULL)
1568 {
1569 bfd_set_error (bfd_error_invalid_operation);
1570 goto error_return;
1571 }
1572
1573 rel_ptr_ptr = sec->orelocation;
1574 rel_end = rel_ptr_ptr + sec->reloc_count;
1575 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1576 {
1577 arelent *rel;
1578 asymbol *sym;
1579
1580 rel = *rel_ptr_ptr;
1581 sym = *rel->sym_ptr_ptr;
1582
1583 if (bfd_get_section (sym) != &bfd_und_section)
1584 {
1585 ++internal_reloc_count;
1586 if ((*write_import_func) (abfd, sec, rel) == false)
1587 goto error_return;
1588 }
1589 else
1590 ++external_reloc_count;
1591 }
1592 }
1593 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1594
1595 /* Write out the imports (relocs against external symbols). These
1596 are output as a symbol name followed by all the relocs for that
1597 symbol, so we must first gather together all the relocs against
1598 external symbols and sort them. */
1599 external_relocs =
1600 (struct reloc_and_sec *) bfd_alloc (abfd,
1601 (external_reloc_count
1602 * sizeof (struct reloc_and_sec)));
1603 if (external_relocs == (struct reloc_and_sec *) NULL)
1604 {
1605 bfd_set_error (bfd_error_no_memory);
1606 goto error_return;
1607 }
1608 i = 0;
1609 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1610 {
1611 arelent **rel_ptr_ptr, **rel_end;
1612
1613 if (sec->reloc_count == 0)
1614 continue;
1615
1616 rel_ptr_ptr = sec->orelocation;
1617 rel_end = rel_ptr_ptr + sec->reloc_count;
1618 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1619 {
1620 arelent *rel;
1621 asymbol *sym;
1622
1623 rel = *rel_ptr_ptr;
1624 sym = *rel->sym_ptr_ptr;
1625
1626 if (bfd_get_section (sym) != &bfd_und_section)
1627 continue;
1628
1629 external_relocs[i].rel = rel;
1630 external_relocs[i].sec = sec;
1631 ++i;
1632 }
1633 }
1634
1635 BFD_ASSERT (i == external_reloc_count);
1636
1637 /* Sort the external relocs by name. */
1638 qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1639 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1640
1641 /* Write out the external relocs. */
1642 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1643 c = 0;
1644 i = 0;
1645 while (i < external_reloc_count)
1646 {
1647 arelent *rel;
1648 asymbol *sym;
1649 bfd_size_type j, cnt;
1650
1651 ++c;
1652
1653 rel = external_relocs[i].rel;
1654 sym = *rel->sym_ptr_ptr;
1655
1656 cnt = 0;
1657 for (j = i;
1658 (j < external_reloc_count
1659 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1660 j++)
1661 ++cnt;
1662
1663 if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1664 &external_relocs[i])
1665 == false)
1666 goto error_return;
1667
1668 i += cnt;
1669 }
1670
1671 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1672
1673 /* Write out the public symbols (exports). */
1674 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1675 if (sym_ptr_ptr != (asymbol **) NULL)
1676 {
1677 bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1678 boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1679
1680 asymbol **sym_end;
1681
1682 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1683 get_public_offset_func = nlm_get_public_offset_func (abfd);
1684 write_export_func = nlm_write_export_func (abfd);
1685 c = 0;
1686 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1687 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1688 {
1689 asymbol *sym;
1690 bfd_byte len;
1691 bfd_vma offset;
1692 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1693
1694 sym = *sym_ptr_ptr;
1695
1696 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1697 || bfd_get_section (sym) == &bfd_und_section)
1698 continue;
1699
1700 ++c;
1701
1702 if (get_public_offset_func)
1703 {
1704 /* Most backends can use the code below, but
1705 unfortunately some use a different scheme. */
1706 offset = (*get_public_offset_func) (abfd, sym);
1707 }
1708 else
1709 {
1710 offset = bfd_asymbol_value (sym);
1711 sec = sym->section;
1712 if (sec->flags & SEC_CODE)
1713 {
1714 offset -= nlm_get_text_low (abfd);
1715 offset |= NLM_HIBIT;
1716 }
1717 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1718 {
1719 /* SEC_ALLOC is for the .bss section. */
1720 offset -= nlm_get_data_low (abfd);
1721 }
1722 else
1723 {
1724 /* We can't handle an exported symbol that is not in
1725 the code or data segment. */
1726 bfd_set_error (bfd_error_invalid_operation);
1727 goto error_return;
1728 }
1729 }
1730
1731 if (write_export_func)
1732 {
1733 if ((*write_export_func) (abfd, sym, offset) == false)
1734 goto error_return;
1735 }
1736 else
1737 {
1738 len = strlen (sym->name);
1739 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1740 != sizeof (bfd_byte))
1741 || bfd_write (sym->name, len, 1, abfd) != len)
1742 goto error_return;
1743
1744 put_word (abfd, offset, temp);
1745 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1746 goto error_return;
1747 }
1748 }
1749 nlm_fixed_header (abfd)->numberOfPublics = c;
1750
1751 /* Write out the debugging records. The NLM conversion program
1752 wants to be able to inhibit this, so as a special hack if
1753 debugInfoOffset is set to -1 we don't write any debugging
1754 information. This can not be handled by fiddling with the
1755 symbol table, because exported symbols appear in both the
1756 exported symbol list and the debugging information. */
1757 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1758 {
1759 nlm_fixed_header (abfd)->debugInfoOffset = 0;
1760 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1761 }
1762 else
1763 {
1764 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1765 c = 0;
1766 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1767 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1768 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1769 {
1770 asymbol *sym;
1771 bfd_byte type, len;
1772 bfd_vma offset;
1773 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1774
1775 sym = *sym_ptr_ptr;
1776
1777 /* The NLM notion of a debugging symbol is actually what
1778 BFD calls a local or global symbol. What BFD calls a
1779 debugging symbol NLM does not understand at all. */
1780 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1781 || (sym->flags & BSF_DEBUGGING) != 0
1782 || bfd_get_section (sym) == &bfd_und_section)
1783 continue;
1784
1785 ++c;
1786
1787 offset = bfd_asymbol_value (sym);
1788 sec = sym->section;
1789 if (sec->flags & SEC_CODE)
1790 {
1791 offset -= nlm_get_text_low (abfd);
1792 type = 1;
1793 }
1794 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1795 {
1796 /* SEC_ALLOC is for the .bss section. */
1797 offset -= nlm_get_data_low (abfd);
1798 type = 0;
1799 }
1800 else
1801 type = 2;
1802
1803 /* The type is 0 for data, 1 for code, 2 for absolute. */
1804 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1805 != sizeof (bfd_byte))
1806 goto error_return;
1807
1808 put_word (abfd, offset, temp);
1809 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1810 goto error_return;
1811
1812 len = strlen (sym->name);
1813 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1814 != sizeof (bfd_byte))
1815 || bfd_write (sym->name, len, 1, abfd) != len)
1816 goto error_return;
1817 }
1818 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1819 }
1820 }
1821
1822 /* NLMLINK fills in offset values even if there is no data, so we do
1823 the same. */
1824 last = bfd_tell (abfd);
1825 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1826 nlm_fixed_header (abfd)->codeImageOffset = last;
1827 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
1828 nlm_fixed_header (abfd)->dataImageOffset = last;
1829 if (nlm_fixed_header (abfd)->customDataOffset == 0)
1830 nlm_fixed_header (abfd)->customDataOffset = last;
1831 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
1832 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
1833 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
1834 nlm_fixed_header (abfd)->relocationFixupOffset = last;
1835 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
1836 nlm_fixed_header (abfd)->externalReferencesOffset = last;
1837 if (nlm_fixed_header (abfd)->publicsOffset == 0)
1838 nlm_fixed_header (abfd)->publicsOffset = last;
1839 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
1840 nlm_fixed_header (abfd)->debugInfoOffset = last;
1841
1842 /* At this point everything has been written out except the fixed
1843 header. */
1844 memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
1845 NLM_SIGNATURE_SIZE);
1846 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
1847 nlm_fixed_header (abfd)->codeStartOffset =
1848 (bfd_get_start_address (abfd)
1849 - nlm_get_text_low (abfd));
1850
1851 /* We have no convenient way for the caller to pass in the exit
1852 procedure or the check unload procedure, so the caller must set
1853 the values in the header to the values of the symbols. */
1854 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
1855 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
1856 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
1857 nlm_get_text_low (abfd);
1858
1859 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
1860 goto error_return;
1861
1862 write_prefix_func = nlm_write_prefix_func (abfd);
1863 if (write_prefix_func)
1864 {
1865 if ((*write_prefix_func) (abfd) == false)
1866 goto error_return;
1867 }
1868
1869 BFD_ASSERT (bfd_tell (abfd) == nlm_optional_prefix_size (abfd));
1870
1871 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
1872 if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
1873 != nlm_fixed_header_size (abfd))
1874 goto error_return;
1875
1876 if (fixed_header != NULL)
1877 free (fixed_header);
1878 return true;
1879
1880 error_return:
1881 if (fixed_header != NULL)
1882 free (fixed_header);
1883 return false;
1884 }
This page took 0.123698 seconds and 5 git commands to generate.