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