* aoutx.h (NAME(aout,canonicalize_reloc)): Don't error out if
[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) && count != 0)
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 }
1140 secs = nlm_relocation_fixup_secs (abfd);
1141
1142 ret = 0;
1143 count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
1144 for (i = 0; i < count; i++, rels++, secs++)
1145 {
1146 if (*secs == sec)
1147 {
1148 *relptr++ = rels;
1149 ++ret;
1150 }
1151 }
1152
1153 /* Get the import symbols. */
1154 count = bfd_get_symcount (abfd);
1155 for (i = 0; i < count; i++, symbols++)
1156 {
1157 asymbol *sym;
1158
1159 sym = *symbols;
1160 if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
1161 {
1162 nlm_symbol_type *nlm_sym;
1163 bfd_size_type j;
1164
1165 nlm_sym = (nlm_symbol_type *) sym;
1166 for (j = 0; j < nlm_sym->rcnt; j++)
1167 {
1168 if (nlm_sym->relocs[j].section == sec)
1169 {
1170 *relptr = &nlm_sym->relocs[j].reloc;
1171 (*relptr)->sym_ptr_ptr = symbols;
1172 ++relptr;
1173 ++ret;
1174 }
1175 }
1176 }
1177 }
1178
1179 *relptr = NULL;
1180
1181 return ret;
1182 }
1183 \f
1184 /* Compute the section file positions for an NLM file. All variable
1185 length data in the file headers must be set before this function is
1186 called. If the variable length data is changed later, the
1187 resulting object file will be incorrect. Unfortunately, there is
1188 no way to check this.
1189
1190 This routine also sets the Size and Offset fields in the fixed
1191 header.
1192
1193 It also looks over the symbols and moves any common symbols into
1194 the .bss section; NLM has no way to represent a common symbol.
1195 This approach means that either the symbols must already have been
1196 set at this point, or there must be no common symbols. We need to
1197 move the symbols at this point so that mangle_relocs can see the
1198 final values. */
1199
1200 static boolean
1201 nlm_compute_section_file_positions (abfd)
1202 bfd *abfd;
1203 {
1204 file_ptr sofar;
1205 asection *sec;
1206 bfd_vma text, data, bss;
1207 bfd_vma text_low, data_low;
1208 int text_align, data_align, other_align;
1209 file_ptr text_ptr, data_ptr, other_ptr;
1210 asection *bss_sec;
1211 asymbol **sym_ptr_ptr;
1212
1213 if (abfd->output_has_begun == true)
1214 return true;
1215
1216 /* Make sure we have a section to hold uninitialized data. */
1217 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1218 if (bss_sec == NULL)
1219 {
1220 if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
1221 (file_ptr) 0, (bfd_size_type) 0,
1222 SEC_ALLOC))
1223 return false;
1224 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
1225 }
1226
1227 abfd->output_has_begun = true;
1228
1229 /* The fixed header. */
1230 sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
1231
1232 /* The variable header. */
1233 sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
1234 + nlm_variable_header (abfd)->descriptionLength + 1
1235 + NLM_TARGET_LONG_SIZE /* stackSize */
1236 + NLM_TARGET_LONG_SIZE /* reserved */
1237 + sizeof (nlm_variable_header (abfd)->oldThreadName)
1238 + sizeof (nlm_variable_header (abfd)->screenNameLength)
1239 + nlm_variable_header (abfd)->screenNameLength + 1
1240 + sizeof (nlm_variable_header (abfd)->threadNameLength)
1241 + nlm_variable_header (abfd)->threadNameLength + 1);
1242
1243 /* The auxiliary headers. */
1244 if (find_nonzero ((PTR) nlm_version_header (abfd),
1245 sizeof (Nlm_Internal_Version_Header)))
1246 sofar += sizeof (Nlm_External_Version_Header);
1247 if (find_nonzero ((PTR) nlm_extended_header (abfd),
1248 sizeof (Nlm_Internal_Extended_Header)))
1249 sofar += sizeof (Nlm_External_Extended_Header);
1250 if (find_nonzero ((PTR) nlm_custom_header (abfd),
1251 sizeof (Nlm_Internal_Custom_Header)))
1252 sofar += sizeof (Nlm_External_Custom_Header);
1253 if (find_nonzero ((PTR) nlm_copyright_header (abfd),
1254 sizeof (Nlm_Internal_Copyright_Header)))
1255 sofar += (sizeof (Nlm_External_Copyright_Header)
1256 + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
1257
1258 /* Compute the section file positions in two passes. First get the
1259 sizes of the text and data sections, and then set the file
1260 positions. This code aligns the sections in the file using the
1261 same alignment restrictions that apply to the sections in memory;
1262 this may not be necessary. */
1263 text = 0;
1264 text_low = (bfd_vma) - 1;
1265 text_align = 0;
1266 data = 0;
1267 data_low = (bfd_vma) - 1;
1268 data_align = 0;
1269 bss = 0;
1270 other_align = 0;
1271 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1272 {
1273 flagword f;
1274
1275 sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
1276
1277 f = bfd_get_section_flags (abfd, sec);
1278 if (f & SEC_CODE)
1279 {
1280 text += sec->_raw_size;
1281 if (bfd_get_section_vma (abfd, sec) < text_low)
1282 text_low = bfd_get_section_vma (abfd, sec);
1283 if (sec->alignment_power > text_align)
1284 text_align = sec->alignment_power;
1285 }
1286 else if (f & SEC_DATA)
1287 {
1288 data += sec->_raw_size;
1289 if (bfd_get_section_vma (abfd, sec) < data_low)
1290 data_low = bfd_get_section_vma (abfd, sec);
1291 if (sec->alignment_power > data_align)
1292 data_align = sec->alignment_power;
1293 }
1294 else if (f & SEC_HAS_CONTENTS)
1295 {
1296 if (sec->alignment_power > other_align)
1297 other_align = sec->alignment_power;
1298 }
1299 else if (f & SEC_ALLOC)
1300 bss += sec->_raw_size;
1301 }
1302
1303 nlm_set_text_low (abfd, text_low);
1304 nlm_set_data_low (abfd, data_low);
1305
1306 if (nlm_no_uninitialized_data (abfd))
1307 {
1308 /* This NetWare format does not use uninitialized data. We must
1309 increase the size of the data section. We will never wind up
1310 writing those file locations, so they will remain zero. */
1311 data += bss;
1312 bss = 0;
1313 }
1314
1315 text_ptr = BFD_ALIGN (sofar, 1 << text_align);
1316 data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
1317 other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
1318
1319 /* Fill in some fields in the header for which we now have the
1320 information. */
1321 nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
1322 nlm_fixed_header (abfd)->codeImageSize = text;
1323 nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
1324 nlm_fixed_header (abfd)->dataImageSize = data;
1325 nlm_fixed_header (abfd)->uninitializedDataSize = bss;
1326
1327 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1328 {
1329 flagword f;
1330
1331 f = bfd_get_section_flags (abfd, sec);
1332
1333 if (f & SEC_CODE)
1334 {
1335 sec->filepos = text_ptr;
1336 text_ptr += sec->_raw_size;
1337 }
1338 else if (f & SEC_DATA)
1339 {
1340 sec->filepos = data_ptr;
1341 data_ptr += sec->_raw_size;
1342 }
1343 else if (f & SEC_HAS_CONTENTS)
1344 {
1345 sec->filepos = other_ptr;
1346 other_ptr += sec->_raw_size;
1347 }
1348 }
1349
1350 nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
1351
1352 /* Move all common symbols into the .bss section. */
1353
1354 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1355 if (sym_ptr_ptr != NULL)
1356 {
1357 asymbol **sym_end;
1358 bfd_vma add;
1359
1360 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1361 add = 0;
1362 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1363 {
1364 asymbol *sym;
1365 bfd_vma size;
1366
1367 sym = *sym_ptr_ptr;
1368
1369 if (!bfd_is_com_section (bfd_get_section (sym)))
1370 continue;
1371
1372 /* Put the common symbol in the .bss section, and increase
1373 the size of the .bss section by the size of the common
1374 symbol (which is the old value of the symbol). */
1375 sym->section = bss_sec;
1376 size = sym->value;
1377 sym->value = bss_sec->_raw_size + add;
1378 add += size;
1379 add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
1380 }
1381 if (add != 0)
1382 {
1383 if (nlm_no_uninitialized_data (abfd))
1384 {
1385 /* We could handle this case, but so far it hasn't been
1386 necessary. */
1387 abort ();
1388 }
1389 nlm_fixed_header (abfd)->uninitializedDataSize += add;
1390 bss_sec->_raw_size += add;
1391 }
1392 }
1393
1394 return true;
1395 }
1396
1397 /* Set the contents of a section. To do this we need to know where
1398 the section is going to be located in the output file. That means
1399 that the sizes of all the sections must be set, and all the
1400 variable size header information must be known. */
1401
1402 boolean
1403 nlm_set_section_contents (abfd, section, location, offset, count)
1404 bfd *abfd;
1405 asection *section;
1406 PTR location;
1407 file_ptr offset;
1408 bfd_size_type count;
1409 {
1410 if (abfd->output_has_begun == false
1411 && nlm_compute_section_file_positions (abfd) == false)
1412 return false;
1413
1414 if (count == 0)
1415 return true;
1416
1417 /* i386 NetWare has a very restricted set of relocs. In order for
1418 objcopy to work, the NLM i386 backend needs a chance to rework
1419 the section contents so that its set of relocs will work. If all
1420 the relocs are already acceptable, this will not do anything. */
1421 if (section->reloc_count != 0)
1422 {
1423 boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
1424 bfd_vma, bfd_size_type));
1425
1426 mangle_relocs_func = nlm_mangle_relocs_func (abfd);
1427 if (mangle_relocs_func != NULL)
1428 {
1429 if (!(*mangle_relocs_func) (abfd, section, location,
1430 (bfd_vma) offset, count))
1431 return false;
1432 }
1433 }
1434
1435 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
1436 || bfd_write (location, 1, count, abfd) != count)
1437 return false;
1438
1439 return true;
1440 }
1441
1442 /* We need to sort a list of relocs associated with sections when we
1443 write out the external relocs. */
1444
1445 static int
1446 nlm_external_reloc_compare (p1, p2)
1447 const void *p1;
1448 const void *p2;
1449 {
1450 const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
1451 const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
1452 int cmp;
1453
1454 cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
1455 (*r2->rel->sym_ptr_ptr)->name);
1456 if (cmp != 0)
1457 return cmp;
1458
1459 /* We sort by address within symbol to make the sort more stable and
1460 increase the chances that different hosts will generate bit for
1461 bit equivalent results. */
1462 return (int) (r1->rel->address - r2->rel->address);
1463 }
1464
1465 /* Write out an NLM file. We write out the information in this order:
1466 fixed header
1467 variable header
1468 auxiliary headers
1469 code sections
1470 data sections
1471 other sections (custom data, messages, help, shared NLM, RPC,
1472 module dependencies)
1473 relocation fixups
1474 external references (imports)
1475 public symbols (exports)
1476 debugging records
1477 This is similar to the order used by the NetWare tools; the
1478 difference is that NetWare puts the sections other than code, data
1479 and custom data at the end of the NLM. It is convenient for us to
1480 know where the sections are going to be before worrying about the
1481 size of the other information.
1482
1483 By the time this function is called, all the section data should
1484 have been output using set_section_contents. Note that custom
1485 data, the message file, the help file, the shared NLM file, the RPC
1486 data, and the module dependencies are all considered to be
1487 sections; the caller is responsible for filling in the offset and
1488 length fields in the NLM headers. The relocation fixups and
1489 imports are both obtained from the list of relocs attached to each
1490 section. The exports and debugging records are obtained from the
1491 list of outsymbols. */
1492
1493 boolean
1494 nlm_write_object_contents (abfd)
1495 bfd *abfd;
1496 {
1497 asection *sec;
1498 boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
1499 bfd_size_type external_reloc_count, internal_reloc_count, i, c;
1500 struct reloc_and_sec *external_relocs;
1501 asymbol **sym_ptr_ptr;
1502 file_ptr last;
1503 boolean (*write_prefix_func) PARAMS ((bfd *));
1504 unsigned char *fixed_header = NULL;
1505
1506 fixed_header = (unsigned char *) malloc (nlm_fixed_header_size (abfd));
1507 if (fixed_header == NULL)
1508 {
1509 bfd_set_error (bfd_error_no_memory);
1510 goto error_return;
1511 }
1512
1513 if (abfd->output_has_begun == false
1514 && nlm_compute_section_file_positions (abfd) == false)
1515 goto error_return;
1516
1517 /* Write out the variable length headers. */
1518 if (bfd_seek (abfd,
1519 nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
1520 SEEK_SET) != 0)
1521 goto error_return;
1522 if (nlm_swap_variable_header_out (abfd) == false
1523 || nlm_swap_auxiliary_headers_out (abfd) == false)
1524 {
1525 bfd_set_error (bfd_error_system_call);
1526 goto error_return;
1527 }
1528
1529 /* A weak check on whether the section file positions were
1530 reasonable. */
1531 if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
1532 {
1533 bfd_set_error (bfd_error_invalid_operation);
1534 goto error_return;
1535 }
1536
1537 /* Advance to the relocs. */
1538 if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
1539 SEEK_SET) != 0)
1540 goto error_return;
1541
1542 /* The format of the relocation entries is dependent upon the
1543 particular target. We use an external routine to write the reloc
1544 out. */
1545 write_import_func = nlm_write_import_func (abfd);
1546
1547 /* Write out the internal relocation fixups. While we're looping
1548 over the relocs, we also count the external relocs, which is
1549 needed when they are written out below. */
1550 internal_reloc_count = 0;
1551 external_reloc_count = 0;
1552 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1553 {
1554 arelent **rel_ptr_ptr, **rel_end;
1555
1556 if (sec->reloc_count == 0)
1557 continue;
1558
1559 /* We can only represent relocs within a code or data
1560 section. We ignore them for a debugging section. */
1561 if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
1562 continue;
1563
1564 /* We need to know how to write out imports */
1565 if (write_import_func == NULL)
1566 {
1567 bfd_set_error (bfd_error_invalid_operation);
1568 goto error_return;
1569 }
1570
1571 rel_ptr_ptr = sec->orelocation;
1572 rel_end = rel_ptr_ptr + sec->reloc_count;
1573 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1574 {
1575 arelent *rel;
1576 asymbol *sym;
1577
1578 rel = *rel_ptr_ptr;
1579 sym = *rel->sym_ptr_ptr;
1580
1581 if (bfd_get_section (sym) != &bfd_und_section)
1582 {
1583 ++internal_reloc_count;
1584 if ((*write_import_func) (abfd, sec, rel) == false)
1585 goto error_return;
1586 }
1587 else
1588 ++external_reloc_count;
1589 }
1590 }
1591 nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
1592
1593 /* Write out the imports (relocs against external symbols). These
1594 are output as a symbol name followed by all the relocs for that
1595 symbol, so we must first gather together all the relocs against
1596 external symbols and sort them. */
1597 external_relocs =
1598 (struct reloc_and_sec *) bfd_alloc (abfd,
1599 (external_reloc_count
1600 * sizeof (struct reloc_and_sec)));
1601 if (external_relocs == (struct reloc_and_sec *) NULL)
1602 {
1603 bfd_set_error (bfd_error_no_memory);
1604 goto error_return;
1605 }
1606 i = 0;
1607 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
1608 {
1609 arelent **rel_ptr_ptr, **rel_end;
1610
1611 if (sec->reloc_count == 0)
1612 continue;
1613
1614 rel_ptr_ptr = sec->orelocation;
1615 rel_end = rel_ptr_ptr + sec->reloc_count;
1616 for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
1617 {
1618 arelent *rel;
1619 asymbol *sym;
1620
1621 rel = *rel_ptr_ptr;
1622 sym = *rel->sym_ptr_ptr;
1623
1624 if (bfd_get_section (sym) != &bfd_und_section)
1625 continue;
1626
1627 external_relocs[i].rel = rel;
1628 external_relocs[i].sec = sec;
1629 ++i;
1630 }
1631 }
1632
1633 BFD_ASSERT (i == external_reloc_count);
1634
1635 /* Sort the external relocs by name. */
1636 qsort ((PTR) external_relocs, (size_t) external_reloc_count,
1637 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
1638
1639 /* Write out the external relocs. */
1640 nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
1641 c = 0;
1642 i = 0;
1643 while (i < external_reloc_count)
1644 {
1645 arelent *rel;
1646 asymbol *sym;
1647 bfd_size_type j, cnt;
1648
1649 ++c;
1650
1651 rel = external_relocs[i].rel;
1652 sym = *rel->sym_ptr_ptr;
1653
1654 cnt = 0;
1655 for (j = i;
1656 (j < external_reloc_count
1657 && *external_relocs[j].rel->sym_ptr_ptr == sym);
1658 j++)
1659 ++cnt;
1660
1661 if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
1662 &external_relocs[i])
1663 == false)
1664 goto error_return;
1665
1666 i += cnt;
1667 }
1668
1669 nlm_fixed_header (abfd)->numberOfExternalReferences = c;
1670
1671 /* Write out the public symbols (exports). */
1672 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1673 if (sym_ptr_ptr != (asymbol **) NULL)
1674 {
1675 bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
1676 boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
1677
1678 asymbol **sym_end;
1679
1680 nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
1681 get_public_offset_func = nlm_get_public_offset_func (abfd);
1682 write_export_func = nlm_write_export_func (abfd);
1683 c = 0;
1684 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1685 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1686 {
1687 asymbol *sym;
1688 bfd_byte len;
1689 bfd_vma offset;
1690 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1691
1692 sym = *sym_ptr_ptr;
1693
1694 if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
1695 || bfd_get_section (sym) == &bfd_und_section)
1696 continue;
1697
1698 ++c;
1699
1700 if (get_public_offset_func)
1701 {
1702 /* Most backends can use the code below, but
1703 unfortunately some use a different scheme. */
1704 offset = (*get_public_offset_func) (abfd, sym);
1705 }
1706 else
1707 {
1708 offset = bfd_asymbol_value (sym);
1709 sec = sym->section;
1710 if (sec->flags & SEC_CODE)
1711 {
1712 offset -= nlm_get_text_low (abfd);
1713 offset |= NLM_HIBIT;
1714 }
1715 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1716 {
1717 /* SEC_ALLOC is for the .bss section. */
1718 offset -= nlm_get_data_low (abfd);
1719 }
1720 else
1721 {
1722 /* We can't handle an exported symbol that is not in
1723 the code or data segment. */
1724 bfd_set_error (bfd_error_invalid_operation);
1725 goto error_return;
1726 }
1727 }
1728
1729 if (write_export_func)
1730 {
1731 if ((*write_export_func) (abfd, sym, offset) == false)
1732 goto error_return;
1733 }
1734 else
1735 {
1736 len = strlen (sym->name);
1737 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1738 != sizeof (bfd_byte))
1739 || bfd_write (sym->name, len, 1, abfd) != len)
1740 goto error_return;
1741
1742 put_word (abfd, offset, temp);
1743 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1744 goto error_return;
1745 }
1746 }
1747 nlm_fixed_header (abfd)->numberOfPublics = c;
1748
1749 /* Write out the debugging records. The NLM conversion program
1750 wants to be able to inhibit this, so as a special hack if
1751 debugInfoOffset is set to -1 we don't write any debugging
1752 information. This can not be handled by fiddling with the
1753 symbol table, because exported symbols appear in both the
1754 exported symbol list and the debugging information. */
1755 if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
1756 {
1757 nlm_fixed_header (abfd)->debugInfoOffset = 0;
1758 nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
1759 }
1760 else
1761 {
1762 nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
1763 c = 0;
1764 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1765 sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
1766 for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
1767 {
1768 asymbol *sym;
1769 bfd_byte type, len;
1770 bfd_vma offset;
1771 bfd_byte temp[NLM_TARGET_LONG_SIZE];
1772
1773 sym = *sym_ptr_ptr;
1774
1775 /* The NLM notion of a debugging symbol is actually what
1776 BFD calls a local or global symbol. What BFD calls a
1777 debugging symbol NLM does not understand at all. */
1778 if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
1779 || (sym->flags & BSF_DEBUGGING) != 0
1780 || bfd_get_section (sym) == &bfd_und_section)
1781 continue;
1782
1783 ++c;
1784
1785 offset = bfd_asymbol_value (sym);
1786 sec = sym->section;
1787 if (sec->flags & SEC_CODE)
1788 {
1789 offset -= nlm_get_text_low (abfd);
1790 type = 1;
1791 }
1792 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
1793 {
1794 /* SEC_ALLOC is for the .bss section. */
1795 offset -= nlm_get_data_low (abfd);
1796 type = 0;
1797 }
1798 else
1799 type = 2;
1800
1801 /* The type is 0 for data, 1 for code, 2 for absolute. */
1802 if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
1803 != sizeof (bfd_byte))
1804 goto error_return;
1805
1806 put_word (abfd, offset, temp);
1807 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
1808 goto error_return;
1809
1810 len = strlen (sym->name);
1811 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
1812 != sizeof (bfd_byte))
1813 || bfd_write (sym->name, len, 1, abfd) != len)
1814 goto error_return;
1815 }
1816 nlm_fixed_header (abfd)->numberOfDebugRecords = c;
1817 }
1818 }
1819
1820 /* NLMLINK fills in offset values even if there is no data, so we do
1821 the same. */
1822 last = bfd_tell (abfd);
1823 if (nlm_fixed_header (abfd)->codeImageOffset == 0)
1824 nlm_fixed_header (abfd)->codeImageOffset = last;
1825 if (nlm_fixed_header (abfd)->dataImageOffset == 0)
1826 nlm_fixed_header (abfd)->dataImageOffset = last;
1827 if (nlm_fixed_header (abfd)->customDataOffset == 0)
1828 nlm_fixed_header (abfd)->customDataOffset = last;
1829 if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
1830 nlm_fixed_header (abfd)->moduleDependencyOffset = last;
1831 if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
1832 nlm_fixed_header (abfd)->relocationFixupOffset = last;
1833 if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
1834 nlm_fixed_header (abfd)->externalReferencesOffset = last;
1835 if (nlm_fixed_header (abfd)->publicsOffset == 0)
1836 nlm_fixed_header (abfd)->publicsOffset = last;
1837 if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
1838 nlm_fixed_header (abfd)->debugInfoOffset = last;
1839
1840 /* At this point everything has been written out except the fixed
1841 header. */
1842 memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
1843 NLM_SIGNATURE_SIZE);
1844 nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
1845 nlm_fixed_header (abfd)->codeStartOffset =
1846 (bfd_get_start_address (abfd)
1847 - nlm_get_text_low (abfd));
1848
1849 /* We have no convenient way for the caller to pass in the exit
1850 procedure or the check unload procedure, so the caller must set
1851 the values in the header to the values of the symbols. */
1852 nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
1853 if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
1854 nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
1855 nlm_get_text_low (abfd);
1856
1857 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
1858 goto error_return;
1859
1860 write_prefix_func = nlm_write_prefix_func (abfd);
1861 if (write_prefix_func)
1862 {
1863 if ((*write_prefix_func) (abfd) == false)
1864 goto error_return;
1865 }
1866
1867 BFD_ASSERT (bfd_tell (abfd) == nlm_optional_prefix_size (abfd));
1868
1869 nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
1870 if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
1871 != nlm_fixed_header_size (abfd))
1872 goto error_return;
1873
1874 if (fixed_header != NULL)
1875 free (fixed_header);
1876 return true;
1877
1878 error_return:
1879 if (fixed_header != NULL)
1880 free (fixed_header);
1881 return false;
1882 }
This page took 0.069567 seconds and 5 git commands to generate.