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