xref: /openbsd-src/gnu/usr.bin/binutils/bfd/i386lynx.c (revision c074d1c999f3e07019cd5e9a2f190b057ef3b935)
12159047fSniklas /* BFD back-end for i386 a.out binaries under LynxOS.
2*c074d1c9Sdrahn    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2001, 2002, 2003
3b305b0f1Sespie    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas This file is part of BFD, the Binary File Descriptor library.
62159047fSniklas 
72159047fSniklas This program is free software; you can redistribute it and/or modify
82159047fSniklas it under the terms of the GNU General Public License as published by
92159047fSniklas the Free Software Foundation; either version 2 of the License, or
102159047fSniklas (at your option) any later version.
112159047fSniklas 
122159047fSniklas This program is distributed in the hope that it will be useful,
132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152159047fSniklas GNU General Public License for more details.
162159047fSniklas 
172159047fSniklas You should have received a copy of the GNU General Public License
182159047fSniklas along with this program; if not, write to the Free Software
192159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
202159047fSniklas 
212159047fSniklas #define N_SHARED_LIB(x) 0
222159047fSniklas 
232159047fSniklas #define TEXT_START_ADDR 0
242159047fSniklas #define TARGET_PAGE_SIZE 4096
252159047fSniklas #define SEGMENT_SIZE TARGET_PAGE_SIZE
262159047fSniklas #define DEFAULT_ARCH bfd_arch_i386
272159047fSniklas 
28*c074d1c9Sdrahn /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
29*c074d1c9Sdrahn    remove whitespace added here, and thus will fail to concatenate
30*c074d1c9Sdrahn    the tokens.  */
31*c074d1c9Sdrahn #define MY(OP) CONCAT2 (i386lynx_aout_,OP)
322159047fSniklas #define TARGETNAME "a.out-i386-lynx"
332159047fSniklas 
342159047fSniklas #include "bfd.h"
352159047fSniklas #include "sysdep.h"
362159047fSniklas #include "libbfd.h"
372159047fSniklas 
382159047fSniklas #ifndef WRITE_HEADERS
392159047fSniklas #define WRITE_HEADERS(abfd, execp)					      \
402159047fSniklas       {									      \
412159047fSniklas 	bfd_size_type text_size; /* dummy vars */			      \
422159047fSniklas 	file_ptr text_end;						      \
432159047fSniklas 	if (adata(abfd).magic == undecided_magic)			      \
442159047fSniklas 	  NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);     \
452159047fSniklas     									      \
462159047fSniklas 	execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;	      \
472159047fSniklas 	execp->a_entry = bfd_get_start_address (abfd);			      \
482159047fSniklas     									      \
492159047fSniklas 	execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *		      \
502159047fSniklas 			   obj_reloc_entry_size (abfd));		      \
512159047fSniklas 	execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *		      \
522159047fSniklas 			   obj_reloc_entry_size (abfd));		      \
532159047fSniklas 	NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);	      \
542159047fSniklas 									      \
55*c074d1c9Sdrahn 	if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0		      \
56*c074d1c9Sdrahn 	    || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
57*c074d1c9Sdrahn 			  abfd) != EXEC_BYTES_SIZE)			      \
58*c074d1c9Sdrahn 	  return FALSE;							      \
592159047fSniklas 	/* Now write out reloc info, followed by syms and strings */	      \
602159047fSniklas   									      \
612159047fSniklas 	if (bfd_get_symcount (abfd) != 0) 				      \
622159047fSniklas 	    {								      \
632159047fSniklas 	      if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET)    \
642159047fSniklas 		  != 0)							      \
65*c074d1c9Sdrahn 	        return FALSE;						      \
662159047fSniklas 									      \
67*c074d1c9Sdrahn 	      if (! NAME(aout,write_syms) (abfd)) return FALSE;		      \
682159047fSniklas 									      \
692159047fSniklas 	      if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET)   \
702159047fSniklas 		  != 0)							      \
71*c074d1c9Sdrahn 	        return FALSE;						      \
722159047fSniklas 									      \
732159047fSniklas 	      if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd)))   \
74*c074d1c9Sdrahn 		return FALSE;						      \
752159047fSniklas 	      if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET)   \
762159047fSniklas 		  != 0)							      \
772159047fSniklas 	        return 0;						      \
782159047fSniklas 									      \
792159047fSniklas 	      if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd)))   \
80*c074d1c9Sdrahn 		return FALSE;						      \
812159047fSniklas 	    }								      \
822159047fSniklas       }
832159047fSniklas #endif
842159047fSniklas 
852159047fSniklas #include "libaout.h"
862159047fSniklas #include "aout/aout64.h"
872159047fSniklas 
88*c074d1c9Sdrahn void NAME (lynx,swap_std_reloc_out)
89*c074d1c9Sdrahn   PARAMS ((bfd *, arelent *, struct reloc_std_external *));
90*c074d1c9Sdrahn void NAME (lynx,swap_ext_reloc_out)
91*c074d1c9Sdrahn   PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
92*c074d1c9Sdrahn void NAME (lynx,swap_ext_reloc_in)
93*c074d1c9Sdrahn   PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **,
94*c074d1c9Sdrahn 	   bfd_size_type));
95*c074d1c9Sdrahn void NAME (lynx,swap_std_reloc_in)
96*c074d1c9Sdrahn   PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **,
97*c074d1c9Sdrahn 	   bfd_size_type));
98*c074d1c9Sdrahn bfd_boolean NAME (lynx,slurp_reloc_table)
99*c074d1c9Sdrahn   PARAMS ((bfd *, sec_ptr, asymbol **));
100*c074d1c9Sdrahn bfd_boolean NAME (lynx,squirt_out_relocs)
101*c074d1c9Sdrahn   PARAMS ((bfd *, asection *));
102*c074d1c9Sdrahn long NAME (lynx,canonicalize_reloc)
103*c074d1c9Sdrahn   PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
104*c074d1c9Sdrahn 
1052159047fSniklas #ifdef LYNX_CORE
1062159047fSniklas 
1072159047fSniklas char *lynx_core_file_failing_command ();
1082159047fSniklas int lynx_core_file_failing_signal ();
109*c074d1c9Sdrahn bfd_boolean lynx_core_file_matches_executable_p ();
1102159047fSniklas const bfd_target *lynx_core_file_p ();
1112159047fSniklas 
1122159047fSniklas #define	MY_core_file_failing_command lynx_core_file_failing_command
1132159047fSniklas #define	MY_core_file_failing_signal lynx_core_file_failing_signal
1142159047fSniklas #define	MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
1152159047fSniklas #define	MY_core_file_p lynx_core_file_p
1162159047fSniklas 
1172159047fSniklas #endif /* LYNX_CORE */
1182159047fSniklas 
1192159047fSniklas 
1200c6d0228Sniklas #define KEEPIT udata.i
1212159047fSniklas 
1222159047fSniklas extern reloc_howto_type aout_32_ext_howto_table[];
1232159047fSniklas extern reloc_howto_type aout_32_std_howto_table[];
1242159047fSniklas 
1252159047fSniklas /* Standard reloc stuff */
1262159047fSniklas /* Output standard relocation information to a file in target byte order. */
1272159047fSniklas 
1282159047fSniklas void
1292159047fSniklas NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
1302159047fSniklas      bfd *abfd;
1312159047fSniklas      arelent *g;
1322159047fSniklas      struct reloc_std_external *natptr;
1332159047fSniklas {
1342159047fSniklas   int r_index;
1352159047fSniklas   asymbol *sym = *(g->sym_ptr_ptr);
1362159047fSniklas   int r_extern;
1372159047fSniklas   unsigned int r_length;
1382159047fSniklas   int r_pcrel;
1392159047fSniklas   int r_baserel, r_jmptable, r_relative;
1402159047fSniklas   unsigned int r_addend;
1412159047fSniklas   asection *output_section = sym->section->output_section;
1422159047fSniklas 
1432159047fSniklas   PUT_WORD (abfd, g->address, natptr->r_address);
1442159047fSniklas 
1452159047fSniklas   r_length = g->howto->size;	/* Size as a power of two */
1462159047fSniklas   r_pcrel = (int) g->howto->pc_relative;	/* Relative to PC? */
1472159047fSniklas   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1482159047fSniklas   r_baserel = 0;
1492159047fSniklas   r_jmptable = 0;
1502159047fSniklas   r_relative = 0;
1512159047fSniklas 
1522159047fSniklas   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1532159047fSniklas 
1542159047fSniklas   /* name was clobbered by aout_write_syms to be symbol index */
1552159047fSniklas 
1562159047fSniklas   /* If this relocation is relative to a symbol then set the
1572159047fSniklas      r_index to the symbols index, and the r_extern bit.
1582159047fSniklas 
1592159047fSniklas      Absolute symbols can come in in two ways, either as an offset
1602159047fSniklas      from the abs section, or as a symbol which has an abs value.
1612159047fSniklas      check for that here
1622159047fSniklas   */
1632159047fSniklas 
1642159047fSniklas 
1652159047fSniklas   if (bfd_is_com_section (output_section)
1662159047fSniklas       || bfd_is_abs_section (output_section)
1672159047fSniklas       || bfd_is_und_section (output_section))
1682159047fSniklas     {
1692159047fSniklas       if (bfd_abs_section_ptr->symbol == sym)
1702159047fSniklas 	{
1712159047fSniklas 	  /* Whoops, looked like an abs symbol, but is really an offset
1722159047fSniklas 	     from the abs section */
1732159047fSniklas 	  r_index = 0;
1742159047fSniklas 	  r_extern = 0;
1752159047fSniklas 	}
1762159047fSniklas       else
1772159047fSniklas 	{
1782159047fSniklas 	  /* Fill in symbol */
1792159047fSniklas 	  r_extern = 1;
1800c6d0228Sniklas 	  r_index = (*g->sym_ptr_ptr)->KEEPIT;
1812159047fSniklas 	}
1822159047fSniklas     }
1832159047fSniklas   else
1842159047fSniklas     {
1852159047fSniklas       /* Just an ordinary section */
1862159047fSniklas       r_extern = 0;
1872159047fSniklas       r_index = output_section->target_index;
1882159047fSniklas     }
1892159047fSniklas 
1902159047fSniklas   /* now the fun stuff */
191c88b1d6cSniklas   if (bfd_header_big_endian (abfd))
1922159047fSniklas     {
1932159047fSniklas       natptr->r_index[0] = r_index >> 16;
1942159047fSniklas       natptr->r_index[1] = r_index >> 8;
1952159047fSniklas       natptr->r_index[2] = r_index;
1962159047fSniklas       natptr->r_type[0] =
1972159047fSniklas 	(r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
1982159047fSniklas 	| (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
1992159047fSniklas 	| (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
2002159047fSniklas 	| (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
2012159047fSniklas 	| (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
2022159047fSniklas 	| (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
2032159047fSniklas     }
2042159047fSniklas   else
2052159047fSniklas     {
2062159047fSniklas       natptr->r_index[2] = r_index >> 16;
2072159047fSniklas       natptr->r_index[1] = r_index >> 8;
2082159047fSniklas       natptr->r_index[0] = r_index;
2092159047fSniklas       natptr->r_type[0] =
2102159047fSniklas 	(r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
2112159047fSniklas 	| (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
2122159047fSniklas 	| (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
2132159047fSniklas 	| (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
2142159047fSniklas 	| (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
2152159047fSniklas 	| (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
2162159047fSniklas     }
2172159047fSniklas }
2182159047fSniklas 
2192159047fSniklas 
2202159047fSniklas /* Extended stuff */
2212159047fSniklas /* Output extended relocation information to a file in target byte order. */
2222159047fSniklas 
2232159047fSniklas void
2242159047fSniklas NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
2252159047fSniklas      bfd *abfd;
2262159047fSniklas      arelent *g;
2272159047fSniklas      register struct reloc_ext_external *natptr;
2282159047fSniklas {
2292159047fSniklas   int r_index;
2302159047fSniklas   int r_extern;
2312159047fSniklas   unsigned int r_type;
2322159047fSniklas   unsigned int r_addend;
2332159047fSniklas   asymbol *sym = *(g->sym_ptr_ptr);
2342159047fSniklas   asection *output_section = sym->section->output_section;
2352159047fSniklas 
2362159047fSniklas   PUT_WORD (abfd, g->address, natptr->r_address);
2372159047fSniklas 
2382159047fSniklas   r_type = (unsigned int) g->howto->type;
2392159047fSniklas 
2402159047fSniklas   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2412159047fSniklas 
2422159047fSniklas 
2432159047fSniklas   /* If this relocation is relative to a symbol then set the
2442159047fSniklas      r_index to the symbols index, and the r_extern bit.
2452159047fSniklas 
2462159047fSniklas      Absolute symbols can come in in two ways, either as an offset
2472159047fSniklas      from the abs section, or as a symbol which has an abs value.
2482159047fSniklas      check for that here
2492159047fSniklas      */
2502159047fSniklas 
2512159047fSniklas   if (bfd_is_com_section (output_section)
2522159047fSniklas       || bfd_is_abs_section (output_section)
2532159047fSniklas       || bfd_is_und_section (output_section))
2542159047fSniklas     {
2552159047fSniklas       if (bfd_abs_section_ptr->symbol == sym)
2562159047fSniklas 	{
2572159047fSniklas 	  /* Whoops, looked like an abs symbol, but is really an offset
2582159047fSniklas 	 from the abs section */
2592159047fSniklas 	  r_index = 0;
2602159047fSniklas 	  r_extern = 0;
2612159047fSniklas 	}
2622159047fSniklas       else
2632159047fSniklas 	{
2642159047fSniklas 	  r_extern = 1;
2650c6d0228Sniklas 	  r_index = (*g->sym_ptr_ptr)->KEEPIT;
2662159047fSniklas 	}
2672159047fSniklas     }
2682159047fSniklas   else
2692159047fSniklas     {
2702159047fSniklas       /* Just an ordinary section */
2712159047fSniklas       r_extern = 0;
2722159047fSniklas       r_index = output_section->target_index;
2732159047fSniklas     }
2742159047fSniklas 
2752159047fSniklas 
2762159047fSniklas   /* now the fun stuff */
277c88b1d6cSniklas   if (bfd_header_big_endian (abfd))
2782159047fSniklas     {
2792159047fSniklas       natptr->r_index[0] = r_index >> 16;
2802159047fSniklas       natptr->r_index[1] = r_index >> 8;
2812159047fSniklas       natptr->r_index[2] = r_index;
2822159047fSniklas       natptr->r_type[0] =
2832159047fSniklas 	(r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
2842159047fSniklas 	| (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
2852159047fSniklas     }
2862159047fSniklas   else
2872159047fSniklas     {
2882159047fSniklas       natptr->r_index[2] = r_index >> 16;
2892159047fSniklas       natptr->r_index[1] = r_index >> 8;
2902159047fSniklas       natptr->r_index[0] = r_index;
2912159047fSniklas       natptr->r_type[0] =
2922159047fSniklas 	(r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
2932159047fSniklas 	| (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2942159047fSniklas     }
2952159047fSniklas 
2962159047fSniklas   PUT_WORD (abfd, r_addend, natptr->r_addend);
2972159047fSniklas }
2982159047fSniklas 
2992159047fSniklas /* BFD deals internally with all things based from the section they're
3002159047fSniklas    in. so, something in 10 bytes into a text section  with a base of
3012159047fSniklas    50 would have a symbol (.text+10) and know .text vma was 50.
3022159047fSniklas 
3032159047fSniklas    Aout keeps all it's symbols based from zero, so the symbol would
3042159047fSniklas    contain 60. This macro subs the base of each section from the value
3052159047fSniklas    to give the true offset from the section */
3062159047fSniklas 
3072159047fSniklas 
3082159047fSniklas #define MOVE_ADDRESS(ad)       						\
3092159047fSniklas   if (r_extern) {							\
3102159047fSniklas    /* undefined symbol */						\
3112159047fSniklas      cache_ptr->sym_ptr_ptr = symbols + r_index;			\
3122159047fSniklas      cache_ptr->addend = ad;						\
3132159047fSniklas      } else {								\
3142159047fSniklas     /* defined, section relative. replace symbol with pointer to    	\
3152159047fSniklas        symbol which points to section  */				\
3162159047fSniklas     switch (r_index) {							\
3172159047fSniklas     case N_TEXT:							\
3182159047fSniklas     case N_TEXT | N_EXT:						\
3192159047fSniklas       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;	\
3202159047fSniklas       cache_ptr->addend = ad  - su->textsec->vma;			\
3212159047fSniklas       break;								\
3222159047fSniklas     case N_DATA:							\
3232159047fSniklas     case N_DATA | N_EXT:						\
3242159047fSniklas       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;	\
3252159047fSniklas       cache_ptr->addend = ad - su->datasec->vma;			\
3262159047fSniklas       break;								\
3272159047fSniklas     case N_BSS:								\
3282159047fSniklas     case N_BSS | N_EXT:							\
3292159047fSniklas       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;	\
3302159047fSniklas       cache_ptr->addend = ad - su->bsssec->vma;				\
3312159047fSniklas       break;								\
3322159047fSniklas     default:								\
3332159047fSniklas     case N_ABS:								\
3342159047fSniklas     case N_ABS | N_EXT:							\
3352159047fSniklas      cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	\
3362159047fSniklas       cache_ptr->addend = ad;						\
3372159047fSniklas       break;								\
3382159047fSniklas     }									\
3392159047fSniklas   }     								\
3402159047fSniklas 
3412159047fSniklas void
3422159047fSniklas NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
3432159047fSniklas      bfd *abfd;
3442159047fSniklas      struct reloc_ext_external *bytes;
3452159047fSniklas      arelent *cache_ptr;
3462159047fSniklas      asymbol **symbols;
347b305b0f1Sespie      bfd_size_type symcount ATTRIBUTE_UNUSED;
3482159047fSniklas {
3492159047fSniklas   int r_index;
3502159047fSniklas   int r_extern;
3512159047fSniklas   unsigned int r_type;
3522159047fSniklas   struct aoutdata *su = &(abfd->tdata.aout_data->a);
3532159047fSniklas 
3542159047fSniklas   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
3552159047fSniklas 
3562159047fSniklas   r_index = bytes->r_index[1];
3572159047fSniklas   r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
3582159047fSniklas   r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
3592159047fSniklas     >> RELOC_EXT_BITS_TYPE_SH_BIG;
3602159047fSniklas 
3612159047fSniklas   cache_ptr->howto = aout_32_ext_howto_table + r_type;
3622159047fSniklas   MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
3632159047fSniklas }
3642159047fSniklas 
3652159047fSniklas void
3662159047fSniklas NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
3672159047fSniklas      bfd *abfd;
3682159047fSniklas      struct reloc_std_external *bytes;
3692159047fSniklas      arelent *cache_ptr;
3702159047fSniklas      asymbol **symbols;
371b305b0f1Sespie      bfd_size_type symcount ATTRIBUTE_UNUSED;
3722159047fSniklas {
3732159047fSniklas   int r_index;
3742159047fSniklas   int r_extern;
3752159047fSniklas   unsigned int r_length;
3762159047fSniklas   int r_pcrel;
3772159047fSniklas   int r_baserel, r_jmptable, r_relative;
3782159047fSniklas   struct aoutdata *su = &(abfd->tdata.aout_data->a);
3792159047fSniklas 
380*c074d1c9Sdrahn   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
3812159047fSniklas 
3822159047fSniklas   r_index = bytes->r_index[1];
3832159047fSniklas   r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
3842159047fSniklas   r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
3852159047fSniklas   r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
3862159047fSniklas   r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
3872159047fSniklas   r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
3882159047fSniklas   r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
3892159047fSniklas     >> RELOC_STD_BITS_LENGTH_SH_BIG;
3902159047fSniklas 
3912159047fSniklas   cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
3922159047fSniklas   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
3932159047fSniklas 
3942159047fSniklas   MOVE_ADDRESS (0);
3952159047fSniklas }
3962159047fSniklas 
3972159047fSniklas /* Reloc hackery */
3982159047fSniklas 
399*c074d1c9Sdrahn bfd_boolean
4002159047fSniklas NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
4012159047fSniklas      bfd *abfd;
4022159047fSniklas      sec_ptr asect;
4032159047fSniklas      asymbol **symbols;
4042159047fSniklas {
405*c074d1c9Sdrahn   bfd_size_type count;
4062159047fSniklas   bfd_size_type reloc_size;
4072159047fSniklas   PTR relocs;
4082159047fSniklas   arelent *reloc_cache;
4092159047fSniklas   size_t each_size;
4102159047fSniklas 
4112159047fSniklas   if (asect->relocation)
412*c074d1c9Sdrahn     return TRUE;
4132159047fSniklas 
4142159047fSniklas   if (asect->flags & SEC_CONSTRUCTOR)
415*c074d1c9Sdrahn     return TRUE;
4162159047fSniklas 
4172159047fSniklas   if (asect == obj_datasec (abfd))
4182159047fSniklas     {
4192159047fSniklas       reloc_size = exec_hdr (abfd)->a_drsize;
4202159047fSniklas       goto doit;
4212159047fSniklas     }
4222159047fSniklas 
4232159047fSniklas   if (asect == obj_textsec (abfd))
4242159047fSniklas     {
4252159047fSniklas       reloc_size = exec_hdr (abfd)->a_trsize;
4262159047fSniklas       goto doit;
4272159047fSniklas     }
4282159047fSniklas 
4292159047fSniklas   bfd_set_error (bfd_error_invalid_operation);
430*c074d1c9Sdrahn   return FALSE;
4312159047fSniklas 
4322159047fSniklas doit:
4332159047fSniklas   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
434*c074d1c9Sdrahn     return FALSE;
4352159047fSniklas   each_size = obj_reloc_entry_size (abfd);
4362159047fSniklas 
4372159047fSniklas   count = reloc_size / each_size;
4382159047fSniklas 
4392159047fSniklas 
440*c074d1c9Sdrahn   reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
4412159047fSniklas   if (!reloc_cache && count != 0)
442*c074d1c9Sdrahn     return FALSE;
4432159047fSniklas 
4442159047fSniklas   relocs = (PTR) bfd_alloc (abfd, reloc_size);
4452159047fSniklas   if (!relocs && reloc_size != 0)
4462159047fSniklas     {
4472159047fSniklas       free (reloc_cache);
448*c074d1c9Sdrahn       return FALSE;
4492159047fSniklas     }
4502159047fSniklas 
451*c074d1c9Sdrahn   if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
4522159047fSniklas     {
4532159047fSniklas       bfd_release (abfd, relocs);
4542159047fSniklas       free (reloc_cache);
455*c074d1c9Sdrahn       return FALSE;
4562159047fSniklas     }
4572159047fSniklas 
4582159047fSniklas   if (each_size == RELOC_EXT_SIZE)
4592159047fSniklas     {
4602159047fSniklas       register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
4612159047fSniklas       unsigned int counter = 0;
4622159047fSniklas       arelent *cache_ptr = reloc_cache;
4632159047fSniklas 
4642159047fSniklas       for (; counter < count; counter++, rptr++, cache_ptr++)
4652159047fSniklas 	{
4662159047fSniklas 	  NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
467*c074d1c9Sdrahn 					(bfd_size_type) bfd_get_symcount (abfd));
4682159047fSniklas 	}
4692159047fSniklas     }
4702159047fSniklas   else
4712159047fSniklas     {
4722159047fSniklas       register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
4732159047fSniklas       unsigned int counter = 0;
4742159047fSniklas       arelent *cache_ptr = reloc_cache;
4752159047fSniklas 
4762159047fSniklas       for (; counter < count; counter++, rptr++, cache_ptr++)
4772159047fSniklas 	{
4782159047fSniklas 	  NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
479*c074d1c9Sdrahn 					(bfd_size_type) bfd_get_symcount (abfd));
4802159047fSniklas 	}
4812159047fSniklas 
4822159047fSniklas     }
4832159047fSniklas 
4842159047fSniklas   bfd_release (abfd, relocs);
4852159047fSniklas   asect->relocation = reloc_cache;
4862159047fSniklas   asect->reloc_count = count;
487*c074d1c9Sdrahn   return TRUE;
4882159047fSniklas }
4892159047fSniklas 
4902159047fSniklas 
4912159047fSniklas 
4922159047fSniklas /* Write out a relocation section into an object file.  */
4932159047fSniklas 
494*c074d1c9Sdrahn bfd_boolean
4952159047fSniklas NAME(lynx,squirt_out_relocs) (abfd, section)
4962159047fSniklas      bfd *abfd;
4972159047fSniklas      asection *section;
4982159047fSniklas {
4992159047fSniklas   arelent **generic;
5002159047fSniklas   unsigned char *native, *natptr;
5012159047fSniklas   size_t each_size;
5022159047fSniklas 
5032159047fSniklas   unsigned int count = section->reloc_count;
504*c074d1c9Sdrahn   bfd_size_type natsize;
5052159047fSniklas 
5062159047fSniklas   if (count == 0)
507*c074d1c9Sdrahn     return TRUE;
5082159047fSniklas 
5092159047fSniklas   each_size = obj_reloc_entry_size (abfd);
510*c074d1c9Sdrahn   natsize = count;
511*c074d1c9Sdrahn   natsize *= each_size;
5122159047fSniklas   native = (unsigned char *) bfd_zalloc (abfd, natsize);
5132159047fSniklas   if (!native)
514*c074d1c9Sdrahn     return FALSE;
5152159047fSniklas 
5162159047fSniklas   generic = section->orelocation;
5172159047fSniklas 
5182159047fSniklas   if (each_size == RELOC_EXT_SIZE)
5192159047fSniklas     {
5202159047fSniklas       for (natptr = native;
5212159047fSniklas 	   count != 0;
5222159047fSniklas 	   --count, natptr += each_size, ++generic)
5232159047fSniklas 	NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
5242159047fSniklas     }
5252159047fSniklas   else
5262159047fSniklas     {
5272159047fSniklas       for (natptr = native;
5282159047fSniklas 	   count != 0;
5292159047fSniklas 	   --count, natptr += each_size, ++generic)
5302159047fSniklas 	NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
5312159047fSniklas     }
5322159047fSniklas 
533*c074d1c9Sdrahn   if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
5342159047fSniklas     {
5352159047fSniklas       bfd_release (abfd, native);
536*c074d1c9Sdrahn       return FALSE;
5372159047fSniklas     }
5382159047fSniklas   bfd_release (abfd, native);
5392159047fSniklas 
540*c074d1c9Sdrahn   return TRUE;
5412159047fSniklas }
5422159047fSniklas 
5432159047fSniklas /* This is stupid.  This function should be a boolean predicate */
5442159047fSniklas long
5452159047fSniklas NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
5462159047fSniklas      bfd *abfd;
5472159047fSniklas      sec_ptr section;
5482159047fSniklas      arelent **relptr;
5492159047fSniklas      asymbol **symbols;
5502159047fSniklas {
5512159047fSniklas   arelent *tblptr = section->relocation;
5522159047fSniklas   unsigned int count;
5532159047fSniklas 
5542159047fSniklas   if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
5552159047fSniklas     return -1;
5562159047fSniklas 
5572159047fSniklas   if (section->flags & SEC_CONSTRUCTOR)
5582159047fSniklas     {
5592159047fSniklas       arelent_chain *chain = section->constructor_chain;
5602159047fSniklas       for (count = 0; count < section->reloc_count; count++)
5612159047fSniklas 	{
5622159047fSniklas 	  *relptr++ = &chain->relent;
5632159047fSniklas 	  chain = chain->next;
5642159047fSniklas 	}
5652159047fSniklas     }
5662159047fSniklas   else
5672159047fSniklas     {
5682159047fSniklas       tblptr = section->relocation;
5692159047fSniklas 
5702159047fSniklas       for (count = 0; count++ < section->reloc_count;)
5712159047fSniklas 	{
5722159047fSniklas 	  *relptr++ = tblptr++;
5732159047fSniklas 	}
5742159047fSniklas     }
5752159047fSniklas   *relptr = 0;
5762159047fSniklas 
5772159047fSniklas   return section->reloc_count;
5782159047fSniklas }
5792159047fSniklas 
5802159047fSniklas #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
5812159047fSniklas 
5822159047fSniklas #include "aout-target.h"
583