1 /* BFD back-end for Intel 960 b.out binaries.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #include "aout/stab_gnu.h"
29 #include "libaout.h" /* BFD a.out internal data structures */
32 extern bfd_error_vector_type bfd_error_vector;
33 PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section));
34 PROTO (static bfd_target *, b_out_callback, (bfd *));
36 PROTO (boolean, aout_32_slurp_symbol_table, (bfd *abfd));
37 PROTO (void , aout_32_write_syms, ());
39 /* Swaps the information in an executable header taken from a raw byte
40 stream memory image, into the internal exec_header structure. */
42 PROTO(void, bout_swap_exec_header_in,
44 struct external_exec *raw_bytes,
45 struct internal_exec *execp));
48 DEFUN(bout_swap_exec_header_in,(abfd, raw_bytes, execp),
50 struct external_exec *raw_bytes AND
51 struct internal_exec *execp)
53 struct external_exec *bytes = (struct external_exec *)raw_bytes;
55 /* Now fill in fields in the execp, from the bytes in the raw data. */
56 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
57 execp->a_text = GET_WORD (abfd, bytes->e_text);
58 execp->a_data = GET_WORD (abfd, bytes->e_data);
59 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
60 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
61 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
62 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
63 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
64 execp->a_tload = GET_WORD (abfd, bytes->e_tload);
65 execp->a_dload = GET_WORD (abfd, bytes->e_dload);
66 execp->a_talign = bytes->e_talign[0];
67 execp->a_dalign = bytes->e_dalign[0];
68 execp->a_balign = bytes->e_balign[0];
69 execp->a_relaxable = bytes->e_relaxable[0];
72 /* Swaps the information in an internal exec header structure into the
73 supplied buffer ready for writing to disk. */
75 PROTO(void, bout_swap_exec_header_out,
77 struct internal_exec *execp,
78 struct external_exec *raw_bytes));
80 DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes),
82 struct internal_exec *execp AND
83 struct external_exec *raw_bytes)
85 struct external_exec *bytes = (struct external_exec *)raw_bytes;
87 /* Now fill in fields in the raw data, from the fields in the exec struct. */
88 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
89 PUT_WORD (abfd, execp->a_text , bytes->e_text);
90 PUT_WORD (abfd, execp->a_data , bytes->e_data);
91 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
92 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
93 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
94 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
95 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
96 PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
97 PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
98 bytes->e_talign[0] = execp->a_talign;
99 bytes->e_dalign[0] = execp->a_dalign;
100 bytes->e_balign[0] = execp->a_balign;
101 bytes->e_relaxable[0] = execp->a_relaxable;
106 b_out_object_p (abfd)
109 struct internal_exec anexec;
110 struct external_exec exec_bytes;
112 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
113 != EXEC_BYTES_SIZE) {
114 bfd_error = wrong_format;
118 anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
120 if (N_BADMAG (anexec)) {
121 bfd_error = wrong_format;
125 bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
126 return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
130 /* Finish up the opening of a b.out file for reading. Fill in all the
131 fields that are not handled by common code. */
134 b_out_callback (abfd)
137 struct internal_exec *execp = exec_hdr (abfd);
138 unsigned long bss_start;
140 /* Architecture and machine type */
141 bfd_set_arch_mach(abfd,
142 bfd_arch_i960, /* B.out only used on i960 */
143 bfd_mach_i960_core /* Default */
146 /* The positions of the string table and symbol table. */
147 obj_str_filepos (abfd) = N_STROFF (*execp);
148 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
150 /* The alignments of the sections */
151 obj_textsec (abfd)->alignment_power = execp->a_talign;
152 obj_datasec (abfd)->alignment_power = execp->a_dalign;
153 obj_bsssec (abfd)->alignment_power = execp->a_balign;
155 /* The starting addresses of the sections. */
156 obj_textsec (abfd)->vma = execp->a_tload;
157 obj_datasec (abfd)->vma = execp->a_dload;
159 /* And reload the sizes, since the aout module zaps them */
160 obj_textsec (abfd)->_raw_size = execp->a_text;
162 bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
163 obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
165 /* The file positions of the sections */
166 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
167 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
169 /* The file positions of the relocation info */
170 obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
171 obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
173 adata(abfd).page_size = 1; /* Not applicable. */
174 adata(abfd).segment_size = 1; /* Not applicable. */
175 adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
177 if (execp->a_relaxable)
178 abfd->flags |= BFD_IS_RELAXABLE;
182 struct bout_data_struct {
184 struct internal_exec e;
188 b_out_mkobject (abfd)
191 struct bout_data_struct *rawptr;
193 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
194 if (rawptr == NULL) {
195 bfd_error = no_memory;
199 abfd->tdata.bout_data = rawptr;
200 exec_hdr (abfd) = &rawptr->e;
202 /* For simplicity's sake we just make all the sections right here. */
203 obj_textsec (abfd) = (asection *)NULL;
204 obj_datasec (abfd) = (asection *)NULL;
205 obj_bsssec (abfd) = (asection *)NULL;
207 bfd_make_section (abfd, ".text");
208 bfd_make_section (abfd, ".data");
209 bfd_make_section (abfd, ".bss");
215 b_out_write_object_contents (abfd)
218 struct external_exec swapped_hdr;
220 exec_hdr (abfd)->a_info = BMAGIC;
222 exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size;
223 exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size;
224 exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size;
225 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
226 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
227 exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
228 sizeof (struct relocation_info));
229 exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
230 sizeof (struct relocation_info));
232 exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
233 exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
234 exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
236 exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
237 exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
239 bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
241 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
242 bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd);
244 /* Now write out reloc info, followed by syms and strings */
245 if (bfd_get_symcount (abfd) != 0)
247 bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
249 aout_32_write_syms (abfd);
251 bfd_seek (abfd, (file_ptr)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
253 if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
254 bfd_seek (abfd, (file_ptr)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
256 if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
261 /** Some reloc hackery */
263 #define CALLS 0x66003800 /* Template for 'calls' instruction */
264 #define BAL 0x0b000000 /* Template for 'bal' instruction */
265 #define BALX 0x85000000 /* Template for 'balx' instruction */
266 #define BAL_MASK 0x00ffffff
267 #define CALL 0x09000000
268 #define PCREL13_MASK 0x1fff
269 /* Magic to turn callx into calljx */
270 static bfd_reloc_status_type
271 DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section, seclet),
273 arelent *reloc_entry AND
276 asection *input_section AND
277 bfd_seclet_type *seclet)
279 int word = bfd_get_32(abfd, src);
280 asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
281 aout_symbol_type *symbol = aout_symbol(symbol_in);
283 if (symbol_in->section == &bfd_und_section)
285 bfd_error_vector.undefined_symbol(reloc_entry, seclet);
288 if (IS_CALLNAME(symbol->other))
291 aout_symbol_type *balsym = symbol+1;
292 int inst = bfd_get_32(abfd, (bfd_byte *) src-4);
293 /* The next symbol should be an N_BALNAME */
294 BFD_ASSERT(IS_BALNAME(balsym->other));
297 bfd_put_32(abfd, inst, (bfd_byte *) dst-4);
301 word += symbol->symbol.section->output_offset +
302 symbol->symbol.section->output_section->vma +
303 symbol->symbol.value + reloc_entry->addend;
305 bfd_put_32(abfd, word, dst);
310 /* Magic to turn call into callj */
311 static bfd_reloc_status_type
312 DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx,
313 input_section, seclet),
315 arelent *reloc_entry AND
317 unsigned int srcidx AND
318 unsigned int dstidx AND
319 asection *input_section AND
320 bfd_seclet_type *seclet)
322 int word = bfd_get_32(abfd, (bfd_byte *) data + srcidx);
323 asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
325 aout_symbol_type *symbol = aout_symbol(symbol_in);
327 if (symbol_in->section == &bfd_und_section)
329 bfd_error_vector.undefined_symbol(reloc_entry, seclet);
332 if (IS_OTHER(symbol->other))
334 /* Call to a system procedure - replace code with system
336 word = CALLS | (symbol->other - 1);
340 else if (IS_CALLNAME(symbol->other))
342 aout_symbol_type *balsym = symbol+1;
343 /* The next symbol should be an N_BALNAME */
344 BFD_ASSERT(IS_BALNAME(balsym->other));
346 /* We are calling a leaf - so replace the call instruction
350 (((word & BAL_MASK) +
351 balsym->symbol.section->output_offset +
352 balsym->symbol.section->output_section->vma+
353 balsym->symbol.value + reloc_entry->addend - dstidx -
354 ( input_section->output_section->vma + input_section->output_offset))
363 (((word & BAL_MASK) +
364 symbol->symbol.section->output_offset +
365 symbol->symbol.section->output_section->vma+
366 symbol->symbol.value + reloc_entry->addend - dstidx -
367 ( input_section->output_section->vma + input_section->output_offset))
370 bfd_put_32(abfd, word, (bfd_byte *) data + dstidx);
374 /* type rshift size bitsize pcrel bitpos absolute overflow check*/
377 #define ABS32CODE_SHRUNK 1
382 #define ABS32_MAYBE_RELAXABLE 1
383 #define ABS32_WAS_RELAXABLE 2
387 static reloc_howto_type howto_reloc_callj =
388 HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
389 static reloc_howto_type howto_reloc_abs32 =
390 HOWTO(ABS32, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
391 static reloc_howto_type howto_reloc_pcrel24 =
392 HOWTO(PCREL24, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
394 static reloc_howto_type howto_reloc_pcrel13 =
395 HOWTO(PCREL13, 0, 2, 13, true, 0, true, true,0,"pcrel13", true, 0x00001fff,0x00001fff,false);
398 static reloc_howto_type howto_reloc_abs32codeshrunk =
399 HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false);
401 static reloc_howto_type howto_reloc_abs32code =
402 HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
404 static reloc_howto_type howto_align_table[] = {
405 HOWTO (ALIGNER, 0, 0x1, 0, false, 0, false, false, 0, "align16", false, 0, 0, false),
406 HOWTO (ALIGNER, 0, 0x3, 0, false, 0, false, false, 0, "align32", false, 0, 0, false),
407 HOWTO (ALIGNER, 0, 0x7, 0, false, 0, false, false, 0, "align64", false, 0, 0, false),
408 HOWTO (ALIGNER, 0, 0xf, 0, false, 0, false, false, 0, "align128", false, 0, 0, false),
411 static reloc_howto_type howto_done_align_table[] = {
412 HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, false, false, 0, "donealign16", false, 0, 0, false),
413 HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, false, false, 0, "donealign32", false, 0, 0, false),
414 HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, false, false, 0, "donealign64", false, 0, 0, false),
415 HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, false, false, 0, "donealign128", false, 0, 0, false),
418 static reloc_howto_type *
419 b_out_reloc_type_lookup (abfd, code)
421 bfd_reloc_code_real_type code;
427 case BFD_RELOC_I960_CALLJ:
428 return &howto_reloc_callj;
430 return &howto_reloc_abs32;
431 case BFD_RELOC_24_PCREL:
432 return &howto_reloc_pcrel24;
436 /* Allocate enough room for all the reloc entries, plus pointers to them all */
439 b_out_slurp_reloc_table (abfd, asect, symbols)
444 register struct relocation_info *rptr;
445 unsigned int counter ;
447 int extern_mask, pcrel_mask, callj_mask, length_shift;
450 bfd_vma prev_addr = 0;
453 struct relocation_info *relocs;
454 arelent *reloc_cache;
456 if (asect->relocation) return true;
457 if (!aout_32_slurp_symbol_table (abfd)) return false;
459 if (asect == obj_datasec (abfd)) {
460 reloc_size = exec_hdr(abfd)->a_drsize;
464 if (asect == obj_textsec (abfd)) {
465 reloc_size = exec_hdr(abfd)->a_trsize;
469 bfd_error = invalid_operation;
473 bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET);
474 count = reloc_size / sizeof (struct relocation_info);
476 relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);
478 bfd_error = no_memory;
481 reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent));
483 free ((char*)relocs);
484 bfd_error = no_memory;
488 if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
489 bfd_error = system_call_error;
497 if (abfd->xvec->header_byteorder_big_p) {
498 /* big-endian bit field allocation order */
506 /* little-endian bit field allocation order */
515 for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
517 counter++, rptr++, cache_ptr++)
519 unsigned char *raw = (unsigned char *)rptr;
521 cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
522 cache_ptr->howto = 0;
523 if (abfd->xvec->header_byteorder_big_p)
525 symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
529 symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
532 if (raw[7] & extern_mask)
534 /* if this is set then the r_index is a index into the symbol table;
535 * if the bit is not set then r_index contains a section map.
536 * we either fill in the sym entry with a pointer to the symbol,
537 * or point to the correct section
539 cache_ptr->sym_ptr_ptr = symbols + symnum;
540 cache_ptr->addend = 0;
543 /* in a.out symbols are relative to the beginning of the
544 * file rather than sections ?
545 * (look in translate_from_native_sym_flags)
546 * the reloc entry addend has added to it the offset into the
547 * file of the data, so subtract the base to make the reloc
548 * section relative */
551 /* sign-extend symnum from 24 bits to whatever host uses */
556 cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
561 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
562 cache_ptr->addend = - obj_textsec(abfd)->vma;
566 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
567 cache_ptr->addend = - obj_datasec(abfd)->vma;
571 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
572 cache_ptr->addend = - obj_bsssec(abfd)->vma;
576 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
577 cache_ptr->addend = 0;
579 case -2: /* .align */
580 if (raw[7] & pcrel_mask)
582 cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
583 cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;
590 cache_ptr->addend = 0;
599 /* the i960 only has a few relocation types:
600 abs 32-bit and pcrel 24bit. except for callj's! */
601 if (cache_ptr->howto != 0)
603 else if (raw[7] & callj_mask)
605 cache_ptr->howto = &howto_reloc_callj;
607 else if ( raw[7] & pcrel_mask)
609 if (raw[7] & size_mask)
610 cache_ptr->howto = &howto_reloc_pcrel13;
612 cache_ptr->howto = &howto_reloc_pcrel24;
616 if (raw[7] & incode_mask)
618 cache_ptr->howto = &howto_reloc_abs32code;
622 cache_ptr->howto = &howto_reloc_abs32;
625 if (cache_ptr->address < prev_addr)
627 /* Ouch! this reloc is out of order, insert into the right place
630 arelent *cursor = cache_ptr-1;
631 bfd_vma stop = cache_ptr->address;
633 while (cursor->address > stop && cursor >= reloc_cache)
635 cursor[1] = cursor[0];
642 prev_addr = cache_ptr->address;
648 asect->relocation = reloc_cache;
649 asect->reloc_count = count;
657 b_out_squirt_out_relocs (abfd, section)
667 unsigned int count = section->reloc_count;
668 struct relocation_info *native, *natptr;
669 size_t natsize = count * sizeof (struct relocation_info);
670 int extern_mask, pcrel_mask, len_2, callj_mask;
671 if (count == 0) return true;
672 generic = section->orelocation;
673 native = ((struct relocation_info *) bfd_xmalloc (natsize));
675 bfd_error = no_memory;
679 if (abfd->xvec->header_byteorder_big_p)
681 /* Big-endian bit field allocation order */
691 /* Little-endian bit field allocation order */
700 for (natptr = native; count > 0; --count, ++natptr, ++generic)
702 arelent *g = *generic;
703 unsigned char *raw = (unsigned char *)natptr;
704 asymbol *sym = *(g->sym_ptr_ptr);
706 asection *output_section = sym->section->output_section;
708 bfd_h_put_32(abfd, g->address, raw);
709 /* Find a type in the output format which matches the input howto -
710 * at the moment we assume input format == output format FIXME!!
713 /* FIXME: Need callj stuff here, and to check the howto entries to
714 be sure they are real for this architecture. */
715 if (g->howto== &howto_reloc_callj)
717 raw[7] = callj_mask + pcrel_mask + len_2;
719 else if (g->howto == &howto_reloc_pcrel24)
721 raw[7] = pcrel_mask + len_2;
723 else if (g->howto == &howto_reloc_pcrel13)
725 raw[7] = pcrel_mask + len_1;
727 else if (g->howto == &howto_reloc_abs32code)
729 raw[7] = len_2 + incode_mask;
731 else if (g->howto >= howto_align_table
732 && g->howto <= (howto_align_table
733 + sizeof (howto_align_table) / sizeof (howto_align_table[0])
736 /* symnum == -2; extern_mask not set, pcrel_mask set */
740 | ((g->howto - howto_align_table) << 1));
747 /* already mucked with r_extern, r_idx */;
748 else if (bfd_is_com_section (output_section)
749 || output_section == &bfd_abs_section
750 || output_section == &bfd_und_section)
753 if (bfd_abs_section.symbol == sym)
755 /* Whoops, looked like an abs symbol, but is really an offset
756 from the abs section */
765 r_idx = stoi((*(g->sym_ptr_ptr))->flags);
770 /* Just an ordinary section */
772 r_idx = output_section->target_index;
775 if (abfd->xvec->header_byteorder_big_p) {
776 raw[4] = (unsigned char) (r_idx >> 16);
777 raw[5] = (unsigned char) (r_idx >> 8);
778 raw[6] = (unsigned char) (r_idx );
780 raw[6] = (unsigned char) (r_idx >> 16);
781 raw[5] = (unsigned char) (r_idx>> 8);
782 raw[4] = (unsigned char) (r_idx );
785 raw[7] |= extern_mask;
788 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
797 /* This is stupid. This function should be a boolean predicate */
799 b_out_canonicalize_reloc (abfd, section, relptr, symbols)
805 arelent *tblptr = section->relocation;
806 unsigned int count = 0;
808 if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
809 tblptr = section->relocation;
810 if (!tblptr) return 0;
812 for (; count++ < section->reloc_count;)
813 *relptr++ = tblptr++;
817 return section->reloc_count;
821 b_out_get_reloc_upper_bound (abfd, asect)
825 if (bfd_get_format (abfd) != bfd_object) {
826 bfd_error = invalid_operation;
830 if (asect == obj_datasec (abfd))
831 return (sizeof (arelent *) *
832 ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
835 if (asect == obj_textsec (abfd))
836 return (sizeof (arelent *) *
837 ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
840 bfd_error = invalid_operation;
845 b_out_set_section_contents (abfd, section, location, offset, count)
848 unsigned char *location;
853 if (abfd->output_has_begun == false) { /* set by bfd.c handler */
854 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
855 (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) {
856 bfd_error = invalid_operation;
860 obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
861 obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos
862 + obj_textsec (abfd)->_raw_size;
865 /* regardless, once we know what we're doing, we might as well get going */
866 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
869 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
875 b_out_set_arch_mach (abfd, arch, machine)
877 enum bfd_architecture arch;
878 unsigned long machine;
880 bfd_default_set_arch_mach(abfd, arch, machine);
882 if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
884 if (arch == bfd_arch_i960) /* i960 default is OK */
886 case bfd_mach_i960_core:
887 case bfd_mach_i960_kb_sb:
888 case bfd_mach_i960_mc:
889 case bfd_mach_i960_xa:
890 case bfd_mach_i960_ca:
891 case bfd_mach_i960_ka_sa:
902 DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
906 return sizeof(struct internal_exec);
911 /************************************************************************/
913 DEFUN(get_value,(reloc, seclet),
915 bfd_seclet_type *seclet)
918 asymbol *symbol = *(reloc->sym_ptr_ptr);
920 /* A symbol holds a pointer to a section, and an offset from the
921 base of the section. To relocate, we find where the section will
922 live in the output and add that in */
924 if (symbol->section == &bfd_und_section)
926 /* Ouch, this is an undefined symbol.. */
927 bfd_error_vector.undefined_symbol(reloc, seclet);
928 value = symbol->value;
932 value = symbol->value +
933 symbol->section->output_offset +
934 symbol->section->output_section->vma;
937 /* Add the value contained in the relocation */
938 value += (short)((reloc->addend) & 0xffff);
944 DEFUN(perform_slip,(s, slip, input_section, value),
946 unsigned int slip AND
947 asection *input_section AND
951 /* Find all symbols past this point, and make them know
956 if (p->section == input_section)
958 /* This was pointing into this section, so mangle it */
959 if (p->value > value)
969 /* This routine works out if the thing we want to get to can be
970 reached with a 24bit offset instead of a 32 bit one.
971 If it can, then it changes the amode */
974 DEFUN(abs32code,(input_section, symbols, r, shrink),
975 asection *input_section AND
976 asymbol **symbols AND
980 bfd_vma value = get_value(r,0);
981 bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address;
984 /* See if the address we're looking at within 2^23 bytes of where
985 we are, if so then we can use a small branch rather than the
986 jump we were going to */
988 gap = value - (dot - shrink);
991 if (-1<<23 < (long)gap && (long)gap < 1<<23 )
993 /* Change the reloc type from 32bitcode possible 24, to 24bit
996 r->howto = &howto_reloc_abs32codeshrunk;
997 /* The place to relc moves back by four bytes */
1000 /* This will be four bytes smaller in the long run */
1002 perform_slip(symbols, 4, input_section, r->address-shrink +4);
1008 DEFUN(aligncode,(input_section, symbols, r, shrink),
1009 asection *input_section AND
1010 asymbol **symbols AND
1012 unsigned int shrink)
1014 bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address;
1019 int size = r->howto->size;
1021 /* Reduce the size of the alignment so that it's still aligned but
1022 smaller - the current size is already the same size as or bigger
1023 than the alignment required. */
1025 /* calculate the first byte following the padding before we optimize */
1026 old_end = ((dot + size ) & ~size) + size+1;
1027 /* work out where the new end will be - remember that we're smaller
1028 than we used to be */
1029 new_end = ((dot - shrink + size) & ~size);
1031 /* This is the new end */
1032 gap = old_end - ((dot + size) & ~size);
1034 shrink_delta = (old_end - new_end) - shrink;
1038 /* Change the reloc so that it knows how far to align to */
1039 r->howto = howto_done_align_table + (r->howto - howto_align_table);
1041 /* Encode the stuff into the addend - for future use we need to
1042 know how big the reloc used to be */
1043 r->addend = old_end ;
1045 /* This will be N bytes smaller in the long run, adjust all the symbols */
1046 perform_slip(symbols, shrink_delta, input_section, r->address - shrink );
1047 shrink += shrink_delta;
1054 DEFUN(b_out_relax_section,(abfd, i, symbols),
1060 /* Get enough memory to hold the stuff */
1061 bfd *input_bfd = i->owner;
1062 asection *input_section = i;
1064 boolean new = false;
1066 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1068 arelent **reloc_vector = (arelent **)alloca(reloc_size);
1070 /* Get the relocs and think about them */
1071 if (bfd_canonicalize_reloc(input_bfd,
1077 for (parent = reloc_vector; *parent; parent++)
1079 arelent *r = *parent;
1080 switch (r->howto->type) {
1082 /* An alignment reloc */
1083 shrink = aligncode(input_section, symbols, r,shrink);
1087 /* A 32bit reloc in an addressing mode */
1088 shrink = abs32code(input_section, symbols, r,shrink);
1091 case ABS32CODE_SHRUNK:
1097 input_section->_cooked_size = input_section->_raw_size - shrink;
1104 DEFUN(b_out_get_relocated_section_contents,(in_abfd,
1109 bfd_seclet_type *seclet AND
1111 boolean relocateable)
1113 /* Get enough memory to hold the stuff */
1114 bfd *input_bfd = seclet->u.indirect.section->owner;
1115 asection *input_section = seclet->u.indirect.section;
1116 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1118 arelent **reloc_vector = (arelent **)alloca(reloc_size);
1120 /* If producing relocateable output, don't bother to relax. */
1122 return bfd_generic_get_relocated_section_contents (in_abfd, seclet,
1123 data, relocateable);
1125 /* read in the section */
1126 bfd_get_section_contents(input_bfd,
1130 input_section->_raw_size);
1133 if (bfd_canonicalize_reloc(input_bfd,
1136 seclet->u.indirect.symbols) )
1138 arelent **parent = reloc_vector;
1143 unsigned int dst_address = 0;
1144 unsigned int src_address = 0;
1148 /* Find how long a run we can do */
1149 while (dst_address < seclet->size)
1155 /* Note that the relaxing didn't tie up the addresses in the
1156 relocation, so we use the original address to work out the
1157 run of non-relocated data */
1158 run = reloc->address - src_address;
1164 run = seclet->size - dst_address;
1166 /* Copy the bytes */
1167 for (idx = 0; idx < run; idx++)
1169 data[dst_address++] = data[src_address++];
1172 /* Now do the relocation */
1176 switch (reloc->howto->type)
1179 calljx_callback(in_abfd, reloc, src_address + data, dst_address+data,
1180 input_section, seclet);
1185 bfd_put_32(in_abfd, get_value(reloc, seclet), data+dst_address);
1190 callj_callback(in_abfd, reloc ,data,src_address,dst_address,
1191 input_section, seclet);
1196 src_address = reloc->addend;
1197 dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
1199 case ABS32CODE_SHRUNK:
1200 /* This used to be a callx, but we've found out that a
1201 callj will reach, so do the right thing */
1202 callj_callback(in_abfd, reloc,data,src_address+4, dst_address,
1203 input_section, seclet);
1210 long int word = bfd_get_32(in_abfd, data+src_address);
1211 asymbol *symbol = *(reloc->sym_ptr_ptr);
1212 if (symbol->section == &bfd_und_section)
1214 bfd_error_vector.undefined_symbol(reloc, seclet);
1216 word = (word & ~BAL_MASK) |
1217 (((word & BAL_MASK) +
1218 symbol->section->output_offset +
1219 symbol->section->output_section->vma+
1220 symbol->value + reloc->addend - dst_address -
1221 ( input_section->output_section->vma + input_section->output_offset))
1224 bfd_put_32(in_abfd,word, data+dst_address);
1233 long int word = bfd_get_32(in_abfd, data+src_address);
1234 asymbol *symbol = *(reloc->sym_ptr_ptr);
1235 if (symbol->section == &bfd_und_section)
1237 bfd_error_vector.undefined_symbol(reloc, seclet);
1239 word = (word & ~PCREL13_MASK) |
1240 (((word & PCREL13_MASK) +
1241 symbol->section->output_offset +
1242 symbol->section->output_section->vma+
1243 symbol->value + reloc->addend - dst_address -
1244 ( input_section->output_section->vma + input_section->output_offset))
1247 bfd_put_32(in_abfd,word, data+dst_address);
1263 /***********************************************************************/
1265 /* Build the transfer vectors for Big and Little-Endian B.OUT files. */
1267 /* We don't have core files. */
1268 #define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
1269 #define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1270 #define aout_32_core_file_matches_executable_p \
1271 _bfd_dummy_core_file_matches_executable_p
1273 /* We use BSD-Unix generic archive files. */
1274 #define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
1275 #define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt
1276 #define aout_32_slurp_armap bfd_slurp_bsd_armap
1277 #define aout_32_slurp_extended_name_table bfd_true
1278 #define aout_32_write_armap bsd_write_armap
1279 #define aout_32_truncate_arname bfd_bsd_truncate_arname
1281 /* We override these routines from the usual a.out file routines. */
1282 #define aout_32_canonicalize_reloc b_out_canonicalize_reloc
1283 #define aout_32_get_reloc_upper_bound b_out_get_reloc_upper_bound
1284 #define aout_32_set_section_contents b_out_set_section_contents
1285 #define aout_32_set_arch_mach b_out_set_arch_mach
1286 #define aout_32_sizeof_headers b_out_sizeof_headers
1288 #define aout_32_bfd_debug_info_start bfd_void
1289 #define aout_32_bfd_debug_info_end bfd_void
1290 #define aout_32_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1292 #define aout_32_bfd_get_relocated_section_contents b_out_get_relocated_section_contents
1293 #define aout_32_bfd_relax_section b_out_relax_section
1294 #define aout_32_bfd_seclet_link bfd_generic_seclet_link
1296 bfd_target b_out_vec_big_host =
1298 "b.out.big", /* name */
1299 bfd_target_aout_flavour,
1300 false, /* data byte order is little */
1301 true, /* hdr byte order is big */
1302 (HAS_RELOC | EXEC_P | /* object flags */
1303 HAS_LINENO | HAS_DEBUG |
1304 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1305 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1306 '_', /* symbol leading char */
1307 ' ', /* ar_pad_char */
1308 16, /* ar_max_namelen */
1309 2, /* minumum alignment power */
1311 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1312 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1313 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1314 bfd_generic_archive_p, _bfd_dummy_target},
1315 {bfd_false, b_out_mkobject, /* bfd_set_format */
1316 _bfd_generic_mkarchive, bfd_false},
1317 {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1318 _bfd_write_archive_contents, bfd_false},
1320 JUMP_TABLE(aout_32),
1321 b_out_reloc_type_lookup,
1325 bfd_target b_out_vec_little_host =
1327 "b.out.little", /* name */
1328 bfd_target_aout_flavour,
1329 false, /* data byte order is little */
1330 false, /* header byte order is little */
1331 (HAS_RELOC | EXEC_P | /* object flags */
1332 HAS_LINENO | HAS_DEBUG |
1333 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1334 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1335 '_', /* symbol leading char */
1336 ' ', /* ar_pad_char */
1337 16, /* ar_max_namelen */
1338 2, /* minum align */
1339 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1340 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
1342 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1343 bfd_generic_archive_p, _bfd_dummy_target},
1344 {bfd_false, b_out_mkobject, /* bfd_set_format */
1345 _bfd_generic_mkarchive, bfd_false},
1346 {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1347 _bfd_write_archive_contents, bfd_false},
1348 JUMP_TABLE(aout_32),
1349 b_out_reloc_type_lookup,