* nlm32-i386.c (nlm_i386_read_import): Null terminate the symbol
[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 {
458 bfd_set_error (bfd_error_system_call);
459 return false;
460 }
461
462 /* Swap in the fields. */
463 l_vaddr = bfd_h_get_32 (abfd, ext.l_vaddr);
464 l_symndx = bfd_h_get_32 (abfd, ext.l_symndx);
465 l_rtype = bfd_h_get_16 (abfd, ext.l_rtype);
466 l_rsecnm = bfd_h_get_16 (abfd, ext.l_rsecnm);
467
468 /* Get the sections now, for convenience. */
469 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
470 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
471 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
472
473 /* Work out the arelent fields. */
474 if (sym != NULL)
475 {
476 /* This is an import. sym_ptr_ptr is filled in by
477 nlm_canonicalize_reloc. */
478 rel->sym_ptr_ptr = NULL;
479 }
480 else
481 {
482 asection *sec;
483
484 if (l_symndx == 0)
485 sec = code_sec;
486 else if (l_symndx == 1)
487 sec = data_sec;
488 else if (l_symndx == 2)
489 sec = bss_sec;
490 else
491 {
492 bfd_set_error (bfd_error_bad_value);
493 return false;
494 }
495
496 rel->sym_ptr_ptr = sec->symbol_ptr_ptr;
497 }
498
499 rel->addend = 0;
500
501 BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT);
502
503 rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff);
504
505 BFD_ASSERT (rel->howto->name != NULL
506 && ((l_rtype & 0x8000) != 0
507 ? (rel->howto->complain_on_overflow
508 == complain_overflow_signed)
509 : (rel->howto->complain_on_overflow
510 == complain_overflow_bitfield))
511 && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1);
512
513 if (l_rsecnm == 0)
514 *secp = code_sec;
515 else if (l_rsecnm == 1)
516 {
517 *secp = data_sec;
518 l_vaddr -= bfd_section_size (abfd, code_sec);
519 }
520 else
521 {
522 bfd_set_error (bfd_error_bad_value);
523 return false;
524 }
525
526 rel->address = l_vaddr;
527
528 return true;
529 }
530
531 /* Mangle PowerPC NLM relocs for output. */
532
533 static boolean
534 nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count)
535 bfd *abfd;
536 asection *sec;
537 PTR data;
538 bfd_vma offset;
539 bfd_size_type count;
540 {
541 return true;
542 }
543
544 /* Read a PowerPC NLM import record */
545
546 static boolean
547 nlm_powerpc_read_import (abfd, sym)
548 bfd *abfd;
549 nlmNAME(symbol_type) *sym;
550 {
551 struct nlm_relent *nlm_relocs; /* relocation records for symbol */
552 bfd_size_type rcount; /* number of relocs */
553 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
554 unsigned char symlength; /* length of symbol name */
555 char *name;
556
557 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
558 != sizeof (symlength))
559 {
560 bfd_set_error (bfd_error_system_call);
561 return (false);
562 }
563 sym -> symbol.the_bfd = abfd;
564 name = bfd_alloc (abfd, symlength + 1);
565 if (name == NULL)
566 {
567 bfd_set_error (bfd_error_no_memory);
568 return false;
569 }
570 if (bfd_read (name, symlength, 1, abfd) != symlength)
571 {
572 bfd_set_error (bfd_error_system_call);
573 return (false);
574 }
575 name[symlength] = '\0';
576 sym -> symbol.name = name;
577 sym -> symbol.flags = 0;
578 sym -> symbol.value = 0;
579 sym -> symbol.section = &bfd_und_section;
580 if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
581 {
582 bfd_set_error (bfd_error_system_call);
583 return (false);
584 }
585 rcount = bfd_h_get_32 (abfd, temp);
586 nlm_relocs = ((struct nlm_relent *)
587 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
588 if (nlm_relocs == (struct nlm_relent *) NULL)
589 {
590 bfd_set_error (bfd_error_no_memory);
591 return false;
592 }
593 sym -> relocs = nlm_relocs;
594 sym -> rcnt = 0;
595 while (sym -> rcnt < rcount)
596 {
597 asection *section;
598
599 if (nlm_powerpc_read_reloc (abfd, sym, &section,
600 &nlm_relocs -> reloc)
601 == false)
602 return false;
603 nlm_relocs -> section = section;
604 nlm_relocs++;
605 sym -> rcnt++;
606 }
607 return true;
608 }
609
610 /* Write a PowerPC NLM reloc. */
611
612 static boolean
613 nlm_powerpc_write_reloc (abfd, sec, rel, indx)
614 bfd *abfd;
615 asection *sec;
616 arelent *rel;
617 int indx;
618 {
619 struct nlm32_powerpc_external_reloc ext;
620 asection *code_sec, *data_sec, *bss_sec;
621 asymbol *sym;
622 asection *symsec;
623 unsigned long l_symndx;
624 int l_rtype;
625 int l_rsecnm;
626 const reloc_howto_type *howto;
627 bfd_size_type address;
628
629 /* Get the sections now, for convenience. */
630 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
631 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
632 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
633
634 sym = *rel->sym_ptr_ptr;
635 symsec = bfd_get_section (sym);
636 if (indx != -1)
637 {
638 BFD_ASSERT (symsec == &bfd_und_section);
639 l_symndx = indx + 3;
640 }
641 else
642 {
643 if (symsec == code_sec)
644 l_symndx = 0;
645 else if (symsec == data_sec)
646 l_symndx = 1;
647 else if (symsec == bss_sec)
648 l_symndx = 2;
649 else
650 {
651 bfd_set_error (bfd_error_bad_value);
652 return false;
653 }
654 }
655
656 bfd_h_put_32 (abfd, (bfd_vma) l_symndx, ext.l_symndx);
657
658 for (howto = nlm_powerpc_howto_table;
659 howto < nlm_powerpc_howto_table + HOWTO_COUNT;
660 howto++)
661 {
662 if (howto->rightshift == rel->howto->rightshift
663 && howto->size == rel->howto->size
664 && howto->bitsize == rel->howto->bitsize
665 && howto->pc_relative == rel->howto->pc_relative
666 && howto->bitpos == rel->howto->bitpos
667 && (howto->partial_inplace == rel->howto->partial_inplace
668 || (! rel->howto->partial_inplace
669 && rel->addend == 0))
670 && (howto->src_mask == rel->howto->src_mask
671 || (rel->howto->src_mask == 0
672 && rel->addend == 0))
673 && howto->dst_mask == rel->howto->dst_mask
674 && howto->pcrel_offset == rel->howto->pcrel_offset)
675 break;
676 }
677 if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT)
678 {
679 bfd_set_error (bfd_error_bad_value);
680 return false;
681 }
682
683 l_rtype = howto->type;
684 if (howto->complain_on_overflow == complain_overflow_signed)
685 l_rtype |= 0x8000;
686 l_rtype |= (howto->bitsize - 1) << 8;
687 bfd_h_put_16 (abfd, (bfd_vma) l_rtype, ext.l_rtype);
688
689 address = rel->address;
690
691 if (sec == code_sec)
692 l_rsecnm = 0;
693 else if (sec == data_sec)
694 {
695 l_rsecnm = 1;
696 address += bfd_section_size (abfd, code_sec);
697 }
698 else
699 {
700 bfd_set_error (bfd_error_bad_value);
701 return false;
702 }
703
704 bfd_h_put_16 (abfd, (bfd_vma) l_rsecnm, ext.l_rsecnm);
705 bfd_h_put_32 (abfd, (bfd_vma) address, ext.l_vaddr);
706
707 if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext)
708 return false;
709
710 return true;
711 }
712
713 /* Write a PowerPC NLM import. */
714
715 static boolean
716 nlm_powerpc_write_import (abfd, sec, rel)
717 bfd *abfd;
718 asection *sec;
719 arelent *rel;
720 {
721 return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
722 }
723
724 /* Write a PowerPC NLM external symbol. This routine keeps a static
725 count of the symbol index. FIXME: I don't know if this is
726 necessary, and the index never gets reset. */
727
728 static boolean
729 nlm_powerpc_write_external (abfd, count, sym, relocs)
730 bfd *abfd;
731 bfd_size_type count;
732 asymbol *sym;
733 struct reloc_and_sec *relocs;
734 {
735 int i;
736 bfd_byte len;
737 unsigned char temp[NLM_TARGET_LONG_SIZE];
738 static int indx;
739
740 len = strlen (sym->name);
741 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
742 || bfd_write (sym->name, len, 1, abfd) != len)
743 {
744 bfd_set_error (bfd_error_system_call);
745 return false;
746 }
747
748 bfd_put_32 (abfd, count, temp);
749 if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
750 {
751 bfd_set_error (bfd_error_system_call);
752 return false;
753 }
754
755 for (i = 0; i < count; i++)
756 {
757 if (nlm_powerpc_write_reloc (abfd, relocs[i].sec,
758 relocs[i].rel, indx) == false)
759 return false;
760 }
761
762 ++indx;
763
764 return true;
765 }
766
767 #include "nlmswap.h"
768
769 static const struct nlm_backend_data nlm32_powerpc_backend =
770 {
771 "NetWare PowerPC Module \032",
772 sizeof (Nlm32_powerpc_External_Fixed_Header),
773 sizeof (struct nlm32_powerpc_external_prefix_header),
774 bfd_arch_powerpc,
775 0,
776 false,
777 nlm_powerpc_backend_object_p,
778 nlm_powerpc_write_prefix,
779 nlm_powerpc_read_reloc,
780 nlm_powerpc_mangle_relocs,
781 nlm_powerpc_read_import,
782 nlm_powerpc_write_import,
783 0, /* set_public_section */
784 0, /* get_public_offset */
785 nlm_swap_fixed_header_in,
786 nlm_swap_fixed_header_out,
787 nlm_powerpc_write_external,
788 0, /* write_export */
789 };
790
791 #define TARGET_BIG_NAME "nlm32-powerpc"
792 #define TARGET_BIG_SYM nlmNAME(powerpc_vec)
793 #define TARGET_BACKEND_DATA &nlm32_powerpc_backend
794
795 #include "nlm-target.h"
This page took 0.046975 seconds and 5 git commands to generate.