* infttrace.c (child_resume): Simplify and rework to avoid
[deliverable/binutils-gdb.git] / bfd / aout-ns32k.c
CommitLineData
252b5132 1/* BFD back-end for ns32k a.out-ish binaries.
4eb6b71c 2 Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1998, 2000, 2001, 2002
7898deda 3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
5
4eb6b71c 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
4eb6b71c
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
252b5132 12
4eb6b71c
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
252b5132 17
4eb6b71c
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
252b5132
RH
21
22#define BYTES_IN_WORD 4
23
24#include "bfd.h"
25#include "aout/aout64.h"
26#include "ns32k.h"
27
e43d48cc
AM
28/* Do not "beautify" the CONCAT* macro args. Traditional C will not
29 remove whitespace added here, and thus will fail to concatenate
30 the tokens. */
31#define MYNS(OP) CONCAT2 (ns32kaout_,OP)
32
252b5132
RH
33reloc_howto_type *
34MYNS(bfd_reloc_type_lookup)
35 PARAMS((bfd *abfd AND
36 bfd_reloc_code_real_type code));
37
38boolean
39MYNS(write_object_contents)
40 PARAMS((bfd *abfd));
41
1725a96e
NC
42/* Avoid multiple definitions from aoutx if supporting
43 standard a.out format(s) as well as this one. */
e43d48cc 44#define NAME(x,y) CONCAT3 (ns32kaout,_32_,y)
252b5132
RH
45
46void bfd_ns32k_arch PARAMS ((void));
47
48#include "libaout.h"
49
50#define MY(OP) MYNS(OP)
51
4eb6b71c 52#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
252b5132
RH
53#define MY_swap_std_reloc_out MY(swap_std_reloc_out)
54
55static void
4eb6b71c
NC
56MY_swap_std_reloc_in PARAMS ((bfd *, struct reloc_std_external *,
57 arelent *, asymbol **,
58 bfd_size_type));
252b5132 59static void
4eb6b71c
NC
60MY_swap_std_reloc_out PARAMS ((bfd *, arelent *,
61 struct reloc_std_external *));
1725a96e
NC
62reloc_howto_type *
63MY(reloc_howto) PARAMS ((bfd *, struct reloc_std_external *,
64 int *, int *, int *));
65void
dc810e39 66MY(put_reloc) PARAMS ((bfd *, int, int, bfd_vma, reloc_howto_type *,
1725a96e 67 struct reloc_std_external *));
252b5132
RH
68
69/* The ns32k series is ah, unusual, when it comes to relocation.
1725a96e
NC
70 There are three storage methods for relocateable objects. There
71 are displacements, immediate operands and ordinary twos complement
72 data. Of these, only the last fits into the standard relocation
73 scheme. Immediate operands are stored huffman encoded and
74 immediate operands are stored big endian (where as the natural byte
75 order is little endian for this achitecture).
76
77 Note that the ns32k displacement storage method is orthogonal to
78 whether the relocation is pc relative or not. The "displacement"
79 storage scheme is used for essentially all address constants. The
80 displacement can be relative to zero (absolute displacement),
81 relative to the pc (pc relative), the stack pointer, the frame
82 pointer, the static base register and general purpose register etc.
83
84 For example:
dc810e39 85
1725a96e
NC
86 sym1: .long . # pc relative 2's complement
87 sym1: .long foo # 2's complement not pc relative
dc810e39 88
1725a96e
NC
89 self: movd @self, r0 # pc relative displacement
90 movd foo, r0 # non pc relative displacement
91
92 self: movd self, r0 # pc relative immediate
93 movd foo, r0 # non pc relative immediate
dc810e39 94
1725a96e
NC
95 In addition, for historical reasons the encoding of the relocation types
96 in the a.out format relocation entries is such that even the relocation
4eb6b71c 97 methods which are standard are not encoded the standard way. */
252b5132 98
c4dfa77f 99reloc_howto_type MY(howto_table)[] =
1725a96e 100 {
4eb6b71c 101 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
1725a96e 102 /* ns32k immediate operands. */
4eb6b71c 103 HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, complain_overflow_signed,
1725a96e
NC
104 _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
105 true, 0x000000ff,0x000000ff, false),
4eb6b71c 106 HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, complain_overflow_signed,
1725a96e
NC
107 _bfd_ns32k_reloc_imm, "NS32K_IMM_16",
108 true, 0x0000ffff,0x0000ffff, false),
4eb6b71c 109 HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, complain_overflow_signed,
1725a96e
NC
110 _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
111 true, 0xffffffff,0xffffffff, false),
4eb6b71c 112 HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed,
1725a96e
NC
113 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
114 true, 0x000000ff, 0x000000ff, false),
4eb6b71c 115 HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed,
1725a96e
NC
116 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
117 true, 0x0000ffff,0x0000ffff, false),
4eb6b71c 118 HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed,
1725a96e
NC
119 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
120 true, 0xffffffff,0xffffffff, false),
121
122 /* ns32k displacements. */
4eb6b71c 123 HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, false, 0, complain_overflow_signed,
1725a96e
NC
124 _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
125 true, 0x000000ff,0x000000ff, false),
4eb6b71c 126 HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, false, 0, complain_overflow_signed,
1725a96e
NC
127 _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
128 true, 0x0000ffff, 0x0000ffff, false),
4eb6b71c 129 HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, false, 0, complain_overflow_signed,
1725a96e
NC
130 _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
131 true, 0xffffffff, 0xffffffff, false),
4eb6b71c 132 HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, true, 0, complain_overflow_signed,
1725a96e
NC
133 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
134 true, 0x000000ff,0x000000ff, false),
4eb6b71c 135 HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, true, 0, complain_overflow_signed,
1725a96e
NC
136 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
137 true, 0x0000ffff,0x0000ffff, false),
4eb6b71c 138 HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, true, 0, complain_overflow_signed,
1725a96e
NC
139 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
140 true, 0xffffffff,0xffffffff, false),
141
142 /* Normal 2's complement. */
143 HOWTO (BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,
144 "8", true, 0x000000ff,0x000000ff, false),
145 HOWTO (BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,
146 "16", true, 0x0000ffff,0x0000ffff, false),
147 HOWTO (BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,
148 "32", true, 0xffffffff,0xffffffff, false),
149 HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0,
150 "PCREL_8", true, 0x000000ff,0x000000ff, false),
151 HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0,
152 "PCREL_16", true, 0x0000ffff,0x0000ffff, false),
153 HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0,
154 "PCREL_32", true, 0xffffffff,0xffffffff, false),
155 };
252b5132 156
252b5132
RH
157#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14)
158
159#define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06
160#define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60
161#define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1
162#define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5
163
164reloc_howto_type *
beb0d161 165MY(reloc_howto) (abfd, rel, r_index, r_extern, r_pcrel)
5f771d47 166 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
167 struct reloc_std_external *rel;
168 int *r_index;
169 int *r_extern;
170 int *r_pcrel;
171{
172 unsigned int r_length;
173 int r_ns32k_type;
1725a96e
NC
174
175 /* BFD_ASSERT(bfd_header_little_endian (abfd)); */
252b5132
RH
176 *r_index = ((rel->r_index[2] << 16)
177 | (rel->r_index[1] << 8)
178 | rel->r_index[0] );
179 *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
180 *r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
181 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
182 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
183 r_ns32k_type = ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE)
184 >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
185 return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type);
186}
187
dc810e39
AM
188#define MY_reloc_howto(BFD, REL, IN, EX, PC) \
189 MY(reloc_howto) (BFD, REL, &IN, &EX, &PC)
252b5132
RH
190
191void
beb0d161 192MY(put_reloc) (abfd, r_extern, r_index, value, howto, reloc)
252b5132
RH
193 bfd *abfd;
194 int r_extern;
195 int r_index;
dc810e39 196 bfd_vma value;
252b5132
RH
197 reloc_howto_type *howto;
198 struct reloc_std_external *reloc;
199{
200 unsigned int r_length;
201 int r_pcrel;
202 int r_ns32k_type;
1725a96e 203
252b5132 204 PUT_WORD (abfd, value, reloc->r_address);
1725a96e
NC
205 r_length = howto->size ; /* Size as a power of two. */
206 r_pcrel = (int) howto->pc_relative; /* Relative to PC? */
252b5132 207 r_ns32k_type = (howto - MY(howto_table) )/6;
1725a96e
NC
208
209 /* BFD_ASSERT (bfd_header_little_endian (abfd)); */
252b5132
RH
210 reloc->r_index[2] = r_index >> 16;
211 reloc->r_index[1] = r_index >> 8;
212 reloc->r_index[0] = r_index;
213 reloc->r_type[0] =
214 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
215 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
216 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)
217 | (r_ns32k_type << RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
218}
219
220#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
beb0d161 221 MY(put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC)
252b5132
RH
222
223#define STAT_FOR_EXEC
224
225#define MY_final_link_relocate _bfd_ns32k_final_link_relocate
226#define MY_relocate_contents _bfd_ns32k_relocate_contents
227
dc810e39 228#include "aoutx.h"
252b5132
RH
229
230reloc_howto_type *
beb0d161 231MY(bfd_reloc_type_lookup) (abfd,code)
252b5132
RH
232 bfd *abfd;
233 bfd_reloc_code_real_type code;
234{
235
236#define ENTRY(i,j) case i: return &MY(howto_table)[j]
237
238 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
239
240 BFD_ASSERT(ext == 0);
241 if (code == BFD_RELOC_CTOR)
242 switch (bfd_get_arch_info (abfd)->bits_per_address)
243 {
244 case 32:
245 code = BFD_RELOC_32;
246 break;
1725a96e
NC
247 default:
248 break;
252b5132
RH
249 }
250 switch (code)
251 {
252 ENTRY(BFD_RELOC_NS32K_IMM_8, 0);
253 ENTRY(BFD_RELOC_NS32K_IMM_16, 1);
254 ENTRY(BFD_RELOC_NS32K_IMM_32, 2);
255 ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3);
256 ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4);
257 ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5);
258 ENTRY(BFD_RELOC_NS32K_DISP_8, 6);
259 ENTRY(BFD_RELOC_NS32K_DISP_16, 7);
260 ENTRY(BFD_RELOC_NS32K_DISP_32, 8);
261 ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9);
262 ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10);
263 ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11);
264 ENTRY(BFD_RELOC_8, 12);
265 ENTRY(BFD_RELOC_16, 13);
266 ENTRY(BFD_RELOC_32, 14);
267 ENTRY(BFD_RELOC_8_PCREL, 15);
268 ENTRY(BFD_RELOC_16_PCREL, 16);
269 ENTRY(BFD_RELOC_32_PCREL, 17);
1725a96e
NC
270 default:
271 return (reloc_howto_type *) NULL;
252b5132
RH
272 }
273#undef ENTRY
274}
275
252b5132
RH
276static void
277MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
278 bfd *abfd;
279 struct reloc_std_external *bytes;
280 arelent *cache_ptr;
281 asymbol **symbols;
5f771d47 282 bfd_size_type symcount ATTRIBUTE_UNUSED;
252b5132
RH
283{
284 int r_index;
285 int r_extern;
286 int r_pcrel;
287 struct aoutdata *su = &(abfd->tdata.aout_data->a);
288
dc810e39 289 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
252b5132 290
1725a96e 291 /* Now the fun stuff. */
252b5132
RH
292 cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel);
293
1725a96e 294 MOVE_ADDRESS (0);
252b5132
RH
295}
296
297static void
298MY_swap_std_reloc_out (abfd, g, natptr)
299 bfd *abfd;
300 arelent *g;
301 struct reloc_std_external *natptr;
302{
303 int r_index;
304 asymbol *sym = *(g->sym_ptr_ptr);
305 int r_extern;
306 unsigned int r_addend;
307 asection *output_section = sym->section->output_section;
308
309 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
c4dfa77f 310
1725a96e 311 /* Name was clobbered by aout_write_syms to be symbol index. */
252b5132 312
c4dfa77f 313 /* If this relocation is relative to a symbol then set the
252b5132
RH
314 r_index to the symbols index, and the r_extern bit.
315
316 Absolute symbols can come in in two ways, either as an offset
317 from the abs section, or as a symbol which has an abs value.
318 Check for that here. */
252b5132
RH
319 if (bfd_is_com_section (output_section)
320 || output_section == &bfd_abs_section
c4dfa77f 321 || output_section == &bfd_und_section)
252b5132
RH
322 {
323 if (bfd_abs_section.symbol == sym)
324 {
325 /* Whoops, looked like an abs symbol, but is really an offset
1725a96e 326 from the abs section. */
252b5132
RH
327 r_index = 0;
328 r_extern = 0;
329 }
c4dfa77f 330 else
252b5132 331 {
1725a96e 332 /* Fill in symbol. */
252b5132
RH
333 r_extern = 1;
334#undef KEEPIT
335#define KEEPIT udata.i
336 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
c4dfa77f 337#undef KEEPIT
252b5132
RH
338 }
339 }
c4dfa77f 340 else
252b5132 341 {
1725a96e 342 /* Just an ordinary section. */
252b5132 343 r_extern = 0;
c4dfa77f 344 r_index = output_section->target_index;
252b5132
RH
345 }
346
347 MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
348}
349
350bfd_reloc_status_type
351_bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
352 reloc_howto_type *howto;
353 bfd *input_bfd;
354 bfd_vma relocation;
355 bfd_byte *location;
356{
357 int r_ns32k_type = (howto - MY(howto_table)) / 6;
dc810e39 358 bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
4eb6b71c 359 void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
252b5132
RH
360
361 switch (r_ns32k_type)
362 {
363 case 0:
364 get_data = _bfd_ns32k_get_immediate;
365 put_data = _bfd_ns32k_put_immediate;
366 break;
367 case 1:
368 get_data = _bfd_ns32k_get_displacement;
369 put_data = _bfd_ns32k_put_displacement;
370 break;
371 case 2:
372 return _bfd_relocate_contents (howto, input_bfd, relocation,
373 location);
374 /* NOT REACHED */
375 break;
376 default:
377 return bfd_reloc_notsupported;
378 }
379 return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
380 location, get_data, put_data);
381}
This page took 0.175016 seconds and 4 git commands to generate.