Back to index

cell-binutils  2.17cvs20070401
bout.c
Go to the documentation of this file.
00001 /* BFD back-end for Intel 960 b.out binaries.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00004    Free Software Foundation, Inc.
00005    Written by Cygnus Support.
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "libbfd.h"
00026 #include "bfdlink.h"
00027 #include "genlink.h"
00028 #include "bout.h"
00029 #include "libiberty.h"
00030 
00031 #include "aout/stab_gnu.h"
00032 #include "libaout.h"        /* BFD a.out internal data structures.  */
00033 
00034 #define ABS32CODE 0
00035 #define ABS32CODE_SHRUNK 1
00036 #define PCREL24 2
00037 #define CALLJ 3
00038 #define ABS32 4
00039 #define PCREL13 5
00040 #define ABS32_MAYBE_RELAXABLE 1
00041 #define ABS32_WAS_RELAXABLE 2
00042 
00043 #define ALIGNER 10
00044 #define ALIGNDONE 11
00045 
00046 static reloc_howto_type howto_reloc_callj =
00047   HOWTO (CALLJ, 0, 2, 24, TRUE, 0, complain_overflow_signed, 0,"callj", TRUE, 0x00ffffff, 0x00ffffff,FALSE);
00048 static  reloc_howto_type howto_reloc_abs32 =
00049   HOWTO (ABS32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"abs32", TRUE, 0xffffffff,0xffffffff,FALSE);
00050 static reloc_howto_type howto_reloc_pcrel24 =
00051   HOWTO (PCREL24, 0, 2, 24, TRUE, 0, complain_overflow_signed,0,"pcrel24", TRUE, 0x00ffffff,0x00ffffff,FALSE);
00052 static reloc_howto_type howto_reloc_pcrel13 =
00053   HOWTO (PCREL13, 0, 2, 13, TRUE, 0, complain_overflow_signed,0,"pcrel13", TRUE, 0x00001fff,0x00001fff,FALSE);
00054 static reloc_howto_type howto_reloc_abs32codeshrunk =
00055   HOWTO (ABS32CODE_SHRUNK, 0, 2, 24, TRUE, 0, complain_overflow_signed, 0,"callx->callj", TRUE, 0x00ffffff, 0x00ffffff,FALSE);
00056 static  reloc_howto_type howto_reloc_abs32code =
00057   HOWTO (ABS32CODE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"callx", TRUE, 0xffffffff,0xffffffff,FALSE);
00058 
00059 static reloc_howto_type howto_align_table[] =
00060 {
00061   HOWTO (ALIGNER, 0, 0x1, 0, FALSE, 0, complain_overflow_dont, 0, "align16", FALSE, 0, 0, FALSE),
00062   HOWTO (ALIGNER, 0, 0x3, 0, FALSE, 0, complain_overflow_dont, 0, "align32", FALSE, 0, 0, FALSE),
00063   HOWTO (ALIGNER, 0, 0x7, 0, FALSE, 0, complain_overflow_dont, 0, "align64", FALSE, 0, 0, FALSE),
00064   HOWTO (ALIGNER, 0, 0xf, 0, FALSE, 0, complain_overflow_dont, 0, "align128", FALSE, 0, 0, FALSE),
00065 };
00066 
00067 static reloc_howto_type howto_done_align_table[] =
00068 {
00069   HOWTO (ALIGNDONE, 0x1, 0x1, 0, FALSE, 0, complain_overflow_dont, 0, "donealign16", FALSE, 0, 0, FALSE),
00070   HOWTO (ALIGNDONE, 0x3, 0x3, 0, FALSE, 0, complain_overflow_dont, 0, "donealign32", FALSE, 0, 0, FALSE),
00071   HOWTO (ALIGNDONE, 0x7, 0x7, 0, FALSE, 0, complain_overflow_dont, 0, "donealign64", FALSE, 0, 0, FALSE),
00072   HOWTO (ALIGNDONE, 0xf, 0xf, 0, FALSE, 0, complain_overflow_dont, 0, "donealign128", FALSE, 0, 0, FALSE),
00073 };
00074 
00075 /* Swaps the information in an executable header taken from a raw byte
00076    stream memory image, into the internal exec_header structure.  */
00077 
00078 static void
00079 bout_swap_exec_header_in (bfd *abfd,
00080                        struct external_exec *bytes,
00081                        struct internal_exec *execp)
00082 {
00083   /* Now fill in fields in the execp, from the bytes in the raw data.  */
00084   execp->a_info      = H_GET_32 (abfd, bytes->e_info);
00085   execp->a_text      = GET_WORD (abfd, bytes->e_text);
00086   execp->a_data      = GET_WORD (abfd, bytes->e_data);
00087   execp->a_bss       = GET_WORD (abfd, bytes->e_bss);
00088   execp->a_syms      = GET_WORD (abfd, bytes->e_syms);
00089   execp->a_entry     = GET_WORD (abfd, bytes->e_entry);
00090   execp->a_trsize    = GET_WORD (abfd, bytes->e_trsize);
00091   execp->a_drsize    = GET_WORD (abfd, bytes->e_drsize);
00092   execp->a_tload     = GET_WORD (abfd, bytes->e_tload);
00093   execp->a_dload     = GET_WORD (abfd, bytes->e_dload);
00094   execp->a_talign    = bytes->e_talign[0];
00095   execp->a_dalign    = bytes->e_dalign[0];
00096   execp->a_balign    = bytes->e_balign[0];
00097   execp->a_relaxable = bytes->e_relaxable[0];
00098 }
00099 
00100 /* Swaps the information in an internal exec header structure into the
00101    supplied buffer ready for writing to disk.  */
00102 
00103 static void
00104 bout_swap_exec_header_out (bfd *abfd,
00105                         struct internal_exec *execp,
00106                         struct external_exec *bytes)
00107 {
00108   /* Now fill in fields in the raw data, from the fields in the exec struct.  */
00109   H_PUT_32 (abfd, execp->a_info  , bytes->e_info);
00110   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
00111   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
00112   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
00113   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
00114   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
00115   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
00116   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
00117   PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
00118   PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
00119   bytes->e_talign[0]    = execp->a_talign;
00120   bytes->e_dalign[0]    = execp->a_dalign;
00121   bytes->e_balign[0]    = execp->a_balign;
00122   bytes->e_relaxable[0] = execp->a_relaxable;
00123 }
00124 
00125 /* Finish up the opening of a b.out file for reading.  Fill in all the
00126    fields that are not handled by common code.  */
00127 
00128 static const bfd_target *
00129 b_out_callback (bfd *abfd)
00130 {
00131   struct internal_exec *execp = exec_hdr (abfd);
00132   unsigned long bss_start;
00133 
00134   /* Architecture and machine type.  */
00135   bfd_set_arch_mach (abfd,
00136                    bfd_arch_i960,     /* B.out only used on i960.  */
00137                    bfd_mach_i960_core /* Default.  */
00138                    );
00139 
00140   /* The positions of the string table and symbol table.  */
00141   obj_str_filepos (abfd) = N_STROFF (*execp);
00142   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
00143 
00144   /* The alignments of the sections.  */
00145   obj_textsec (abfd)->alignment_power = execp->a_talign;
00146   obj_datasec (abfd)->alignment_power = execp->a_dalign;
00147   obj_bsssec  (abfd)->alignment_power = execp->a_balign;
00148 
00149   /* The starting addresses of the sections.  */
00150   obj_textsec (abfd)->vma = execp->a_tload;
00151   obj_datasec (abfd)->vma = execp->a_dload;
00152 
00153   obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
00154   obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
00155 
00156   /* And reload the sizes, since the aout module zaps them.  */
00157   obj_textsec (abfd)->size = execp->a_text;
00158 
00159   bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section.  */
00160   obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
00161 
00162   obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
00163 
00164   /* The file positions of the sections.  */
00165   obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
00166   obj_datasec (abfd)->filepos = N_DATOFF (*execp);
00167 
00168   /* The file positions of the relocation info.  */
00169   obj_textsec (abfd)->rel_filepos = N_TROFF (*execp);
00170   obj_datasec (abfd)->rel_filepos =  N_DROFF (*execp);
00171 
00172   adata (abfd).page_size = 1;      /* Not applicable.  */
00173   adata (abfd).segment_size = 1; /* Not applicable.  */
00174   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
00175 
00176   if (execp->a_relaxable)
00177    abfd->flags |= BFD_IS_RELAXABLE;
00178   return abfd->xvec;
00179 }
00180 
00181 static const bfd_target *
00182 b_out_object_p (bfd *abfd)
00183 {
00184   struct internal_exec anexec;
00185   struct external_exec exec_bytes;
00186   bfd_size_type amt = EXEC_BYTES_SIZE;
00187 
00188   if (bfd_bread ((void *) &exec_bytes, amt, abfd) != amt)
00189     {
00190       if (bfd_get_error () != bfd_error_system_call)
00191        bfd_set_error (bfd_error_wrong_format);
00192       return 0;
00193     }
00194 
00195   anexec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
00196 
00197   if (N_BADMAG (anexec))
00198     {
00199       bfd_set_error (bfd_error_wrong_format);
00200       return 0;
00201     }
00202 
00203   bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
00204   return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
00205 }
00206 
00207 struct bout_data_struct
00208   {
00209     struct aoutdata a;
00210     struct internal_exec e;
00211   };
00212 
00213 static bfd_boolean
00214 b_out_mkobject (bfd *abfd)
00215 {
00216   struct bout_data_struct *rawptr;
00217   bfd_size_type amt = sizeof (struct bout_data_struct);
00218 
00219   rawptr = bfd_zalloc (abfd, amt);
00220   if (rawptr == NULL)
00221     return FALSE;
00222 
00223   abfd->tdata.bout_data = rawptr;
00224   exec_hdr (abfd) = &rawptr->e;
00225 
00226   obj_textsec (abfd) = NULL;
00227   obj_datasec (abfd) = NULL;
00228   obj_bsssec (abfd)  = NULL;
00229 
00230   return TRUE;
00231 }
00232 
00233 static int
00234 b_out_symbol_cmp (const void * a_ptr, const void * b_ptr)
00235 {
00236   struct aout_symbol ** a = (struct aout_symbol **) a_ptr;
00237   struct aout_symbol ** b = (struct aout_symbol **) b_ptr;
00238   asection *sec;
00239   bfd_vma av, bv;
00240 
00241   /* Primary key is address.  */
00242   sec = bfd_get_section (&(*a)->symbol);
00243   av = sec->output_section->vma + sec->output_offset + (*a)->symbol.value;
00244   sec = bfd_get_section (&(*b)->symbol);
00245   bv = sec->output_section->vma + sec->output_offset + (*b)->symbol.value;
00246 
00247   if (av < bv)
00248     return -1;
00249   if (av > bv)
00250     return 1;
00251 
00252   /* Secondary key puts CALLNAME syms last and BALNAME syms first,
00253      so that they have the best chance of being contiguous.  */
00254   if (IS_BALNAME ((*a)->other) || IS_CALLNAME ((*b)->other))
00255     return -1;
00256   if (IS_CALLNAME ((*a)->other) || IS_BALNAME ((*b)->other))
00257     return 1;
00258 
00259   return 0;
00260 }
00261 
00262 static bfd_boolean
00263 b_out_squirt_out_relocs (bfd *abfd, asection *section)
00264 {
00265   arelent **generic;
00266   int r_extern = 0;
00267   int r_idx;
00268   int incode_mask;
00269   int len_1;
00270   unsigned int count = section->reloc_count;
00271   struct relocation_info *native, *natptr;
00272   bfd_size_type natsize;
00273   int extern_mask, pcrel_mask, len_2, callj_mask;
00274 
00275   if (count == 0)
00276     return TRUE;
00277 
00278   generic = section->orelocation;
00279   natsize = (bfd_size_type) count * sizeof (struct relocation_info);
00280   native = bfd_malloc (natsize);
00281   if (!native && natsize != 0)
00282     return FALSE;
00283 
00284   if (bfd_header_big_endian (abfd))
00285     {
00286       /* Big-endian bit field allocation order.  */
00287       pcrel_mask  = 0x80;
00288       extern_mask = 0x10;
00289       len_2       = 0x40;
00290       len_1       = 0x20;
00291       callj_mask  = 0x02;
00292       incode_mask = 0x08;
00293     }
00294   else
00295     {
00296       /* Little-endian bit field allocation order.  */
00297       pcrel_mask  = 0x01;
00298       extern_mask = 0x08;
00299       len_2       = 0x04;
00300       len_1       = 0x02;
00301       callj_mask  = 0x40;
00302       incode_mask = 0x10;
00303     }
00304 
00305   for (natptr = native; count > 0; --count, ++natptr, ++generic)
00306     {
00307       arelent *g = *generic;
00308       unsigned char *raw = (unsigned char *) natptr;
00309       asymbol *sym = *(g->sym_ptr_ptr);
00310       asection *output_section = sym->section->output_section;
00311 
00312       H_PUT_32 (abfd, g->address, raw);
00313       /* Find a type in the output format which matches the input howto -
00314         at the moment we assume input format == output format FIXME!!  */
00315       r_idx = 0;
00316       /* FIXME:  Need callj stuff here, and to check the howto entries to
00317         be sure they are real for this architecture.  */
00318       if (g->howto== &howto_reloc_callj)
00319        raw[7] = callj_mask + pcrel_mask + len_2;
00320       else if (g->howto == &howto_reloc_pcrel24)
00321        raw[7] = pcrel_mask + len_2;
00322       else if (g->howto == &howto_reloc_pcrel13)
00323        raw[7] = pcrel_mask + len_1;
00324       else if (g->howto == &howto_reloc_abs32code)
00325        raw[7] = len_2 + incode_mask;
00326       else if (g->howto >= howto_align_table
00327               && g->howto <= (howto_align_table + ARRAY_SIZE (howto_align_table) - 1))
00328        {
00329          /* symnum == -2; extern_mask not set, pcrel_mask set.  */
00330          r_idx = -2;
00331          r_extern = 0;
00332          raw[7] = (pcrel_mask
00333                   | ((g->howto - howto_align_table) << 1));
00334        }
00335       else
00336        raw[7] = len_2;
00337 
00338       if (r_idx != 0)
00339        /* Already mucked with r_extern, r_idx.  */;
00340       else if (bfd_is_com_section (output_section)
00341               || bfd_is_abs_section (output_section)
00342               || bfd_is_und_section (output_section))
00343        {
00344          if (bfd_abs_section_ptr->symbol == sym)
00345            {
00346              /* Whoops, looked like an abs symbol, but is really an offset
00347                from the abs section.  */
00348              r_idx = 0;
00349              r_extern = 0;
00350            }
00351          else
00352            {
00353              /* Fill in symbol.  */
00354              r_extern = 1;
00355              r_idx = (*g->sym_ptr_ptr)->udata.i;
00356            }
00357        }
00358       else
00359        {
00360          /* Just an ordinary section.  */
00361          r_extern = 0;
00362          r_idx  = output_section->target_index;
00363        }
00364 
00365       if (bfd_header_big_endian (abfd))
00366        {
00367          raw[4] = (unsigned char) (r_idx >> 16);
00368          raw[5] = (unsigned char) (r_idx >>  8);
00369          raw[6] = (unsigned char) (r_idx      );
00370        }
00371       else
00372        {
00373          raw[6] = (unsigned char) (r_idx >> 16);
00374          raw[5] = (unsigned char) (r_idx>>   8);
00375          raw[4] = (unsigned char) (r_idx      );
00376        }
00377 
00378       if (r_extern)
00379        raw[7] |= extern_mask;
00380     }
00381 
00382   if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
00383     {
00384       free (native);
00385       return FALSE;
00386     }
00387 
00388   free (native);
00389 
00390   return TRUE;
00391 }
00392 
00393 static bfd_boolean
00394 b_out_write_object_contents (bfd *abfd)
00395 {
00396   struct external_exec swapped_hdr;
00397   bfd_size_type amt;
00398 
00399   if (! aout_32_make_sections (abfd))
00400     return FALSE;
00401 
00402   exec_hdr (abfd)->a_info = BMAGIC;
00403 
00404   exec_hdr (abfd)->a_text = obj_textsec (abfd)->size;
00405   exec_hdr (abfd)->a_data = obj_datasec (abfd)->size;
00406   exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size;
00407   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * 12;
00408   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
00409   exec_hdr (abfd)->a_trsize = (obj_textsec (abfd)->reloc_count) * 8;
00410   exec_hdr (abfd)->a_drsize = (obj_datasec (abfd)->reloc_count) * 8;
00411 
00412   exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
00413   exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
00414   exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
00415 
00416   exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
00417   exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
00418 
00419   bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
00420 
00421   amt = EXEC_BYTES_SIZE;
00422   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
00423       || bfd_bwrite ((void *) &swapped_hdr, amt, abfd) != amt)
00424     return FALSE;
00425 
00426   /* Now write out reloc info, followed by syms and strings */
00427   if (bfd_get_symcount (abfd) != 0)
00428     {
00429       /* Make sure {CALL,BAL}NAME symbols remain adjacent on output
00430         by sorting.  This is complicated by the fact that stabs are
00431         also ordered.  Solve this by shifting all stabs to the end
00432         in order, then sorting the rest.  */
00433 
00434       asymbol **outsyms, **p, **q;
00435 
00436       outsyms = bfd_get_outsymbols (abfd);
00437       p = outsyms + bfd_get_symcount (abfd);
00438 
00439       for (q = p--; p >= outsyms; p--)
00440        {
00441          if ((*p)->flags & BSF_DEBUGGING)
00442            {
00443              asymbol *t = *--q;
00444              *q = *p;
00445              *p = t;
00446            }
00447        }
00448 
00449       if (q > outsyms)
00450        qsort (outsyms, (size_t) (q - outsyms), sizeof (asymbol*),
00451               b_out_symbol_cmp);
00452 
00453       /* Back to your regularly scheduled program.  */
00454       if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
00455          != 0)
00456        return FALSE;
00457 
00458       if (! aout_32_write_syms (abfd))
00459        return FALSE;
00460 
00461       if (bfd_seek (abfd, (file_ptr) (N_TROFF (*exec_hdr (abfd))), SEEK_SET)
00462          != 0)
00463        return FALSE;
00464 
00465       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd)))
00466        return FALSE;
00467       if (bfd_seek (abfd, (file_ptr) (N_DROFF (*exec_hdr (abfd))), SEEK_SET)
00468          != 0)
00469        return FALSE;
00470 
00471       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd)))
00472        return FALSE;
00473     }
00474   return TRUE;
00475 }
00476 
00477 /* Some reloc hackery.  */
00478 
00479 #define CALLS   0x66003800  /* Template for 'calls' instruction       */
00480 #define BAL     0x0b000000  /* Template for 'bal' instruction  */
00481 #define BAL_MASK  0x00ffffff
00482 #define BALX    0x85f00000  /* Template for 'balx' instruction */
00483 #define BALX_MASK 0x0007ffff
00484 #define CALL      0x09000000
00485 #define PCREL13_MASK 0x1fff
00486 
00487 #define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma)
00488 
00489 static bfd_vma
00490 get_value (arelent *reloc,
00491           struct bfd_link_info *link_info,
00492           asection *input_section)
00493 {
00494   bfd_vma value;
00495   asymbol *symbol = *(reloc->sym_ptr_ptr);
00496 
00497   /* A symbol holds a pointer to a section, and an offset from the
00498      base of the section.  To relocate, we find where the section will
00499      live in the output and add that in.  */
00500   if (bfd_is_und_section (symbol->section))
00501     {
00502       struct bfd_link_hash_entry *h;
00503 
00504       /* The symbol is undefined in this BFD.  Look it up in the
00505         global linker hash table.  FIXME: This should be changed when
00506         we convert b.out to use a specific final_link function and
00507         change the interface to bfd_relax_section to not require the
00508         generic symbols.  */
00509       h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
00510                                    bfd_asymbol_name (symbol),
00511                                    FALSE, FALSE, TRUE);
00512       if (h != (struct bfd_link_hash_entry *) NULL
00513          && (h->type == bfd_link_hash_defined
00514              || h->type == bfd_link_hash_defweak))
00515        value = h->u.def.value + output_addr (h->u.def.section);
00516       else if (h != (struct bfd_link_hash_entry *) NULL
00517               && h->type == bfd_link_hash_common)
00518        value = h->u.c.size;
00519       else
00520        {
00521          if (! ((*link_info->callbacks->undefined_symbol)
00522                (link_info, bfd_asymbol_name (symbol),
00523                 input_section->owner, input_section, reloc->address,
00524                 TRUE)))
00525            abort ();
00526          value = 0;
00527        }
00528     }
00529   else
00530     value = symbol->value + output_addr (symbol->section);
00531 
00532   /* Add the value contained in the relocation.  */
00533   value += reloc->addend;
00534 
00535   return value;
00536 }
00537 
00538 /* Magic to turn callx into calljx.  */
00539 
00540 static bfd_reloc_status_type
00541 calljx_callback (bfd *abfd,
00542                struct bfd_link_info *link_info,
00543                arelent *reloc_entry,
00544                void * src,
00545                void * dst,
00546                asection *input_section)
00547 {
00548   int word = bfd_get_32 (abfd, src);
00549   asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
00550   aout_symbol_type *symbol = aout_symbol (symbol_in);
00551   bfd_vma value;
00552 
00553   value = get_value (reloc_entry, link_info, input_section);
00554 
00555   if (IS_CALLNAME (symbol->other))
00556     {
00557       aout_symbol_type *balsym = symbol+1;
00558       int inst = bfd_get_32 (abfd, (bfd_byte *) src-4);
00559 
00560       /* The next symbol should be an N_BALNAME.  */
00561       BFD_ASSERT (IS_BALNAME (balsym->other));
00562       inst &= BALX_MASK;
00563       inst |= BALX;
00564       bfd_put_32 (abfd, (bfd_vma) inst, (bfd_byte *) dst-4);
00565       symbol = balsym;
00566       value = (symbol->symbol.value
00567               + output_addr (symbol->symbol.section));
00568     }
00569 
00570   word += value + reloc_entry->addend;
00571 
00572   bfd_put_32 (abfd, (bfd_vma) word, dst);
00573   return bfd_reloc_ok;
00574 }
00575 
00576 /* Magic to turn call into callj.  */
00577 
00578 static bfd_reloc_status_type
00579 callj_callback (bfd *abfd,
00580               struct bfd_link_info *link_info,
00581               arelent *reloc_entry,
00582               void * data,
00583               unsigned int srcidx,
00584               unsigned int dstidx,
00585               asection *input_section,
00586               bfd_boolean shrinking)
00587 {
00588   int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx);
00589   asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
00590   aout_symbol_type *symbol = aout_symbol (symbol_in);
00591   bfd_vma value;
00592 
00593   value = get_value (reloc_entry, link_info, input_section);
00594 
00595   if (IS_OTHER (symbol->other))
00596     /* Call to a system procedure - replace code with system
00597        procedure number.  */
00598     word = CALLS | (symbol->other - 1);
00599 
00600   else if (IS_CALLNAME (symbol->other))
00601     {
00602       aout_symbol_type *balsym = symbol+1;
00603 
00604       /* The next symbol should be an N_BALNAME.  */
00605       BFD_ASSERT (IS_BALNAME (balsym->other));
00606 
00607       /* We are calling a leaf, so replace the call instruction with a
00608         bal.  */
00609       word = BAL | ((word
00610                    + output_addr (balsym->symbol.section)
00611                    + balsym->symbol.value + reloc_entry->addend
00612                    - dstidx
00613                    - output_addr (input_section))
00614                   & BAL_MASK);
00615     }
00616   else if ((symbol->symbol.flags & BSF_SECTION_SYM) != 0)
00617     {
00618       /* A callj against a symbol in the same section is a fully
00619          resolved relative call.  We don't need to do anything here.
00620          If the symbol is not in the same section, I'm not sure what
00621          to do; fortunately, this case will probably never arise.  */
00622       BFD_ASSERT (! shrinking);
00623       BFD_ASSERT (symbol->symbol.section == input_section);
00624     }
00625   else
00626     word = CALL | (((word & BAL_MASK)
00627                   + value
00628                   + reloc_entry->addend
00629                   - (shrinking ? dstidx : 0)
00630                   - output_addr (input_section))
00631                  & BAL_MASK);
00632 
00633   bfd_put_32 (abfd, (bfd_vma) word, (bfd_byte *) data + dstidx);
00634   return bfd_reloc_ok;
00635 }
00636 
00637 static reloc_howto_type *
00638 b_out_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00639                           bfd_reloc_code_real_type code)
00640 {
00641   switch (code)
00642     {
00643     default:
00644       return 0;
00645     case BFD_RELOC_I960_CALLJ:
00646       return &howto_reloc_callj;
00647     case BFD_RELOC_32:
00648     case BFD_RELOC_CTOR:
00649       return &howto_reloc_abs32;
00650     case BFD_RELOC_24_PCREL:
00651       return &howto_reloc_pcrel24;
00652     }
00653 }
00654 
00655 static reloc_howto_type *
00656 b_out_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00657                           const char *r_name)
00658 {
00659   if (strcasecmp (howto_reloc_callj.name, r_name) == 0)
00660     return &howto_reloc_callj;
00661   if (strcasecmp (howto_reloc_abs32.name, r_name) == 0)
00662     return &howto_reloc_abs32;
00663   if (strcasecmp (howto_reloc_pcrel24.name, r_name) == 0)
00664     return &howto_reloc_pcrel24;
00665 
00666   return NULL;
00667 }
00668 
00669 /* Allocate enough room for all the reloc entries, plus pointers to them all.  */
00670 
00671 static bfd_boolean
00672 b_out_slurp_reloc_table (bfd *abfd, sec_ptr asect, asymbol **symbols)
00673 {
00674   struct relocation_info *rptr;
00675   unsigned int counter;
00676   arelent *cache_ptr;
00677   int extern_mask, pcrel_mask, callj_mask, length_shift;
00678   int incode_mask;
00679   int size_mask;
00680   bfd_vma prev_addr = 0;
00681   unsigned int count;
00682   bfd_size_type reloc_size, amt;
00683   struct relocation_info *relocs;
00684   arelent *reloc_cache;
00685 
00686   if (asect->relocation)
00687     return TRUE;
00688 
00689   if (!aout_32_slurp_symbol_table (abfd))
00690     return FALSE;
00691 
00692   if (asect == obj_datasec (abfd))
00693     reloc_size = exec_hdr (abfd)->a_drsize;
00694   else if (asect == obj_textsec (abfd))
00695     reloc_size = exec_hdr (abfd)->a_trsize;
00696   else if (asect == obj_bsssec (abfd))
00697     reloc_size = 0;
00698   else
00699     {
00700       bfd_set_error (bfd_error_invalid_operation);
00701       return FALSE;
00702     }
00703 
00704   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
00705     return FALSE;
00706   count = reloc_size / sizeof (struct relocation_info);
00707 
00708   relocs = bfd_malloc (reloc_size);
00709   if (!relocs && reloc_size != 0)
00710     return FALSE;
00711 
00712   amt = ((bfd_size_type) count + 1) * sizeof (arelent);
00713   reloc_cache = bfd_malloc (amt);
00714   if (!reloc_cache)
00715     {
00716       if (relocs != NULL)
00717        free (relocs);
00718       return FALSE;
00719     }
00720 
00721   if (bfd_bread ((void *) relocs, reloc_size, abfd) != reloc_size)
00722     {
00723       free (reloc_cache);
00724       if (relocs != NULL)
00725        free (relocs);
00726       return FALSE;
00727     }
00728 
00729   if (bfd_header_big_endian (abfd))
00730     {
00731       /* Big-endian bit field allocation order.  */
00732       pcrel_mask  = 0x80;
00733       extern_mask = 0x10;
00734       incode_mask = 0x08;
00735       callj_mask  = 0x02;
00736       size_mask =   0x20;
00737       length_shift = 5;
00738     }
00739   else
00740     {
00741       /* Little-endian bit field allocation order.  */
00742       pcrel_mask  = 0x01;
00743       extern_mask = 0x08;
00744       incode_mask = 0x10;
00745       callj_mask  = 0x40;
00746       size_mask   = 0x02;
00747       length_shift = 1;
00748     }
00749 
00750   for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
00751        counter < count;
00752        counter++, rptr++, cache_ptr++)
00753   {
00754     unsigned char *raw = (unsigned char *)rptr;
00755     unsigned int symnum;
00756 
00757     cache_ptr->address = H_GET_32 (abfd, raw + 0);
00758     cache_ptr->howto = 0;
00759 
00760     if (bfd_header_big_endian (abfd))
00761       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
00762     else
00763       symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
00764 
00765     if (raw[7] & extern_mask)
00766       {
00767        /* If this is set then the r_index is an index into the symbol table;
00768           if the bit is not set then r_index contains a section map.
00769           We either fill in the sym entry with a pointer to the symbol,
00770           or point to the correct section.  */
00771       cache_ptr->sym_ptr_ptr = symbols + symnum;
00772       cache_ptr->addend = 0;
00773       }
00774     else
00775       {
00776        /* In a.out symbols are relative to the beginning of the
00777           file rather than sections ?
00778           (look in translate_from_native_sym_flags)
00779           The reloc entry addend has added to it the offset into the
00780           file of the data, so subtract the base to make the reloc
00781           section relative.  */
00782        int s;
00783 
00784        /* Sign-extend symnum from 24 bits to whatever host uses.  */
00785        s = symnum;
00786        if (s & (1 << 23))
00787          s |= (~0) << 24;
00788 
00789        cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
00790        switch (s)
00791          {
00792          case N_TEXT:
00793          case N_TEXT | N_EXT:
00794            cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr;
00795            cache_ptr->addend = - obj_textsec (abfd)->vma;
00796            break;
00797          case N_DATA:
00798          case N_DATA | N_EXT:
00799            cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr;
00800            cache_ptr->addend = - obj_datasec (abfd)->vma;
00801            break;
00802          case N_BSS:
00803          case N_BSS | N_EXT:
00804            cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;
00805            cache_ptr->addend =  - obj_bsssec (abfd)->vma;
00806            break;
00807          case N_ABS:
00808          case N_ABS | N_EXT:
00809            cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;
00810            cache_ptr->addend = 0;
00811            break;
00812          case -2: /* .align */
00813            if (raw[7] & pcrel_mask)
00814              {
00815               cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
00816               cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00817              }
00818            else
00819              {
00820               /* .org? */
00821               abort ();
00822              }
00823            cache_ptr->addend = 0;
00824            break;
00825          default:
00826            BFD_ASSERT (FALSE);
00827            break;
00828          }
00829       }
00830 
00831     /* The i960 only has a few relocation types:
00832        abs 32-bit and pcrel 24bit.   except for callj's!  */
00833     if (cache_ptr->howto != 0)
00834       ;
00835     else if (raw[7] & callj_mask)
00836       {
00837        cache_ptr->howto = &howto_reloc_callj;
00838       }
00839     else if ( raw[7] & pcrel_mask)
00840       {
00841        if (raw[7] & size_mask)
00842          cache_ptr->howto = &howto_reloc_pcrel13;
00843        else
00844          cache_ptr->howto = &howto_reloc_pcrel24;
00845       }
00846     else
00847       {
00848        if (raw[7] & incode_mask)
00849          cache_ptr->howto = &howto_reloc_abs32code;
00850        else
00851          cache_ptr->howto = &howto_reloc_abs32;
00852       }
00853 
00854     if (cache_ptr->address < prev_addr)
00855       {
00856        /* Ouch! this reloc is out of order, insert into the right place.  */
00857        arelent tmp;
00858        arelent *cursor = cache_ptr-1;
00859        bfd_vma stop = cache_ptr->address;
00860 
00861        tmp  = *cache_ptr;
00862        while (cursor->address > stop && cursor >= reloc_cache)
00863          {
00864            cursor[1] = cursor[0];
00865            cursor--;
00866          }
00867 
00868        cursor[1] = tmp;
00869       }
00870     else
00871       prev_addr = cache_ptr->address;
00872   }
00873 
00874   if (relocs != NULL)
00875     free (relocs);
00876   asect->relocation = reloc_cache;
00877   asect->reloc_count = count;
00878 
00879   return TRUE;
00880 }
00881 
00882 /* This is stupid.  This function should be a boolean predicate.  */
00883 
00884 static long
00885 b_out_canonicalize_reloc (bfd *abfd,
00886                        sec_ptr section,
00887                        arelent **relptr,
00888                        asymbol **symbols)
00889 {
00890   arelent *tblptr;
00891   unsigned int count;
00892 
00893   if ((section->flags & SEC_CONSTRUCTOR) != 0)
00894     {
00895       arelent_chain *chain = section->constructor_chain;
00896 
00897       for (count = 0; count < section->reloc_count; count++)
00898        {
00899          *relptr++ = &chain->relent;
00900          chain = chain->next;
00901        }
00902     }
00903   else
00904     {
00905       if (section->relocation == NULL
00906          && ! b_out_slurp_reloc_table (abfd, section, symbols))
00907        return -1;
00908 
00909       tblptr = section->relocation;
00910       for (count = 0; count++ < section->reloc_count;)
00911        *relptr++ = tblptr++;
00912     }
00913 
00914   *relptr = NULL;
00915 
00916   return section->reloc_count;
00917 }
00918 
00919 static long
00920 b_out_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
00921 {
00922   if (bfd_get_format (abfd) != bfd_object)
00923     {
00924       bfd_set_error (bfd_error_invalid_operation);
00925       return -1;
00926     }
00927 
00928   if (asect->flags & SEC_CONSTRUCTOR)
00929     return sizeof (arelent *) * (asect->reloc_count + 1);
00930 
00931   if (asect == obj_datasec (abfd))
00932     return (sizeof (arelent *) *
00933            ((exec_hdr (abfd)->a_drsize / sizeof (struct relocation_info))
00934             + 1));
00935 
00936   if (asect == obj_textsec (abfd))
00937     return (sizeof (arelent *) *
00938            ((exec_hdr (abfd)->a_trsize / sizeof (struct relocation_info))
00939             + 1));
00940 
00941   if (asect == obj_bsssec (abfd))
00942     return 0;
00943 
00944   bfd_set_error (bfd_error_invalid_operation);
00945   return -1;
00946 }
00947 
00948 
00949 static bfd_boolean
00950 b_out_set_section_contents (bfd *abfd,
00951                          asection *section,
00952                          const void * location,
00953                          file_ptr offset,
00954                          bfd_size_type count)
00955 {
00956   if (! abfd->output_has_begun)
00957     {
00958       /* Set by bfd.c handler.  */
00959       if (! aout_32_make_sections (abfd))
00960        return FALSE;
00961 
00962       obj_textsec (abfd)->filepos = sizeof (struct external_exec);
00963       obj_datasec (abfd)->filepos = obj_textsec (abfd)->filepos
00964        +  obj_textsec (abfd)->size;
00965     }
00966 
00967   /* Regardless, once we know what we're doing, we might as well get going.  */
00968   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
00969     return FALSE;
00970 
00971   if (count == 0)
00972     return TRUE;
00973 
00974   return bfd_bwrite ((void *) location, count, abfd) == count;
00975 }
00976 
00977 static bfd_boolean
00978 b_out_set_arch_mach (bfd *abfd,
00979                    enum bfd_architecture arch,
00980                    unsigned long machine)
00981 {
00982   bfd_default_set_arch_mach (abfd, arch, machine);
00983 
00984   if (arch == bfd_arch_unknown)    /* Unknown machine arch is OK.  */
00985     return TRUE;
00986 
00987   if (arch == bfd_arch_i960)       /* i960 default is OK.  */
00988     switch (machine)
00989       {
00990       case bfd_mach_i960_core:
00991       case bfd_mach_i960_kb_sb:
00992       case bfd_mach_i960_mc:
00993       case bfd_mach_i960_xa:
00994       case bfd_mach_i960_ca:
00995       case bfd_mach_i960_ka_sa:
00996       case bfd_mach_i960_jx:
00997       case bfd_mach_i960_hx:
00998       case 0:
00999        return TRUE;
01000       default:
01001        return FALSE;
01002       }
01003 
01004   return FALSE;
01005 }
01006 
01007 static int
01008 b_out_sizeof_headers (bfd *ignore_abfd ATTRIBUTE_UNUSED,
01009                     struct bfd_link_info *info ATTRIBUTE_UNUSED)
01010 {
01011   return sizeof (struct external_exec);
01012 }
01013 
01014 static void
01015 perform_slip (bfd *abfd,
01016              unsigned int slip,
01017              asection *input_section,
01018              bfd_vma value)
01019 {
01020   asymbol **s;
01021 
01022   s = _bfd_generic_link_get_symbols (abfd);
01023   BFD_ASSERT (s != (asymbol **) NULL);
01024 
01025   /* Find all symbols past this point, and make them know
01026      what's happened.  */
01027   while (*s)
01028     {
01029       asymbol *p = *s;
01030 
01031       if (p->section == input_section)
01032        {
01033          /* This was pointing into this section, so mangle it.  */
01034          if (p->value > value)
01035            {
01036              p->value -=slip;
01037 
01038              if (p->udata.p != NULL)
01039               {
01040                 struct generic_link_hash_entry *h;
01041 
01042                 h = (struct generic_link_hash_entry *) p->udata.p;
01043                 BFD_ASSERT (h->root.type == bfd_link_hash_defined);
01044                 h->root.u.def.value -= slip;
01045                 BFD_ASSERT (h->root.u.def.value == p->value);
01046               }
01047            }
01048        }
01049       s++;
01050     }
01051 }
01052 
01053 /* This routine works out if the thing we want to get to can be
01054    reached with a 24bit offset instead of a 32 bit one.
01055    If it can, then it changes the amode.  */
01056 
01057 static int
01058 abs32code (bfd *abfd,
01059           asection *input_section,
01060           arelent *r,
01061           unsigned int shrink,
01062           struct bfd_link_info *link_info)
01063 {
01064   bfd_vma value = get_value (r, link_info, input_section);
01065   bfd_vma dot = output_addr (input_section) + r->address;
01066   bfd_vma gap;
01067 
01068   /* See if the address we're looking at within 2^23 bytes of where
01069      we are, if so then we can use a small branch rather than the
01070      jump we were going to.  */
01071   gap = value - (dot - shrink);
01072 
01073   if (-1 << 23 < (long)gap && (long)gap < 1 << 23)
01074     {
01075       /* Change the reloc type from 32bitcode possible 24, to 24bit
01076         possible 32.  */
01077       r->howto = &howto_reloc_abs32codeshrunk;
01078       /* The place to relc moves back by four bytes.  */
01079       r->address -=4;
01080 
01081       /* This will be four bytes smaller in the long run.  */
01082       shrink += 4 ;
01083       perform_slip (abfd, 4, input_section, r->address-shrink + 4);
01084     }
01085 
01086   return shrink;
01087 }
01088 
01089 static int
01090 aligncode (bfd *abfd,
01091           asection *input_section,
01092           arelent *r,
01093           unsigned int shrink)
01094 {
01095   bfd_vma dot = output_addr (input_section) + r->address;
01096   bfd_vma gap;
01097   bfd_vma old_end;
01098   bfd_vma new_end;
01099   unsigned int shrink_delta;
01100   int size = r->howto->size;
01101 
01102   /* Reduce the size of the alignment so that it's still aligned but
01103      smaller  - the current size is already the same size as or bigger
01104      than the alignment required.  */
01105 
01106   /* Calculate the first byte following the padding before we optimize.  */
01107   old_end = ((dot + size ) & ~size) + size+1;
01108   /* Work out where the new end will be - remember that we're smaller
01109      than we used to be.  */
01110   new_end = ((dot - shrink + size) & ~size);
01111 
01112   /* This is the new end.  */
01113   gap = old_end - ((dot + size) & ~size);
01114 
01115   shrink_delta = (old_end - new_end) - shrink;
01116 
01117   if (shrink_delta)
01118     {
01119       /* Change the reloc so that it knows how far to align to.  */
01120       r->howto = howto_done_align_table + (r->howto - howto_align_table);
01121 
01122       /* Encode the stuff into the addend - for future use we need to
01123         know how big the reloc used to be.  */
01124       r->addend = old_end - dot + r->address;
01125 
01126       /* This will be N bytes smaller in the long run, adjust all the symbols.  */
01127       perform_slip (abfd, shrink_delta, input_section, r->address - shrink);
01128       shrink += shrink_delta;
01129     }
01130 
01131   return shrink;
01132 }
01133 
01134 static bfd_boolean
01135 b_out_bfd_relax_section (bfd *abfd,
01136                       asection *i,
01137                       struct bfd_link_info *link_info,
01138                       bfd_boolean *again)
01139 {
01140   /* Get enough memory to hold the stuff.  */
01141   bfd *input_bfd = i->owner;
01142   asection *input_section = i;
01143   unsigned int shrink = 0 ;
01144   arelent **reloc_vector = NULL;
01145   long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
01146 
01147   if (reloc_size < 0)
01148     return FALSE;
01149 
01150   /* We only run this relaxation once.  It might work to run it
01151      multiple times, but it hasn't been tested.  */
01152   *again = FALSE;
01153 
01154   if (reloc_size)
01155     {
01156       long reloc_count;
01157 
01158       reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
01159       if (reloc_vector == NULL && reloc_size != 0)
01160        goto error_return;
01161 
01162       /* Get the relocs and think about them.  */
01163       reloc_count =
01164        bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector,
01165                             _bfd_generic_link_get_symbols (input_bfd));
01166       if (reloc_count < 0)
01167        goto error_return;
01168       if (reloc_count > 0)
01169        {
01170          arelent **parent;
01171 
01172          for (parent = reloc_vector; *parent; parent++)
01173            {
01174              arelent *r = *parent;
01175 
01176              switch (r->howto->type)
01177               {
01178               case ALIGNER:
01179                 /* An alignment reloc.  */
01180                 shrink = aligncode (abfd, input_section, r, shrink);
01181                 break;
01182               case ABS32CODE:
01183                 /* A 32bit reloc in an addressing mode.  */
01184                 shrink = abs32code (input_bfd, input_section, r, shrink,
01185                                   link_info);
01186                 break;
01187               case ABS32CODE_SHRUNK:
01188                 shrink += 4;
01189                 break;
01190               }
01191            }
01192        }
01193     }
01194   input_section->size -= shrink;
01195 
01196   if (reloc_vector != NULL)
01197     free (reloc_vector);
01198   return TRUE;
01199  error_return:
01200   if (reloc_vector != NULL)
01201     free (reloc_vector);
01202   return FALSE;
01203 }
01204 
01205 static bfd_byte *
01206 b_out_bfd_get_relocated_section_contents (bfd *output_bfd,
01207                                      struct bfd_link_info *link_info,
01208                                      struct bfd_link_order *link_order,
01209                                      bfd_byte *data,
01210                                      bfd_boolean relocatable,
01211                                      asymbol **symbols)
01212 {
01213   /* Get enough memory to hold the stuff.  */
01214   bfd *input_bfd = link_order->u.indirect.section->owner;
01215   asection *input_section = link_order->u.indirect.section;
01216   long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
01217   arelent **reloc_vector = NULL;
01218   long reloc_count;
01219 
01220   if (reloc_size < 0)
01221     goto error_return;
01222 
01223   /* If producing relocatable output, don't bother to relax.  */
01224   if (relocatable)
01225     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
01226                                                  link_order,
01227                                                  data, relocatable,
01228                                                  symbols);
01229 
01230   reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
01231   if (reloc_vector == NULL && reloc_size != 0)
01232     goto error_return;
01233 
01234   /* Read in the section.  */
01235   BFD_ASSERT (bfd_get_section_contents (input_bfd,
01236                                    input_section,
01237                                    data,
01238                                    (bfd_vma) 0,
01239                                    input_section->size));
01240 
01241   reloc_count = bfd_canonicalize_reloc (input_bfd,
01242                                    input_section,
01243                                    reloc_vector,
01244                                    symbols);
01245   if (reloc_count < 0)
01246     goto error_return;
01247   if (reloc_count > 0)
01248     {
01249       arelent **parent = reloc_vector;
01250       arelent *reloc ;
01251       unsigned int dst_address = 0;
01252       unsigned int src_address = 0;
01253       unsigned int run;
01254       unsigned int idx;
01255 
01256       /* Find how long a run we can do.  */
01257       while (dst_address < link_order->size)
01258        {
01259          reloc = *parent;
01260          if (reloc)
01261            {
01262              /* Note that the relaxing didn't tie up the addresses in the
01263                relocation, so we use the original address to work out the
01264                run of non-relocated data.  */
01265              BFD_ASSERT (reloc->address >= src_address);
01266              run = reloc->address - src_address;
01267              parent++;
01268            }
01269          else
01270            run = link_order->size - dst_address;
01271 
01272          /* Copy the bytes.  */
01273          for (idx = 0; idx < run; idx++)
01274            data[dst_address++] = data[src_address++];
01275 
01276          /* Now do the relocation.  */
01277          if (reloc)
01278            {
01279              switch (reloc->howto->type)
01280               {
01281               case ABS32CODE:
01282                 calljx_callback (input_bfd, link_info, reloc,
01283                                src_address + data, dst_address + data,
01284                                input_section);
01285                 src_address += 4;
01286                 dst_address += 4;
01287                 break;
01288               case ABS32:
01289                 bfd_put_32 (input_bfd,
01290                            (bfd_get_32 (input_bfd, data + src_address)
01291                             + get_value (reloc, link_info, input_section)),
01292                            data + dst_address);
01293                 src_address += 4;
01294                 dst_address += 4;
01295                 break;
01296               case CALLJ:
01297                 callj_callback (input_bfd, link_info, reloc, data,
01298                               src_address, dst_address, input_section,
01299                               FALSE);
01300                 src_address += 4;
01301                 dst_address += 4;
01302                 break;
01303               case ALIGNDONE:
01304                 BFD_ASSERT (reloc->addend >= src_address);
01305                 BFD_ASSERT ((bfd_vma) reloc->addend
01306                            <= input_section->size);
01307                 src_address = reloc->addend;
01308                 dst_address = ((dst_address + reloc->howto->size)
01309                              & ~reloc->howto->size);
01310                 break;
01311               case ABS32CODE_SHRUNK:
01312                 /* This used to be a callx, but we've found out that a
01313                    callj will reach, so do the right thing.  */
01314                 callj_callback (input_bfd, link_info, reloc, data,
01315                               src_address + 4, dst_address, input_section,
01316                               TRUE);
01317                 dst_address += 4;
01318                 src_address += 8;
01319                 break;
01320               case PCREL24:
01321                 {
01322                   long int word = bfd_get_32 (input_bfd,
01323                                           data + src_address);
01324                   bfd_vma value;
01325 
01326                   value = get_value (reloc, link_info, input_section);
01327                   word = ((word & ~BAL_MASK)
01328                          | (((word & BAL_MASK)
01329                             + value
01330                             - output_addr (input_section)
01331                             + reloc->addend)
01332                             & BAL_MASK));
01333 
01334                   bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
01335                   dst_address += 4;
01336                   src_address += 4;
01337 
01338                 }
01339                 break;
01340               case PCREL13:
01341                 {
01342                   long int word = bfd_get_32 (input_bfd,
01343                                           data + src_address);
01344                   bfd_vma value;
01345 
01346                   value = get_value (reloc, link_info, input_section);
01347                   word = ((word & ~PCREL13_MASK)
01348                          | (((word & PCREL13_MASK)
01349                             + value
01350                             + reloc->addend
01351                             - output_addr (input_section))
01352                             & PCREL13_MASK));
01353 
01354                   bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
01355                   dst_address += 4;
01356                   src_address += 4;
01357                 }
01358                 break;
01359 
01360               default:
01361                 abort ();
01362               }
01363            }
01364        }
01365     }
01366   if (reloc_vector != NULL)
01367     free (reloc_vector);
01368   return data;
01369  error_return:
01370   if (reloc_vector != NULL)
01371     free (reloc_vector);
01372   return NULL;
01373 }
01374 
01375 
01376 /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
01377 
01378 #define aout_32_bfd_make_debug_symbol          _bfd_nosymbols_bfd_make_debug_symbol
01379 #define aout_32_close_and_cleanup              aout_32_bfd_free_cached_info
01380 #define b_out_bfd_link_hash_table_create       _bfd_generic_link_hash_table_create
01381 #define b_out_bfd_link_hash_table_free         _bfd_generic_link_hash_table_free
01382 #define b_out_bfd_link_add_symbols             _bfd_generic_link_add_symbols
01383 #define b_out_bfd_link_just_syms               _bfd_generic_link_just_syms
01384 #define b_out_bfd_final_link                   _bfd_generic_final_link
01385 #define b_out_bfd_link_split_section           _bfd_generic_link_split_section
01386 #define b_out_bfd_gc_sections                  bfd_generic_gc_sections
01387 #define b_out_bfd_merge_sections               bfd_generic_merge_sections
01388 #define b_out_bfd_is_group_section             bfd_generic_is_group_section
01389 #define b_out_bfd_discard_group                bfd_generic_discard_group
01390 #define b_out_section_already_linked           _bfd_generic_section_already_linked
01391 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
01392 
01393 extern const bfd_target b_out_vec_little_host;
01394 
01395 const bfd_target b_out_vec_big_host =
01396 {
01397   "b.out.big",                     /* Name.  */
01398   bfd_target_aout_flavour,
01399   BFD_ENDIAN_LITTLE,        /* Data byte order.  */
01400   BFD_ENDIAN_BIG,           /* Header byte order.  */
01401   (HAS_RELOC | EXEC_P |            /* Object flags.  */
01402    HAS_LINENO | HAS_DEBUG |
01403    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
01404   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
01405   '_',                      /* Symbol leading char.  */
01406   ' ',                      /* AR_pad_char.  */
01407   16,                       /* AR_max_namelen.  */
01408 
01409   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01410      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01411      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
01412   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
01413      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
01414      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
01415  {_bfd_dummy_target, b_out_object_p, /* bfd_check_format.  */
01416    bfd_generic_archive_p, _bfd_dummy_target},
01417  {bfd_false, b_out_mkobject,       /* bfd_set_format.  */
01418    _bfd_generic_mkarchive, bfd_false},
01419  {bfd_false, b_out_write_object_contents, /* bfd_write_contents.  */
01420    _bfd_write_archive_contents, bfd_false},
01421 
01422      BFD_JUMP_TABLE_GENERIC (aout_32),
01423      BFD_JUMP_TABLE_COPY (_bfd_generic),
01424      BFD_JUMP_TABLE_CORE (_bfd_nocore),
01425      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
01426      BFD_JUMP_TABLE_SYMBOLS (aout_32),
01427      BFD_JUMP_TABLE_RELOCS (b_out),
01428      BFD_JUMP_TABLE_WRITE (b_out),
01429      BFD_JUMP_TABLE_LINK (b_out),
01430      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
01431 
01432   & b_out_vec_little_host,
01433 
01434   NULL
01435 };
01436 
01437 const bfd_target b_out_vec_little_host =
01438 {
01439   "b.out.little",           /* Name.  */
01440   bfd_target_aout_flavour,
01441   BFD_ENDIAN_LITTLE,        /* Data byte order.  */
01442   BFD_ENDIAN_LITTLE,        /* Header byte order.  */
01443   (HAS_RELOC | EXEC_P |            /* Object flags.  */
01444    HAS_LINENO | HAS_DEBUG |
01445    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
01446   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
01447   '_',                      /* Symbol leading char.  */
01448   ' ',                      /* AR_pad_char.  */
01449   16,                       /* AR_max_namelen.  */
01450   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01451     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01452      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
01453   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01454      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01455      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
01456 
01457   {_bfd_dummy_target, b_out_object_p, /* bfd_check_format.  */
01458      bfd_generic_archive_p, _bfd_dummy_target},
01459   {bfd_false, b_out_mkobject,      /* bfd_set_format.  */
01460      _bfd_generic_mkarchive, bfd_false},
01461   {bfd_false, b_out_write_object_contents, /* bfd_write_contents.  */
01462      _bfd_write_archive_contents, bfd_false},
01463 
01464      BFD_JUMP_TABLE_GENERIC (aout_32),
01465      BFD_JUMP_TABLE_COPY (_bfd_generic),
01466      BFD_JUMP_TABLE_CORE (_bfd_nocore),
01467      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
01468      BFD_JUMP_TABLE_SYMBOLS (aout_32),
01469      BFD_JUMP_TABLE_RELOCS (b_out),
01470      BFD_JUMP_TABLE_WRITE (b_out),
01471      BFD_JUMP_TABLE_LINK (b_out),
01472      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
01473 
01474   & b_out_vec_big_host,
01475 
01476   NULL
01477 };