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