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