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