xref: /openbsd-src/gnu/usr.bin/binutils/bfd/aout-ns32k.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* BFD back-end for ns32k a.out-ish binaries.
2c074d1c9Sdrahn    Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003
3b55d4692Sfgsch    Free Software Foundation, Inc.
42159047fSniklas    Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
52159047fSniklas 
62159047fSniklas    This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas 
82159047fSniklas    This program is free software; you can redistribute it and/or modify
92159047fSniklas    it under the terms of the GNU General Public License as published by
102159047fSniklas    the Free Software Foundation; either version 2 of the License, or
112159047fSniklas    (at your option) any later version.
122159047fSniklas 
132159047fSniklas    This program is distributed in the hope that it will be useful,
142159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162159047fSniklas    GNU General Public License for more details.
172159047fSniklas 
182159047fSniklas    You should have received a copy of the GNU General Public License
192159047fSniklas    along with this program; if not, write to the Free Software
202159047fSniklas    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
212159047fSniklas 
222159047fSniklas #include "bfd.h"
232159047fSniklas #include "aout/aout64.h"
24c88b1d6cSniklas #include "ns32k.h"
252159047fSniklas 
26c074d1c9Sdrahn /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
27c074d1c9Sdrahn    remove whitespace added here, and thus will fail to concatenate
28c074d1c9Sdrahn    the tokens.  */
29c074d1c9Sdrahn #define MYNS(OP) CONCAT2 (ns32kaout_,OP)
30c074d1c9Sdrahn 
312159047fSniklas reloc_howto_type *
322159047fSniklas MYNS(bfd_reloc_type_lookup)
332159047fSniklas   PARAMS((bfd *abfd AND
342159047fSniklas 	  bfd_reloc_code_real_type code));
352159047fSniklas 
36c074d1c9Sdrahn bfd_boolean
372159047fSniklas MYNS(write_object_contents)
382159047fSniklas   PARAMS((bfd *abfd));
392159047fSniklas 
40c074d1c9Sdrahn /* Avoid multiple definitions from aoutx if supporting
41c074d1c9Sdrahn    standard a.out format(s) as well as this one.  */
42c074d1c9Sdrahn #define NAME(x,y) CONCAT3 (ns32kaout,_32_,y)
432159047fSniklas 
442159047fSniklas void bfd_ns32k_arch PARAMS ((void));
452159047fSniklas 
462159047fSniklas #include "libaout.h"
472159047fSniklas 
482159047fSniklas #define MY(OP) MYNS(OP)
492159047fSniklas 
502159047fSniklas #define MY_swap_std_reloc_in  MY(swap_std_reloc_in)
512159047fSniklas #define MY_swap_std_reloc_out MY(swap_std_reloc_out)
522159047fSniklas 
532159047fSniklas static void
54c074d1c9Sdrahn MY_swap_std_reloc_in PARAMS ((bfd *, struct reloc_std_external *,
55c074d1c9Sdrahn 			      arelent *, asymbol **,
56c074d1c9Sdrahn 			      bfd_size_type));
572159047fSniklas static void
58c074d1c9Sdrahn MY_swap_std_reloc_out PARAMS ((bfd *, arelent *,
59c074d1c9Sdrahn 			       struct reloc_std_external *));
60c074d1c9Sdrahn reloc_howto_type *
61c074d1c9Sdrahn MY(reloc_howto) PARAMS ((bfd *, struct reloc_std_external *,
62c074d1c9Sdrahn 			 int *, int *, int *));
63c074d1c9Sdrahn void
64c074d1c9Sdrahn MY(put_reloc) PARAMS ((bfd *, int, int, bfd_vma, reloc_howto_type *,
65c074d1c9Sdrahn 		       struct reloc_std_external *));
662159047fSniklas 
672159047fSniklas /* The ns32k series is ah, unusual, when it comes to relocation.
68*007c2a45Smiod    There are three storage methods for relocatable objects.  There
69c074d1c9Sdrahn    are displacements, immediate operands and ordinary twos complement
70c074d1c9Sdrahn    data. Of these, only the last fits into the standard relocation
71c074d1c9Sdrahn    scheme.  Immediate operands are stored huffman encoded and
72c074d1c9Sdrahn    immediate operands are stored big endian (where as the natural byte
73*007c2a45Smiod    order is little endian for this architecture).
742159047fSniklas 
75c074d1c9Sdrahn    Note that the ns32k displacement storage method is orthogonal to
76c074d1c9Sdrahn    whether the relocation is pc relative or not. The "displacement"
77c074d1c9Sdrahn    storage scheme is used for essentially all address constants. The
78c074d1c9Sdrahn    displacement can be relative to zero (absolute displacement),
79c074d1c9Sdrahn    relative to the pc (pc relative), the stack pointer, the frame
80c074d1c9Sdrahn    pointer, the static base register and general purpose register etc.
812159047fSniklas 
82c074d1c9Sdrahn    For example:
83c074d1c9Sdrahn 
84c074d1c9Sdrahn    sym1: .long .	 # pc relative 2's complement
85c074d1c9Sdrahn    sym1: .long foo	 # 2's complement not pc relative
86c074d1c9Sdrahn 
87c074d1c9Sdrahn    self:  movd @self, r0 # pc relative displacement
88c074d1c9Sdrahn           movd foo, r0   # non pc relative displacement
89c074d1c9Sdrahn 
90c074d1c9Sdrahn    self:  movd self, r0  # pc relative immediate
91c074d1c9Sdrahn           movd foo, r0   # non pc relative immediate
92c074d1c9Sdrahn 
93c074d1c9Sdrahn    In addition, for historical reasons the encoding of the relocation types
94c074d1c9Sdrahn    in the a.out format relocation entries is such that even the relocation
95c074d1c9Sdrahn    methods which are standard are not encoded the standard way.  */
962159047fSniklas 
972159047fSniklas reloc_howto_type MY(howto_table)[] =
982159047fSniklas   {
99c074d1c9Sdrahn     /* type           rs   size bsz  pcrel bitpos ovrf                  sf name          part_inpl readmask setmask pcdone */
100c074d1c9Sdrahn     /* ns32k immediate operands.  */
101c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
102c88b1d6cSniklas 	   _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
103c074d1c9Sdrahn 	   TRUE, 0x000000ff,0x000000ff, FALSE),
104c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
105c88b1d6cSniklas 	   _bfd_ns32k_reloc_imm,  "NS32K_IMM_16",
106c074d1c9Sdrahn 	   TRUE, 0x0000ffff,0x0000ffff, FALSE),
107c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
108c88b1d6cSniklas 	   _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
109c074d1c9Sdrahn 	   TRUE, 0xffffffff,0xffffffff, FALSE),
110c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed,
111c88b1d6cSniklas 	   _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
112c074d1c9Sdrahn 	   TRUE, 0x000000ff, 0x000000ff, FALSE),
113c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed,
114c88b1d6cSniklas 	   _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
115c074d1c9Sdrahn 	   TRUE, 0x0000ffff,0x0000ffff, FALSE),
116c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
117c88b1d6cSniklas 	   _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
118c074d1c9Sdrahn 	   TRUE, 0xffffffff,0xffffffff, FALSE),
1192159047fSniklas 
120c074d1c9Sdrahn     /* ns32k displacements.  */
121c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, FALSE, 0, complain_overflow_signed,
122c88b1d6cSniklas 	   _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
123c074d1c9Sdrahn 	   TRUE, 0x000000ff,0x000000ff, FALSE),
124c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, FALSE, 0, complain_overflow_signed,
125c88b1d6cSniklas 	   _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
126c074d1c9Sdrahn 	   TRUE, 0x0000ffff, 0x0000ffff, FALSE),
127c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, FALSE, 0, complain_overflow_signed,
128c88b1d6cSniklas 	   _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
129c074d1c9Sdrahn 	   TRUE, 0xffffffff, 0xffffffff, FALSE),
130c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, TRUE, 0, complain_overflow_signed,
131c88b1d6cSniklas 	   _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
132c074d1c9Sdrahn 	   TRUE, 0x000000ff,0x000000ff, FALSE),
133c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, TRUE, 0, complain_overflow_signed,
134c88b1d6cSniklas 	   _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
135c074d1c9Sdrahn 	   TRUE, 0x0000ffff,0x0000ffff, FALSE),
136c074d1c9Sdrahn     HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, TRUE, 0, complain_overflow_signed,
137c88b1d6cSniklas 	   _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
138c074d1c9Sdrahn 	   TRUE, 0xffffffff,0xffffffff, FALSE),
1392159047fSniklas 
140c074d1c9Sdrahn     /* Normal 2's complement.  */
141c074d1c9Sdrahn     HOWTO (BFD_RELOC_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,0,
142c074d1c9Sdrahn 	   "8", TRUE, 0x000000ff,0x000000ff, FALSE),
143c074d1c9Sdrahn     HOWTO (BFD_RELOC_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,0,
144c074d1c9Sdrahn 	   "16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
145c074d1c9Sdrahn     HOWTO (BFD_RELOC_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,
146c074d1c9Sdrahn 	   "32", TRUE, 0xffffffff,0xffffffff, FALSE),
147c074d1c9Sdrahn     HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0,
148c074d1c9Sdrahn 	   "PCREL_8", TRUE, 0x000000ff,0x000000ff, FALSE),
149c074d1c9Sdrahn     HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0,
150c074d1c9Sdrahn 	   "PCREL_16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
151c074d1c9Sdrahn     HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0,
152c074d1c9Sdrahn 	   "PCREL_32", TRUE, 0xffffffff,0xffffffff, FALSE),
1532159047fSniklas   };
1542159047fSniklas 
1552159047fSniklas #define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14)
1562159047fSniklas 
1572159047fSniklas #define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06
1582159047fSniklas #define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60
1592159047fSniklas #define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1
1602159047fSniklas #define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5
1612159047fSniklas 
1622159047fSniklas reloc_howto_type *
1632159047fSniklas MY(reloc_howto) (abfd, rel, r_index, r_extern, r_pcrel)
164b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
1652159047fSniklas      struct reloc_std_external *rel;
1662159047fSniklas      int *r_index;
1672159047fSniklas      int *r_extern;
1682159047fSniklas      int *r_pcrel;
1692159047fSniklas {
1702159047fSniklas   unsigned int r_length;
1712159047fSniklas   int r_ns32k_type;
172c074d1c9Sdrahn 
173c88b1d6cSniklas   /*  BFD_ASSERT(bfd_header_little_endian (abfd)); */
1742159047fSniklas   *r_index =  ((rel->r_index[2] << 16)
1752159047fSniklas 	       | (rel->r_index[1] << 8)
1762159047fSniklas 	       |  rel->r_index[0] );
1772159047fSniklas   *r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1782159047fSniklas   *r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1792159047fSniklas   r_length  =  ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1802159047fSniklas 		>> RELOC_STD_BITS_LENGTH_SH_LITTLE);
1812159047fSniklas   r_ns32k_type  =  ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE)
1822159047fSniklas 		    >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
1832159047fSniklas   return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type);
1842159047fSniklas }
1852159047fSniklas 
186c074d1c9Sdrahn #define MY_reloc_howto(BFD, REL, IN, EX, PC) \
187c074d1c9Sdrahn   MY(reloc_howto) (BFD, REL, &IN, &EX, &PC)
1882159047fSniklas 
1892159047fSniklas void
1902159047fSniklas MY(put_reloc) (abfd, r_extern, r_index, value, howto, reloc)
1912159047fSniklas      bfd *abfd;
1922159047fSniklas      int r_extern;
1932159047fSniklas      int r_index;
194c074d1c9Sdrahn      bfd_vma value;
1952159047fSniklas      reloc_howto_type *howto;
1962159047fSniklas      struct reloc_std_external *reloc;
1972159047fSniklas {
1982159047fSniklas   unsigned int r_length;
1992159047fSniklas   int r_pcrel;
2002159047fSniklas   int r_ns32k_type;
201c074d1c9Sdrahn 
2022159047fSniklas   PUT_WORD (abfd, value, reloc->r_address);
203c074d1c9Sdrahn   r_length = howto->size ;	/* Size as a power of two.  */
2042159047fSniklas   r_pcrel  = (int) howto->pc_relative; /* Relative to PC?  */
2052159047fSniklas   r_ns32k_type = (howto - MY(howto_table) )/6;
206c074d1c9Sdrahn 
207c88b1d6cSniklas   /*  BFD_ASSERT (bfd_header_little_endian (abfd)); */
2082159047fSniklas   reloc->r_index[2] = r_index >> 16;
2092159047fSniklas   reloc->r_index[1] = r_index >> 8;
2102159047fSniklas   reloc->r_index[0] = r_index;
2112159047fSniklas   reloc->r_type[0] =
2122159047fSniklas     (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
2132159047fSniklas       | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
2142159047fSniklas 	| (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE)
2152159047fSniklas 	  | (r_ns32k_type <<  RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
2162159047fSniklas }
2172159047fSniklas 
2182159047fSniklas #define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
2192159047fSniklas   MY(put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC)
2202159047fSniklas 
2212159047fSniklas #define STAT_FOR_EXEC
2222159047fSniklas 
223c88b1d6cSniklas #define MY_final_link_relocate _bfd_ns32k_final_link_relocate
224c88b1d6cSniklas #define MY_relocate_contents _bfd_ns32k_relocate_contents
2252159047fSniklas 
226c074d1c9Sdrahn #include "aoutx.h"
2272159047fSniklas 
2282159047fSniklas reloc_howto_type *
2292159047fSniklas MY(bfd_reloc_type_lookup) (abfd,code)
2302159047fSniklas      bfd *abfd;
2312159047fSniklas      bfd_reloc_code_real_type code;
2322159047fSniklas {
2332159047fSniklas 
2342159047fSniklas #define ENTRY(i,j)	case i: return &MY(howto_table)[j]
2352159047fSniklas 
2362159047fSniklas   int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
2372159047fSniklas 
2382159047fSniklas   BFD_ASSERT(ext == 0);
2392159047fSniklas   if (code == BFD_RELOC_CTOR)
2402159047fSniklas     switch (bfd_get_arch_info (abfd)->bits_per_address)
2412159047fSniklas       {
2422159047fSniklas       case 32:
2432159047fSniklas 	code = BFD_RELOC_32;
2442159047fSniklas 	break;
245c074d1c9Sdrahn       default:
246c074d1c9Sdrahn 	break;
2472159047fSniklas       }
2482159047fSniklas   switch (code)
2492159047fSniklas     {
2502159047fSniklas       ENTRY(BFD_RELOC_NS32K_IMM_8, 0);
2512159047fSniklas       ENTRY(BFD_RELOC_NS32K_IMM_16, 1);
2522159047fSniklas       ENTRY(BFD_RELOC_NS32K_IMM_32, 2);
2532159047fSniklas       ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3);
2542159047fSniklas       ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4);
2552159047fSniklas       ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5);
2562159047fSniklas       ENTRY(BFD_RELOC_NS32K_DISP_8, 6);
2572159047fSniklas       ENTRY(BFD_RELOC_NS32K_DISP_16, 7);
2582159047fSniklas       ENTRY(BFD_RELOC_NS32K_DISP_32, 8);
2592159047fSniklas       ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9);
2602159047fSniklas       ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10);
2612159047fSniklas       ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11);
2622159047fSniklas       ENTRY(BFD_RELOC_8, 12);
2632159047fSniklas       ENTRY(BFD_RELOC_16, 13);
2642159047fSniklas       ENTRY(BFD_RELOC_32, 14);
2652159047fSniklas       ENTRY(BFD_RELOC_8_PCREL, 15);
2662159047fSniklas       ENTRY(BFD_RELOC_16_PCREL, 16);
2672159047fSniklas       ENTRY(BFD_RELOC_32_PCREL, 17);
268c074d1c9Sdrahn     default:
269c074d1c9Sdrahn       return (reloc_howto_type *) NULL;
2702159047fSniklas     }
2712159047fSniklas #undef ENTRY
2722159047fSniklas }
2732159047fSniklas 
2742159047fSniklas static void
MY_swap_std_reloc_in(abfd,bytes,cache_ptr,symbols,symcount)2752159047fSniklas MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
2762159047fSniklas      bfd *abfd;
2772159047fSniklas      struct reloc_std_external *bytes;
2782159047fSniklas      arelent *cache_ptr;
2792159047fSniklas      asymbol **symbols;
280b305b0f1Sespie      bfd_size_type symcount ATTRIBUTE_UNUSED;
2812159047fSniklas {
2822159047fSniklas   int r_index;
2832159047fSniklas   int r_extern;
2842159047fSniklas   int r_pcrel;
2852159047fSniklas   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
2862159047fSniklas 
287c074d1c9Sdrahn   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
2882159047fSniklas 
289c074d1c9Sdrahn   /* Now the fun stuff.  */
2902159047fSniklas   cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel);
2912159047fSniklas 
2922159047fSniklas   MOVE_ADDRESS (0);
2932159047fSniklas }
2942159047fSniklas 
2952159047fSniklas static void
MY_swap_std_reloc_out(abfd,g,natptr)2962159047fSniklas MY_swap_std_reloc_out (abfd, g, natptr)
2972159047fSniklas      bfd *abfd;
2982159047fSniklas      arelent *g;
2992159047fSniklas      struct reloc_std_external *natptr;
3002159047fSniklas {
3012159047fSniklas   int r_index;
3022159047fSniklas   asymbol *sym = *(g->sym_ptr_ptr);
3032159047fSniklas   int r_extern;
3042159047fSniklas   unsigned int r_addend;
3052159047fSniklas   asection *output_section = sym->section->output_section;
3062159047fSniklas 
3072159047fSniklas   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
3082159047fSniklas 
309c074d1c9Sdrahn   /* Name was clobbered by aout_write_syms to be symbol index.  */
3102159047fSniklas 
3112159047fSniklas   /* If this relocation is relative to a symbol then set the
3122159047fSniklas      r_index to the symbols index, and the r_extern bit.
3132159047fSniklas 
3142159047fSniklas      Absolute symbols can come in in two ways, either as an offset
3152159047fSniklas      from the abs section, or as a symbol which has an abs value.
3162159047fSniklas      Check for that here.  */
3172159047fSniklas   if (bfd_is_com_section (output_section)
3182159047fSniklas       || output_section == &bfd_abs_section
3192159047fSniklas       || output_section == &bfd_und_section)
3202159047fSniklas     {
3212159047fSniklas       if (bfd_abs_section.symbol == sym)
3222159047fSniklas 	{
3232159047fSniklas 	  /* Whoops, looked like an abs symbol, but is really an offset
324c074d1c9Sdrahn 	     from the abs section.  */
3252159047fSniklas 	  r_index = 0;
3262159047fSniklas 	  r_extern = 0;
3272159047fSniklas 	}
3282159047fSniklas       else
3292159047fSniklas 	{
330c074d1c9Sdrahn 	  /* Fill in symbol.  */
3312159047fSniklas 	  r_extern = 1;
3322159047fSniklas #undef KEEPIT
3332159047fSniklas #define KEEPIT udata.i
3342159047fSniklas 	  r_index =  (*(g->sym_ptr_ptr))->KEEPIT;
3352159047fSniklas #undef KEEPIT
3362159047fSniklas 	}
3372159047fSniklas     }
3382159047fSniklas   else
3392159047fSniklas     {
340c074d1c9Sdrahn       /* Just an ordinary section.  */
3412159047fSniklas       r_extern = 0;
3422159047fSniklas       r_index  = output_section->target_index;
3432159047fSniklas     }
3442159047fSniklas 
3452159047fSniklas   MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
3462159047fSniklas }
3472159047fSniklas 
3482159047fSniklas bfd_reloc_status_type
_bfd_ns32k_relocate_contents(howto,input_bfd,relocation,location)349c88b1d6cSniklas _bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
3502159047fSniklas      reloc_howto_type *howto;
3512159047fSniklas      bfd *input_bfd;
3522159047fSniklas      bfd_vma relocation;
3532159047fSniklas      bfd_byte *location;
3542159047fSniklas {
3552159047fSniklas   int r_ns32k_type = (howto - MY(howto_table)) / 6;
356c074d1c9Sdrahn   bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
357c074d1c9Sdrahn   void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
3582159047fSniklas 
3592159047fSniklas   switch (r_ns32k_type)
3602159047fSniklas     {
3612159047fSniklas     case 0:
362c88b1d6cSniklas       get_data = _bfd_ns32k_get_immediate;
363c88b1d6cSniklas       put_data = _bfd_ns32k_put_immediate;
3642159047fSniklas       break;
3652159047fSniklas     case 1:
366c88b1d6cSniklas       get_data = _bfd_ns32k_get_displacement;
367c88b1d6cSniklas       put_data = _bfd_ns32k_put_displacement;
3682159047fSniklas       break;
3692159047fSniklas     case 2:
3702159047fSniklas       return _bfd_relocate_contents (howto, input_bfd, relocation,
3712159047fSniklas 				    location);
3722159047fSniklas       /* NOT REACHED */
3732159047fSniklas       break;
374b305b0f1Sespie     default:
375b305b0f1Sespie       return bfd_reloc_notsupported;
3762159047fSniklas     }
377c88b1d6cSniklas   return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
3782159047fSniklas 				       location, get_data, put_data);
3792159047fSniklas }
380