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