1 /* BFD back-end for Intel 960 b.out binaries.
2 Copyright (C) 1990-1991 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, 0L, 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)
248 (long)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
250 aout_32_write_syms (abfd);
252 bfd_seek (abfd, (long)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
254 if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
255 bfd_seek (abfd, (long)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
257 if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
262 /** Some reloc hackery */
264 #define CALLS 0x66003800 /* Template for 'calls' instruction */
265 #define BAL 0x0b000000 /* Template for 'bal' instruction */
266 #define BALX 0x85000000 /* Template for 'balx' instruction */
267 #define BAL_MASK 0x00ffffff
268 #define CALL 0x09000000
269 #define PCREL13_MASK 0x1fff
270 /* Magic to turn callx into calljx */
271 static bfd_reloc_status_type
272 DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section),
274 arelent *reloc_entry AND
278 asection *input_section)
280 int word = bfd_get_32(abfd, src);
281 asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
282 aout_symbol_type *symbol = aout_symbol(symbol_in);
284 if (IS_CALLNAME(symbol->other))
287 aout_symbol_type *balsym = symbol+1;
288 int inst = bfd_get_32(abfd, (bfd_byte *) src-4);
289 /* The next symbol should be an N_BALNAME */
290 BFD_ASSERT(IS_BALNAME(balsym->other));
293 bfd_put_32(abfd, inst, (bfd_byte *) dst-4);
297 word += symbol->symbol.section->output_offset +
298 symbol->symbol.section->output_section->vma +
299 symbol->symbol.value + reloc_entry->addend;
301 bfd_put_32(abfd, word, dst);
306 /* Magic to turn call into callj */
307 static bfd_reloc_status_type
308 DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx, input_section),
310 arelent *reloc_entry AND
312 unsigned int srcidx AND
313 unsigned int dstidx AND
314 asection *input_section )
316 int word = bfd_get_32(abfd, (bfd_byte *) data + srcidx);
317 asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
319 aout_symbol_type *symbol = aout_symbol(symbol_in);
321 if (IS_OTHER(symbol->other))
323 /* Call to a system procedure - replace code with system
325 word = CALLS | (symbol->other - 1);
329 else if (IS_CALLNAME(symbol->other))
331 aout_symbol_type *balsym = symbol+1;
332 /* The next symbol should be an N_BALNAME */
333 BFD_ASSERT(IS_BALNAME(balsym->other));
335 /* We are calling a leaf - so replace the call instruction
339 (((word & BAL_MASK) +
340 balsym->symbol.section->output_offset +
341 balsym->symbol.section->output_section->vma+
342 balsym->symbol.value + reloc_entry->addend - dstidx -
343 ( input_section->output_section->vma + input_section->output_offset))
352 (((word & BAL_MASK) +
353 symbol->symbol.section->output_offset +
354 symbol->symbol.section->output_section->vma+
355 symbol->symbol.value + reloc_entry->addend - dstidx -
356 ( input_section->output_section->vma + input_section->output_offset))
359 bfd_put_32(abfd, word, (bfd_byte *) data + dstidx);
363 /* type rshift size bitsize pcrel bitpos absolute overflow check*/
366 #define ABS32CODE_SHRUNK 1
371 #define ABS32_MAYBE_RELAXABLE 1
372 #define ABS32_WAS_RELAXABLE 2
376 static reloc_howto_type howto_reloc_callj =
377 HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
378 static reloc_howto_type howto_reloc_abs32 =
379 HOWTO(ABS32, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
380 static reloc_howto_type howto_reloc_pcrel24 =
381 HOWTO(PCREL24, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
383 static reloc_howto_type howto_reloc_pcrel13 =
384 HOWTO(PCREL13, 0, 2, 13, true, 0, true, true,0,"pcrel13", true, 0x00001fff,0x00001fff,false);
387 static reloc_howto_type howto_reloc_abs32codeshrunk =
388 HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false);
390 static reloc_howto_type howto_reloc_abs32code =
391 HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
393 static reloc_howto_type howto_align_table[] = {
394 HOWTO (ALIGN, 0, 0x1, 0, false, 0, false, false, 0, "align16", false, 0, 0, false),
395 HOWTO (ALIGN, 0, 0x3, 0, false, 0, false, false, 0, "align32", false, 0, 0, false),
396 HOWTO (ALIGN, 0, 0x7, 0, false, 0, false, false, 0, "align64", false, 0, 0, false),
397 HOWTO (ALIGN, 0, 0xf, 0, false, 0, false, false, 0, "align128", false, 0, 0, false),
400 static reloc_howto_type howto_done_align_table[] = {
401 HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, false, false, 0, "donealign16", false, 0, 0, false),
402 HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, false, false, 0, "donealign32", false, 0, 0, false),
403 HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, false, false, 0, "donealign64", false, 0, 0, false),
404 HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, false, false, 0, "donealign128", false, 0, 0, false),
407 static reloc_howto_type *
408 b_out_reloc_type_lookup (abfd, code)
410 bfd_reloc_code_real_type code;
416 case BFD_RELOC_I960_CALLJ:
417 return &howto_reloc_callj;
419 return &howto_reloc_abs32;
420 case BFD_RELOC_24_PCREL:
421 return &howto_reloc_pcrel24;
425 /* Allocate enough room for all the reloc entries, plus pointers to them all */
428 b_out_slurp_reloc_table (abfd, asect, symbols)
433 register struct relocation_info *rptr;
434 unsigned int counter ;
436 int extern_mask, pcrel_mask, callj_mask, length_shift;
439 bfd_vma prev_addr = 0;
442 struct relocation_info *relocs;
443 arelent *reloc_cache;
445 if (asect->relocation) return true;
446 if (!aout_32_slurp_symbol_table (abfd)) return false;
448 if (asect == obj_datasec (abfd)) {
449 reloc_size = exec_hdr(abfd)->a_drsize;
453 if (asect == obj_textsec (abfd)) {
454 reloc_size = exec_hdr(abfd)->a_trsize;
458 bfd_error = invalid_operation;
462 bfd_seek (abfd, (long)(asect->rel_filepos), SEEK_SET);
463 count = reloc_size / sizeof (struct relocation_info);
465 relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);
467 bfd_error = no_memory;
470 reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent));
472 free ((char*)relocs);
473 bfd_error = no_memory;
477 if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
478 bfd_error = system_call_error;
486 if (abfd->xvec->header_byteorder_big_p) {
487 /* big-endian bit field allocation order */
495 /* little-endian bit field allocation order */
504 for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
506 counter++, rptr++, cache_ptr++)
508 unsigned char *raw = (unsigned char *)rptr;
510 cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
511 cache_ptr->howto = 0;
512 if (abfd->xvec->header_byteorder_big_p)
514 symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
518 symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
521 if (raw[7] & extern_mask)
523 /* if this is set then the r_index is a index into the symbol table;
524 * if the bit is not set then r_index contains a section map.
525 * we either fill in the sym entry with a pointer to the symbol,
526 * or point to the correct section
528 cache_ptr->sym_ptr_ptr = symbols + symnum;
529 cache_ptr->addend = 0;
532 /* in a.out symbols are relative to the beginning of the
533 * file rather than sections ?
534 * (look in translate_from_native_sym_flags)
535 * the reloc entry addend has added to it the offset into the
536 * file of the data, so subtract the base to make the reloc
537 * section relative */
540 /* sign-extend symnum from 24 bits to whatever host uses */
545 cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
550 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
551 cache_ptr->addend = - obj_textsec(abfd)->vma;
555 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
556 cache_ptr->addend = - obj_datasec(abfd)->vma;
560 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
561 cache_ptr->addend = - obj_bsssec(abfd)->vma;
565 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
566 cache_ptr->addend = 0;
568 case -2: /* .align */
569 if (raw[7] & pcrel_mask)
571 cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
572 cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;
579 cache_ptr->addend = 0;
588 /* the i960 only has a few relocation types:
589 abs 32-bit and pcrel 24bit. except for callj's! */
590 if (cache_ptr->howto != 0)
592 else if (raw[7] & callj_mask)
594 cache_ptr->howto = &howto_reloc_callj;
596 else if ( raw[7] & pcrel_mask)
598 if (raw[7] & size_mask)
599 cache_ptr->howto = &howto_reloc_pcrel13;
601 cache_ptr->howto = &howto_reloc_pcrel24;
605 if (raw[7] & incode_mask)
607 cache_ptr->howto = &howto_reloc_abs32code;
611 cache_ptr->howto = &howto_reloc_abs32;
614 if (cache_ptr->address < prev_addr)
616 /* Ouch! this reloc is out of order, insert into the right place
619 arelent *cursor = cache_ptr-1;
620 bfd_vma stop = cache_ptr->address;
622 while (cursor->address > stop && cursor >= reloc_cache)
624 cursor[1] = cursor[0];
631 prev_addr = cache_ptr->address;
637 asect->relocation = reloc_cache;
638 asect->reloc_count = count;
646 b_out_squirt_out_relocs (abfd, section)
656 unsigned int count = section->reloc_count;
657 struct relocation_info *native, *natptr;
658 size_t natsize = count * sizeof (struct relocation_info);
659 int extern_mask, pcrel_mask, len_2, callj_mask;
660 if (count == 0) return true;
661 generic = section->orelocation;
662 native = ((struct relocation_info *) bfd_xmalloc (natsize));
664 bfd_error = no_memory;
668 if (abfd->xvec->header_byteorder_big_p)
670 /* Big-endian bit field allocation order */
680 /* Little-endian bit field allocation order */
689 for (natptr = native; count > 0; --count, ++natptr, ++generic)
691 arelent *g = *generic;
692 unsigned char *raw = (unsigned char *)natptr;
693 asymbol *sym = *(g->sym_ptr_ptr);
695 asection *output_section = sym->section->output_section;
696 bfd_h_put_32(abfd, g->address, raw);
697 /* Find a type in the output format which matches the input howto -
698 * at the moment we assume input format == output format FIXME!!
700 /* FIXME: Need callj stuff here, and to check the howto entries to
701 be sure they are real for this architecture. */
702 if (g->howto== &howto_reloc_callj)
704 raw[7] = callj_mask + pcrel_mask + len_2;
706 else if (g->howto == &howto_reloc_pcrel24)
708 raw[7] = pcrel_mask + len_2;
710 else if (g->howto == &howto_reloc_pcrel13)
712 raw[7] = pcrel_mask + len_1;
714 else if (g->howto == &howto_reloc_abs32code)
716 raw[7] = len_2 + incode_mask;
721 if (output_section == &bfd_com_section
722 || output_section == &bfd_abs_section
723 || output_section == &bfd_und_section)
726 if (bfd_abs_section.symbol == sym)
728 /* Whoops, looked like an abs symbol, but is really an offset
729 from the abs section */
738 r_idx = stoi((*(g->sym_ptr_ptr))->flags);
743 /* Just an ordinary section */
745 r_idx = output_section->target_index;
748 if (abfd->xvec->header_byteorder_big_p) {
749 raw[4] = (unsigned char) (r_idx >> 16);
750 raw[5] = (unsigned char) (r_idx >> 8);
751 raw[6] = (unsigned char) (r_idx );
753 raw[6] = (unsigned char) (r_idx >> 16);
754 raw[5] = (unsigned char) (r_idx>> 8);
755 raw[4] = (unsigned char) (r_idx );
758 raw[7] |= extern_mask;
761 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
770 /* This is stupid. This function should be a boolean predicate */
772 b_out_canonicalize_reloc (abfd, section, relptr, symbols)
778 arelent *tblptr = section->relocation;
779 unsigned int count = 0;
781 if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
782 tblptr = section->relocation;
783 if (!tblptr) return 0;
785 for (; count++ < section->reloc_count;)
786 *relptr++ = tblptr++;
790 return section->reloc_count;
794 b_out_get_reloc_upper_bound (abfd, asect)
798 if (bfd_get_format (abfd) != bfd_object) {
799 bfd_error = invalid_operation;
803 if (asect == obj_datasec (abfd))
804 return (sizeof (arelent *) *
805 ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
808 if (asect == obj_textsec (abfd))
809 return (sizeof (arelent *) *
810 ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
813 bfd_error = invalid_operation;
818 b_out_set_section_contents (abfd, section, location, offset, count)
821 unsigned char *location;
826 if (abfd->output_has_begun == false) { /* set by bfd.c handler */
827 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
828 (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) {
829 bfd_error = invalid_operation;
833 obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
834 obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos
835 + obj_textsec (abfd)->_raw_size;
838 /* regardless, once we know what we're doing, we might as well get going */
839 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
842 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
848 b_out_set_arch_mach (abfd, arch, machine)
850 enum bfd_architecture arch;
851 unsigned long machine;
853 bfd_default_set_arch_mach(abfd, arch, machine);
855 if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
857 if (arch == bfd_arch_i960) /* i960 default is OK */
859 case bfd_mach_i960_core:
860 case bfd_mach_i960_kb_sb:
861 case bfd_mach_i960_mc:
862 case bfd_mach_i960_xa:
863 case bfd_mach_i960_ca:
864 case bfd_mach_i960_ka_sa:
875 DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
879 return sizeof(struct internal_exec);
884 /************************************************************************/
886 DEFUN(get_value,(reloc, seclet),
888 bfd_seclet_type *seclet)
891 asymbol *symbol = *(reloc->sym_ptr_ptr);
892 /* A symbol holds a pointer to a section, and an offset from the
893 base of the section. To relocate, we find where the section will
894 live in the output and add that in */
896 if (symbol->section == &bfd_und_section)
898 /* Ouch, this is an undefined symbol.. */
899 bfd_error_vector.undefined_symbol(reloc, seclet);
900 value = symbol->value;
904 value = symbol->value +
905 symbol->section->output_offset +
906 symbol->section->output_section->vma;
910 /* Add the value contained in the relocation */
911 value += (short)((reloc->addend) & 0xffff);
917 DEFUN(perform_slip,(s, slip, input_section, value),
919 unsigned int slip AND
920 asection *input_section AND
924 /* Find all symbols past this point, and make them know
929 if (p->section == input_section)
931 /* This was pointing into this section, so mangle it */
932 if (p->value > value)
942 /* This routine works out if the thing we want to get to can be
943 reached with a 24bit offset instead of a 32 bit one.
944 If it can, then it changes the amode */
947 DEFUN(abs32code,(input_section, symbols, r, shrink),
948 asection *input_section AND
949 asymbol **symbols AND
953 bfd_vma value = get_value(r,0);
954 bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address;
957 /* See if the address we're looking at within 2^23 bytes of where
958 we are, if so then we can use a small branch rather than the
959 jump we were going to */
961 gap = value - (dot - shrink);
964 if (-1<<23 < (long)gap && (long)gap < 1<<23 )
967 /* Change the reloc type from 32bitcode possible 24, to 24bit
970 r->howto = &howto_reloc_abs32codeshrunk;
971 /* The place to relc moves back by four bytes */
974 /* This will be four bytes smaller in the long run */
976 perform_slip(symbols, 4, input_section, r->address-shrink +4);
984 DEFUN(aligncode,(input_section, symbols, r, shrink),
985 asection *input_section AND
986 asymbol **symbols AND
990 bfd_vma value = get_value(r,0);
992 bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address;
997 int size = r->howto->size;
998 /* Reduce the size of the alignment so that it's still aligned but
999 smaller - the current size is already the same size as or bigger
1000 than the alignment required. */
1004 /* calculate the first byte following the padding before we optimize */
1005 old_end = ((dot + size ) & ~size) + size+1;
1006 /* work out where the new end will be - remember that we're smaller
1007 than we used to be */
1008 new_end = ((dot - shrink + size) & ~size);
1010 /* This is the new end */
1011 gap = old_end - ((dot + size) & ~size);
1013 shrink_delta = (old_end - new_end) - shrink;
1018 /* Change the reloc so that it knows how far to align to */
1019 r->howto = howto_done_align_table + (r->howto - howto_align_table);
1021 /* Encode the stuff into the addend - for future use we need to
1022 know how big the reloc used to be */
1023 r->addend = old_end ;
1025 /* This will be N bytes smaller in the long run, adjust all the symbols */
1029 perform_slip(symbols, shrink_delta, input_section, r->address - shrink );
1030 shrink += shrink_delta;
1037 DEFUN(b_out_relax_section,(abfd, i, symbols),
1043 /* Get enough memory to hold the stuff */
1044 bfd *input_bfd = i->owner;
1045 asection *input_section = i;
1047 boolean new = false;
1049 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1051 arelent **reloc_vector = (arelent **)alloca(reloc_size);
1053 /* Get the relocs and think about them */
1054 if (bfd_canonicalize_reloc(input_bfd,
1060 for (parent = reloc_vector; *parent; parent++)
1062 arelent *r = *parent;
1063 switch (r->howto->type) {
1065 /* An alignment reloc */
1066 shrink = aligncode(input_section, symbols, r,shrink);
1070 /* A 32bit reloc in an addressing mode */
1071 shrink = abs32code(input_section, symbols, r,shrink);
1074 case ABS32CODE_SHRUNK:
1080 input_section->_cooked_size = input_section->_raw_size - shrink;
1087 DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
1089 bfd_seclet_type *seclet AND
1093 /* Get enough memory to hold the stuff */
1094 bfd *input_bfd = seclet->u.indirect.section->owner;
1095 asection *input_section = seclet->u.indirect.section;
1096 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1098 arelent **reloc_vector = (arelent **)alloca(reloc_size);
1100 /* read in the section */
1101 bfd_get_section_contents(input_bfd,
1105 input_section->_raw_size);
1108 if (bfd_canonicalize_reloc(input_bfd,
1111 seclet->u.indirect.symbols) )
1113 arelent **parent = reloc_vector;
1118 unsigned int dst_address = 0;
1119 unsigned int src_address = 0;
1123 /* Find how long a run we can do */
1124 while (dst_address < seclet->size)
1130 /* Note that the relaxing didn't tie up the addresses in the
1131 relocation, so we use the original address to work out the
1132 run of non-relocated data */
1133 run = reloc->address - src_address;
1139 run = seclet->size - dst_address;
1141 /* Copy the bytes */
1142 for (idx = 0; idx < run; idx++)
1144 data[dst_address++] = data[src_address++];
1147 /* Now do the relocation */
1151 switch (reloc->howto->type)
1154 calljx_callback(in_abfd, reloc, src_address + data, dst_address+data, input_section);
1159 bfd_put_32(in_abfd, get_value(reloc, seclet), data+dst_address);
1164 callj_callback(in_abfd, reloc ,data,src_address,dst_address,input_section);
1169 src_address = reloc->addend;
1170 dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
1172 case ABS32CODE_SHRUNK:
1173 /* This used to be a callx, but we've found out that a
1174 callj will reach, so do the right thing */
1175 callj_callback(in_abfd, reloc,data,src_address+4, dst_address,input_section);
1182 long int word = bfd_get_32(in_abfd, data+src_address);
1183 asymbol *symbol = *(reloc->sym_ptr_ptr);
1184 word = (word & ~BAL_MASK) |
1185 (((word & BAL_MASK) +
1186 symbol->section->output_offset +
1187 symbol->section->output_section->vma+
1188 symbol->value + reloc->addend - dst_address -
1189 ( input_section->output_section->vma + input_section->output_offset))
1192 bfd_put_32(in_abfd,word, data+dst_address);
1201 long int word = bfd_get_32(in_abfd, data+src_address);
1202 asymbol *symbol = *(reloc->sym_ptr_ptr);
1203 word = (word & ~PCREL13_MASK) |
1204 (((word & PCREL13_MASK) +
1205 symbol->section->output_offset +
1206 symbol->section->output_section->vma+
1207 symbol->value + reloc->addend - dst_address -
1208 ( input_section->output_section->vma + input_section->output_offset))
1211 bfd_put_32(in_abfd,word, data+dst_address);
1227 /***********************************************************************/
1229 /* Build the transfer vectors for Big and Little-Endian B.OUT files. */
1231 /* We don't have core files. */
1232 #define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
1233 #define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1234 #define aout_32_core_file_matches_executable_p \
1235 _bfd_dummy_core_file_matches_executable_p
1237 /* We use BSD-Unix generic archive files. */
1238 #define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
1239 #define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt
1240 #define aout_32_slurp_armap bfd_slurp_bsd_armap
1241 #define aout_32_slurp_extended_name_table bfd_true
1242 #define aout_32_write_armap bsd_write_armap
1243 #define aout_32_truncate_arname bfd_bsd_truncate_arname
1245 /* We override these routines from the usual a.out file routines. */
1246 #define aout_32_canonicalize_reloc b_out_canonicalize_reloc
1247 #define aout_32_get_reloc_upper_bound b_out_get_reloc_upper_bound
1248 #define aout_32_set_section_contents b_out_set_section_contents
1249 #define aout_32_set_arch_mach b_out_set_arch_mach
1250 #define aout_32_sizeof_headers b_out_sizeof_headers
1252 #define aout_32_bfd_debug_info_start bfd_void
1253 #define aout_32_bfd_debug_info_end bfd_void
1254 #define aout_32_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1256 #define aout_32_bfd_get_relocated_section_contents b_out_get_relocated_section_contents
1257 #define aout_32_bfd_relax_section b_out_relax_section
1259 bfd_target b_out_vec_big_host =
1261 "b.out.big", /* name */
1262 bfd_target_aout_flavour,
1263 false, /* data byte order is little */
1264 true, /* hdr byte order is big */
1265 (HAS_RELOC | EXEC_P | /* object flags */
1266 HAS_LINENO | HAS_DEBUG |
1267 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1268 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1269 '_', /* symbol leading char */
1270 ' ', /* ar_pad_char */
1271 16, /* ar_max_namelen */
1272 2, /* minumum alignment power */
1274 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1275 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1276 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1277 bfd_generic_archive_p, _bfd_dummy_target},
1278 {bfd_false, b_out_mkobject, /* bfd_set_format */
1279 _bfd_generic_mkarchive, bfd_false},
1280 {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1281 _bfd_write_archive_contents, bfd_false},
1283 JUMP_TABLE(aout_32),
1284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */
1285 b_out_reloc_type_lookup,
1289 bfd_target b_out_vec_little_host =
1291 "b.out.little", /* name */
1292 bfd_target_aout_flavour,
1293 false, /* data byte order is little */
1294 false, /* header byte order is little */
1295 (HAS_RELOC | EXEC_P | /* object flags */
1296 HAS_LINENO | HAS_DEBUG |
1297 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1298 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1299 '_', /* symbol leading char */
1300 ' ', /* ar_pad_char */
1301 16, /* ar_max_namelen */
1302 2, /* minum align */
1303 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1304 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
1306 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1307 bfd_generic_archive_p, _bfd_dummy_target},
1308 {bfd_false, b_out_mkobject, /* bfd_set_format */
1309 _bfd_generic_mkarchive, bfd_false},
1310 {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1311 _bfd_write_archive_contents, bfd_false},
1312 JUMP_TABLE(aout_32),
1313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */
1314 b_out_reloc_type_lookup,