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