Made sure that every call to bfd_read, bfd_write, and bfd_seek
[deliverable/binutils-gdb.git] / bfd / nlm32-ppc.c
1 /* Support for 32-bit PowerPC NLM (NetWare Loadable Module)
2 Copyright (C) 1994 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23
24 #define ARCH_SIZE 32
25
26 #include "nlm/ppc-ext.h"
27 #define Nlm_External_Fixed_Header Nlm32_powerpc_External_Fixed_Header
28
29 #include "libnlm.h"
30
31 static boolean nlm_powerpc_backend_object_p
32 PARAMS ((bfd *));
33 static boolean nlm_powerpc_write_prefix
34 PARAMS ((bfd *));
35 static boolean nlm_powerpc_read_reloc
36 PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
37 static boolean nlm_powerpc_mangle_relocs
38 PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
39 static boolean nlm_powerpc_read_import
40 PARAMS ((bfd *, nlmNAME(symbol_type) *));
41 static boolean nlm_powerpc_write_reloc
42 PARAMS ((bfd *, asection *, arelent *, int));
43 static boolean nlm_powerpc_write_import
44 PARAMS ((bfd *, asection *, arelent *));
45 static boolean nlm_powerpc_write_external
46 PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
47 \f
48 /* PowerPC NLM's have a prefix header before the standard NLM. This
49 function reads it in, verifies the version, and seeks the bfd to
50 the location before the regular NLM header. */
51
52 static boolean
53 nlm_powerpc_backend_object_p (abfd)
54 bfd *abfd;
55 {
56 struct nlm32_powerpc_external_prefix_header s;
57
58 if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
59 return false;
60
61 if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
62 || bfd_h_get_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
63 return false;
64
65 return true;
66 }
67
68 /* Write out the prefix. */
69
70 static boolean
71 nlm_powerpc_write_prefix (abfd)
72 bfd *abfd;
73 {
74 struct nlm32_powerpc_external_prefix_header s;
75
76 memset (&s, 0, sizeof s);
77 memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
78 bfd_h_put_32 (abfd, (bfd_vma) NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
79 bfd_h_put_32 (abfd, (bfd_vma) 0, s.origins);
80
81 /* FIXME: What should we do about the date? */
82
83 if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
84 return false;
85
86 return true;
87 }
88 \f
89 /* How to process the various reloc types. PowerPC NLMs use XCOFF
90 reloc types, and I have just copied the XCOFF reloc table here. */
91
92 static reloc_howto_type nlm_powerpc_howto_table[] =
93 {
94 /* Standard 32 bit relocation. */
95 HOWTO (0, /* type */
96 0, /* rightshift */
97 2, /* size (0 = byte, 1 = short, 2 = long) */
98 32, /* bitsize */
99 false, /* pc_relative */
100 0, /* bitpos */
101 complain_overflow_bitfield, /* complain_on_overflow */
102 0, /* special_function */
103 "R_POS", /* name */
104 true, /* partial_inplace */
105 0xffffffff, /* src_mask */
106 0xffffffff, /* dst_mask */
107 false), /* pcrel_offset */
108
109 /* 32 bit relocation, but store negative value. */
110 HOWTO (1, /* type */
111 0, /* rightshift */
112 -2, /* size (0 = byte, 1 = short, 2 = long) */
113 32, /* bitsize */
114 false, /* pc_relative */
115 0, /* bitpos */
116 complain_overflow_bitfield, /* complain_on_overflow */
117 0, /* special_function */
118 "R_NEG", /* name */
119 true, /* partial_inplace */
120 0xffffffff, /* src_mask */
121 0xffffffff, /* dst_mask */
122 false), /* pcrel_offset */
123
124 /* 32 bit PC relative relocation. */
125 HOWTO (2, /* type */
126 0, /* rightshift */
127 2, /* size (0 = byte, 1 = short, 2 = long) */
128 32, /* bitsize */
129 true, /* pc_relative */
130 0, /* bitpos */
131 complain_overflow_signed, /* complain_on_overflow */
132 0, /* special_function */
133 "R_REL", /* name */
134 true, /* partial_inplace */
135 0xffffffff, /* src_mask */
136 0xffffffff, /* dst_mask */
137 false), /* pcrel_offset */
138
139 /* 16 bit TOC relative relocation. */
140 HOWTO (3, /* type */
141 0, /* rightshift */
142 1, /* size (0 = byte, 1 = short, 2 = long) */
143 16, /* bitsize */
144 false, /* pc_relative */
145 0, /* bitpos */
146 complain_overflow_signed, /* complain_on_overflow */
147 0, /* special_function */
148 "R_TOC", /* name */
149 true, /* partial_inplace */
150 0xffff, /* src_mask */
151 0xffff, /* dst_mask */
152 false), /* pcrel_offset */
153
154 /* I don't really know what this is. */
155 HOWTO (4, /* type */
156 1, /* rightshift */
157 2, /* size (0 = byte, 1 = short, 2 = long) */
158 32, /* bitsize */
159 false, /* pc_relative */
160 0, /* bitpos */
161 complain_overflow_bitfield, /* complain_on_overflow */
162 0, /* special_function */
163 "R_RTB", /* name */
164 true, /* partial_inplace */
165 0xffffffff, /* src_mask */
166 0xffffffff, /* dst_mask */
167 false), /* pcrel_offset */
168
169 /* External TOC relative symbol. */
170 HOWTO (5, /* type */
171 0, /* rightshift */
172 2, /* size (0 = byte, 1 = short, 2 = long) */
173 16, /* bitsize */
174 false, /* pc_relative */
175 0, /* bitpos */
176 complain_overflow_bitfield, /* complain_on_overflow */
177 0, /* special_function */
178 "R_GL", /* name */
179 true, /* partial_inplace */
180 0xffff, /* src_mask */
181 0xffff, /* dst_mask */
182 false), /* pcrel_offset */
183
184 /* Local TOC relative symbol. */
185 HOWTO (6, /* type */
186 0, /* rightshift */
187 2, /* size (0 = byte, 1 = short, 2 = long) */
188 16, /* bitsize */
189 false, /* pc_relative */
190 0, /* bitpos */
191 complain_overflow_bitfield, /* complain_on_overflow */
192 0, /* special_function */
193 "R_TCL", /* name */
194 true, /* partial_inplace */
195 0xffff, /* src_mask */
196 0xffff, /* dst_mask */
197 false), /* pcrel_offset */
198
199 { 7 },
200
201 /* Non modifiable absolute branch. */
202 HOWTO (8, /* type */
203 0, /* rightshift */
204 2, /* size (0 = byte, 1 = short, 2 = long) */
205 26, /* bitsize */
206 false, /* pc_relative */
207 0, /* bitpos */
208 complain_overflow_bitfield, /* complain_on_overflow */
209 0, /* special_function */
210 "R_BA", /* name */
211 true, /* partial_inplace */
212 0x3fffffc, /* src_mask */
213 0x3fffffc, /* dst_mask */
214 false), /* pcrel_offset */
215
216 { 9 },
217
218 /* Non modifiable relative branch. */
219 HOWTO (0xa, /* type */
220 0, /* rightshift */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
222 26, /* bitsize */
223 true, /* pc_relative */
224 0, /* bitpos */
225 complain_overflow_signed, /* complain_on_overflow */
226 0, /* special_function */
227 "R_BR", /* name */
228 true, /* partial_inplace */
229 0x3fffffc, /* src_mask */
230 0x3fffffc, /* dst_mask */
231 false), /* pcrel_offset */
232
233 { 0xb },
234
235 /* Indirect load. */
236 HOWTO (0xc, /* type */
237 0, /* rightshift */
238 2, /* size (0 = byte, 1 = short, 2 = long) */
239 16, /* bitsize */
240 false, /* pc_relative */
241 0, /* bitpos */
242 complain_overflow_bitfield, /* complain_on_overflow */
243 0, /* special_function */
244 "R_RL", /* name */
245 true, /* partial_inplace */
246 0xffff, /* src_mask */
247 0xffff, /* dst_mask */
248 false), /* pcrel_offset */
249
250 /* Load address. */
251 HOWTO (0xd, /* type */
252 0, /* rightshift */
253 2, /* size (0 = byte, 1 = short, 2 = long) */
254 16, /* bitsize */
255 false, /* pc_relative */
256 0, /* bitpos */
257 complain_overflow_bitfield, /* complain_on_overflow */
258 0, /* special_function */
259 "R_RLA", /* name */
260 true, /* partial_inplace */
261 0xffff, /* src_mask */
262 0xffff, /* dst_mask */
263 false), /* pcrel_offset */
264
265 { 0xe },
266
267 /* Non-relocating reference. */
268 HOWTO (0xf, /* type */
269 0, /* rightshift */
270 2, /* size (0 = byte, 1 = short, 2 = long) */
271 32, /* bitsize */
272 false, /* pc_relative */
273 0, /* bitpos */
274 complain_overflow_bitfield, /* complain_on_overflow */
275 0, /* special_function */
276 "R_REF", /* name */
277 false, /* partial_inplace */
278 0, /* src_mask */
279 0, /* dst_mask */
280 false), /* pcrel_offset */
281
282 { 0x10 },
283 { 0x11 },
284
285 /* TOC relative indirect load. */
286 HOWTO (0x12, /* type */
287 0, /* rightshift */
288 2, /* size (0 = byte, 1 = short, 2 = long) */
289 16, /* bitsize */
290 false, /* pc_relative */
291 0, /* bitpos */
292 complain_overflow_bitfield, /* complain_on_overflow */
293 0, /* special_function */
294 "R_TRL", /* name */
295 true, /* partial_inplace */
296 0xffff, /* src_mask */
297 0xffff, /* dst_mask */
298 false), /* pcrel_offset */
299
300 /* TOC relative load address. */
301 HOWTO (0x13, /* type */
302 0, /* rightshift */
303 2, /* size (0 = byte, 1 = short, 2 = long) */
304 16, /* bitsize */
305 false, /* pc_relative */
306 0, /* bitpos */
307 complain_overflow_bitfield, /* complain_on_overflow */
308 0, /* special_function */
309 "R_TRLA", /* name */
310 true, /* partial_inplace */
311 0xffff, /* src_mask */
312 0xffff, /* dst_mask */
313 false), /* pcrel_offset */
314
315 /* Modifiable relative branch. */
316 HOWTO (0x14, /* type */
317 1, /* rightshift */
318 2, /* size (0 = byte, 1 = short, 2 = long) */
319 32, /* bitsize */
320 false, /* pc_relative */
321 0, /* bitpos */
322 complain_overflow_bitfield, /* complain_on_overflow */
323 0, /* special_function */
324 "R_RRTBI", /* name */
325 true, /* partial_inplace */
326 0xffffffff, /* src_mask */
327 0xffffffff, /* dst_mask */
328 false), /* pcrel_offset */
329
330 /* Modifiable absolute branch. */
331 HOWTO (0x15, /* type */
332 1, /* rightshift */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
334 32, /* bitsize */
335 false, /* pc_relative */
336 0, /* bitpos */
337 complain_overflow_bitfield, /* complain_on_overflow */
338 0, /* special_function */
339 "R_RRTBA", /* name */
340 true, /* partial_inplace */
341 0xffffffff, /* src_mask */
342 0xffffffff, /* dst_mask */
343 false), /* pcrel_offset */
344
345 /* Modifiable call absolute indirect. */
346 HOWTO (0x16, /* type */
347 0, /* rightshift */
348 2, /* size (0 = byte, 1 = short, 2 = long) */
349 16, /* bitsize */
350 false, /* pc_relative */
351 0, /* bitpos */
352 complain_overflow_bitfield, /* complain_on_overflow */
353 0, /* special_function */
354 "R_CAI", /* name */
355 true, /* partial_inplace */
356 0xffff, /* src_mask */
357 0xffff, /* dst_mask */
358 false), /* pcrel_offset */
359
360 /* Modifiable call relative. */
361 HOWTO (0x17, /* type */
362 0, /* rightshift */
363 2, /* size (0 = byte, 1 = short, 2 = long) */
364 16, /* bitsize */
365 false, /* pc_relative */
366 0, /* bitpos */
367 complain_overflow_bitfield, /* complain_on_overflow */
368 0, /* special_function */
369 "R_REL", /* name */
370 true, /* partial_inplace */
371 0xffff, /* src_mask */
372 0xffff, /* dst_mask */
373 false), /* pcrel_offset */
374
375 /* Modifiable branch absolute. */
376 HOWTO (0x18, /* type */
377 0, /* rightshift */
378 2, /* size (0 = byte, 1 = short, 2 = long) */
379 16, /* bitsize */
380 false, /* pc_relative */
381 0, /* bitpos */
382 complain_overflow_bitfield, /* complain_on_overflow */
383 0, /* special_function */
384 "R_RBA", /* name */
385 true, /* partial_inplace */
386 0xffff, /* src_mask */
387 0xffff, /* dst_mask */
388 false), /* pcrel_offset */
389
390 /* Modifiable branch absolute. */
391 HOWTO (0x19, /* type */
392 0, /* rightshift */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
394 16, /* bitsize */
395 false, /* pc_relative */
396 0, /* bitpos */
397 complain_overflow_bitfield, /* complain_on_overflow */
398 0, /* special_function */
399 "R_RBAC", /* name */
400 true, /* partial_inplace */
401 0xffff, /* src_mask */
402 0xffff, /* dst_mask */
403 false), /* pcrel_offset */
404
405 /* Modifiable branch relative. */
406 HOWTO (0x1a, /* type */
407 0, /* rightshift */
408 2, /* size (0 = byte, 1 = short, 2 = long) */
409 26, /* bitsize */
410 false, /* pc_relative */
411 0, /* bitpos */
412 complain_overflow_signed, /* complain_on_overflow */
413 0, /* special_function */
414 "R_REL", /* name */
415 true, /* partial_inplace */
416 0xffff, /* src_mask */
417 0xffff, /* dst_mask */
418 false), /* pcrel_offset */
419
420 /* Modifiable branch absolute. */
421 HOWTO (0x1b, /* type */
422 0, /* rightshift */
423 2, /* size (0 = byte, 1 = short, 2 = long) */
424 16, /* bitsize */
425 false, /* pc_relative */
426 0, /* bitpos */
427 complain_overflow_bitfield, /* complain_on_overflow */
428 0, /* special_function */
429 "R_REL", /* name */
430 true, /* partial_inplace */
431 0xffff, /* src_mask */
432 0xffff, /* dst_mask */
433 false) /* pcrel_offset */
434 };
435
436 #define HOWTO_COUNT (sizeof nlm_powerpc_howto_table \
437 / sizeof nlm_powerpc_howto_table[0])
438
439 /* Read a PowerPC NLM reloc. */
440
441 static boolean
442 nlm_powerpc_read_reloc (abfd, sym, secp, rel)
443 bfd *abfd;
444 nlmNAME(symbol_type) *sym;
445 asection **secp;
446 arelent *rel;
447 {
448 struct nlm32_powerpc_external_reloc ext;
449 bfd_vma l_vaddr;
450 unsigned long l_symndx;
451 int l_rtype;
452 int l_rsecnm;
453 asection *code_sec, *data_sec, *bss_sec;
454
455 /* Read the reloc from the file. */
456 if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext)
457 return false;
458
459 /* Swap in the fields. */
460 l_vaddr = bfd_h_get_32 (abfd, ext.l_vaddr);
461 l_symndx = bfd_h_get_32 (abfd, ext.l_symndx);
462 l_rtype = bfd_h_get_16 (abfd, ext.l_rtype);
463 l_rsecnm = bfd_h_get_16 (abfd, ext.l_rsecnm);
464
465 /* Get the sections now, for convenience. */
466 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
467 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
468 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
469
470 /* Work out the arelent fields. */
471 if (sym != NULL)
472 {
473 /* This is an import. sym_ptr_ptr is filled in by
474 nlm_canonicalize_reloc. */
475 rel->sym_ptr_ptr = NULL;
476 }
477 else
478 {
479 asection *sec;
480
481 if (l_symndx == 0)
482 sec = code_sec;
483 else if (l_symndx == 1)
484 sec = data_sec;
485 else if (l_symndx == 2)
486 sec = bss_sec;
487 else
488 {
489 bfd_set_error (bfd_error_bad_value);
490 return false;
491 }
492
493 rel->sym_ptr_ptr = sec->symbol_ptr_ptr;
494 }
495
496 rel->addend = 0;
497
498 BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT);
499
500 rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff);
501
502 BFD_ASSERT (rel->howto->name != NULL
503 && ((l_rtype & 0x8000) != 0
504 ? (rel->howto->complain_on_overflow
505 == complain_overflow_signed)
506 : (rel->howto->complain_on_overflow
507 == complain_overflow_bitfield))
508 && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1);
509
510 if (l_rsecnm == 0)
511 *secp = code_sec;
512 else if (l_rsecnm == 1)
513 {
514 *secp = data_sec;
515 l_vaddr -= bfd_section_size (abfd, code_sec);
516 }
517 else
518 {
519 bfd_set_error (bfd_error_bad_value);
520 return false;
521 }
522
523 rel->address = l_vaddr;
524
525 return true;
526 }
527
528 /* Mangle PowerPC NLM relocs for output. */
529
530 static boolean
531 nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count)
532 bfd *abfd;
533 asection *sec;
534 PTR data;
535 bfd_vma offset;
536 bfd_size_type count;
537 {
538 return true;
539 }
540
541 /* Read a PowerPC NLM import record */
542
543 static boolean
544 nlm_powerpc_read_import (abfd, sym)
545 bfd *abfd;
546 nlmNAME(symbol_type) *sym;
547 {
548 struct nlm_relent *nlm_relocs; /* relocation records for symbol */
549 bfd_size_type rcount; /* number of relocs */
550 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
551 unsigned char symlength; /* length of symbol name */
552 char *name;
553
554 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
555 != sizeof (symlength))
556 return (false);
557 sym -> symbol.the_bfd = abfd;
558 name = bfd_alloc (abfd, symlength + 1);
559 if (name == NULL)
560 {
561 bfd_set_error (bfd_error_no_memory);
562 return false;
563 }
564 if (bfd_read (name, symlength, 1, abfd) != symlength)
565 return (false);
566 name[symlength] = '\0';
567 sym -> symbol.name = name;
568 sym -> symbol.flags = 0;
569 sym -> symbol.value = 0;
570 sym -> symbol.section = &bfd_und_section;
571 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
572 return (false);
573 rcount = bfd_h_get_32 (abfd, temp);
574 nlm_relocs = ((struct nlm_relent *)
575 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
576 if (nlm_relocs == (struct nlm_relent *) NULL)
577 {
578 bfd_set_error (bfd_error_no_memory);
579 return false;
580 }
581 sym -> relocs = nlm_relocs;
582 sym -> rcnt = 0;
583 while (sym -> rcnt < rcount)
584 {
585 asection *section;
586
587 if (nlm_powerpc_read_reloc (abfd, sym, &section,
588 &nlm_relocs -> reloc)
589 == false)
590 return false;
591 nlm_relocs -> section = section;
592 nlm_relocs++;
593 sym -> rcnt++;
594 }
595 return true;
596 }
597
598 /* Write a PowerPC NLM reloc. */
599
600 static boolean
601 nlm_powerpc_write_reloc (abfd, sec, rel, indx)
602 bfd *abfd;
603 asection *sec;
604 arelent *rel;
605 int indx;
606 {
607 struct nlm32_powerpc_external_reloc ext;
608 asection *code_sec, *data_sec, *bss_sec;
609 asymbol *sym;
610 asection *symsec;
611 unsigned long l_symndx;
612 int l_rtype;
613 int l_rsecnm;
614 const reloc_howto_type *howto;
615 bfd_size_type address;
616
617 /* Get the sections now, for convenience. */
618 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
619 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
620 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
621
622 sym = *rel->sym_ptr_ptr;
623 symsec = bfd_get_section (sym);
624 if (indx != -1)
625 {
626 BFD_ASSERT (symsec == &bfd_und_section);
627 l_symndx = indx + 3;
628 }
629 else
630 {
631 if (symsec == code_sec)
632 l_symndx = 0;
633 else if (symsec == data_sec)
634 l_symndx = 1;
635 else if (symsec == bss_sec)
636 l_symndx = 2;
637 else
638 {
639 bfd_set_error (bfd_error_bad_value);
640 return false;
641 }
642 }
643
644 bfd_h_put_32 (abfd, (bfd_vma) l_symndx, ext.l_symndx);
645
646 for (howto = nlm_powerpc_howto_table;
647 howto < nlm_powerpc_howto_table + HOWTO_COUNT;
648 howto++)
649 {
650 if (howto->rightshift == rel->howto->rightshift
651 && howto->size == rel->howto->size
652 && howto->bitsize == rel->howto->bitsize
653 && howto->pc_relative == rel->howto->pc_relative
654 && howto->bitpos == rel->howto->bitpos
655 && (howto->partial_inplace == rel->howto->partial_inplace
656 || (! rel->howto->partial_inplace
657 && rel->addend == 0))
658 && (howto->src_mask == rel->howto->src_mask
659 || (rel->howto->src_mask == 0
660 && rel->addend == 0))
661 && howto->dst_mask == rel->howto->dst_mask
662 && howto->pcrel_offset == rel->howto->pcrel_offset)
663 break;
664 }
665 if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT)
666 {
667 bfd_set_error (bfd_error_bad_value);
668 return false;
669 }
670
671 l_rtype = howto->type;
672 if (howto->complain_on_overflow == complain_overflow_signed)
673 l_rtype |= 0x8000;
674 l_rtype |= (howto->bitsize - 1) << 8;
675 bfd_h_put_16 (abfd, (bfd_vma) l_rtype, ext.l_rtype);
676
677 address = rel->address;
678
679 if (sec == code_sec)
680 l_rsecnm = 0;
681 else if (sec == data_sec)
682 {
683 l_rsecnm = 1;
684 address += bfd_section_size (abfd, code_sec);
685 }
686 else
687 {
688 bfd_set_error (bfd_error_bad_value);
689 return false;
690 }
691
692 bfd_h_put_16 (abfd, (bfd_vma) l_rsecnm, ext.l_rsecnm);
693 bfd_h_put_32 (abfd, (bfd_vma) address, ext.l_vaddr);
694
695 if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext)
696 return false;
697
698 return true;
699 }
700
701 /* Write a PowerPC NLM import. */
702
703 static boolean
704 nlm_powerpc_write_import (abfd, sec, rel)
705 bfd *abfd;
706 asection *sec;
707 arelent *rel;
708 {
709 return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
710 }
711
712 /* Write a PowerPC NLM external symbol. This routine keeps a static
713 count of the symbol index. FIXME: I don't know if this is
714 necessary, and the index never gets reset. */
715
716 static boolean
717 nlm_powerpc_write_external (abfd, count, sym, relocs)
718 bfd *abfd;
719 bfd_size_type count;
720 asymbol *sym;
721 struct reloc_and_sec *relocs;
722 {
723 int i;
724 bfd_byte len;
725 unsigned char temp[NLM_TARGET_LONG_SIZE];
726 static int indx;
727
728 len = strlen (sym->name);
729 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
730 || bfd_write (sym->name, len, 1, abfd) != len)
731 return false;
732
733 bfd_put_32 (abfd, count, temp);
734 if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
735 return false;
736
737 for (i = 0; i < count; i++)
738 {
739 if (nlm_powerpc_write_reloc (abfd, relocs[i].sec,
740 relocs[i].rel, indx) == false)
741 return false;
742 }
743
744 ++indx;
745
746 return true;
747 }
748
749 #include "nlmswap.h"
750
751 static const struct nlm_backend_data nlm32_powerpc_backend =
752 {
753 "NetWare PowerPC Module \032",
754 sizeof (Nlm32_powerpc_External_Fixed_Header),
755 sizeof (struct nlm32_powerpc_external_prefix_header),
756 bfd_arch_powerpc,
757 0,
758 false,
759 nlm_powerpc_backend_object_p,
760 nlm_powerpc_write_prefix,
761 nlm_powerpc_read_reloc,
762 nlm_powerpc_mangle_relocs,
763 nlm_powerpc_read_import,
764 nlm_powerpc_write_import,
765 0, /* set_public_section */
766 0, /* get_public_offset */
767 nlm_swap_fixed_header_in,
768 nlm_swap_fixed_header_out,
769 nlm_powerpc_write_external,
770 0, /* write_export */
771 };
772
773 #define TARGET_BIG_NAME "nlm32-powerpc"
774 #define TARGET_BIG_SYM nlmNAME(powerpc_vec)
775 #define TARGET_BACKEND_DATA &nlm32_powerpc_backend
776
777 #include "nlm-target.h"
This page took 0.049561 seconds and 5 git commands to generate.