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