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