Home | History | Annotate | Line # | Download | only in bfd
i386lynx.c revision 1.1
      1  1.1  skrll /* BFD back-end for i386 a.out binaries under LynxOS.
      2  1.1  skrll    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2002,
      3  1.1  skrll    2003, 2007 Free Software Foundation, Inc.
      4  1.1  skrll 
      5  1.1  skrll    This file is part of BFD, the Binary File Descriptor library.
      6  1.1  skrll 
      7  1.1  skrll    This program is free software; you can redistribute it and/or modify
      8  1.1  skrll    it under the terms of the GNU General Public License as published by
      9  1.1  skrll    the Free Software Foundation; either version 3 of the License, or
     10  1.1  skrll    (at your option) any later version.
     11  1.1  skrll 
     12  1.1  skrll    This program is distributed in the hope that it will be useful,
     13  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  skrll    GNU General Public License for more details.
     16  1.1  skrll 
     17  1.1  skrll    You should have received a copy of the GNU General Public License
     18  1.1  skrll    along with this program; if not, write to the Free Software
     19  1.1  skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20  1.1  skrll    MA 02110-1301, USA.  */
     21  1.1  skrll 
     22  1.1  skrll #define N_SHARED_LIB(x) 0
     23  1.1  skrll 
     24  1.1  skrll #define TEXT_START_ADDR 0
     25  1.1  skrll #define TARGET_PAGE_SIZE 4096
     26  1.1  skrll #define SEGMENT_SIZE TARGET_PAGE_SIZE
     27  1.1  skrll #define DEFAULT_ARCH bfd_arch_i386
     28  1.1  skrll 
     29  1.1  skrll /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
     30  1.1  skrll    remove whitespace added here, and thus will fail to concatenate
     31  1.1  skrll    the tokens.  */
     32  1.1  skrll #define MY(OP) CONCAT2 (i386lynx_aout_,OP)
     33  1.1  skrll #define TARGETNAME "a.out-i386-lynx"
     34  1.1  skrll 
     35  1.1  skrll #include "sysdep.h"
     36  1.1  skrll #include "bfd.h"
     37  1.1  skrll #include "libbfd.h"
     38  1.1  skrll 
     39  1.1  skrll #ifndef WRITE_HEADERS
     40  1.1  skrll #define WRITE_HEADERS(abfd, execp)					      \
     41  1.1  skrll       {									      \
     42  1.1  skrll 	bfd_size_type text_size; /* dummy vars */			      \
     43  1.1  skrll 	file_ptr text_end;						      \
     44  1.1  skrll 	if (adata(abfd).magic == undecided_magic)			      \
     45  1.1  skrll 	  NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);     \
     46  1.1  skrll     									      \
     47  1.1  skrll 	execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;	      \
     48  1.1  skrll 	execp->a_entry = bfd_get_start_address (abfd);			      \
     49  1.1  skrll     									      \
     50  1.1  skrll 	execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *		      \
     51  1.1  skrll 			   obj_reloc_entry_size (abfd));		      \
     52  1.1  skrll 	execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *		      \
     53  1.1  skrll 			   obj_reloc_entry_size (abfd));		      \
     54  1.1  skrll 	NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);	      \
     55  1.1  skrll 									      \
     56  1.1  skrll 	if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0		      \
     57  1.1  skrll 	    || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
     58  1.1  skrll 			  abfd) != EXEC_BYTES_SIZE)			      \
     59  1.1  skrll 	  return FALSE;							      \
     60  1.1  skrll 	/* Now write out reloc info, followed by syms and strings */	      \
     61  1.1  skrll   									      \
     62  1.1  skrll 	if (bfd_get_symcount (abfd) != 0) 				      \
     63  1.1  skrll 	    {								      \
     64  1.1  skrll 	      if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET)    \
     65  1.1  skrll 		  != 0)							      \
     66  1.1  skrll 	        return FALSE;						      \
     67  1.1  skrll 									      \
     68  1.1  skrll 	      if (! NAME(aout,write_syms) (abfd)) return FALSE;		      \
     69  1.1  skrll 									      \
     70  1.1  skrll 	      if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET)   \
     71  1.1  skrll 		  != 0)							      \
     72  1.1  skrll 	        return FALSE;						      \
     73  1.1  skrll 									      \
     74  1.1  skrll 	      if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd)))   \
     75  1.1  skrll 		return FALSE;						      \
     76  1.1  skrll 	      if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET)   \
     77  1.1  skrll 		  != 0)							      \
     78  1.1  skrll 	        return 0;						      \
     79  1.1  skrll 									      \
     80  1.1  skrll 	      if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd)))   \
     81  1.1  skrll 		return FALSE;						      \
     82  1.1  skrll 	    }								      \
     83  1.1  skrll       }
     84  1.1  skrll #endif
     85  1.1  skrll 
     86  1.1  skrll #include "libaout.h"
     87  1.1  skrll #include "aout/aout64.h"
     88  1.1  skrll 
     89  1.1  skrll void NAME (lynx,swap_std_reloc_out)
     90  1.1  skrll   PARAMS ((bfd *, arelent *, struct reloc_std_external *));
     91  1.1  skrll void NAME (lynx,swap_ext_reloc_out)
     92  1.1  skrll   PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
     93  1.1  skrll void NAME (lynx,swap_ext_reloc_in)
     94  1.1  skrll   PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **,
     95  1.1  skrll 	   bfd_size_type));
     96  1.1  skrll void NAME (lynx,swap_std_reloc_in)
     97  1.1  skrll   PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **,
     98  1.1  skrll 	   bfd_size_type));
     99  1.1  skrll bfd_boolean NAME (lynx,slurp_reloc_table)
    100  1.1  skrll   PARAMS ((bfd *, sec_ptr, asymbol **));
    101  1.1  skrll bfd_boolean NAME (lynx,squirt_out_relocs)
    102  1.1  skrll   PARAMS ((bfd *, asection *));
    103  1.1  skrll long NAME (lynx,canonicalize_reloc)
    104  1.1  skrll   PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
    105  1.1  skrll 
    106  1.1  skrll #ifdef LYNX_CORE
    107  1.1  skrll 
    108  1.1  skrll char *lynx_core_file_failing_command ();
    109  1.1  skrll int lynx_core_file_failing_signal ();
    110  1.1  skrll bfd_boolean lynx_core_file_matches_executable_p ();
    111  1.1  skrll const bfd_target *lynx_core_file_p ();
    112  1.1  skrll 
    113  1.1  skrll #define	MY_core_file_failing_command lynx_core_file_failing_command
    114  1.1  skrll #define	MY_core_file_failing_signal lynx_core_file_failing_signal
    115  1.1  skrll #define	MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
    116  1.1  skrll #define	MY_core_file_p lynx_core_file_p
    117  1.1  skrll 
    118  1.1  skrll #endif /* LYNX_CORE */
    119  1.1  skrll 
    120  1.1  skrll 
    122  1.1  skrll #define KEEPIT udata.i
    123  1.1  skrll 
    124  1.1  skrll extern reloc_howto_type aout_32_ext_howto_table[];
    125  1.1  skrll extern reloc_howto_type aout_32_std_howto_table[];
    126  1.1  skrll 
    127  1.1  skrll /* Standard reloc stuff */
    128  1.1  skrll /* Output standard relocation information to a file in target byte order. */
    129  1.1  skrll 
    130  1.1  skrll void
    131  1.1  skrll NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
    132  1.1  skrll      bfd *abfd;
    133  1.1  skrll      arelent *g;
    134  1.1  skrll      struct reloc_std_external *natptr;
    135  1.1  skrll {
    136  1.1  skrll   int r_index;
    137  1.1  skrll   asymbol *sym = *(g->sym_ptr_ptr);
    138  1.1  skrll   int r_extern;
    139  1.1  skrll   unsigned int r_length;
    140  1.1  skrll   int r_pcrel;
    141  1.1  skrll   int r_baserel, r_jmptable, r_relative;
    142  1.1  skrll   unsigned int r_addend;
    143  1.1  skrll   asection *output_section = sym->section->output_section;
    144  1.1  skrll 
    145  1.1  skrll   PUT_WORD (abfd, g->address, natptr->r_address);
    146  1.1  skrll 
    147  1.1  skrll   r_length = g->howto->size;	/* Size as a power of two */
    148  1.1  skrll   r_pcrel = (int) g->howto->pc_relative;	/* Relative to PC? */
    149  1.1  skrll   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
    150  1.1  skrll   r_baserel = 0;
    151  1.1  skrll   r_jmptable = 0;
    152  1.1  skrll   r_relative = 0;
    153  1.1  skrll 
    154  1.1  skrll   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
    155  1.1  skrll 
    156  1.1  skrll   /* name was clobbered by aout_write_syms to be symbol index */
    157  1.1  skrll 
    158  1.1  skrll   /* If this relocation is relative to a symbol then set the
    159  1.1  skrll      r_index to the symbols index, and the r_extern bit.
    160  1.1  skrll 
    161  1.1  skrll      Absolute symbols can come in in two ways, either as an offset
    162  1.1  skrll      from the abs section, or as a symbol which has an abs value.
    163  1.1  skrll      check for that here
    164  1.1  skrll   */
    165  1.1  skrll 
    166  1.1  skrll 
    167  1.1  skrll   if (bfd_is_com_section (output_section)
    168  1.1  skrll       || bfd_is_abs_section (output_section)
    169  1.1  skrll       || bfd_is_und_section (output_section))
    170  1.1  skrll     {
    171  1.1  skrll       if (bfd_abs_section_ptr->symbol == sym)
    172  1.1  skrll 	{
    173  1.1  skrll 	  /* Whoops, looked like an abs symbol, but is really an offset
    174  1.1  skrll 	     from the abs section */
    175  1.1  skrll 	  r_index = 0;
    176  1.1  skrll 	  r_extern = 0;
    177  1.1  skrll 	}
    178  1.1  skrll       else
    179  1.1  skrll 	{
    180  1.1  skrll 	  /* Fill in symbol */
    181  1.1  skrll 	  r_extern = 1;
    182  1.1  skrll 	  r_index = (*g->sym_ptr_ptr)->KEEPIT;
    183  1.1  skrll 	}
    184  1.1  skrll     }
    185  1.1  skrll   else
    186  1.1  skrll     {
    187  1.1  skrll       /* Just an ordinary section */
    188  1.1  skrll       r_extern = 0;
    189  1.1  skrll       r_index = output_section->target_index;
    190  1.1  skrll     }
    191  1.1  skrll 
    192  1.1  skrll   /* now the fun stuff */
    193  1.1  skrll   if (bfd_header_big_endian (abfd))
    194  1.1  skrll     {
    195  1.1  skrll       natptr->r_index[0] = r_index >> 16;
    196  1.1  skrll       natptr->r_index[1] = r_index >> 8;
    197  1.1  skrll       natptr->r_index[2] = r_index;
    198  1.1  skrll       natptr->r_type[0] =
    199  1.1  skrll 	(r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
    200  1.1  skrll 	| (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
    201  1.1  skrll 	| (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
    202  1.1  skrll 	| (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
    203  1.1  skrll 	| (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
    204  1.1  skrll 	| (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
    205  1.1  skrll     }
    206  1.1  skrll   else
    207  1.1  skrll     {
    208  1.1  skrll       natptr->r_index[2] = r_index >> 16;
    209  1.1  skrll       natptr->r_index[1] = r_index >> 8;
    210  1.1  skrll       natptr->r_index[0] = r_index;
    211  1.1  skrll       natptr->r_type[0] =
    212  1.1  skrll 	(r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
    213  1.1  skrll 	| (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
    214  1.1  skrll 	| (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
    215  1.1  skrll 	| (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
    216  1.1  skrll 	| (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
    217  1.1  skrll 	| (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
    218  1.1  skrll     }
    219  1.1  skrll }
    220  1.1  skrll 
    221  1.1  skrll 
    222  1.1  skrll /* Extended stuff */
    223  1.1  skrll /* Output extended relocation information to a file in target byte order. */
    224  1.1  skrll 
    225  1.1  skrll void
    226  1.1  skrll NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
    227  1.1  skrll      bfd *abfd;
    228  1.1  skrll      arelent *g;
    229  1.1  skrll      register struct reloc_ext_external *natptr;
    230  1.1  skrll {
    231  1.1  skrll   int r_index;
    232  1.1  skrll   int r_extern;
    233  1.1  skrll   unsigned int r_type;
    234  1.1  skrll   unsigned int r_addend;
    235  1.1  skrll   asymbol *sym = *(g->sym_ptr_ptr);
    236  1.1  skrll   asection *output_section = sym->section->output_section;
    237  1.1  skrll 
    238  1.1  skrll   PUT_WORD (abfd, g->address, natptr->r_address);
    239  1.1  skrll 
    240  1.1  skrll   r_type = (unsigned int) g->howto->type;
    241  1.1  skrll 
    242  1.1  skrll   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
    243  1.1  skrll 
    244  1.1  skrll 
    245  1.1  skrll   /* If this relocation is relative to a symbol then set the
    246  1.1  skrll      r_index to the symbols index, and the r_extern bit.
    247  1.1  skrll 
    248  1.1  skrll      Absolute symbols can come in in two ways, either as an offset
    249  1.1  skrll      from the abs section, or as a symbol which has an abs value.
    250  1.1  skrll      check for that here
    251  1.1  skrll      */
    252  1.1  skrll 
    253  1.1  skrll   if (bfd_is_com_section (output_section)
    254  1.1  skrll       || bfd_is_abs_section (output_section)
    255  1.1  skrll       || bfd_is_und_section (output_section))
    256  1.1  skrll     {
    257  1.1  skrll       if (bfd_abs_section_ptr->symbol == sym)
    258  1.1  skrll 	{
    259  1.1  skrll 	  /* Whoops, looked like an abs symbol, but is really an offset
    260  1.1  skrll 	 from the abs section */
    261  1.1  skrll 	  r_index = 0;
    262  1.1  skrll 	  r_extern = 0;
    263  1.1  skrll 	}
    264  1.1  skrll       else
    265  1.1  skrll 	{
    266  1.1  skrll 	  r_extern = 1;
    267  1.1  skrll 	  r_index = (*g->sym_ptr_ptr)->KEEPIT;
    268  1.1  skrll 	}
    269  1.1  skrll     }
    270  1.1  skrll   else
    271  1.1  skrll     {
    272  1.1  skrll       /* Just an ordinary section */
    273  1.1  skrll       r_extern = 0;
    274  1.1  skrll       r_index = output_section->target_index;
    275  1.1  skrll     }
    276  1.1  skrll 
    277  1.1  skrll 
    278  1.1  skrll   /* now the fun stuff */
    279  1.1  skrll   if (bfd_header_big_endian (abfd))
    280  1.1  skrll     {
    281  1.1  skrll       natptr->r_index[0] = r_index >> 16;
    282  1.1  skrll       natptr->r_index[1] = r_index >> 8;
    283  1.1  skrll       natptr->r_index[2] = r_index;
    284  1.1  skrll       natptr->r_type[0] =
    285  1.1  skrll 	(r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
    286  1.1  skrll 	| (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
    287  1.1  skrll     }
    288  1.1  skrll   else
    289  1.1  skrll     {
    290  1.1  skrll       natptr->r_index[2] = r_index >> 16;
    291  1.1  skrll       natptr->r_index[1] = r_index >> 8;
    292  1.1  skrll       natptr->r_index[0] = r_index;
    293  1.1  skrll       natptr->r_type[0] =
    294  1.1  skrll 	(r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
    295  1.1  skrll 	| (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
    296  1.1  skrll     }
    297  1.1  skrll 
    298  1.1  skrll   PUT_WORD (abfd, r_addend, natptr->r_addend);
    299  1.1  skrll }
    300  1.1  skrll 
    301  1.1  skrll /* BFD deals internally with all things based from the section they're
    302  1.1  skrll    in. so, something in 10 bytes into a text section  with a base of
    303  1.1  skrll    50 would have a symbol (.text+10) and know .text vma was 50.
    304  1.1  skrll 
    305  1.1  skrll    Aout keeps all it's symbols based from zero, so the symbol would
    306  1.1  skrll    contain 60. This macro subs the base of each section from the value
    307  1.1  skrll    to give the true offset from the section */
    308  1.1  skrll 
    309  1.1  skrll 
    310  1.1  skrll #define MOVE_ADDRESS(ad)       						\
    311  1.1  skrll   if (r_extern) {							\
    312  1.1  skrll    /* undefined symbol */						\
    313  1.1  skrll      cache_ptr->sym_ptr_ptr = symbols + r_index;			\
    314  1.1  skrll      cache_ptr->addend = ad;						\
    315  1.1  skrll      } else {								\
    316  1.1  skrll     /* defined, section relative. replace symbol with pointer to    	\
    317  1.1  skrll        symbol which points to section  */				\
    318  1.1  skrll     switch (r_index) {							\
    319  1.1  skrll     case N_TEXT:							\
    320  1.1  skrll     case N_TEXT | N_EXT:						\
    321  1.1  skrll       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;	\
    322  1.1  skrll       cache_ptr->addend = ad  - su->textsec->vma;			\
    323  1.1  skrll       break;								\
    324  1.1  skrll     case N_DATA:							\
    325  1.1  skrll     case N_DATA | N_EXT:						\
    326  1.1  skrll       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;	\
    327  1.1  skrll       cache_ptr->addend = ad - su->datasec->vma;			\
    328  1.1  skrll       break;								\
    329  1.1  skrll     case N_BSS:								\
    330  1.1  skrll     case N_BSS | N_EXT:							\
    331  1.1  skrll       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;	\
    332  1.1  skrll       cache_ptr->addend = ad - su->bsssec->vma;				\
    333  1.1  skrll       break;								\
    334  1.1  skrll     default:								\
    335  1.1  skrll     case N_ABS:								\
    336  1.1  skrll     case N_ABS | N_EXT:							\
    337  1.1  skrll      cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	\
    338  1.1  skrll       cache_ptr->addend = ad;						\
    339  1.1  skrll       break;								\
    340  1.1  skrll     }									\
    341  1.1  skrll   }     								\
    342  1.1  skrll 
    343  1.1  skrll void
    344  1.1  skrll NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
    345  1.1  skrll      bfd *abfd;
    346  1.1  skrll      struct reloc_ext_external *bytes;
    347  1.1  skrll      arelent *cache_ptr;
    348  1.1  skrll      asymbol **symbols;
    349  1.1  skrll      bfd_size_type symcount ATTRIBUTE_UNUSED;
    350  1.1  skrll {
    351  1.1  skrll   int r_index;
    352  1.1  skrll   int r_extern;
    353  1.1  skrll   unsigned int r_type;
    354  1.1  skrll   struct aoutdata *su = &(abfd->tdata.aout_data->a);
    355  1.1  skrll 
    356  1.1  skrll   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
    357  1.1  skrll 
    358  1.1  skrll   r_index = bytes->r_index[1];
    359  1.1  skrll   r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
    360  1.1  skrll   r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
    361  1.1  skrll     >> RELOC_EXT_BITS_TYPE_SH_BIG;
    362  1.1  skrll 
    363  1.1  skrll   cache_ptr->howto = aout_32_ext_howto_table + r_type;
    364  1.1  skrll   MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
    365  1.1  skrll }
    366  1.1  skrll 
    367  1.1  skrll void
    368  1.1  skrll NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
    369  1.1  skrll      bfd *abfd;
    370  1.1  skrll      struct reloc_std_external *bytes;
    371  1.1  skrll      arelent *cache_ptr;
    372  1.1  skrll      asymbol **symbols;
    373  1.1  skrll      bfd_size_type symcount ATTRIBUTE_UNUSED;
    374  1.1  skrll {
    375  1.1  skrll   int r_index;
    376  1.1  skrll   int r_extern;
    377  1.1  skrll   unsigned int r_length;
    378  1.1  skrll   int r_pcrel;
    379  1.1  skrll   int r_baserel, r_jmptable, r_relative;
    380  1.1  skrll   struct aoutdata *su = &(abfd->tdata.aout_data->a);
    381  1.1  skrll 
    382  1.1  skrll   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
    383  1.1  skrll 
    384  1.1  skrll   r_index = bytes->r_index[1];
    385  1.1  skrll   r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
    386  1.1  skrll   r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
    387  1.1  skrll   r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
    388  1.1  skrll   r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
    389  1.1  skrll   r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
    390  1.1  skrll   r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
    391  1.1  skrll     >> RELOC_STD_BITS_LENGTH_SH_BIG;
    392  1.1  skrll 
    393  1.1  skrll   cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
    394  1.1  skrll   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
    395  1.1  skrll 
    396  1.1  skrll   MOVE_ADDRESS (0);
    397  1.1  skrll }
    398  1.1  skrll 
    399  1.1  skrll /* Reloc hackery */
    400  1.1  skrll 
    401  1.1  skrll bfd_boolean
    402  1.1  skrll NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
    403  1.1  skrll      bfd *abfd;
    404  1.1  skrll      sec_ptr asect;
    405  1.1  skrll      asymbol **symbols;
    406  1.1  skrll {
    407  1.1  skrll   bfd_size_type count;
    408  1.1  skrll   bfd_size_type reloc_size;
    409  1.1  skrll   PTR relocs;
    410  1.1  skrll   arelent *reloc_cache;
    411  1.1  skrll   size_t each_size;
    412  1.1  skrll 
    413  1.1  skrll   if (asect->relocation)
    414  1.1  skrll     return TRUE;
    415  1.1  skrll 
    416  1.1  skrll   if (asect->flags & SEC_CONSTRUCTOR)
    417  1.1  skrll     return TRUE;
    418  1.1  skrll 
    419  1.1  skrll   if (asect == obj_datasec (abfd))
    420  1.1  skrll     {
    421  1.1  skrll       reloc_size = exec_hdr (abfd)->a_drsize;
    422  1.1  skrll       goto doit;
    423  1.1  skrll     }
    424  1.1  skrll 
    425  1.1  skrll   if (asect == obj_textsec (abfd))
    426  1.1  skrll     {
    427  1.1  skrll       reloc_size = exec_hdr (abfd)->a_trsize;
    428  1.1  skrll       goto doit;
    429  1.1  skrll     }
    430  1.1  skrll 
    431  1.1  skrll   bfd_set_error (bfd_error_invalid_operation);
    432  1.1  skrll   return FALSE;
    433  1.1  skrll 
    434  1.1  skrll doit:
    435  1.1  skrll   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
    436  1.1  skrll     return FALSE;
    437  1.1  skrll   each_size = obj_reloc_entry_size (abfd);
    438  1.1  skrll 
    439  1.1  skrll   count = reloc_size / each_size;
    440  1.1  skrll 
    441  1.1  skrll 
    442  1.1  skrll   reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
    443  1.1  skrll   if (!reloc_cache && count != 0)
    444  1.1  skrll     return FALSE;
    445  1.1  skrll 
    446  1.1  skrll   relocs = (PTR) bfd_alloc (abfd, reloc_size);
    447  1.1  skrll   if (!relocs && reloc_size != 0)
    448  1.1  skrll     {
    449  1.1  skrll       free (reloc_cache);
    450  1.1  skrll       return FALSE;
    451  1.1  skrll     }
    452  1.1  skrll 
    453  1.1  skrll   if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
    454  1.1  skrll     {
    455  1.1  skrll       bfd_release (abfd, relocs);
    456  1.1  skrll       free (reloc_cache);
    457  1.1  skrll       return FALSE;
    458  1.1  skrll     }
    459  1.1  skrll 
    460  1.1  skrll   if (each_size == RELOC_EXT_SIZE)
    461  1.1  skrll     {
    462  1.1  skrll       register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
    463  1.1  skrll       unsigned int counter = 0;
    464  1.1  skrll       arelent *cache_ptr = reloc_cache;
    465  1.1  skrll 
    466  1.1  skrll       for (; counter < count; counter++, rptr++, cache_ptr++)
    467  1.1  skrll 	{
    468  1.1  skrll 	  NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
    469  1.1  skrll 					(bfd_size_type) bfd_get_symcount (abfd));
    470  1.1  skrll 	}
    471  1.1  skrll     }
    472  1.1  skrll   else
    473  1.1  skrll     {
    474  1.1  skrll       register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
    475  1.1  skrll       unsigned int counter = 0;
    476  1.1  skrll       arelent *cache_ptr = reloc_cache;
    477  1.1  skrll 
    478  1.1  skrll       for (; counter < count; counter++, rptr++, cache_ptr++)
    479  1.1  skrll 	{
    480  1.1  skrll 	  NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
    481  1.1  skrll 					(bfd_size_type) bfd_get_symcount (abfd));
    482  1.1  skrll 	}
    483  1.1  skrll 
    484  1.1  skrll     }
    485  1.1  skrll 
    486  1.1  skrll   bfd_release (abfd, relocs);
    487  1.1  skrll   asect->relocation = reloc_cache;
    488  1.1  skrll   asect->reloc_count = count;
    489  1.1  skrll   return TRUE;
    490  1.1  skrll }
    491  1.1  skrll 
    492  1.1  skrll 
    493  1.1  skrll 
    494  1.1  skrll /* Write out a relocation section into an object file.  */
    495  1.1  skrll 
    496  1.1  skrll bfd_boolean
    497  1.1  skrll NAME(lynx,squirt_out_relocs) (abfd, section)
    498  1.1  skrll      bfd *abfd;
    499  1.1  skrll      asection *section;
    500  1.1  skrll {
    501  1.1  skrll   arelent **generic;
    502  1.1  skrll   unsigned char *native, *natptr;
    503  1.1  skrll   size_t each_size;
    504  1.1  skrll 
    505  1.1  skrll   unsigned int count = section->reloc_count;
    506  1.1  skrll   bfd_size_type natsize;
    507  1.1  skrll 
    508  1.1  skrll   if (count == 0)
    509  1.1  skrll     return TRUE;
    510  1.1  skrll 
    511  1.1  skrll   each_size = obj_reloc_entry_size (abfd);
    512  1.1  skrll   natsize = count;
    513  1.1  skrll   natsize *= each_size;
    514  1.1  skrll   native = (unsigned char *) bfd_zalloc (abfd, natsize);
    515  1.1  skrll   if (!native)
    516  1.1  skrll     return FALSE;
    517  1.1  skrll 
    518  1.1  skrll   generic = section->orelocation;
    519  1.1  skrll 
    520  1.1  skrll   if (each_size == RELOC_EXT_SIZE)
    521  1.1  skrll     {
    522  1.1  skrll       for (natptr = native;
    523  1.1  skrll 	   count != 0;
    524  1.1  skrll 	   --count, natptr += each_size, ++generic)
    525  1.1  skrll 	NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
    526  1.1  skrll     }
    527  1.1  skrll   else
    528  1.1  skrll     {
    529  1.1  skrll       for (natptr = native;
    530  1.1  skrll 	   count != 0;
    531  1.1  skrll 	   --count, natptr += each_size, ++generic)
    532  1.1  skrll 	NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
    533  1.1  skrll     }
    534  1.1  skrll 
    535  1.1  skrll   if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
    536  1.1  skrll     {
    537  1.1  skrll       bfd_release (abfd, native);
    538  1.1  skrll       return FALSE;
    539  1.1  skrll     }
    540  1.1  skrll   bfd_release (abfd, native);
    541  1.1  skrll 
    542  1.1  skrll   return TRUE;
    543  1.1  skrll }
    544  1.1  skrll 
    545  1.1  skrll /* This is stupid.  This function should be a boolean predicate */
    546  1.1  skrll long
    547  1.1  skrll NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
    548  1.1  skrll      bfd *abfd;
    549  1.1  skrll      sec_ptr section;
    550  1.1  skrll      arelent **relptr;
    551  1.1  skrll      asymbol **symbols;
    552  1.1  skrll {
    553  1.1  skrll   arelent *tblptr = section->relocation;
    554  1.1  skrll   unsigned int count;
    555  1.1  skrll 
    556  1.1  skrll   if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
    557  1.1  skrll     return -1;
    558  1.1  skrll 
    559  1.1  skrll   if (section->flags & SEC_CONSTRUCTOR)
    560  1.1  skrll     {
    561  1.1  skrll       arelent_chain *chain = section->constructor_chain;
    562  1.1  skrll       for (count = 0; count < section->reloc_count; count++)
    563  1.1  skrll 	{
    564  1.1  skrll 	  *relptr++ = &chain->relent;
    565  1.1  skrll 	  chain = chain->next;
    566  1.1  skrll 	}
    567  1.1  skrll     }
    568  1.1  skrll   else
    569  1.1  skrll     {
    570  1.1  skrll       tblptr = section->relocation;
    571  1.1  skrll 
    572  1.1  skrll       for (count = 0; count++ < section->reloc_count;)
    573  1.1  skrll 	{
    574  1.1  skrll 	  *relptr++ = tblptr++;
    575  1.1  skrll 	}
    576  1.1  skrll     }
    577  1.1  skrll   *relptr = 0;
    578  1.1  skrll 
    579  1.1  skrll   return section->reloc_count;
    580  1.1  skrll }
    581  1.1  skrll 
    582  1.1  skrll #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
    583  1.1  skrll 
    584             #include "aout-target.h"
    585