source: trunk/src/binutils/bfd/bout.c@ 10

Last change on this file since 10 was 10, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 43.3 KB
Line 
1/* BFD back-end for Intel 960 b.out binaries.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000
4 Free Software Foundation, Inc.
5 Written by Cygnus Support.
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "libbfd.h"
26#include "bfdlink.h"
27#include "genlink.h"
28#include "bout.h"
29
30#include "aout/stab_gnu.h"
31#include "libaout.h" /* BFD a.out internal data structures */
32
33static int aligncode PARAMS ((bfd *abfd, asection *input_section,
34 arelent *r, unsigned int shrink));
35static void perform_slip PARAMS ((bfd *abfd, unsigned int slip,
36 asection *input_section, bfd_vma value));
37static boolean b_out_squirt_out_relocs PARAMS ((bfd *abfd, asection *section));
38static const bfd_target *b_out_callback PARAMS ((bfd *));
39static bfd_reloc_status_type calljx_callback
40 PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR src, PTR dst,
41 asection *));
42static bfd_reloc_status_type callj_callback
43 PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR data,
44 unsigned int srcidx, unsigned int dstidx, asection *, boolean));
45static bfd_vma get_value PARAMS ((arelent *, struct bfd_link_info *,
46 asection *));
47static int abs32code PARAMS ((bfd *, asection *, arelent *,
48 unsigned int, struct bfd_link_info *));
49static boolean b_out_bfd_relax_section PARAMS ((bfd *, asection *,
50 struct bfd_link_info *,
51 boolean *));
52static bfd_byte *b_out_bfd_get_relocated_section_contents
53 PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
54 bfd_byte *, boolean, asymbol **));
55
56/* Swaps the information in an executable header taken from a raw byte
57 stream memory image, into the internal exec_header structure. */
58
59void
60bout_swap_exec_header_in (abfd, raw_bytes, execp)
61 bfd *abfd;
62 struct external_exec *raw_bytes;
63 struct internal_exec *execp;
64{
65 struct external_exec *bytes = (struct external_exec *)raw_bytes;
66
67 /* Now fill in fields in the execp, from the bytes in the raw data. */
68 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
69 execp->a_text = GET_WORD (abfd, bytes->e_text);
70 execp->a_data = GET_WORD (abfd, bytes->e_data);
71 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
72 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
73 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
74 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
75 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
76 execp->a_tload = GET_WORD (abfd, bytes->e_tload);
77 execp->a_dload = GET_WORD (abfd, bytes->e_dload);
78 execp->a_talign = bytes->e_talign[0];
79 execp->a_dalign = bytes->e_dalign[0];
80 execp->a_balign = bytes->e_balign[0];
81 execp->a_relaxable = bytes->e_relaxable[0];
82}
83
84/* Swaps the information in an internal exec header structure into the
85 supplied buffer ready for writing to disk. */
86
87PROTO(void, bout_swap_exec_header_out,
88 (bfd *abfd,
89 struct internal_exec *execp,
90 struct external_exec *raw_bytes));
91void
92bout_swap_exec_header_out (abfd, execp, raw_bytes)
93 bfd *abfd;
94 struct internal_exec *execp;
95 struct external_exec *raw_bytes;
96{
97 struct external_exec *bytes = (struct external_exec *)raw_bytes;
98
99 /* Now fill in fields in the raw data, from the fields in the exec struct. */
100 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
101 PUT_WORD (abfd, execp->a_text , bytes->e_text);
102 PUT_WORD (abfd, execp->a_data , bytes->e_data);
103 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
104 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
105 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
106 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
107 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
108 PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
109 PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
110 bytes->e_talign[0] = execp->a_talign;
111 bytes->e_dalign[0] = execp->a_dalign;
112 bytes->e_balign[0] = execp->a_balign;
113 bytes->e_relaxable[0] = execp->a_relaxable;
114}
115
116static const bfd_target *
117b_out_object_p (abfd)
118 bfd *abfd;
119{
120 struct internal_exec anexec;
121 struct external_exec exec_bytes;
122
123 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
124 != EXEC_BYTES_SIZE) {
125 if (bfd_get_error () != bfd_error_system_call)
126 bfd_set_error (bfd_error_wrong_format);
127 return 0;
128 }
129
130 anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
131
132 if (N_BADMAG (anexec)) {
133 bfd_set_error (bfd_error_wrong_format);
134 return 0;
135 }
136
137 bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
138 return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
139}
140
141/* Finish up the opening of a b.out file for reading. Fill in all the
142 fields that are not handled by common code. */
143
144static const bfd_target *
145b_out_callback (abfd)
146 bfd *abfd;
147{
148 struct internal_exec *execp = exec_hdr (abfd);
149 unsigned long bss_start;
150
151 /* Architecture and machine type */
152 bfd_set_arch_mach(abfd,
153 bfd_arch_i960, /* B.out only used on i960 */
154 bfd_mach_i960_core /* Default */
155 );
156
157 /* The positions of the string table and symbol table. */
158 obj_str_filepos (abfd) = N_STROFF (*execp);
159 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
160
161 /* The alignments of the sections */
162 obj_textsec (abfd)->alignment_power = execp->a_talign;
163 obj_datasec (abfd)->alignment_power = execp->a_dalign;
164 obj_bsssec (abfd)->alignment_power = execp->a_balign;
165
166 /* The starting addresses of the sections. */
167 obj_textsec (abfd)->vma = execp->a_tload;
168 obj_datasec (abfd)->vma = execp->a_dload;
169
170 obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
171 obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
172
173 /* And reload the sizes, since the aout module zaps them */
174 obj_textsec (abfd)->_raw_size = execp->a_text;
175
176 bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
177 obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
178
179 obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
180
181 /* The file positions of the sections */
182 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
183 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
184
185 /* The file positions of the relocation info */
186 obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
187 obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
188
189 adata(abfd).page_size = 1; /* Not applicable. */
190 adata(abfd).segment_size = 1; /* Not applicable. */
191 adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
192
193 if (execp->a_relaxable)
194 abfd->flags |= BFD_IS_RELAXABLE;
195 return abfd->xvec;
196}
197
198struct bout_data_struct {
199 struct aoutdata a;
200 struct internal_exec e;
201};
202
203static boolean
204b_out_mkobject (abfd)
205 bfd *abfd;
206{
207 struct bout_data_struct *rawptr;
208
209 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
210 if (rawptr == NULL)
211 return false;
212
213 abfd->tdata.bout_data = rawptr;
214 exec_hdr (abfd) = &rawptr->e;
215
216 obj_textsec (abfd) = (asection *)NULL;
217 obj_datasec (abfd) = (asection *)NULL;
218 obj_bsssec (abfd) = (asection *)NULL;
219
220 return true;
221}
222
223static int
224b_out_symbol_cmp (a, b)
225 struct aout_symbol **a, **b;
226{
227 asection *sec;
228 bfd_vma av, bv;
229
230 /* Primary key is address */
231 sec = bfd_get_section (&(*a)->symbol);
232 av = sec->output_section->vma + sec->output_offset + (*a)->symbol.value;
233 sec = bfd_get_section (&(*b)->symbol);
234 bv = sec->output_section->vma + sec->output_offset + (*b)->symbol.value;
235
236 if (av < bv)
237 return -1;
238 if (av > bv)
239 return 1;
240
241 /* Secondary key puts CALLNAME syms last and BALNAME syms first, so
242 that they have the best chance of being contiguous. */
243 if (IS_BALNAME ((*a)->other) || IS_CALLNAME ((*b)->other))
244 return -1;
245 if (IS_CALLNAME ((*a)->other) || IS_BALNAME ((*b)->other))
246 return 1;
247
248 return 0;
249}
250
251static boolean
252b_out_write_object_contents (abfd)
253 bfd *abfd;
254{
255 struct external_exec swapped_hdr;
256
257 if (! aout_32_make_sections (abfd))
258 return false;
259
260 exec_hdr (abfd)->a_info = BMAGIC;
261
262 exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size;
263 exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size;
264 exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size;
265 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
266 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
267 exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
268 sizeof (struct relocation_info));
269 exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
270 sizeof (struct relocation_info));
271
272 exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
273 exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
274 exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
275
276 exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
277 exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
278
279 bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
280
281 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
282 || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
283 != EXEC_BYTES_SIZE))
284 return false;
285
286 /* Now write out reloc info, followed by syms and strings */
287 if (bfd_get_symcount (abfd) != 0)
288 {
289 /* Make sure {CALL,BAL}NAME symbols remain adjacent on output
290 by sorting. This is complicated by the fact that stabs are
291 also ordered. Solve this by shifting all stabs to the end
292 in order, then sorting the rest. */
293
294 asymbol **outsyms, **p, **q;
295
296 outsyms = bfd_get_outsymbols (abfd);
297 p = outsyms + bfd_get_symcount (abfd);
298
299 for (q = p--; p >= outsyms; p--)
300 {
301 if ((*p)->flags & BSF_DEBUGGING)
302 {
303 asymbol *t = *--q;
304 *q = *p;
305 *p = t;
306 }
307 }
308
309 if (q > outsyms)
310 qsort (outsyms, q - outsyms, sizeof (asymbol*), b_out_symbol_cmp);
311
312 /* Back to your regularly scheduled program. */
313
314 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*exec_hdr(abfd))), SEEK_SET)
315 != 0)
316 return false;
317
318 if (! aout_32_write_syms (abfd))
319 return false;
320
321 if (bfd_seek (abfd, (file_ptr) (N_TROFF(*exec_hdr(abfd))), SEEK_SET) != 0)
322 return false;
323
324 if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
325 if (bfd_seek (abfd, (file_ptr) (N_DROFF(*exec_hdr(abfd))), SEEK_SET)
326 != 0)
327 return false;
328
329 if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
330 }
331 return true;
332}
333
334
335/** Some reloc hackery */
336
337#define CALLS 0x66003800 /* Template for 'calls' instruction */
338#define BAL 0x0b000000 /* Template for 'bal' instruction */
339#define BAL_MASK 0x00ffffff
340#define BALX 0x85f00000 /* Template for 'balx' instruction */
341#define BALX_MASK 0x0007ffff
342#define CALL 0x09000000
343#define PCREL13_MASK 0x1fff
344
345#define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma)
346
347/* Magic to turn callx into calljx */
348static bfd_reloc_status_type
349calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section)
350 bfd *abfd;
351 struct bfd_link_info *link_info;
352 arelent *reloc_entry;
353 PTR src;
354 PTR dst;
355 asection *input_section;
356{
357 int word = bfd_get_32 (abfd, src);
358 asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
359 aout_symbol_type *symbol = aout_symbol (symbol_in);
360 bfd_vma value;
361
362 value = get_value (reloc_entry, link_info, input_section);
363
364 if (IS_CALLNAME (symbol->other))
365 {
366 aout_symbol_type *balsym = symbol+1;
367 int inst = bfd_get_32 (abfd, (bfd_byte *) src-4);
368 /* The next symbol should be an N_BALNAME */
369 BFD_ASSERT (IS_BALNAME (balsym->other));
370 inst &= BALX_MASK;
371 inst |= BALX;
372 bfd_put_32 (abfd, inst, (bfd_byte *) dst-4);
373 symbol = balsym;
374 value = (symbol->symbol.value
375 + output_addr (symbol->symbol.section));
376 }
377
378 word += value + reloc_entry->addend;
379
380 bfd_put_32 (abfd, word, dst);
381 return bfd_reloc_ok;
382}
383
384/* Magic to turn call into callj */
385static bfd_reloc_status_type
386callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx,
387 input_section, shrinking)
388 bfd *abfd;
389 struct bfd_link_info *link_info;
390 arelent *reloc_entry;
391 PTR data;
392 unsigned int srcidx;
393 unsigned int dstidx;
394 asection *input_section;
395 boolean shrinking;
396{
397 int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx);
398 asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
399 aout_symbol_type *symbol = aout_symbol (symbol_in);
400 bfd_vma value;
401
402 value = get_value (reloc_entry, link_info, input_section);
403
404 if (IS_OTHER(symbol->other))
405 {
406 /* Call to a system procedure - replace code with system
407 procedure number. */
408 word = CALLS | (symbol->other - 1);
409 }
410 else if (IS_CALLNAME(symbol->other))
411 {
412 aout_symbol_type *balsym = symbol+1;
413
414 /* The next symbol should be an N_BALNAME. */
415 BFD_ASSERT(IS_BALNAME(balsym->other));
416
417 /* We are calling a leaf, so replace the call instruction with a
418 bal. */
419 word = BAL | ((word
420 + output_addr (balsym->symbol.section)
421 + balsym->symbol.value + reloc_entry->addend
422 - dstidx
423 - output_addr (input_section))
424 & BAL_MASK);
425 }
426 else if ((symbol->symbol.flags & BSF_SECTION_SYM) != 0)
427 {
428 /* A callj against a symbol in the same section is a fully
429 resolved relative call. We don't need to do anything here.
430 If the symbol is not in the same section, I'm not sure what
431 to do; fortunately, this case will probably never arise. */
432 BFD_ASSERT (! shrinking);
433 BFD_ASSERT (symbol->symbol.section == input_section);
434 }
435 else
436 {
437 word = CALL | (((word & BAL_MASK)
438 + value
439 + reloc_entry->addend
440 - (shrinking ? dstidx : 0)
441 - output_addr (input_section))
442 & BAL_MASK);
443 }
444 bfd_put_32 (abfd, word, (bfd_byte *) data + dstidx);
445 return bfd_reloc_ok;
446}
447
448/* type rshift size bitsize pcrel bitpos absolute overflow check*/
449
450#define ABS32CODE 0
451#define ABS32CODE_SHRUNK 1
452#define PCREL24 2
453#define CALLJ 3
454#define ABS32 4
455#define PCREL13 5
456#define ABS32_MAYBE_RELAXABLE 1
457#define ABS32_WAS_RELAXABLE 2
458
459#define ALIGNER 10
460#define ALIGNDONE 11
461static reloc_howto_type howto_reloc_callj =
462HOWTO(CALLJ, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
463static reloc_howto_type howto_reloc_abs32 =
464HOWTO(ABS32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"abs32", true, 0xffffffff,0xffffffff,false);
465static reloc_howto_type howto_reloc_pcrel24 =
466HOWTO(PCREL24, 0, 2, 24, true, 0, complain_overflow_signed,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
467
468static reloc_howto_type howto_reloc_pcrel13 =
469HOWTO(PCREL13, 0, 2, 13, true, 0, complain_overflow_signed,0,"pcrel13", true, 0x00001fff,0x00001fff,false);
470
471static reloc_howto_type howto_reloc_abs32codeshrunk =
472HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false);
473
474static reloc_howto_type howto_reloc_abs32code =
475HOWTO(ABS32CODE, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"callx", true, 0xffffffff,0xffffffff,false);
476
477static reloc_howto_type howto_align_table[] = {
478 HOWTO (ALIGNER, 0, 0x1, 0, false, 0, complain_overflow_dont, 0, "align16", false, 0, 0, false),
479 HOWTO (ALIGNER, 0, 0x3, 0, false, 0, complain_overflow_dont, 0, "align32", false, 0, 0, false),
480 HOWTO (ALIGNER, 0, 0x7, 0, false, 0, complain_overflow_dont, 0, "align64", false, 0, 0, false),
481 HOWTO (ALIGNER, 0, 0xf, 0, false, 0, complain_overflow_dont, 0, "align128", false, 0, 0, false),
482};
483
484static reloc_howto_type howto_done_align_table[] = {
485 HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, complain_overflow_dont, 0, "donealign16", false, 0, 0, false),
486 HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, complain_overflow_dont, 0, "donealign32", false, 0, 0, false),
487 HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, complain_overflow_dont, 0, "donealign64", false, 0, 0, false),
488 HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, complain_overflow_dont, 0, "donealign128", false, 0, 0, false),
489};
490
491static reloc_howto_type *
492b_out_bfd_reloc_type_lookup (abfd, code)
493 bfd *abfd ATTRIBUTE_UNUSED;
494 bfd_reloc_code_real_type code;
495{
496 switch (code)
497 {
498 default:
499 return 0;
500 case BFD_RELOC_I960_CALLJ:
501 return &howto_reloc_callj;
502 case BFD_RELOC_32:
503 case BFD_RELOC_CTOR:
504 return &howto_reloc_abs32;
505 case BFD_RELOC_24_PCREL:
506 return &howto_reloc_pcrel24;
507 }
508}
509
510/* Allocate enough room for all the reloc entries, plus pointers to them all */
511
512static boolean
513b_out_slurp_reloc_table (abfd, asect, symbols)
514 bfd *abfd;
515 sec_ptr asect;
516 asymbol **symbols;
517{
518 register struct relocation_info *rptr;
519 unsigned int counter ;
520 arelent *cache_ptr ;
521 int extern_mask, pcrel_mask, callj_mask, length_shift;
522 int incode_mask;
523 int size_mask;
524 bfd_vma prev_addr = 0;
525 unsigned int count;
526 size_t reloc_size;
527 struct relocation_info *relocs;
528 arelent *reloc_cache;
529
530 if (asect->relocation)
531 return true;
532 if (!aout_32_slurp_symbol_table (abfd))
533 return false;
534
535 if (asect == obj_datasec (abfd)) {
536 reloc_size = exec_hdr(abfd)->a_drsize;
537 goto doit;
538 }
539
540 if (asect == obj_textsec (abfd)) {
541 reloc_size = exec_hdr(abfd)->a_trsize;
542 goto doit;
543 }
544
545 if (asect == obj_bsssec (abfd)) {
546 reloc_size = 0;
547 goto doit;
548 }
549
550 bfd_set_error (bfd_error_invalid_operation);
551 return false;
552
553 doit:
554 if (bfd_seek (abfd, (file_ptr) (asect->rel_filepos), SEEK_SET) != 0)
555 return false;
556 count = reloc_size / sizeof (struct relocation_info);
557
558 relocs = (struct relocation_info *) bfd_malloc (reloc_size);
559 if (!relocs && reloc_size != 0)
560 return false;
561 reloc_cache = (arelent *) bfd_malloc ((count+1) * sizeof (arelent));
562 if (!reloc_cache) {
563 if (relocs != NULL)
564 free ((char*)relocs);
565 return false;
566 }
567
568 if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
569 free (reloc_cache);
570 if (relocs != NULL)
571 free (relocs);
572 return false;
573 }
574
575 if (bfd_header_big_endian (abfd)) {
576 /* big-endian bit field allocation order */
577 pcrel_mask = 0x80;
578 extern_mask = 0x10;
579 incode_mask = 0x08;
580 callj_mask = 0x02;
581 size_mask = 0x20;
582 length_shift = 5;
583 } else {
584 /* little-endian bit field allocation order */
585 pcrel_mask = 0x01;
586 extern_mask = 0x08;
587 incode_mask = 0x10;
588 callj_mask = 0x40;
589 size_mask = 0x02;
590 length_shift = 1;
591 }
592
593 for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
594 counter < count;
595 counter++, rptr++, cache_ptr++)
596 {
597 unsigned char *raw = (unsigned char *)rptr;
598 unsigned int symnum;
599 cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
600 cache_ptr->howto = 0;
601 if (bfd_header_big_endian (abfd))
602 {
603 symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
604 }
605 else
606 {
607 symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
608 }
609
610 if (raw[7] & extern_mask)
611 {
612 /* if this is set then the r_index is a index into the symbol table;
613 * if the bit is not set then r_index contains a section map.
614 * we either fill in the sym entry with a pointer to the symbol,
615 * or point to the correct section
616 */
617 cache_ptr->sym_ptr_ptr = symbols + symnum;
618 cache_ptr->addend = 0;
619 } else
620 {
621 /* in a.out symbols are relative to the beginning of the
622 * file rather than sections ?
623 * (look in translate_from_native_sym_flags)
624 * the reloc entry addend has added to it the offset into the
625 * file of the data, so subtract the base to make the reloc
626 * section relative */
627 int s;
628 {
629 /* sign-extend symnum from 24 bits to whatever host uses */
630 s = symnum;
631 if (s & (1 << 23))
632 s |= (~0) << 24;
633 }
634 cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
635 switch (s)
636 {
637 case N_TEXT:
638 case N_TEXT | N_EXT:
639 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
640 cache_ptr->addend = - obj_textsec(abfd)->vma;
641 break;
642 case N_DATA:
643 case N_DATA | N_EXT:
644 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
645 cache_ptr->addend = - obj_datasec(abfd)->vma;
646 break;
647 case N_BSS:
648 case N_BSS | N_EXT:
649 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
650 cache_ptr->addend = - obj_bsssec(abfd)->vma;
651 break;
652 case N_ABS:
653 case N_ABS | N_EXT:
654 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
655 cache_ptr->addend = 0;
656 break;
657 case -2: /* .align */
658 if (raw[7] & pcrel_mask)
659 {
660 cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
661 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
662 }
663 else
664 {
665 /* .org? */
666 abort ();
667 }
668 cache_ptr->addend = 0;
669 break;
670 default:
671 BFD_ASSERT(0);
672 break;
673 }
674
675 }
676
677 /* the i960 only has a few relocation types:
678 abs 32-bit and pcrel 24bit. except for callj's! */
679 if (cache_ptr->howto != 0)
680 ;
681 else if (raw[7] & callj_mask)
682 {
683 cache_ptr->howto = &howto_reloc_callj;
684 }
685 else if ( raw[7] & pcrel_mask)
686 {
687 if (raw[7] & size_mask)
688 cache_ptr->howto = &howto_reloc_pcrel13;
689 else
690 cache_ptr->howto = &howto_reloc_pcrel24;
691 }
692 else
693 {
694 if (raw[7] & incode_mask)
695 {
696 cache_ptr->howto = &howto_reloc_abs32code;
697 }
698 else
699 {
700 cache_ptr->howto = &howto_reloc_abs32;
701 }
702 }
703 if (cache_ptr->address < prev_addr)
704 {
705 /* Ouch! this reloc is out of order, insert into the right place
706 */
707 arelent tmp;
708 arelent *cursor = cache_ptr-1;
709 bfd_vma stop = cache_ptr->address;
710 tmp = *cache_ptr;
711 while (cursor->address > stop && cursor >= reloc_cache)
712 {
713 cursor[1] = cursor[0];
714 cursor--;
715 }
716 cursor[1] = tmp;
717 }
718 else
719 {
720 prev_addr = cache_ptr->address;
721 }
722 }
723
724 if (relocs != NULL)
725 free (relocs);
726 asect->relocation = reloc_cache;
727 asect->reloc_count = count;
728
729 return true;
730}
731
732static boolean
733b_out_squirt_out_relocs (abfd, section)
734 bfd *abfd;
735 asection *section;
736{
737 arelent **generic;
738 int r_extern = 0;
739 int r_idx;
740 int incode_mask;
741 int len_1;
742 unsigned int count = section->reloc_count;
743 struct relocation_info *native, *natptr;
744 size_t natsize = count * sizeof (struct relocation_info);
745 int extern_mask, pcrel_mask, len_2, callj_mask;
746 if (count == 0) return true;
747 generic = section->orelocation;
748 native = ((struct relocation_info *) bfd_malloc (natsize));
749 if (!native && natsize != 0)
750 return false;
751
752 if (bfd_header_big_endian (abfd))
753 {
754 /* Big-endian bit field allocation order */
755 pcrel_mask = 0x80;
756 extern_mask = 0x10;
757 len_2 = 0x40;
758 len_1 = 0x20;
759 callj_mask = 0x02;
760 incode_mask = 0x08;
761 }
762 else
763 {
764 /* Little-endian bit field allocation order */
765 pcrel_mask = 0x01;
766 extern_mask = 0x08;
767 len_2 = 0x04;
768 len_1 = 0x02;
769 callj_mask = 0x40;
770 incode_mask = 0x10;
771 }
772
773 for (natptr = native; count > 0; --count, ++natptr, ++generic)
774 {
775 arelent *g = *generic;
776 unsigned char *raw = (unsigned char *)natptr;
777 asymbol *sym = *(g->sym_ptr_ptr);
778
779 asection *output_section = sym->section->output_section;
780
781 bfd_h_put_32(abfd, g->address, raw);
782 /* Find a type in the output format which matches the input howto -
783 * at the moment we assume input format == output format FIXME!!
784 */
785 r_idx = 0;
786 /* FIXME: Need callj stuff here, and to check the howto entries to
787 be sure they are real for this architecture. */
788 if (g->howto== &howto_reloc_callj)
789 {
790 raw[7] = callj_mask + pcrel_mask + len_2;
791 }
792 else if (g->howto == &howto_reloc_pcrel24)
793 {
794 raw[7] = pcrel_mask + len_2;
795 }
796 else if (g->howto == &howto_reloc_pcrel13)
797 {
798 raw[7] = pcrel_mask + len_1;
799 }
800 else if (g->howto == &howto_reloc_abs32code)
801 {
802 raw[7] = len_2 + incode_mask;
803 }
804 else if (g->howto >= howto_align_table
805 && g->howto <= (howto_align_table
806 + sizeof (howto_align_table) / sizeof (howto_align_table[0])
807 - 1))
808 {
809 /* symnum == -2; extern_mask not set, pcrel_mask set */
810 r_idx = -2;
811 r_extern = 0;
812 raw[7] = (pcrel_mask
813 | ((g->howto - howto_align_table) << 1));
814 }
815 else {
816 raw[7] = len_2;
817 }
818
819 if (r_idx != 0)
820 /* already mucked with r_extern, r_idx */;
821 else if (bfd_is_com_section (output_section)
822 || bfd_is_abs_section (output_section)
823 || bfd_is_und_section (output_section))
824 {
825
826 if (bfd_abs_section_ptr->symbol == sym)
827 {
828 /* Whoops, looked like an abs symbol, but is really an offset
829 from the abs section */
830 r_idx = 0;
831 r_extern = 0;
832 }
833 else
834 {
835 /* Fill in symbol */
836
837 r_extern = 1;
838 r_idx = (*g->sym_ptr_ptr)->udata.i;
839 }
840 }
841 else
842 {
843 /* Just an ordinary section */
844 r_extern = 0;
845 r_idx = output_section->target_index;
846 }
847
848 if (bfd_header_big_endian (abfd)) {
849 raw[4] = (unsigned char) (r_idx >> 16);
850 raw[5] = (unsigned char) (r_idx >> 8);
851 raw[6] = (unsigned char) (r_idx );
852 } else {
853 raw[6] = (unsigned char) (r_idx >> 16);
854 raw[5] = (unsigned char) (r_idx>> 8);
855 raw[4] = (unsigned char) (r_idx );
856 }
857 if (r_extern)
858 raw[7] |= extern_mask;
859 }
860
861 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
862 free((PTR)native);
863 return false;
864 }
865 free ((PTR)native);
866
867 return true;
868}
869
870/* This is stupid. This function should be a boolean predicate */
871static long
872b_out_canonicalize_reloc (abfd, section, relptr, symbols)
873 bfd *abfd;
874 sec_ptr section;
875 arelent **relptr;
876 asymbol **symbols;
877{
878 arelent *tblptr;
879 unsigned int count;
880
881 if ((section->flags & SEC_CONSTRUCTOR) != 0)
882 {
883 arelent_chain *chain = section->constructor_chain;
884 for (count = 0; count < section->reloc_count; count++)
885 {
886 *relptr++ = &chain->relent;
887 chain = chain->next;
888 }
889 }
890 else
891 {
892 if (section->relocation == NULL
893 && ! b_out_slurp_reloc_table (abfd, section, symbols))
894 return -1;
895
896 tblptr = section->relocation;
897 for (count = 0; count++ < section->reloc_count;)
898 *relptr++ = tblptr++;
899 }
900
901 *relptr = NULL;
902
903 return section->reloc_count;
904}
905
906static long
907b_out_get_reloc_upper_bound (abfd, asect)
908 bfd *abfd;
909 sec_ptr asect;
910{
911 if (bfd_get_format (abfd) != bfd_object) {
912 bfd_set_error (bfd_error_invalid_operation);
913 return -1;
914 }
915
916 if (asect->flags & SEC_CONSTRUCTOR)
917 return sizeof (arelent *) * (asect->reloc_count + 1);
918
919 if (asect == obj_datasec (abfd))
920 return (sizeof (arelent *) *
921 ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
922 +1));
923
924 if (asect == obj_textsec (abfd))
925 return (sizeof (arelent *) *
926 ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
927 +1));
928
929 if (asect == obj_bsssec (abfd))
930 return 0;
931
932 bfd_set_error (bfd_error_invalid_operation);
933 return -1;
934}
935
936
937static boolean
938b_out_set_section_contents (abfd, section, location, offset, count)
939 bfd *abfd;
940 asection *section;
941 PTR location;
942 file_ptr offset;
943 bfd_size_type count;
944{
945
946 if (abfd->output_has_begun == false) { /* set by bfd.c handler */
947 if (! aout_32_make_sections (abfd))
948 return false;
949
950 obj_textsec (abfd)->filepos = sizeof (struct internal_exec);
951 obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos
952 + obj_textsec (abfd)->_raw_size;
953
954 }
955 /* regardless, once we know what we're doing, we might as well get going */
956 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
957 return false;
958
959 if (count != 0) {
960 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
961 }
962 return true;
963}
964
965static boolean
966b_out_set_arch_mach (abfd, arch, machine)
967 bfd *abfd;
968 enum bfd_architecture arch;
969 unsigned long machine;
970{
971 bfd_default_set_arch_mach(abfd, arch, machine);
972
973 if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
974 return true;
975 if (arch == bfd_arch_i960) /* i960 default is OK */
976 switch (machine) {
977 case bfd_mach_i960_core:
978 case bfd_mach_i960_kb_sb:
979 case bfd_mach_i960_mc:
980 case bfd_mach_i960_xa:
981 case bfd_mach_i960_ca:
982 case bfd_mach_i960_ka_sa:
983 case bfd_mach_i960_jx:
984 case bfd_mach_i960_hx:
985 case 0:
986 return true;
987 default:
988 return false;
989 }
990
991 return false;
992}
993
994static int
995b_out_sizeof_headers (ignore_abfd, ignore)
996 bfd *ignore_abfd ATTRIBUTE_UNUSED;
997 boolean ignore ATTRIBUTE_UNUSED;
998{
999 return sizeof (struct internal_exec);
1000}
1001
1002/************************************************************************/
1003static bfd_vma
1004get_value (reloc, link_info, input_section)
1005 arelent *reloc;
1006 struct bfd_link_info *link_info;
1007 asection *input_section;
1008{
1009 bfd_vma value;
1010 asymbol *symbol = *(reloc->sym_ptr_ptr);
1011
1012 /* A symbol holds a pointer to a section, and an offset from the
1013 base of the section. To relocate, we find where the section will
1014 live in the output and add that in */
1015
1016 if (bfd_is_und_section (symbol->section))
1017 {
1018 struct bfd_link_hash_entry *h;
1019
1020 /* The symbol is undefined in this BFD. Look it up in the
1021 global linker hash table. FIXME: This should be changed when
1022 we convert b.out to use a specific final_link function and
1023 change the interface to bfd_relax_section to not require the
1024 generic symbols. */
1025 h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
1026 bfd_asymbol_name (symbol),
1027 false, false, true);
1028 if (h != (struct bfd_link_hash_entry *) NULL
1029 && (h->type == bfd_link_hash_defined
1030 || h->type == bfd_link_hash_defweak))
1031 value = h->u.def.value + output_addr (h->u.def.section);
1032 else if (h != (struct bfd_link_hash_entry *) NULL
1033 && h->type == bfd_link_hash_common)
1034 value = h->u.c.size;
1035 else
1036 {
1037 if (! ((*link_info->callbacks->undefined_symbol)
1038 (link_info, bfd_asymbol_name (symbol),
1039 input_section->owner, input_section, reloc->address,
1040 true)))
1041 abort ();
1042 value = 0;
1043 }
1044 }
1045 else
1046 {
1047 value = symbol->value + output_addr (symbol->section);
1048 }
1049
1050 /* Add the value contained in the relocation */
1051 value += reloc->addend;
1052
1053 return value;
1054}
1055
1056static void
1057perform_slip (abfd, slip, input_section, value)
1058 bfd *abfd;
1059 unsigned int slip;
1060 asection *input_section;
1061 bfd_vma value;
1062{
1063 asymbol **s;
1064
1065 s = _bfd_generic_link_get_symbols (abfd);
1066 BFD_ASSERT (s != (asymbol **) NULL);
1067
1068 /* Find all symbols past this point, and make them know
1069 what's happened */
1070 while (*s)
1071 {
1072 asymbol *p = *s;
1073 if (p->section == input_section)
1074 {
1075 /* This was pointing into this section, so mangle it */
1076 if (p->value > value)
1077 {
1078 p->value -=slip;
1079 if (p->udata.p != NULL)
1080 {
1081 struct generic_link_hash_entry *h;
1082
1083 h = (struct generic_link_hash_entry *) p->udata.p;
1084 BFD_ASSERT (h->root.type == bfd_link_hash_defined);
1085 h->root.u.def.value -= slip;
1086 BFD_ASSERT (h->root.u.def.value == p->value);
1087 }
1088 }
1089 }
1090 s++;
1091
1092 }
1093}
1094
1095/* This routine works out if the thing we want to get to can be
1096 reached with a 24bit offset instead of a 32 bit one.
1097 If it can, then it changes the amode */
1098
1099static int
1100abs32code (abfd, input_section, r, shrink, link_info)
1101 bfd *abfd;
1102 asection *input_section;
1103 arelent *r;
1104 unsigned int shrink;
1105 struct bfd_link_info *link_info;
1106{
1107 bfd_vma value = get_value (r, link_info, input_section);
1108 bfd_vma dot = output_addr (input_section) + r->address;
1109 bfd_vma gap;
1110
1111 /* See if the address we're looking at within 2^23 bytes of where
1112 we are, if so then we can use a small branch rather than the
1113 jump we were going to */
1114
1115 gap = value - (dot - shrink);
1116
1117 if (-1<<23 < (long)gap && (long)gap < 1<<23 )
1118 {
1119 /* Change the reloc type from 32bitcode possible 24, to 24bit
1120 possible 32 */
1121
1122 r->howto = &howto_reloc_abs32codeshrunk;
1123 /* The place to relc moves back by four bytes */
1124 r->address -=4;
1125
1126 /* This will be four bytes smaller in the long run */
1127 shrink += 4 ;
1128 perform_slip (abfd, 4, input_section, r->address-shrink + 4);
1129 }
1130 return shrink;
1131}
1132
1133static int
1134aligncode (abfd, input_section, r, shrink)
1135 bfd *abfd;
1136 asection *input_section;
1137 arelent *r;
1138 unsigned int shrink;
1139{
1140 bfd_vma dot = output_addr (input_section) + r->address;
1141 bfd_vma gap;
1142 bfd_vma old_end;
1143 bfd_vma new_end;
1144 int shrink_delta;
1145 int size = r->howto->size;
1146
1147 /* Reduce the size of the alignment so that it's still aligned but
1148 smaller - the current size is already the same size as or bigger
1149 than the alignment required. */
1150
1151 /* calculate the first byte following the padding before we optimize */
1152 old_end = ((dot + size ) & ~size) + size+1;
1153 /* work out where the new end will be - remember that we're smaller
1154 than we used to be */
1155 new_end = ((dot - shrink + size) & ~size);
1156
1157 /* This is the new end */
1158 gap = old_end - ((dot + size) & ~size);
1159
1160 shrink_delta = (old_end - new_end) - shrink;
1161
1162 if (shrink_delta)
1163 {
1164 /* Change the reloc so that it knows how far to align to */
1165 r->howto = howto_done_align_table + (r->howto - howto_align_table);
1166
1167 /* Encode the stuff into the addend - for future use we need to
1168 know how big the reloc used to be */
1169 r->addend = old_end - dot + r->address;
1170
1171 /* This will be N bytes smaller in the long run, adjust all the symbols */
1172 perform_slip (abfd, shrink_delta, input_section, r->address - shrink);
1173 shrink += shrink_delta;
1174 }
1175 return shrink;
1176}
1177
1178static boolean
1179b_out_bfd_relax_section (abfd, i, link_info, again)
1180 bfd *abfd;
1181 asection *i;
1182 struct bfd_link_info *link_info;
1183 boolean *again;
1184{
1185 /* Get enough memory to hold the stuff */
1186 bfd *input_bfd = i->owner;
1187 asection *input_section = i;
1188 int shrink = 0 ;
1189 arelent **reloc_vector = NULL;
1190 long reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1191 input_section);
1192
1193 if (reloc_size < 0)
1194 return false;
1195
1196 /* We only run this relaxation once. It might work to run it
1197 multiple times, but it hasn't been tested. */
1198 *again = false;
1199
1200 if (reloc_size)
1201 {
1202 long reloc_count;
1203
1204 reloc_vector = (arelent **) bfd_malloc (reloc_size);
1205 if (reloc_vector == NULL && reloc_size != 0)
1206 goto error_return;
1207
1208 /* Get the relocs and think about them */
1209 reloc_count =
1210 bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector,
1211 _bfd_generic_link_get_symbols (input_bfd));
1212 if (reloc_count < 0)
1213 goto error_return;
1214 if (reloc_count > 0)
1215 {
1216 arelent **parent;
1217 for (parent = reloc_vector; *parent; parent++)
1218 {
1219 arelent *r = *parent;
1220 switch (r->howto->type)
1221 {
1222 case ALIGNER:
1223 /* An alignment reloc */
1224 shrink = aligncode (abfd, input_section, r, shrink);
1225 break;
1226 case ABS32CODE:
1227 /* A 32bit reloc in an addressing mode */
1228 shrink = abs32code (input_bfd, input_section, r, shrink,
1229 link_info);
1230 break;
1231 case ABS32CODE_SHRUNK:
1232 shrink+=4;
1233 break;
1234 }
1235 }
1236 }
1237 }
1238 input_section->_cooked_size = input_section->_raw_size - shrink;
1239
1240 if (reloc_vector != NULL)
1241 free (reloc_vector);
1242 return true;
1243 error_return:
1244 if (reloc_vector != NULL)
1245 free (reloc_vector);
1246 return false;
1247}
1248
1249static bfd_byte *
1250b_out_bfd_get_relocated_section_contents (output_bfd, link_info, link_order,
1251 data, relocateable, symbols)
1252 bfd *output_bfd;
1253 struct bfd_link_info *link_info;
1254 struct bfd_link_order *link_order;
1255 bfd_byte *data;
1256 boolean relocateable;
1257 asymbol **symbols;
1258{
1259 /* Get enough memory to hold the stuff */
1260 bfd *input_bfd = link_order->u.indirect.section->owner;
1261 asection *input_section = link_order->u.indirect.section;
1262 long reloc_size = bfd_get_reloc_upper_bound (input_bfd,
1263 input_section);
1264 arelent **reloc_vector = NULL;
1265 long reloc_count;
1266
1267 if (reloc_size < 0)
1268 goto error_return;
1269
1270 /* If producing relocateable output, don't bother to relax. */
1271 if (relocateable)
1272 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1273 link_order,
1274 data, relocateable,
1275 symbols);
1276
1277 reloc_vector = (arelent **) bfd_malloc (reloc_size);
1278 if (reloc_vector == NULL && reloc_size != 0)
1279 goto error_return;
1280
1281 input_section->reloc_done = 1;
1282
1283 /* read in the section */
1284 BFD_ASSERT (true == bfd_get_section_contents (input_bfd,
1285 input_section,
1286 data,
1287 0,
1288 input_section->_raw_size));
1289
1290 reloc_count = bfd_canonicalize_reloc (input_bfd,
1291 input_section,
1292 reloc_vector,
1293 symbols);
1294 if (reloc_count < 0)
1295 goto error_return;
1296 if (reloc_count > 0)
1297 {
1298 arelent **parent = reloc_vector;
1299 arelent *reloc ;
1300
1301 unsigned int dst_address = 0;
1302 unsigned int src_address = 0;
1303 unsigned int run;
1304 unsigned int idx;
1305
1306 /* Find how long a run we can do */
1307 while (dst_address < link_order->size)
1308 {
1309 reloc = *parent;
1310 if (reloc)
1311 {
1312 /* Note that the relaxing didn't tie up the addresses in the
1313 relocation, so we use the original address to work out the
1314 run of non-relocated data */
1315 BFD_ASSERT (reloc->address >= src_address);
1316 run = reloc->address - src_address;
1317 parent++;
1318 }
1319 else
1320 {
1321 run = link_order->size - dst_address;
1322 }
1323 /* Copy the bytes */
1324 for (idx = 0; idx < run; idx++)
1325 {
1326 data[dst_address++] = data[src_address++];
1327 }
1328
1329 /* Now do the relocation */
1330
1331 if (reloc)
1332 {
1333 switch (reloc->howto->type)
1334 {
1335 case ABS32CODE:
1336 calljx_callback (input_bfd, link_info, reloc,
1337 src_address + data, dst_address + data,
1338 input_section);
1339 src_address+=4;
1340 dst_address+=4;
1341 break;
1342 case ABS32:
1343 bfd_put_32 (input_bfd,
1344 (bfd_get_32 (input_bfd, data + src_address)
1345 + get_value (reloc, link_info, input_section)),
1346 data + dst_address);
1347 src_address+=4;
1348 dst_address+=4;
1349 break;
1350 case CALLJ:
1351 callj_callback (input_bfd, link_info, reloc, data,
1352 src_address, dst_address, input_section,
1353 false);
1354 src_address+=4;
1355 dst_address+=4;
1356 break;
1357 case ALIGNDONE:
1358 BFD_ASSERT (reloc->addend >= src_address);
1359 BFD_ASSERT (reloc->addend <= input_section->_raw_size);
1360 src_address = reloc->addend;
1361 dst_address = ((dst_address + reloc->howto->size)
1362 & ~reloc->howto->size);
1363 break;
1364 case ABS32CODE_SHRUNK:
1365 /* This used to be a callx, but we've found out that a
1366 callj will reach, so do the right thing. */
1367 callj_callback (input_bfd, link_info, reloc, data,
1368 src_address + 4, dst_address, input_section,
1369 true);
1370 dst_address+=4;
1371 src_address+=8;
1372 break;
1373 case PCREL24:
1374 {
1375 long int word = bfd_get_32 (input_bfd,
1376 data + src_address);
1377 bfd_vma value;
1378
1379 value = get_value (reloc, link_info, input_section);
1380 word = ((word & ~BAL_MASK)
1381 | (((word & BAL_MASK)
1382 + value
1383 - output_addr (input_section)
1384 + reloc->addend)
1385 & BAL_MASK));
1386
1387 bfd_put_32 (input_bfd, word, data + dst_address);
1388 dst_address+=4;
1389 src_address+=4;
1390
1391 }
1392 break;
1393
1394 case PCREL13:
1395 {
1396 long int word = bfd_get_32 (input_bfd,
1397 data + src_address);
1398 bfd_vma value;
1399
1400 value = get_value (reloc, link_info, input_section);
1401 word = ((word & ~PCREL13_MASK)
1402 | (((word & PCREL13_MASK)
1403 + value
1404 + reloc->addend
1405 - output_addr (input_section))
1406 & PCREL13_MASK));
1407
1408 bfd_put_32 (input_bfd, word, data + dst_address);
1409 dst_address+=4;
1410 src_address+=4;
1411
1412 }
1413 break;
1414
1415 default:
1416 abort ();
1417 }
1418 }
1419 }
1420 }
1421 if (reloc_vector != NULL)
1422 free (reloc_vector);
1423 return data;
1424 error_return:
1425 if (reloc_vector != NULL)
1426 free (reloc_vector);
1427 return NULL;
1428}
1429/***********************************************************************/
1430
1431/* Build the transfer vectors for Big and Little-Endian B.OUT files. */
1432
1433#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1434#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
1435
1436#define b_out_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1437#define b_out_bfd_link_add_symbols _bfd_generic_link_add_symbols
1438#define b_out_bfd_final_link _bfd_generic_final_link
1439#define b_out_bfd_link_split_section _bfd_generic_link_split_section
1440#define b_out_bfd_gc_sections bfd_generic_gc_sections
1441
1442#define aout_32_get_section_contents_in_window \
1443 _bfd_generic_get_section_contents_in_window
1444
1445extern const bfd_target b_out_vec_little_host;
1446
1447const bfd_target b_out_vec_big_host =
1448{
1449 "b.out.big", /* name */
1450 bfd_target_aout_flavour,
1451 BFD_ENDIAN_LITTLE, /* data byte order is little */
1452 BFD_ENDIAN_BIG, /* hdr byte order is big */
1453 (HAS_RELOC | EXEC_P | /* object flags */
1454 HAS_LINENO | HAS_DEBUG |
1455 HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
1456 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1457 '_', /* symbol leading char */
1458 ' ', /* ar_pad_char */
1459 16, /* ar_max_namelen */
1460
1461 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1462 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1463 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1464 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1465 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1466 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1467 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1468 bfd_generic_archive_p, _bfd_dummy_target},
1469 {bfd_false, b_out_mkobject, /* bfd_set_format */
1470 _bfd_generic_mkarchive, bfd_false},
1471 {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1472 _bfd_write_archive_contents, bfd_false},
1473
1474 BFD_JUMP_TABLE_GENERIC (aout_32),
1475 BFD_JUMP_TABLE_COPY (_bfd_generic),
1476 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1477 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
1478 BFD_JUMP_TABLE_SYMBOLS (aout_32),
1479 BFD_JUMP_TABLE_RELOCS (b_out),
1480 BFD_JUMP_TABLE_WRITE (b_out),
1481 BFD_JUMP_TABLE_LINK (b_out),
1482 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1483
1484 & b_out_vec_little_host,
1485
1486 (PTR) 0,
1487};
1488
1489const bfd_target b_out_vec_little_host =
1490{
1491 "b.out.little", /* name */
1492 bfd_target_aout_flavour,
1493 BFD_ENDIAN_LITTLE, /* data byte order is little */
1494 BFD_ENDIAN_LITTLE, /* header byte order is little */
1495 (HAS_RELOC | EXEC_P | /* object flags */
1496 HAS_LINENO | HAS_DEBUG |
1497 HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
1498 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1499 '_', /* symbol leading char */
1500 ' ', /* ar_pad_char */
1501 16, /* ar_max_namelen */
1502 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1503 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1504 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1505 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1506 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1507 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1508
1509 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1510 bfd_generic_archive_p, _bfd_dummy_target},
1511 {bfd_false, b_out_mkobject, /* bfd_set_format */
1512 _bfd_generic_mkarchive, bfd_false},
1513 {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1514 _bfd_write_archive_contents, bfd_false},
1515
1516 BFD_JUMP_TABLE_GENERIC (aout_32),
1517 BFD_JUMP_TABLE_COPY (_bfd_generic),
1518 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1519 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
1520 BFD_JUMP_TABLE_SYMBOLS (aout_32),
1521 BFD_JUMP_TABLE_RELOCS (b_out),
1522 BFD_JUMP_TABLE_WRITE (b_out),
1523 BFD_JUMP_TABLE_LINK (b_out),
1524 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1525
1526 & b_out_vec_big_host,
1527
1528 (PTR) 0
1529};
Note: See TracBrowser for help on using the repository browser.