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

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

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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