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