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