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