xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/coff-sh.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* BFD back-end for Renesas Super-H COFF binaries.
2*3d8817e4Smiod    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3*3d8817e4Smiod    2003, 2004, 2005 Free Software Foundation, Inc.
4*3d8817e4Smiod    Contributed by Cygnus Support.
5*3d8817e4Smiod    Written by Steve Chamberlain, <sac@cygnus.com>.
6*3d8817e4Smiod    Relaxing code written by Ian Lance Taylor, <ian@cygnus.com>.
7*3d8817e4Smiod 
8*3d8817e4Smiod    This file is part of BFD, the Binary File Descriptor library.
9*3d8817e4Smiod 
10*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
11*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
12*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
13*3d8817e4Smiod    (at your option) any later version.
14*3d8817e4Smiod 
15*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
16*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
17*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*3d8817e4Smiod    GNU General Public License for more details.
19*3d8817e4Smiod 
20*3d8817e4Smiod    You should have received a copy of the GNU General Public License
21*3d8817e4Smiod    along with this program; if not, write to the Free Software
22*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
23*3d8817e4Smiod 
24*3d8817e4Smiod #include "bfd.h"
25*3d8817e4Smiod #include "sysdep.h"
26*3d8817e4Smiod #include "libiberty.h"
27*3d8817e4Smiod #include "libbfd.h"
28*3d8817e4Smiod #include "bfdlink.h"
29*3d8817e4Smiod #include "coff/sh.h"
30*3d8817e4Smiod #include "coff/internal.h"
31*3d8817e4Smiod 
32*3d8817e4Smiod #ifdef COFF_WITH_PE
33*3d8817e4Smiod #include "coff/pe.h"
34*3d8817e4Smiod 
35*3d8817e4Smiod #ifndef COFF_IMAGE_WITH_PE
36*3d8817e4Smiod static bfd_boolean sh_align_load_span
37*3d8817e4Smiod   PARAMS ((bfd *, asection *, bfd_byte *,
38*3d8817e4Smiod 	   bfd_boolean (*) (bfd *, asection *, PTR, bfd_byte *, bfd_vma),
39*3d8817e4Smiod 	   PTR, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *));
40*3d8817e4Smiod 
41*3d8817e4Smiod #define _bfd_sh_align_load_span sh_align_load_span
42*3d8817e4Smiod #endif
43*3d8817e4Smiod #endif
44*3d8817e4Smiod 
45*3d8817e4Smiod #include "libcoff.h"
46*3d8817e4Smiod 
47*3d8817e4Smiod /* Internal functions.  */
48*3d8817e4Smiod static bfd_reloc_status_type sh_reloc
49*3d8817e4Smiod   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
50*3d8817e4Smiod static long get_symbol_value PARAMS ((asymbol *));
51*3d8817e4Smiod static bfd_boolean sh_relax_section
52*3d8817e4Smiod   PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
53*3d8817e4Smiod static bfd_boolean sh_relax_delete_bytes
54*3d8817e4Smiod   PARAMS ((bfd *, asection *, bfd_vma, int));
55*3d8817e4Smiod #ifndef COFF_IMAGE_WITH_PE
56*3d8817e4Smiod static const struct sh_opcode *sh_insn_info PARAMS ((unsigned int));
57*3d8817e4Smiod #endif
58*3d8817e4Smiod static bfd_boolean sh_align_loads
59*3d8817e4Smiod   PARAMS ((bfd *, asection *, struct internal_reloc *, bfd_byte *,
60*3d8817e4Smiod 	   bfd_boolean *));
61*3d8817e4Smiod static bfd_boolean sh_swap_insns
62*3d8817e4Smiod   PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
63*3d8817e4Smiod static bfd_boolean sh_relocate_section
64*3d8817e4Smiod   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
65*3d8817e4Smiod 	   struct internal_reloc *, struct internal_syment *, asection **));
66*3d8817e4Smiod static bfd_byte *sh_coff_get_relocated_section_contents
67*3d8817e4Smiod   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
68*3d8817e4Smiod 	   bfd_byte *, bfd_boolean, asymbol **));
69*3d8817e4Smiod static reloc_howto_type * sh_coff_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
70*3d8817e4Smiod 
71*3d8817e4Smiod #ifdef COFF_WITH_PE
72*3d8817e4Smiod /* Can't build import tables with 2**4 alignment.  */
73*3d8817e4Smiod #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER	2
74*3d8817e4Smiod #else
75*3d8817e4Smiod /* Default section alignment to 2**4.  */
76*3d8817e4Smiod #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER	4
77*3d8817e4Smiod #endif
78*3d8817e4Smiod 
79*3d8817e4Smiod #ifdef COFF_IMAGE_WITH_PE
80*3d8817e4Smiod /* Align PE executables.  */
81*3d8817e4Smiod #define COFF_PAGE_SIZE 0x1000
82*3d8817e4Smiod #endif
83*3d8817e4Smiod 
84*3d8817e4Smiod /* Generate long file names.  */
85*3d8817e4Smiod #define COFF_LONG_FILENAMES
86*3d8817e4Smiod 
87*3d8817e4Smiod #ifdef COFF_WITH_PE
88*3d8817e4Smiod static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
89*3d8817e4Smiod /* Return TRUE if this relocation should
90*3d8817e4Smiod    appear in the output .reloc section.  */
in_reloc_p(abfd,howto)91*3d8817e4Smiod static bfd_boolean in_reloc_p (abfd, howto)
92*3d8817e4Smiod      bfd * abfd ATTRIBUTE_UNUSED;
93*3d8817e4Smiod      reloc_howto_type * howto;
94*3d8817e4Smiod {
95*3d8817e4Smiod   return ! howto->pc_relative && howto->type != R_SH_IMAGEBASE;
96*3d8817e4Smiod }
97*3d8817e4Smiod #endif
98*3d8817e4Smiod 
99*3d8817e4Smiod /* The supported relocations.  There are a lot of relocations defined
100*3d8817e4Smiod    in coff/internal.h which we do not expect to ever see.  */
101*3d8817e4Smiod static reloc_howto_type sh_coff_howtos[] =
102*3d8817e4Smiod {
103*3d8817e4Smiod   EMPTY_HOWTO (0),
104*3d8817e4Smiod   EMPTY_HOWTO (1),
105*3d8817e4Smiod #ifdef COFF_WITH_PE
106*3d8817e4Smiod   /* Windows CE */
107*3d8817e4Smiod   HOWTO (R_SH_IMM32CE,		/* type */
108*3d8817e4Smiod 	 0,			/* rightshift */
109*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
110*3d8817e4Smiod 	 32,			/* bitsize */
111*3d8817e4Smiod 	 FALSE,			/* pc_relative */
112*3d8817e4Smiod 	 0,			/* bitpos */
113*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
114*3d8817e4Smiod 	 sh_reloc,		/* special_function */
115*3d8817e4Smiod 	 "r_imm32ce",		/* name */
116*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
117*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
118*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
119*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
120*3d8817e4Smiod #else
121*3d8817e4Smiod   EMPTY_HOWTO (2),
122*3d8817e4Smiod #endif
123*3d8817e4Smiod   EMPTY_HOWTO (3), /* R_SH_PCREL8 */
124*3d8817e4Smiod   EMPTY_HOWTO (4), /* R_SH_PCREL16 */
125*3d8817e4Smiod   EMPTY_HOWTO (5), /* R_SH_HIGH8 */
126*3d8817e4Smiod   EMPTY_HOWTO (6), /* R_SH_IMM24 */
127*3d8817e4Smiod   EMPTY_HOWTO (7), /* R_SH_LOW16 */
128*3d8817e4Smiod   EMPTY_HOWTO (8),
129*3d8817e4Smiod   EMPTY_HOWTO (9), /* R_SH_PCDISP8BY4 */
130*3d8817e4Smiod 
131*3d8817e4Smiod   HOWTO (R_SH_PCDISP8BY2,	/* type */
132*3d8817e4Smiod 	 1,			/* rightshift */
133*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
134*3d8817e4Smiod 	 8,			/* bitsize */
135*3d8817e4Smiod 	 TRUE,			/* pc_relative */
136*3d8817e4Smiod 	 0,			/* bitpos */
137*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
138*3d8817e4Smiod 	 sh_reloc,		/* special_function */
139*3d8817e4Smiod 	 "r_pcdisp8by2",	/* name */
140*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
141*3d8817e4Smiod 	 0xff,			/* src_mask */
142*3d8817e4Smiod 	 0xff,			/* dst_mask */
143*3d8817e4Smiod 	 TRUE),			/* pcrel_offset */
144*3d8817e4Smiod 
145*3d8817e4Smiod   EMPTY_HOWTO (11), /* R_SH_PCDISP8 */
146*3d8817e4Smiod 
147*3d8817e4Smiod   HOWTO (R_SH_PCDISP,		/* type */
148*3d8817e4Smiod 	 1,			/* rightshift */
149*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
150*3d8817e4Smiod 	 12,			/* bitsize */
151*3d8817e4Smiod 	 TRUE,			/* pc_relative */
152*3d8817e4Smiod 	 0,			/* bitpos */
153*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
154*3d8817e4Smiod 	 sh_reloc,		/* special_function */
155*3d8817e4Smiod 	 "r_pcdisp12by2",	/* name */
156*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
157*3d8817e4Smiod 	 0xfff,			/* src_mask */
158*3d8817e4Smiod 	 0xfff,			/* dst_mask */
159*3d8817e4Smiod 	 TRUE),			/* pcrel_offset */
160*3d8817e4Smiod 
161*3d8817e4Smiod   EMPTY_HOWTO (13),
162*3d8817e4Smiod 
163*3d8817e4Smiod   HOWTO (R_SH_IMM32,		/* type */
164*3d8817e4Smiod 	 0,			/* rightshift */
165*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
166*3d8817e4Smiod 	 32,			/* bitsize */
167*3d8817e4Smiod 	 FALSE,			/* pc_relative */
168*3d8817e4Smiod 	 0,			/* bitpos */
169*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
170*3d8817e4Smiod 	 sh_reloc,		/* special_function */
171*3d8817e4Smiod 	 "r_imm32",		/* name */
172*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
173*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
174*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
175*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
176*3d8817e4Smiod 
177*3d8817e4Smiod   EMPTY_HOWTO (15),
178*3d8817e4Smiod #ifdef COFF_WITH_PE
179*3d8817e4Smiod   HOWTO (R_SH_IMAGEBASE,        /* type */
180*3d8817e4Smiod 	 0,	                /* rightshift */
181*3d8817e4Smiod 	 2,	                /* size (0 = byte, 1 = short, 2 = long) */
182*3d8817e4Smiod 	 32,	                /* bitsize */
183*3d8817e4Smiod 	 FALSE,	                /* pc_relative */
184*3d8817e4Smiod 	 0,	                /* bitpos */
185*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
186*3d8817e4Smiod 	 sh_reloc,       	/* special_function */
187*3d8817e4Smiod 	 "rva32",	        /* name */
188*3d8817e4Smiod 	 TRUE,	                /* partial_inplace */
189*3d8817e4Smiod 	 0xffffffff,            /* src_mask */
190*3d8817e4Smiod 	 0xffffffff,            /* dst_mask */
191*3d8817e4Smiod 	 FALSE),                /* pcrel_offset */
192*3d8817e4Smiod #else
193*3d8817e4Smiod   EMPTY_HOWTO (16), /* R_SH_IMM8 */
194*3d8817e4Smiod #endif
195*3d8817e4Smiod   EMPTY_HOWTO (17), /* R_SH_IMM8BY2 */
196*3d8817e4Smiod   EMPTY_HOWTO (18), /* R_SH_IMM8BY4 */
197*3d8817e4Smiod   EMPTY_HOWTO (19), /* R_SH_IMM4 */
198*3d8817e4Smiod   EMPTY_HOWTO (20), /* R_SH_IMM4BY2 */
199*3d8817e4Smiod   EMPTY_HOWTO (21), /* R_SH_IMM4BY4 */
200*3d8817e4Smiod 
201*3d8817e4Smiod   HOWTO (R_SH_PCRELIMM8BY2,	/* type */
202*3d8817e4Smiod 	 1,			/* rightshift */
203*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
204*3d8817e4Smiod 	 8,			/* bitsize */
205*3d8817e4Smiod 	 TRUE,			/* pc_relative */
206*3d8817e4Smiod 	 0,			/* bitpos */
207*3d8817e4Smiod 	 complain_overflow_unsigned, /* complain_on_overflow */
208*3d8817e4Smiod 	 sh_reloc,		/* special_function */
209*3d8817e4Smiod 	 "r_pcrelimm8by2",	/* name */
210*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
211*3d8817e4Smiod 	 0xff,			/* src_mask */
212*3d8817e4Smiod 	 0xff,			/* dst_mask */
213*3d8817e4Smiod 	 TRUE),			/* pcrel_offset */
214*3d8817e4Smiod 
215*3d8817e4Smiod   HOWTO (R_SH_PCRELIMM8BY4,	/* type */
216*3d8817e4Smiod 	 2,			/* rightshift */
217*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
218*3d8817e4Smiod 	 8,			/* bitsize */
219*3d8817e4Smiod 	 TRUE,			/* pc_relative */
220*3d8817e4Smiod 	 0,			/* bitpos */
221*3d8817e4Smiod 	 complain_overflow_unsigned, /* complain_on_overflow */
222*3d8817e4Smiod 	 sh_reloc,		/* special_function */
223*3d8817e4Smiod 	 "r_pcrelimm8by4",	/* name */
224*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
225*3d8817e4Smiod 	 0xff,			/* src_mask */
226*3d8817e4Smiod 	 0xff,			/* dst_mask */
227*3d8817e4Smiod 	 TRUE),			/* pcrel_offset */
228*3d8817e4Smiod 
229*3d8817e4Smiod   HOWTO (R_SH_IMM16,		/* type */
230*3d8817e4Smiod 	 0,			/* rightshift */
231*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
232*3d8817e4Smiod 	 16,			/* bitsize */
233*3d8817e4Smiod 	 FALSE,			/* pc_relative */
234*3d8817e4Smiod 	 0,			/* bitpos */
235*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
236*3d8817e4Smiod 	 sh_reloc,		/* special_function */
237*3d8817e4Smiod 	 "r_imm16",		/* name */
238*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
239*3d8817e4Smiod 	 0xffff,		/* src_mask */
240*3d8817e4Smiod 	 0xffff,		/* dst_mask */
241*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
242*3d8817e4Smiod 
243*3d8817e4Smiod   HOWTO (R_SH_SWITCH16,		/* type */
244*3d8817e4Smiod 	 0,			/* rightshift */
245*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
246*3d8817e4Smiod 	 16,			/* bitsize */
247*3d8817e4Smiod 	 FALSE,			/* pc_relative */
248*3d8817e4Smiod 	 0,			/* bitpos */
249*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
250*3d8817e4Smiod 	 sh_reloc,		/* special_function */
251*3d8817e4Smiod 	 "r_switch16",		/* name */
252*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
253*3d8817e4Smiod 	 0xffff,		/* src_mask */
254*3d8817e4Smiod 	 0xffff,		/* dst_mask */
255*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
256*3d8817e4Smiod 
257*3d8817e4Smiod   HOWTO (R_SH_SWITCH32,		/* type */
258*3d8817e4Smiod 	 0,			/* rightshift */
259*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
260*3d8817e4Smiod 	 32,			/* bitsize */
261*3d8817e4Smiod 	 FALSE,			/* pc_relative */
262*3d8817e4Smiod 	 0,			/* bitpos */
263*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
264*3d8817e4Smiod 	 sh_reloc,		/* special_function */
265*3d8817e4Smiod 	 "r_switch32",		/* name */
266*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
267*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
268*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
269*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
270*3d8817e4Smiod 
271*3d8817e4Smiod   HOWTO (R_SH_USES,		/* type */
272*3d8817e4Smiod 	 0,			/* rightshift */
273*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
274*3d8817e4Smiod 	 16,			/* bitsize */
275*3d8817e4Smiod 	 FALSE,			/* pc_relative */
276*3d8817e4Smiod 	 0,			/* bitpos */
277*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
278*3d8817e4Smiod 	 sh_reloc,		/* special_function */
279*3d8817e4Smiod 	 "r_uses",		/* name */
280*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
281*3d8817e4Smiod 	 0xffff,		/* src_mask */
282*3d8817e4Smiod 	 0xffff,		/* dst_mask */
283*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
284*3d8817e4Smiod 
285*3d8817e4Smiod   HOWTO (R_SH_COUNT,		/* type */
286*3d8817e4Smiod 	 0,			/* rightshift */
287*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
288*3d8817e4Smiod 	 32,			/* bitsize */
289*3d8817e4Smiod 	 FALSE,			/* pc_relative */
290*3d8817e4Smiod 	 0,			/* bitpos */
291*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
292*3d8817e4Smiod 	 sh_reloc,		/* special_function */
293*3d8817e4Smiod 	 "r_count",		/* name */
294*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
295*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
296*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
297*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
298*3d8817e4Smiod 
299*3d8817e4Smiod   HOWTO (R_SH_ALIGN,		/* type */
300*3d8817e4Smiod 	 0,			/* rightshift */
301*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
302*3d8817e4Smiod 	 32,			/* bitsize */
303*3d8817e4Smiod 	 FALSE,			/* pc_relative */
304*3d8817e4Smiod 	 0,			/* bitpos */
305*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
306*3d8817e4Smiod 	 sh_reloc,		/* special_function */
307*3d8817e4Smiod 	 "r_align",		/* name */
308*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
309*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
310*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
311*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
312*3d8817e4Smiod 
313*3d8817e4Smiod   HOWTO (R_SH_CODE,		/* type */
314*3d8817e4Smiod 	 0,			/* rightshift */
315*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
316*3d8817e4Smiod 	 32,			/* bitsize */
317*3d8817e4Smiod 	 FALSE,			/* pc_relative */
318*3d8817e4Smiod 	 0,			/* bitpos */
319*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
320*3d8817e4Smiod 	 sh_reloc,		/* special_function */
321*3d8817e4Smiod 	 "r_code",		/* name */
322*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
323*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
324*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
325*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
326*3d8817e4Smiod 
327*3d8817e4Smiod   HOWTO (R_SH_DATA,		/* type */
328*3d8817e4Smiod 	 0,			/* rightshift */
329*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
330*3d8817e4Smiod 	 32,			/* bitsize */
331*3d8817e4Smiod 	 FALSE,			/* pc_relative */
332*3d8817e4Smiod 	 0,			/* bitpos */
333*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
334*3d8817e4Smiod 	 sh_reloc,		/* special_function */
335*3d8817e4Smiod 	 "r_data",		/* name */
336*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
337*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
338*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
339*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
340*3d8817e4Smiod 
341*3d8817e4Smiod   HOWTO (R_SH_LABEL,		/* type */
342*3d8817e4Smiod 	 0,			/* rightshift */
343*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
344*3d8817e4Smiod 	 32,			/* bitsize */
345*3d8817e4Smiod 	 FALSE,			/* pc_relative */
346*3d8817e4Smiod 	 0,			/* bitpos */
347*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
348*3d8817e4Smiod 	 sh_reloc,		/* special_function */
349*3d8817e4Smiod 	 "r_label",		/* name */
350*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
351*3d8817e4Smiod 	 0xffffffff,		/* src_mask */
352*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
353*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
354*3d8817e4Smiod 
355*3d8817e4Smiod   HOWTO (R_SH_SWITCH8,		/* type */
356*3d8817e4Smiod 	 0,			/* rightshift */
357*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
358*3d8817e4Smiod 	 8,			/* bitsize */
359*3d8817e4Smiod 	 FALSE,			/* pc_relative */
360*3d8817e4Smiod 	 0,			/* bitpos */
361*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
362*3d8817e4Smiod 	 sh_reloc,		/* special_function */
363*3d8817e4Smiod 	 "r_switch8",		/* name */
364*3d8817e4Smiod 	 TRUE,			/* partial_inplace */
365*3d8817e4Smiod 	 0xff,			/* src_mask */
366*3d8817e4Smiod 	 0xff,			/* dst_mask */
367*3d8817e4Smiod 	 FALSE)			/* pcrel_offset */
368*3d8817e4Smiod };
369*3d8817e4Smiod 
370*3d8817e4Smiod #define SH_COFF_HOWTO_COUNT (sizeof sh_coff_howtos / sizeof sh_coff_howtos[0])
371*3d8817e4Smiod 
372*3d8817e4Smiod /* Check for a bad magic number.  */
373*3d8817e4Smiod #define BADMAG(x) SHBADMAG(x)
374*3d8817e4Smiod 
375*3d8817e4Smiod /* Customize coffcode.h (this is not currently used).  */
376*3d8817e4Smiod #define SH 1
377*3d8817e4Smiod 
378*3d8817e4Smiod /* FIXME: This should not be set here.  */
379*3d8817e4Smiod #define __A_MAGIC_SET__
380*3d8817e4Smiod 
381*3d8817e4Smiod #ifndef COFF_WITH_PE
382*3d8817e4Smiod /* Swap the r_offset field in and out.  */
383*3d8817e4Smiod #define SWAP_IN_RELOC_OFFSET  H_GET_32
384*3d8817e4Smiod #define SWAP_OUT_RELOC_OFFSET H_PUT_32
385*3d8817e4Smiod 
386*3d8817e4Smiod /* Swap out extra information in the reloc structure.  */
387*3d8817e4Smiod #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst)	\
388*3d8817e4Smiod   do						\
389*3d8817e4Smiod     {						\
390*3d8817e4Smiod       dst->r_stuff[0] = 'S';			\
391*3d8817e4Smiod       dst->r_stuff[1] = 'C';			\
392*3d8817e4Smiod     }						\
393*3d8817e4Smiod   while (0)
394*3d8817e4Smiod #endif
395*3d8817e4Smiod 
396*3d8817e4Smiod /* Get the value of a symbol, when performing a relocation.  */
397*3d8817e4Smiod 
398*3d8817e4Smiod static long
get_symbol_value(symbol)399*3d8817e4Smiod get_symbol_value (symbol)
400*3d8817e4Smiod      asymbol *symbol;
401*3d8817e4Smiod {
402*3d8817e4Smiod   bfd_vma relocation;
403*3d8817e4Smiod 
404*3d8817e4Smiod   if (bfd_is_com_section (symbol->section))
405*3d8817e4Smiod     relocation = 0;
406*3d8817e4Smiod   else
407*3d8817e4Smiod     relocation = (symbol->value +
408*3d8817e4Smiod 		  symbol->section->output_section->vma +
409*3d8817e4Smiod 		  symbol->section->output_offset);
410*3d8817e4Smiod 
411*3d8817e4Smiod   return relocation;
412*3d8817e4Smiod }
413*3d8817e4Smiod 
414*3d8817e4Smiod #ifdef COFF_WITH_PE
415*3d8817e4Smiod /* Convert an rtype to howto for the COFF backend linker.
416*3d8817e4Smiod    Copied from coff-i386.  */
417*3d8817e4Smiod #define coff_rtype_to_howto coff_sh_rtype_to_howto
418*3d8817e4Smiod static reloc_howto_type * coff_sh_rtype_to_howto PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
419*3d8817e4Smiod 
420*3d8817e4Smiod static reloc_howto_type *
coff_sh_rtype_to_howto(abfd,sec,rel,h,sym,addendp)421*3d8817e4Smiod coff_sh_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
422*3d8817e4Smiod      bfd * abfd ATTRIBUTE_UNUSED;
423*3d8817e4Smiod      asection * sec;
424*3d8817e4Smiod      struct internal_reloc * rel;
425*3d8817e4Smiod      struct coff_link_hash_entry * h;
426*3d8817e4Smiod      struct internal_syment * sym;
427*3d8817e4Smiod      bfd_vma * addendp;
428*3d8817e4Smiod {
429*3d8817e4Smiod   reloc_howto_type * howto;
430*3d8817e4Smiod 
431*3d8817e4Smiod   howto = sh_coff_howtos + rel->r_type;
432*3d8817e4Smiod 
433*3d8817e4Smiod   *addendp = 0;
434*3d8817e4Smiod 
435*3d8817e4Smiod   if (howto->pc_relative)
436*3d8817e4Smiod     *addendp += sec->vma;
437*3d8817e4Smiod 
438*3d8817e4Smiod   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
439*3d8817e4Smiod     {
440*3d8817e4Smiod       /* This is a common symbol.  The section contents include the
441*3d8817e4Smiod 	 size (sym->n_value) as an addend.  The relocate_section
442*3d8817e4Smiod 	 function will be adding in the final value of the symbol.  We
443*3d8817e4Smiod 	 need to subtract out the current size in order to get the
444*3d8817e4Smiod 	 correct result.  */
445*3d8817e4Smiod       BFD_ASSERT (h != NULL);
446*3d8817e4Smiod     }
447*3d8817e4Smiod 
448*3d8817e4Smiod   if (howto->pc_relative)
449*3d8817e4Smiod     {
450*3d8817e4Smiod       *addendp -= 4;
451*3d8817e4Smiod 
452*3d8817e4Smiod       /* If the symbol is defined, then the generic code is going to
453*3d8817e4Smiod          add back the symbol value in order to cancel out an
454*3d8817e4Smiod          adjustment it made to the addend.  However, we set the addend
455*3d8817e4Smiod          to 0 at the start of this function.  We need to adjust here,
456*3d8817e4Smiod          to avoid the adjustment the generic code will make.  FIXME:
457*3d8817e4Smiod          This is getting a bit hackish.  */
458*3d8817e4Smiod       if (sym != NULL && sym->n_scnum != 0)
459*3d8817e4Smiod 	*addendp -= sym->n_value;
460*3d8817e4Smiod     }
461*3d8817e4Smiod 
462*3d8817e4Smiod   if (rel->r_type == R_SH_IMAGEBASE)
463*3d8817e4Smiod     *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
464*3d8817e4Smiod 
465*3d8817e4Smiod   return howto;
466*3d8817e4Smiod }
467*3d8817e4Smiod 
468*3d8817e4Smiod #endif /* COFF_WITH_PE */
469*3d8817e4Smiod 
470*3d8817e4Smiod /* This structure is used to map BFD reloc codes to SH PE relocs.  */
471*3d8817e4Smiod struct shcoff_reloc_map
472*3d8817e4Smiod {
473*3d8817e4Smiod   bfd_reloc_code_real_type bfd_reloc_val;
474*3d8817e4Smiod   unsigned char shcoff_reloc_val;
475*3d8817e4Smiod };
476*3d8817e4Smiod 
477*3d8817e4Smiod #ifdef COFF_WITH_PE
478*3d8817e4Smiod /* An array mapping BFD reloc codes to SH PE relocs.  */
479*3d8817e4Smiod static const struct shcoff_reloc_map sh_reloc_map[] =
480*3d8817e4Smiod {
481*3d8817e4Smiod   { BFD_RELOC_32, R_SH_IMM32CE },
482*3d8817e4Smiod   { BFD_RELOC_RVA, R_SH_IMAGEBASE },
483*3d8817e4Smiod   { BFD_RELOC_CTOR, R_SH_IMM32CE },
484*3d8817e4Smiod };
485*3d8817e4Smiod #else
486*3d8817e4Smiod /* An array mapping BFD reloc codes to SH PE relocs.  */
487*3d8817e4Smiod static const struct shcoff_reloc_map sh_reloc_map[] =
488*3d8817e4Smiod {
489*3d8817e4Smiod   { BFD_RELOC_32, R_SH_IMM32 },
490*3d8817e4Smiod   { BFD_RELOC_CTOR, R_SH_IMM32 },
491*3d8817e4Smiod };
492*3d8817e4Smiod #endif
493*3d8817e4Smiod 
494*3d8817e4Smiod /* Given a BFD reloc code, return the howto structure for the
495*3d8817e4Smiod    corresponding SH PE reloc.  */
496*3d8817e4Smiod #define coff_bfd_reloc_type_lookup	sh_coff_reloc_type_lookup
497*3d8817e4Smiod 
498*3d8817e4Smiod static reloc_howto_type *
sh_coff_reloc_type_lookup(abfd,code)499*3d8817e4Smiod sh_coff_reloc_type_lookup (abfd, code)
500*3d8817e4Smiod      bfd * abfd ATTRIBUTE_UNUSED;
501*3d8817e4Smiod      bfd_reloc_code_real_type code;
502*3d8817e4Smiod {
503*3d8817e4Smiod   unsigned int i;
504*3d8817e4Smiod 
505*3d8817e4Smiod   for (i = ARRAY_SIZE (sh_reloc_map); i--;)
506*3d8817e4Smiod     if (sh_reloc_map[i].bfd_reloc_val == code)
507*3d8817e4Smiod       return &sh_coff_howtos[(int) sh_reloc_map[i].shcoff_reloc_val];
508*3d8817e4Smiod 
509*3d8817e4Smiod   fprintf (stderr, "SH Error: unknown reloc type %d\n", code);
510*3d8817e4Smiod   return NULL;
511*3d8817e4Smiod }
512*3d8817e4Smiod 
513*3d8817e4Smiod /* This macro is used in coffcode.h to get the howto corresponding to
514*3d8817e4Smiod    an internal reloc.  */
515*3d8817e4Smiod 
516*3d8817e4Smiod #define RTYPE2HOWTO(relent, internal)		\
517*3d8817e4Smiod   ((relent)->howto =				\
518*3d8817e4Smiod    ((internal)->r_type < SH_COFF_HOWTO_COUNT	\
519*3d8817e4Smiod     ? &sh_coff_howtos[(internal)->r_type]	\
520*3d8817e4Smiod     : (reloc_howto_type *) NULL))
521*3d8817e4Smiod 
522*3d8817e4Smiod /* This is the same as the macro in coffcode.h, except that it copies
523*3d8817e4Smiod    r_offset into reloc_entry->addend for some relocs.  */
524*3d8817e4Smiod #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
525*3d8817e4Smiod   {                                                             \
526*3d8817e4Smiod     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
527*3d8817e4Smiod     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
528*3d8817e4Smiod       coffsym = (obj_symbols (abfd)                             \
529*3d8817e4Smiod                  + (cache_ptr->sym_ptr_ptr - symbols));         \
530*3d8817e4Smiod     else if (ptr)                                               \
531*3d8817e4Smiod       coffsym = coff_symbol_from (abfd, ptr);                   \
532*3d8817e4Smiod     if (coffsym != (coff_symbol_type *) NULL                    \
533*3d8817e4Smiod         && coffsym->native->u.syment.n_scnum == 0)              \
534*3d8817e4Smiod       cache_ptr->addend = 0;                                    \
535*3d8817e4Smiod     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
536*3d8817e4Smiod              && ptr->section != (asection *) NULL)              \
537*3d8817e4Smiod       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
538*3d8817e4Smiod     else                                                        \
539*3d8817e4Smiod       cache_ptr->addend = 0;                                    \
540*3d8817e4Smiod     if ((reloc).r_type == R_SH_SWITCH8				\
541*3d8817e4Smiod 	|| (reloc).r_type == R_SH_SWITCH16			\
542*3d8817e4Smiod 	|| (reloc).r_type == R_SH_SWITCH32			\
543*3d8817e4Smiod 	|| (reloc).r_type == R_SH_USES				\
544*3d8817e4Smiod 	|| (reloc).r_type == R_SH_COUNT				\
545*3d8817e4Smiod 	|| (reloc).r_type == R_SH_ALIGN)			\
546*3d8817e4Smiod       cache_ptr->addend = (reloc).r_offset;			\
547*3d8817e4Smiod   }
548*3d8817e4Smiod 
549*3d8817e4Smiod /* This is the howto function for the SH relocations.  */
550*3d8817e4Smiod 
551*3d8817e4Smiod static bfd_reloc_status_type
sh_reloc(abfd,reloc_entry,symbol_in,data,input_section,output_bfd,error_message)552*3d8817e4Smiod sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
553*3d8817e4Smiod 	  error_message)
554*3d8817e4Smiod      bfd *abfd;
555*3d8817e4Smiod      arelent *reloc_entry;
556*3d8817e4Smiod      asymbol *symbol_in;
557*3d8817e4Smiod      PTR data;
558*3d8817e4Smiod      asection *input_section;
559*3d8817e4Smiod      bfd *output_bfd;
560*3d8817e4Smiod      char **error_message ATTRIBUTE_UNUSED;
561*3d8817e4Smiod {
562*3d8817e4Smiod   unsigned long insn;
563*3d8817e4Smiod   bfd_vma sym_value;
564*3d8817e4Smiod   unsigned short r_type;
565*3d8817e4Smiod   bfd_vma addr = reloc_entry->address;
566*3d8817e4Smiod   bfd_byte *hit_data = addr + (bfd_byte *) data;
567*3d8817e4Smiod 
568*3d8817e4Smiod   r_type = reloc_entry->howto->type;
569*3d8817e4Smiod 
570*3d8817e4Smiod   if (output_bfd != NULL)
571*3d8817e4Smiod     {
572*3d8817e4Smiod       /* Partial linking--do nothing.  */
573*3d8817e4Smiod       reloc_entry->address += input_section->output_offset;
574*3d8817e4Smiod       return bfd_reloc_ok;
575*3d8817e4Smiod     }
576*3d8817e4Smiod 
577*3d8817e4Smiod   /* Almost all relocs have to do with relaxing.  If any work must be
578*3d8817e4Smiod      done for them, it has been done in sh_relax_section.  */
579*3d8817e4Smiod   if (r_type != R_SH_IMM32
580*3d8817e4Smiod #ifdef COFF_WITH_PE
581*3d8817e4Smiod       && r_type != R_SH_IMM32CE
582*3d8817e4Smiod       && r_type != R_SH_IMAGEBASE
583*3d8817e4Smiod #endif
584*3d8817e4Smiod       && (r_type != R_SH_PCDISP
585*3d8817e4Smiod 	  || (symbol_in->flags & BSF_LOCAL) != 0))
586*3d8817e4Smiod     return bfd_reloc_ok;
587*3d8817e4Smiod 
588*3d8817e4Smiod   if (symbol_in != NULL
589*3d8817e4Smiod       && bfd_is_und_section (symbol_in->section))
590*3d8817e4Smiod     return bfd_reloc_undefined;
591*3d8817e4Smiod 
592*3d8817e4Smiod   sym_value = get_symbol_value (symbol_in);
593*3d8817e4Smiod 
594*3d8817e4Smiod   switch (r_type)
595*3d8817e4Smiod     {
596*3d8817e4Smiod     case R_SH_IMM32:
597*3d8817e4Smiod #ifdef COFF_WITH_PE
598*3d8817e4Smiod     case R_SH_IMM32CE:
599*3d8817e4Smiod #endif
600*3d8817e4Smiod       insn = bfd_get_32 (abfd, hit_data);
601*3d8817e4Smiod       insn += sym_value + reloc_entry->addend;
602*3d8817e4Smiod       bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
603*3d8817e4Smiod       break;
604*3d8817e4Smiod #ifdef COFF_WITH_PE
605*3d8817e4Smiod     case R_SH_IMAGEBASE:
606*3d8817e4Smiod       insn = bfd_get_32 (abfd, hit_data);
607*3d8817e4Smiod       insn += sym_value + reloc_entry->addend;
608*3d8817e4Smiod       insn -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
609*3d8817e4Smiod       bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
610*3d8817e4Smiod       break;
611*3d8817e4Smiod #endif
612*3d8817e4Smiod     case R_SH_PCDISP:
613*3d8817e4Smiod       insn = bfd_get_16 (abfd, hit_data);
614*3d8817e4Smiod       sym_value += reloc_entry->addend;
615*3d8817e4Smiod       sym_value -= (input_section->output_section->vma
616*3d8817e4Smiod 		    + input_section->output_offset
617*3d8817e4Smiod 		    + addr
618*3d8817e4Smiod 		    + 4);
619*3d8817e4Smiod       sym_value += (insn & 0xfff) << 1;
620*3d8817e4Smiod       if (insn & 0x800)
621*3d8817e4Smiod 	sym_value -= 0x1000;
622*3d8817e4Smiod       insn = (insn & 0xf000) | (sym_value & 0xfff);
623*3d8817e4Smiod       bfd_put_16 (abfd, (bfd_vma) insn, hit_data);
624*3d8817e4Smiod       if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000)
625*3d8817e4Smiod 	return bfd_reloc_overflow;
626*3d8817e4Smiod       break;
627*3d8817e4Smiod     default:
628*3d8817e4Smiod       abort ();
629*3d8817e4Smiod       break;
630*3d8817e4Smiod     }
631*3d8817e4Smiod 
632*3d8817e4Smiod   return bfd_reloc_ok;
633*3d8817e4Smiod }
634*3d8817e4Smiod 
635*3d8817e4Smiod #define coff_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
636*3d8817e4Smiod 
637*3d8817e4Smiod /* We can do relaxing.  */
638*3d8817e4Smiod #define coff_bfd_relax_section sh_relax_section
639*3d8817e4Smiod 
640*3d8817e4Smiod /* We use the special COFF backend linker.  */
641*3d8817e4Smiod #define coff_relocate_section sh_relocate_section
642*3d8817e4Smiod 
643*3d8817e4Smiod /* When relaxing, we need to use special code to get the relocated
644*3d8817e4Smiod    section contents.  */
645*3d8817e4Smiod #define coff_bfd_get_relocated_section_contents \
646*3d8817e4Smiod   sh_coff_get_relocated_section_contents
647*3d8817e4Smiod 
648*3d8817e4Smiod #include "coffcode.h"
649*3d8817e4Smiod 
650*3d8817e4Smiod /* This function handles relaxing on the SH.
651*3d8817e4Smiod 
652*3d8817e4Smiod    Function calls on the SH look like this:
653*3d8817e4Smiod 
654*3d8817e4Smiod        movl  L1,r0
655*3d8817e4Smiod        ...
656*3d8817e4Smiod        jsr   @r0
657*3d8817e4Smiod        ...
658*3d8817e4Smiod      L1:
659*3d8817e4Smiod        .long function
660*3d8817e4Smiod 
661*3d8817e4Smiod    The compiler and assembler will cooperate to create R_SH_USES
662*3d8817e4Smiod    relocs on the jsr instructions.  The r_offset field of the
663*3d8817e4Smiod    R_SH_USES reloc is the PC relative offset to the instruction which
664*3d8817e4Smiod    loads the register (the r_offset field is computed as though it
665*3d8817e4Smiod    were a jump instruction, so the offset value is actually from four
666*3d8817e4Smiod    bytes past the instruction).  The linker can use this reloc to
667*3d8817e4Smiod    determine just which function is being called, and thus decide
668*3d8817e4Smiod    whether it is possible to replace the jsr with a bsr.
669*3d8817e4Smiod 
670*3d8817e4Smiod    If multiple function calls are all based on a single register load
671*3d8817e4Smiod    (i.e., the same function is called multiple times), the compiler
672*3d8817e4Smiod    guarantees that each function call will have an R_SH_USES reloc.
673*3d8817e4Smiod    Therefore, if the linker is able to convert each R_SH_USES reloc
674*3d8817e4Smiod    which refers to that address, it can safely eliminate the register
675*3d8817e4Smiod    load.
676*3d8817e4Smiod 
677*3d8817e4Smiod    When the assembler creates an R_SH_USES reloc, it examines it to
678*3d8817e4Smiod    determine which address is being loaded (L1 in the above example).
679*3d8817e4Smiod    It then counts the number of references to that address, and
680*3d8817e4Smiod    creates an R_SH_COUNT reloc at that address.  The r_offset field of
681*3d8817e4Smiod    the R_SH_COUNT reloc will be the number of references.  If the
682*3d8817e4Smiod    linker is able to eliminate a register load, it can use the
683*3d8817e4Smiod    R_SH_COUNT reloc to see whether it can also eliminate the function
684*3d8817e4Smiod    address.
685*3d8817e4Smiod 
686*3d8817e4Smiod    SH relaxing also handles another, unrelated, matter.  On the SH, if
687*3d8817e4Smiod    a load or store instruction is not aligned on a four byte boundary,
688*3d8817e4Smiod    the memory cycle interferes with the 32 bit instruction fetch,
689*3d8817e4Smiod    causing a one cycle bubble in the pipeline.  Therefore, we try to
690*3d8817e4Smiod    align load and store instructions on four byte boundaries if we
691*3d8817e4Smiod    can, by swapping them with one of the adjacent instructions.  */
692*3d8817e4Smiod 
693*3d8817e4Smiod static bfd_boolean
sh_relax_section(abfd,sec,link_info,again)694*3d8817e4Smiod sh_relax_section (abfd, sec, link_info, again)
695*3d8817e4Smiod      bfd *abfd;
696*3d8817e4Smiod      asection *sec;
697*3d8817e4Smiod      struct bfd_link_info *link_info;
698*3d8817e4Smiod      bfd_boolean *again;
699*3d8817e4Smiod {
700*3d8817e4Smiod   struct internal_reloc *internal_relocs;
701*3d8817e4Smiod   bfd_boolean have_code;
702*3d8817e4Smiod   struct internal_reloc *irel, *irelend;
703*3d8817e4Smiod   bfd_byte *contents = NULL;
704*3d8817e4Smiod 
705*3d8817e4Smiod   *again = FALSE;
706*3d8817e4Smiod 
707*3d8817e4Smiod   if (link_info->relocatable
708*3d8817e4Smiod       || (sec->flags & SEC_RELOC) == 0
709*3d8817e4Smiod       || sec->reloc_count == 0)
710*3d8817e4Smiod     return TRUE;
711*3d8817e4Smiod 
712*3d8817e4Smiod   if (coff_section_data (abfd, sec) == NULL)
713*3d8817e4Smiod     {
714*3d8817e4Smiod       bfd_size_type amt = sizeof (struct coff_section_tdata);
715*3d8817e4Smiod       sec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
716*3d8817e4Smiod       if (sec->used_by_bfd == NULL)
717*3d8817e4Smiod 	return FALSE;
718*3d8817e4Smiod     }
719*3d8817e4Smiod 
720*3d8817e4Smiod   internal_relocs = (_bfd_coff_read_internal_relocs
721*3d8817e4Smiod 		     (abfd, sec, link_info->keep_memory,
722*3d8817e4Smiod 		      (bfd_byte *) NULL, FALSE,
723*3d8817e4Smiod 		      (struct internal_reloc *) NULL));
724*3d8817e4Smiod   if (internal_relocs == NULL)
725*3d8817e4Smiod     goto error_return;
726*3d8817e4Smiod 
727*3d8817e4Smiod   have_code = FALSE;
728*3d8817e4Smiod 
729*3d8817e4Smiod   irelend = internal_relocs + sec->reloc_count;
730*3d8817e4Smiod   for (irel = internal_relocs; irel < irelend; irel++)
731*3d8817e4Smiod     {
732*3d8817e4Smiod       bfd_vma laddr, paddr, symval;
733*3d8817e4Smiod       unsigned short insn;
734*3d8817e4Smiod       struct internal_reloc *irelfn, *irelscan, *irelcount;
735*3d8817e4Smiod       struct internal_syment sym;
736*3d8817e4Smiod       bfd_signed_vma foff;
737*3d8817e4Smiod 
738*3d8817e4Smiod       if (irel->r_type == R_SH_CODE)
739*3d8817e4Smiod 	have_code = TRUE;
740*3d8817e4Smiod 
741*3d8817e4Smiod       if (irel->r_type != R_SH_USES)
742*3d8817e4Smiod 	continue;
743*3d8817e4Smiod 
744*3d8817e4Smiod       /* Get the section contents.  */
745*3d8817e4Smiod       if (contents == NULL)
746*3d8817e4Smiod 	{
747*3d8817e4Smiod 	  if (coff_section_data (abfd, sec)->contents != NULL)
748*3d8817e4Smiod 	    contents = coff_section_data (abfd, sec)->contents;
749*3d8817e4Smiod 	  else
750*3d8817e4Smiod 	    {
751*3d8817e4Smiod 	      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
752*3d8817e4Smiod 		goto error_return;
753*3d8817e4Smiod 	    }
754*3d8817e4Smiod 	}
755*3d8817e4Smiod 
756*3d8817e4Smiod       /* The r_offset field of the R_SH_USES reloc will point us to
757*3d8817e4Smiod          the register load.  The 4 is because the r_offset field is
758*3d8817e4Smiod          computed as though it were a jump offset, which are based
759*3d8817e4Smiod          from 4 bytes after the jump instruction.  */
760*3d8817e4Smiod       laddr = irel->r_vaddr - sec->vma + 4;
761*3d8817e4Smiod       /* Careful to sign extend the 32-bit offset.  */
762*3d8817e4Smiod       laddr += ((irel->r_offset & 0xffffffff) ^ 0x80000000) - 0x80000000;
763*3d8817e4Smiod       if (laddr >= sec->size)
764*3d8817e4Smiod 	{
765*3d8817e4Smiod 	  (*_bfd_error_handler) ("%B: 0x%lx: warning: bad R_SH_USES offset",
766*3d8817e4Smiod 				 abfd, (unsigned long) irel->r_vaddr);
767*3d8817e4Smiod 	  continue;
768*3d8817e4Smiod 	}
769*3d8817e4Smiod       insn = bfd_get_16 (abfd, contents + laddr);
770*3d8817e4Smiod 
771*3d8817e4Smiod       /* If the instruction is not mov.l NN,rN, we don't know what to do.  */
772*3d8817e4Smiod       if ((insn & 0xf000) != 0xd000)
773*3d8817e4Smiod 	{
774*3d8817e4Smiod 	  ((*_bfd_error_handler)
775*3d8817e4Smiod 	   ("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x",
776*3d8817e4Smiod 	    abfd, (unsigned long) irel->r_vaddr, insn));
777*3d8817e4Smiod 	  continue;
778*3d8817e4Smiod 	}
779*3d8817e4Smiod 
780*3d8817e4Smiod       /* Get the address from which the register is being loaded.  The
781*3d8817e4Smiod       	 displacement in the mov.l instruction is quadrupled.  It is a
782*3d8817e4Smiod       	 displacement from four bytes after the movl instruction, but,
783*3d8817e4Smiod       	 before adding in the PC address, two least significant bits
784*3d8817e4Smiod       	 of the PC are cleared.  We assume that the section is aligned
785*3d8817e4Smiod       	 on a four byte boundary.  */
786*3d8817e4Smiod       paddr = insn & 0xff;
787*3d8817e4Smiod       paddr *= 4;
788*3d8817e4Smiod       paddr += (laddr + 4) &~ (bfd_vma) 3;
789*3d8817e4Smiod       if (paddr >= sec->size)
790*3d8817e4Smiod 	{
791*3d8817e4Smiod 	  ((*_bfd_error_handler)
792*3d8817e4Smiod 	   ("%B: 0x%lx: warning: bad R_SH_USES load offset",
793*3d8817e4Smiod 	    abfd, (unsigned long) irel->r_vaddr));
794*3d8817e4Smiod 	  continue;
795*3d8817e4Smiod 	}
796*3d8817e4Smiod 
797*3d8817e4Smiod       /* Get the reloc for the address from which the register is
798*3d8817e4Smiod          being loaded.  This reloc will tell us which function is
799*3d8817e4Smiod          actually being called.  */
800*3d8817e4Smiod       paddr += sec->vma;
801*3d8817e4Smiod       for (irelfn = internal_relocs; irelfn < irelend; irelfn++)
802*3d8817e4Smiod 	if (irelfn->r_vaddr == paddr
803*3d8817e4Smiod #ifdef COFF_WITH_PE
804*3d8817e4Smiod 	    && (irelfn->r_type == R_SH_IMM32
805*3d8817e4Smiod 		|| irelfn->r_type == R_SH_IMM32CE
806*3d8817e4Smiod 		|| irelfn->r_type == R_SH_IMAGEBASE)
807*3d8817e4Smiod 
808*3d8817e4Smiod #else
809*3d8817e4Smiod 	    && irelfn->r_type == R_SH_IMM32
810*3d8817e4Smiod #endif
811*3d8817e4Smiod 	    )
812*3d8817e4Smiod 	  break;
813*3d8817e4Smiod       if (irelfn >= irelend)
814*3d8817e4Smiod 	{
815*3d8817e4Smiod 	  ((*_bfd_error_handler)
816*3d8817e4Smiod 	   ("%B: 0x%lx: warning: could not find expected reloc",
817*3d8817e4Smiod 	    abfd, (unsigned long) paddr));
818*3d8817e4Smiod 	  continue;
819*3d8817e4Smiod 	}
820*3d8817e4Smiod 
821*3d8817e4Smiod       /* Get the value of the symbol referred to by the reloc.  */
822*3d8817e4Smiod       if (! _bfd_coff_get_external_symbols (abfd))
823*3d8817e4Smiod 	goto error_return;
824*3d8817e4Smiod       bfd_coff_swap_sym_in (abfd,
825*3d8817e4Smiod 			    ((bfd_byte *) obj_coff_external_syms (abfd)
826*3d8817e4Smiod 			     + (irelfn->r_symndx
827*3d8817e4Smiod 				* bfd_coff_symesz (abfd))),
828*3d8817e4Smiod 			    &sym);
829*3d8817e4Smiod       if (sym.n_scnum != 0 && sym.n_scnum != sec->target_index)
830*3d8817e4Smiod 	{
831*3d8817e4Smiod 	  ((*_bfd_error_handler)
832*3d8817e4Smiod 	   ("%B: 0x%lx: warning: symbol in unexpected section",
833*3d8817e4Smiod 	    abfd, (unsigned long) paddr));
834*3d8817e4Smiod 	  continue;
835*3d8817e4Smiod 	}
836*3d8817e4Smiod 
837*3d8817e4Smiod       if (sym.n_sclass != C_EXT)
838*3d8817e4Smiod 	{
839*3d8817e4Smiod 	  symval = (sym.n_value
840*3d8817e4Smiod 		    - sec->vma
841*3d8817e4Smiod 		    + sec->output_section->vma
842*3d8817e4Smiod 		    + sec->output_offset);
843*3d8817e4Smiod 	}
844*3d8817e4Smiod       else
845*3d8817e4Smiod 	{
846*3d8817e4Smiod 	  struct coff_link_hash_entry *h;
847*3d8817e4Smiod 
848*3d8817e4Smiod 	  h = obj_coff_sym_hashes (abfd)[irelfn->r_symndx];
849*3d8817e4Smiod 	  BFD_ASSERT (h != NULL);
850*3d8817e4Smiod 	  if (h->root.type != bfd_link_hash_defined
851*3d8817e4Smiod 	      && h->root.type != bfd_link_hash_defweak)
852*3d8817e4Smiod 	    {
853*3d8817e4Smiod 	      /* This appears to be a reference to an undefined
854*3d8817e4Smiod                  symbol.  Just ignore it--it will be caught by the
855*3d8817e4Smiod                  regular reloc processing.  */
856*3d8817e4Smiod 	      continue;
857*3d8817e4Smiod 	    }
858*3d8817e4Smiod 
859*3d8817e4Smiod 	  symval = (h->root.u.def.value
860*3d8817e4Smiod 		    + h->root.u.def.section->output_section->vma
861*3d8817e4Smiod 		    + h->root.u.def.section->output_offset);
862*3d8817e4Smiod 	}
863*3d8817e4Smiod 
864*3d8817e4Smiod       symval += bfd_get_32 (abfd, contents + paddr - sec->vma);
865*3d8817e4Smiod 
866*3d8817e4Smiod       /* See if this function call can be shortened.  */
867*3d8817e4Smiod       foff = (symval
868*3d8817e4Smiod 	      - (irel->r_vaddr
869*3d8817e4Smiod 		 - sec->vma
870*3d8817e4Smiod 		 + sec->output_section->vma
871*3d8817e4Smiod 		 + sec->output_offset
872*3d8817e4Smiod 		 + 4));
873*3d8817e4Smiod       if (foff < -0x1000 || foff >= 0x1000)
874*3d8817e4Smiod 	{
875*3d8817e4Smiod 	  /* After all that work, we can't shorten this function call.  */
876*3d8817e4Smiod 	  continue;
877*3d8817e4Smiod 	}
878*3d8817e4Smiod 
879*3d8817e4Smiod       /* Shorten the function call.  */
880*3d8817e4Smiod 
881*3d8817e4Smiod       /* For simplicity of coding, we are going to modify the section
882*3d8817e4Smiod 	 contents, the section relocs, and the BFD symbol table.  We
883*3d8817e4Smiod 	 must tell the rest of the code not to free up this
884*3d8817e4Smiod 	 information.  It would be possible to instead create a table
885*3d8817e4Smiod 	 of changes which have to be made, as is done in coff-mips.c;
886*3d8817e4Smiod 	 that would be more work, but would require less memory when
887*3d8817e4Smiod 	 the linker is run.  */
888*3d8817e4Smiod 
889*3d8817e4Smiod       coff_section_data (abfd, sec)->relocs = internal_relocs;
890*3d8817e4Smiod       coff_section_data (abfd, sec)->keep_relocs = TRUE;
891*3d8817e4Smiod 
892*3d8817e4Smiod       coff_section_data (abfd, sec)->contents = contents;
893*3d8817e4Smiod       coff_section_data (abfd, sec)->keep_contents = TRUE;
894*3d8817e4Smiod 
895*3d8817e4Smiod       obj_coff_keep_syms (abfd) = TRUE;
896*3d8817e4Smiod 
897*3d8817e4Smiod       /* Replace the jsr with a bsr.  */
898*3d8817e4Smiod 
899*3d8817e4Smiod       /* Change the R_SH_USES reloc into an R_SH_PCDISP reloc, and
900*3d8817e4Smiod          replace the jsr with a bsr.  */
901*3d8817e4Smiod       irel->r_type = R_SH_PCDISP;
902*3d8817e4Smiod       irel->r_symndx = irelfn->r_symndx;
903*3d8817e4Smiod       if (sym.n_sclass != C_EXT)
904*3d8817e4Smiod 	{
905*3d8817e4Smiod 	  /* If this needs to be changed because of future relaxing,
906*3d8817e4Smiod              it will be handled here like other internal PCDISP
907*3d8817e4Smiod              relocs.  */
908*3d8817e4Smiod 	  bfd_put_16 (abfd,
909*3d8817e4Smiod 		      (bfd_vma) 0xb000 | ((foff >> 1) & 0xfff),
910*3d8817e4Smiod 		      contents + irel->r_vaddr - sec->vma);
911*3d8817e4Smiod 	}
912*3d8817e4Smiod       else
913*3d8817e4Smiod 	{
914*3d8817e4Smiod 	  /* We can't fully resolve this yet, because the external
915*3d8817e4Smiod              symbol value may be changed by future relaxing.  We let
916*3d8817e4Smiod              the final link phase handle it.  */
917*3d8817e4Smiod 	  bfd_put_16 (abfd, (bfd_vma) 0xb000,
918*3d8817e4Smiod 		      contents + irel->r_vaddr - sec->vma);
919*3d8817e4Smiod 	}
920*3d8817e4Smiod 
921*3d8817e4Smiod       /* See if there is another R_SH_USES reloc referring to the same
922*3d8817e4Smiod          register load.  */
923*3d8817e4Smiod       for (irelscan = internal_relocs; irelscan < irelend; irelscan++)
924*3d8817e4Smiod 	if (irelscan->r_type == R_SH_USES
925*3d8817e4Smiod 	    && laddr == irelscan->r_vaddr - sec->vma + 4 + irelscan->r_offset)
926*3d8817e4Smiod 	  break;
927*3d8817e4Smiod       if (irelscan < irelend)
928*3d8817e4Smiod 	{
929*3d8817e4Smiod 	  /* Some other function call depends upon this register load,
930*3d8817e4Smiod 	     and we have not yet converted that function call.
931*3d8817e4Smiod 	     Indeed, we may never be able to convert it.  There is
932*3d8817e4Smiod 	     nothing else we can do at this point.  */
933*3d8817e4Smiod 	  continue;
934*3d8817e4Smiod 	}
935*3d8817e4Smiod 
936*3d8817e4Smiod       /* Look for a R_SH_COUNT reloc on the location where the
937*3d8817e4Smiod          function address is stored.  Do this before deleting any
938*3d8817e4Smiod          bytes, to avoid confusion about the address.  */
939*3d8817e4Smiod       for (irelcount = internal_relocs; irelcount < irelend; irelcount++)
940*3d8817e4Smiod 	if (irelcount->r_vaddr == paddr
941*3d8817e4Smiod 	    && irelcount->r_type == R_SH_COUNT)
942*3d8817e4Smiod 	  break;
943*3d8817e4Smiod 
944*3d8817e4Smiod       /* Delete the register load.  */
945*3d8817e4Smiod       if (! sh_relax_delete_bytes (abfd, sec, laddr, 2))
946*3d8817e4Smiod 	goto error_return;
947*3d8817e4Smiod 
948*3d8817e4Smiod       /* That will change things, so, just in case it permits some
949*3d8817e4Smiod          other function call to come within range, we should relax
950*3d8817e4Smiod          again.  Note that this is not required, and it may be slow.  */
951*3d8817e4Smiod       *again = TRUE;
952*3d8817e4Smiod 
953*3d8817e4Smiod       /* Now check whether we got a COUNT reloc.  */
954*3d8817e4Smiod       if (irelcount >= irelend)
955*3d8817e4Smiod 	{
956*3d8817e4Smiod 	  ((*_bfd_error_handler)
957*3d8817e4Smiod 	   ("%B: 0x%lx: warning: could not find expected COUNT reloc",
958*3d8817e4Smiod 	    abfd, (unsigned long) paddr));
959*3d8817e4Smiod 	  continue;
960*3d8817e4Smiod 	}
961*3d8817e4Smiod 
962*3d8817e4Smiod       /* The number of uses is stored in the r_offset field.  We've
963*3d8817e4Smiod          just deleted one.  */
964*3d8817e4Smiod       if (irelcount->r_offset == 0)
965*3d8817e4Smiod 	{
966*3d8817e4Smiod 	  ((*_bfd_error_handler) ("%B: 0x%lx: warning: bad count",
967*3d8817e4Smiod 				  abfd, (unsigned long) paddr));
968*3d8817e4Smiod 	  continue;
969*3d8817e4Smiod 	}
970*3d8817e4Smiod 
971*3d8817e4Smiod       --irelcount->r_offset;
972*3d8817e4Smiod 
973*3d8817e4Smiod       /* If there are no more uses, we can delete the address.  Reload
974*3d8817e4Smiod          the address from irelfn, in case it was changed by the
975*3d8817e4Smiod          previous call to sh_relax_delete_bytes.  */
976*3d8817e4Smiod       if (irelcount->r_offset == 0)
977*3d8817e4Smiod 	{
978*3d8817e4Smiod 	  if (! sh_relax_delete_bytes (abfd, sec,
979*3d8817e4Smiod 				       irelfn->r_vaddr - sec->vma, 4))
980*3d8817e4Smiod 	    goto error_return;
981*3d8817e4Smiod 	}
982*3d8817e4Smiod 
983*3d8817e4Smiod       /* We've done all we can with that function call.  */
984*3d8817e4Smiod     }
985*3d8817e4Smiod 
986*3d8817e4Smiod   /* Look for load and store instructions that we can align on four
987*3d8817e4Smiod      byte boundaries.  */
988*3d8817e4Smiod   if (have_code)
989*3d8817e4Smiod     {
990*3d8817e4Smiod       bfd_boolean swapped;
991*3d8817e4Smiod 
992*3d8817e4Smiod       /* Get the section contents.  */
993*3d8817e4Smiod       if (contents == NULL)
994*3d8817e4Smiod 	{
995*3d8817e4Smiod 	  if (coff_section_data (abfd, sec)->contents != NULL)
996*3d8817e4Smiod 	    contents = coff_section_data (abfd, sec)->contents;
997*3d8817e4Smiod 	  else
998*3d8817e4Smiod 	    {
999*3d8817e4Smiod 	      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1000*3d8817e4Smiod 		goto error_return;
1001*3d8817e4Smiod 	    }
1002*3d8817e4Smiod 	}
1003*3d8817e4Smiod 
1004*3d8817e4Smiod       if (! sh_align_loads (abfd, sec, internal_relocs, contents, &swapped))
1005*3d8817e4Smiod 	goto error_return;
1006*3d8817e4Smiod 
1007*3d8817e4Smiod       if (swapped)
1008*3d8817e4Smiod 	{
1009*3d8817e4Smiod 	  coff_section_data (abfd, sec)->relocs = internal_relocs;
1010*3d8817e4Smiod 	  coff_section_data (abfd, sec)->keep_relocs = TRUE;
1011*3d8817e4Smiod 
1012*3d8817e4Smiod 	  coff_section_data (abfd, sec)->contents = contents;
1013*3d8817e4Smiod 	  coff_section_data (abfd, sec)->keep_contents = TRUE;
1014*3d8817e4Smiod 
1015*3d8817e4Smiod 	  obj_coff_keep_syms (abfd) = TRUE;
1016*3d8817e4Smiod 	}
1017*3d8817e4Smiod     }
1018*3d8817e4Smiod 
1019*3d8817e4Smiod   if (internal_relocs != NULL
1020*3d8817e4Smiod       && internal_relocs != coff_section_data (abfd, sec)->relocs)
1021*3d8817e4Smiod     {
1022*3d8817e4Smiod       if (! link_info->keep_memory)
1023*3d8817e4Smiod 	free (internal_relocs);
1024*3d8817e4Smiod       else
1025*3d8817e4Smiod 	coff_section_data (abfd, sec)->relocs = internal_relocs;
1026*3d8817e4Smiod     }
1027*3d8817e4Smiod 
1028*3d8817e4Smiod   if (contents != NULL && contents != coff_section_data (abfd, sec)->contents)
1029*3d8817e4Smiod     {
1030*3d8817e4Smiod       if (! link_info->keep_memory)
1031*3d8817e4Smiod 	free (contents);
1032*3d8817e4Smiod       else
1033*3d8817e4Smiod 	/* Cache the section contents for coff_link_input_bfd.  */
1034*3d8817e4Smiod 	coff_section_data (abfd, sec)->contents = contents;
1035*3d8817e4Smiod     }
1036*3d8817e4Smiod 
1037*3d8817e4Smiod   return TRUE;
1038*3d8817e4Smiod 
1039*3d8817e4Smiod  error_return:
1040*3d8817e4Smiod   if (internal_relocs != NULL
1041*3d8817e4Smiod       && internal_relocs != coff_section_data (abfd, sec)->relocs)
1042*3d8817e4Smiod     free (internal_relocs);
1043*3d8817e4Smiod   if (contents != NULL && contents != coff_section_data (abfd, sec)->contents)
1044*3d8817e4Smiod     free (contents);
1045*3d8817e4Smiod   return FALSE;
1046*3d8817e4Smiod }
1047*3d8817e4Smiod 
1048*3d8817e4Smiod /* Delete some bytes from a section while relaxing.  */
1049*3d8817e4Smiod 
1050*3d8817e4Smiod static bfd_boolean
sh_relax_delete_bytes(abfd,sec,addr,count)1051*3d8817e4Smiod sh_relax_delete_bytes (abfd, sec, addr, count)
1052*3d8817e4Smiod      bfd *abfd;
1053*3d8817e4Smiod      asection *sec;
1054*3d8817e4Smiod      bfd_vma addr;
1055*3d8817e4Smiod      int count;
1056*3d8817e4Smiod {
1057*3d8817e4Smiod   bfd_byte *contents;
1058*3d8817e4Smiod   struct internal_reloc *irel, *irelend;
1059*3d8817e4Smiod   struct internal_reloc *irelalign;
1060*3d8817e4Smiod   bfd_vma toaddr;
1061*3d8817e4Smiod   bfd_byte *esym, *esymend;
1062*3d8817e4Smiod   bfd_size_type symesz;
1063*3d8817e4Smiod   struct coff_link_hash_entry **sym_hash;
1064*3d8817e4Smiod   asection *o;
1065*3d8817e4Smiod 
1066*3d8817e4Smiod   contents = coff_section_data (abfd, sec)->contents;
1067*3d8817e4Smiod 
1068*3d8817e4Smiod   /* The deletion must stop at the next ALIGN reloc for an aligment
1069*3d8817e4Smiod      power larger than the number of bytes we are deleting.  */
1070*3d8817e4Smiod 
1071*3d8817e4Smiod   irelalign = NULL;
1072*3d8817e4Smiod   toaddr = sec->size;
1073*3d8817e4Smiod 
1074*3d8817e4Smiod   irel = coff_section_data (abfd, sec)->relocs;
1075*3d8817e4Smiod   irelend = irel + sec->reloc_count;
1076*3d8817e4Smiod   for (; irel < irelend; irel++)
1077*3d8817e4Smiod     {
1078*3d8817e4Smiod       if (irel->r_type == R_SH_ALIGN
1079*3d8817e4Smiod 	  && irel->r_vaddr - sec->vma > addr
1080*3d8817e4Smiod 	  && count < (1 << irel->r_offset))
1081*3d8817e4Smiod 	{
1082*3d8817e4Smiod 	  irelalign = irel;
1083*3d8817e4Smiod 	  toaddr = irel->r_vaddr - sec->vma;
1084*3d8817e4Smiod 	  break;
1085*3d8817e4Smiod 	}
1086*3d8817e4Smiod     }
1087*3d8817e4Smiod 
1088*3d8817e4Smiod   /* Actually delete the bytes.  */
1089*3d8817e4Smiod   memmove (contents + addr, contents + addr + count,
1090*3d8817e4Smiod 	   (size_t) (toaddr - addr - count));
1091*3d8817e4Smiod   if (irelalign == NULL)
1092*3d8817e4Smiod     sec->size -= count;
1093*3d8817e4Smiod   else
1094*3d8817e4Smiod     {
1095*3d8817e4Smiod       int i;
1096*3d8817e4Smiod 
1097*3d8817e4Smiod #define NOP_OPCODE (0x0009)
1098*3d8817e4Smiod 
1099*3d8817e4Smiod       BFD_ASSERT ((count & 1) == 0);
1100*3d8817e4Smiod       for (i = 0; i < count; i += 2)
1101*3d8817e4Smiod 	bfd_put_16 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i);
1102*3d8817e4Smiod     }
1103*3d8817e4Smiod 
1104*3d8817e4Smiod   /* Adjust all the relocs.  */
1105*3d8817e4Smiod   for (irel = coff_section_data (abfd, sec)->relocs; irel < irelend; irel++)
1106*3d8817e4Smiod     {
1107*3d8817e4Smiod       bfd_vma nraddr, stop;
1108*3d8817e4Smiod       bfd_vma start = 0;
1109*3d8817e4Smiod       int insn = 0;
1110*3d8817e4Smiod       struct internal_syment sym;
1111*3d8817e4Smiod       int off, adjust, oinsn;
1112*3d8817e4Smiod       bfd_signed_vma voff = 0;
1113*3d8817e4Smiod       bfd_boolean overflow;
1114*3d8817e4Smiod 
1115*3d8817e4Smiod       /* Get the new reloc address.  */
1116*3d8817e4Smiod       nraddr = irel->r_vaddr - sec->vma;
1117*3d8817e4Smiod       if ((irel->r_vaddr - sec->vma > addr
1118*3d8817e4Smiod 	   && irel->r_vaddr - sec->vma < toaddr)
1119*3d8817e4Smiod 	  || (irel->r_type == R_SH_ALIGN
1120*3d8817e4Smiod 	      && irel->r_vaddr - sec->vma == toaddr))
1121*3d8817e4Smiod 	nraddr -= count;
1122*3d8817e4Smiod 
1123*3d8817e4Smiod       /* See if this reloc was for the bytes we have deleted, in which
1124*3d8817e4Smiod 	 case we no longer care about it.  Don't delete relocs which
1125*3d8817e4Smiod 	 represent addresses, though.  */
1126*3d8817e4Smiod       if (irel->r_vaddr - sec->vma >= addr
1127*3d8817e4Smiod 	  && irel->r_vaddr - sec->vma < addr + count
1128*3d8817e4Smiod 	  && irel->r_type != R_SH_ALIGN
1129*3d8817e4Smiod 	  && irel->r_type != R_SH_CODE
1130*3d8817e4Smiod 	  && irel->r_type != R_SH_DATA
1131*3d8817e4Smiod 	  && irel->r_type != R_SH_LABEL)
1132*3d8817e4Smiod 	irel->r_type = R_SH_UNUSED;
1133*3d8817e4Smiod 
1134*3d8817e4Smiod       /* If this is a PC relative reloc, see if the range it covers
1135*3d8817e4Smiod          includes the bytes we have deleted.  */
1136*3d8817e4Smiod       switch (irel->r_type)
1137*3d8817e4Smiod 	{
1138*3d8817e4Smiod 	default:
1139*3d8817e4Smiod 	  break;
1140*3d8817e4Smiod 
1141*3d8817e4Smiod 	case R_SH_PCDISP8BY2:
1142*3d8817e4Smiod 	case R_SH_PCDISP:
1143*3d8817e4Smiod 	case R_SH_PCRELIMM8BY2:
1144*3d8817e4Smiod 	case R_SH_PCRELIMM8BY4:
1145*3d8817e4Smiod 	  start = irel->r_vaddr - sec->vma;
1146*3d8817e4Smiod 	  insn = bfd_get_16 (abfd, contents + nraddr);
1147*3d8817e4Smiod 	  break;
1148*3d8817e4Smiod 	}
1149*3d8817e4Smiod 
1150*3d8817e4Smiod       switch (irel->r_type)
1151*3d8817e4Smiod 	{
1152*3d8817e4Smiod 	default:
1153*3d8817e4Smiod 	  start = stop = addr;
1154*3d8817e4Smiod 	  break;
1155*3d8817e4Smiod 
1156*3d8817e4Smiod 	case R_SH_IMM32:
1157*3d8817e4Smiod #ifdef COFF_WITH_PE
1158*3d8817e4Smiod 	case R_SH_IMM32CE:
1159*3d8817e4Smiod 	case R_SH_IMAGEBASE:
1160*3d8817e4Smiod #endif
1161*3d8817e4Smiod 	  /* If this reloc is against a symbol defined in this
1162*3d8817e4Smiod              section, and the symbol will not be adjusted below, we
1163*3d8817e4Smiod              must check the addend to see it will put the value in
1164*3d8817e4Smiod              range to be adjusted, and hence must be changed.  */
1165*3d8817e4Smiod 	  bfd_coff_swap_sym_in (abfd,
1166*3d8817e4Smiod 				((bfd_byte *) obj_coff_external_syms (abfd)
1167*3d8817e4Smiod 				 + (irel->r_symndx
1168*3d8817e4Smiod 				    * bfd_coff_symesz (abfd))),
1169*3d8817e4Smiod 				&sym);
1170*3d8817e4Smiod 	  if (sym.n_sclass != C_EXT
1171*3d8817e4Smiod 	      && sym.n_scnum == sec->target_index
1172*3d8817e4Smiod 	      && ((bfd_vma) sym.n_value <= addr
1173*3d8817e4Smiod 		  || (bfd_vma) sym.n_value >= toaddr))
1174*3d8817e4Smiod 	    {
1175*3d8817e4Smiod 	      bfd_vma val;
1176*3d8817e4Smiod 
1177*3d8817e4Smiod 	      val = bfd_get_32 (abfd, contents + nraddr);
1178*3d8817e4Smiod 	      val += sym.n_value;
1179*3d8817e4Smiod 	      if (val > addr && val < toaddr)
1180*3d8817e4Smiod 		bfd_put_32 (abfd, val - count, contents + nraddr);
1181*3d8817e4Smiod 	    }
1182*3d8817e4Smiod 	  start = stop = addr;
1183*3d8817e4Smiod 	  break;
1184*3d8817e4Smiod 
1185*3d8817e4Smiod 	case R_SH_PCDISP8BY2:
1186*3d8817e4Smiod 	  off = insn & 0xff;
1187*3d8817e4Smiod 	  if (off & 0x80)
1188*3d8817e4Smiod 	    off -= 0x100;
1189*3d8817e4Smiod 	  stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
1190*3d8817e4Smiod 	  break;
1191*3d8817e4Smiod 
1192*3d8817e4Smiod 	case R_SH_PCDISP:
1193*3d8817e4Smiod 	  bfd_coff_swap_sym_in (abfd,
1194*3d8817e4Smiod 				((bfd_byte *) obj_coff_external_syms (abfd)
1195*3d8817e4Smiod 				 + (irel->r_symndx
1196*3d8817e4Smiod 				    * bfd_coff_symesz (abfd))),
1197*3d8817e4Smiod 				&sym);
1198*3d8817e4Smiod 	  if (sym.n_sclass == C_EXT)
1199*3d8817e4Smiod 	    start = stop = addr;
1200*3d8817e4Smiod 	  else
1201*3d8817e4Smiod 	    {
1202*3d8817e4Smiod 	      off = insn & 0xfff;
1203*3d8817e4Smiod 	      if (off & 0x800)
1204*3d8817e4Smiod 		off -= 0x1000;
1205*3d8817e4Smiod 	      stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
1206*3d8817e4Smiod 	    }
1207*3d8817e4Smiod 	  break;
1208*3d8817e4Smiod 
1209*3d8817e4Smiod 	case R_SH_PCRELIMM8BY2:
1210*3d8817e4Smiod 	  off = insn & 0xff;
1211*3d8817e4Smiod 	  stop = start + 4 + off * 2;
1212*3d8817e4Smiod 	  break;
1213*3d8817e4Smiod 
1214*3d8817e4Smiod 	case R_SH_PCRELIMM8BY4:
1215*3d8817e4Smiod 	  off = insn & 0xff;
1216*3d8817e4Smiod 	  stop = (start &~ (bfd_vma) 3) + 4 + off * 4;
1217*3d8817e4Smiod 	  break;
1218*3d8817e4Smiod 
1219*3d8817e4Smiod 	case R_SH_SWITCH8:
1220*3d8817e4Smiod 	case R_SH_SWITCH16:
1221*3d8817e4Smiod 	case R_SH_SWITCH32:
1222*3d8817e4Smiod 	  /* These relocs types represent
1223*3d8817e4Smiod 	       .word L2-L1
1224*3d8817e4Smiod 	     The r_offset field holds the difference between the reloc
1225*3d8817e4Smiod 	     address and L1.  That is the start of the reloc, and
1226*3d8817e4Smiod 	     adding in the contents gives us the top.  We must adjust
1227*3d8817e4Smiod 	     both the r_offset field and the section contents.  */
1228*3d8817e4Smiod 
1229*3d8817e4Smiod 	  start = irel->r_vaddr - sec->vma;
1230*3d8817e4Smiod 	  stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_offset);
1231*3d8817e4Smiod 
1232*3d8817e4Smiod 	  if (start > addr
1233*3d8817e4Smiod 	      && start < toaddr
1234*3d8817e4Smiod 	      && (stop <= addr || stop >= toaddr))
1235*3d8817e4Smiod 	    irel->r_offset += count;
1236*3d8817e4Smiod 	  else if (stop > addr
1237*3d8817e4Smiod 		   && stop < toaddr
1238*3d8817e4Smiod 		   && (start <= addr || start >= toaddr))
1239*3d8817e4Smiod 	    irel->r_offset -= count;
1240*3d8817e4Smiod 
1241*3d8817e4Smiod 	  start = stop;
1242*3d8817e4Smiod 
1243*3d8817e4Smiod 	  if (irel->r_type == R_SH_SWITCH16)
1244*3d8817e4Smiod 	    voff = bfd_get_signed_16 (abfd, contents + nraddr);
1245*3d8817e4Smiod 	  else if (irel->r_type == R_SH_SWITCH8)
1246*3d8817e4Smiod 	    voff = bfd_get_8 (abfd, contents + nraddr);
1247*3d8817e4Smiod 	  else
1248*3d8817e4Smiod 	    voff = bfd_get_signed_32 (abfd, contents + nraddr);
1249*3d8817e4Smiod 	  stop = (bfd_vma) ((bfd_signed_vma) start + voff);
1250*3d8817e4Smiod 
1251*3d8817e4Smiod 	  break;
1252*3d8817e4Smiod 
1253*3d8817e4Smiod 	case R_SH_USES:
1254*3d8817e4Smiod 	  start = irel->r_vaddr - sec->vma;
1255*3d8817e4Smiod 	  stop = (bfd_vma) ((bfd_signed_vma) start
1256*3d8817e4Smiod 			    + (long) irel->r_offset
1257*3d8817e4Smiod 			    + 4);
1258*3d8817e4Smiod 	  break;
1259*3d8817e4Smiod 	}
1260*3d8817e4Smiod 
1261*3d8817e4Smiod       if (start > addr
1262*3d8817e4Smiod 	  && start < toaddr
1263*3d8817e4Smiod 	  && (stop <= addr || stop >= toaddr))
1264*3d8817e4Smiod 	adjust = count;
1265*3d8817e4Smiod       else if (stop > addr
1266*3d8817e4Smiod 	       && stop < toaddr
1267*3d8817e4Smiod 	       && (start <= addr || start >= toaddr))
1268*3d8817e4Smiod 	adjust = - count;
1269*3d8817e4Smiod       else
1270*3d8817e4Smiod 	adjust = 0;
1271*3d8817e4Smiod 
1272*3d8817e4Smiod       if (adjust != 0)
1273*3d8817e4Smiod 	{
1274*3d8817e4Smiod 	  oinsn = insn;
1275*3d8817e4Smiod 	  overflow = FALSE;
1276*3d8817e4Smiod 	  switch (irel->r_type)
1277*3d8817e4Smiod 	    {
1278*3d8817e4Smiod 	    default:
1279*3d8817e4Smiod 	      abort ();
1280*3d8817e4Smiod 	      break;
1281*3d8817e4Smiod 
1282*3d8817e4Smiod 	    case R_SH_PCDISP8BY2:
1283*3d8817e4Smiod 	    case R_SH_PCRELIMM8BY2:
1284*3d8817e4Smiod 	      insn += adjust / 2;
1285*3d8817e4Smiod 	      if ((oinsn & 0xff00) != (insn & 0xff00))
1286*3d8817e4Smiod 		overflow = TRUE;
1287*3d8817e4Smiod 	      bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
1288*3d8817e4Smiod 	      break;
1289*3d8817e4Smiod 
1290*3d8817e4Smiod 	    case R_SH_PCDISP:
1291*3d8817e4Smiod 	      insn += adjust / 2;
1292*3d8817e4Smiod 	      if ((oinsn & 0xf000) != (insn & 0xf000))
1293*3d8817e4Smiod 		overflow = TRUE;
1294*3d8817e4Smiod 	      bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
1295*3d8817e4Smiod 	      break;
1296*3d8817e4Smiod 
1297*3d8817e4Smiod 	    case R_SH_PCRELIMM8BY4:
1298*3d8817e4Smiod 	      BFD_ASSERT (adjust == count || count >= 4);
1299*3d8817e4Smiod 	      if (count >= 4)
1300*3d8817e4Smiod 		insn += adjust / 4;
1301*3d8817e4Smiod 	      else
1302*3d8817e4Smiod 		{
1303*3d8817e4Smiod 		  if ((irel->r_vaddr & 3) == 0)
1304*3d8817e4Smiod 		    ++insn;
1305*3d8817e4Smiod 		}
1306*3d8817e4Smiod 	      if ((oinsn & 0xff00) != (insn & 0xff00))
1307*3d8817e4Smiod 		overflow = TRUE;
1308*3d8817e4Smiod 	      bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
1309*3d8817e4Smiod 	      break;
1310*3d8817e4Smiod 
1311*3d8817e4Smiod 	    case R_SH_SWITCH8:
1312*3d8817e4Smiod 	      voff += adjust;
1313*3d8817e4Smiod 	      if (voff < 0 || voff >= 0xff)
1314*3d8817e4Smiod 		overflow = TRUE;
1315*3d8817e4Smiod 	      bfd_put_8 (abfd, (bfd_vma) voff, contents + nraddr);
1316*3d8817e4Smiod 	      break;
1317*3d8817e4Smiod 
1318*3d8817e4Smiod 	    case R_SH_SWITCH16:
1319*3d8817e4Smiod 	      voff += adjust;
1320*3d8817e4Smiod 	      if (voff < - 0x8000 || voff >= 0x8000)
1321*3d8817e4Smiod 		overflow = TRUE;
1322*3d8817e4Smiod 	      bfd_put_signed_16 (abfd, (bfd_vma) voff, contents + nraddr);
1323*3d8817e4Smiod 	      break;
1324*3d8817e4Smiod 
1325*3d8817e4Smiod 	    case R_SH_SWITCH32:
1326*3d8817e4Smiod 	      voff += adjust;
1327*3d8817e4Smiod 	      bfd_put_signed_32 (abfd, (bfd_vma) voff, contents + nraddr);
1328*3d8817e4Smiod 	      break;
1329*3d8817e4Smiod 
1330*3d8817e4Smiod 	    case R_SH_USES:
1331*3d8817e4Smiod 	      irel->r_offset += adjust;
1332*3d8817e4Smiod 	      break;
1333*3d8817e4Smiod 	    }
1334*3d8817e4Smiod 
1335*3d8817e4Smiod 	  if (overflow)
1336*3d8817e4Smiod 	    {
1337*3d8817e4Smiod 	      ((*_bfd_error_handler)
1338*3d8817e4Smiod 	       ("%B: 0x%lx: fatal: reloc overflow while relaxing",
1339*3d8817e4Smiod 		abfd, (unsigned long) irel->r_vaddr));
1340*3d8817e4Smiod 	      bfd_set_error (bfd_error_bad_value);
1341*3d8817e4Smiod 	      return FALSE;
1342*3d8817e4Smiod 	    }
1343*3d8817e4Smiod 	}
1344*3d8817e4Smiod 
1345*3d8817e4Smiod       irel->r_vaddr = nraddr + sec->vma;
1346*3d8817e4Smiod     }
1347*3d8817e4Smiod 
1348*3d8817e4Smiod   /* Look through all the other sections.  If there contain any IMM32
1349*3d8817e4Smiod      relocs against internal symbols which we are not going to adjust
1350*3d8817e4Smiod      below, we may need to adjust the addends.  */
1351*3d8817e4Smiod   for (o = abfd->sections; o != NULL; o = o->next)
1352*3d8817e4Smiod     {
1353*3d8817e4Smiod       struct internal_reloc *internal_relocs;
1354*3d8817e4Smiod       struct internal_reloc *irelscan, *irelscanend;
1355*3d8817e4Smiod       bfd_byte *ocontents;
1356*3d8817e4Smiod 
1357*3d8817e4Smiod       if (o == sec
1358*3d8817e4Smiod 	  || (o->flags & SEC_RELOC) == 0
1359*3d8817e4Smiod 	  || o->reloc_count == 0)
1360*3d8817e4Smiod 	continue;
1361*3d8817e4Smiod 
1362*3d8817e4Smiod       /* We always cache the relocs.  Perhaps, if info->keep_memory is
1363*3d8817e4Smiod          FALSE, we should free them, if we are permitted to, when we
1364*3d8817e4Smiod          leave sh_coff_relax_section.  */
1365*3d8817e4Smiod       internal_relocs = (_bfd_coff_read_internal_relocs
1366*3d8817e4Smiod 			 (abfd, o, TRUE, (bfd_byte *) NULL, FALSE,
1367*3d8817e4Smiod 			  (struct internal_reloc *) NULL));
1368*3d8817e4Smiod       if (internal_relocs == NULL)
1369*3d8817e4Smiod 	return FALSE;
1370*3d8817e4Smiod 
1371*3d8817e4Smiod       ocontents = NULL;
1372*3d8817e4Smiod       irelscanend = internal_relocs + o->reloc_count;
1373*3d8817e4Smiod       for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++)
1374*3d8817e4Smiod 	{
1375*3d8817e4Smiod 	  struct internal_syment sym;
1376*3d8817e4Smiod 
1377*3d8817e4Smiod #ifdef COFF_WITH_PE
1378*3d8817e4Smiod 	  if (irelscan->r_type != R_SH_IMM32
1379*3d8817e4Smiod 	      && irelscan->r_type != R_SH_IMAGEBASE
1380*3d8817e4Smiod 	      && irelscan->r_type != R_SH_IMM32CE)
1381*3d8817e4Smiod #else
1382*3d8817e4Smiod 	  if (irelscan->r_type != R_SH_IMM32)
1383*3d8817e4Smiod #endif
1384*3d8817e4Smiod 	    continue;
1385*3d8817e4Smiod 
1386*3d8817e4Smiod 	  bfd_coff_swap_sym_in (abfd,
1387*3d8817e4Smiod 				((bfd_byte *) obj_coff_external_syms (abfd)
1388*3d8817e4Smiod 				 + (irelscan->r_symndx
1389*3d8817e4Smiod 				    * bfd_coff_symesz (abfd))),
1390*3d8817e4Smiod 				&sym);
1391*3d8817e4Smiod 	  if (sym.n_sclass != C_EXT
1392*3d8817e4Smiod 	      && sym.n_scnum == sec->target_index
1393*3d8817e4Smiod 	      && ((bfd_vma) sym.n_value <= addr
1394*3d8817e4Smiod 		  || (bfd_vma) sym.n_value >= toaddr))
1395*3d8817e4Smiod 	    {
1396*3d8817e4Smiod 	      bfd_vma val;
1397*3d8817e4Smiod 
1398*3d8817e4Smiod 	      if (ocontents == NULL)
1399*3d8817e4Smiod 		{
1400*3d8817e4Smiod 		  if (coff_section_data (abfd, o)->contents != NULL)
1401*3d8817e4Smiod 		    ocontents = coff_section_data (abfd, o)->contents;
1402*3d8817e4Smiod 		  else
1403*3d8817e4Smiod 		    {
1404*3d8817e4Smiod 		      if (!bfd_malloc_and_get_section (abfd, o, &ocontents))
1405*3d8817e4Smiod 			return FALSE;
1406*3d8817e4Smiod 		      /* We always cache the section contents.
1407*3d8817e4Smiod                          Perhaps, if info->keep_memory is FALSE, we
1408*3d8817e4Smiod                          should free them, if we are permitted to,
1409*3d8817e4Smiod                          when we leave sh_coff_relax_section.  */
1410*3d8817e4Smiod 		      coff_section_data (abfd, o)->contents = ocontents;
1411*3d8817e4Smiod 		    }
1412*3d8817e4Smiod 		}
1413*3d8817e4Smiod 
1414*3d8817e4Smiod 	      val = bfd_get_32 (abfd, ocontents + irelscan->r_vaddr - o->vma);
1415*3d8817e4Smiod 	      val += sym.n_value;
1416*3d8817e4Smiod 	      if (val > addr && val < toaddr)
1417*3d8817e4Smiod 		bfd_put_32 (abfd, val - count,
1418*3d8817e4Smiod 			    ocontents + irelscan->r_vaddr - o->vma);
1419*3d8817e4Smiod 
1420*3d8817e4Smiod 	      coff_section_data (abfd, o)->keep_contents = TRUE;
1421*3d8817e4Smiod 	    }
1422*3d8817e4Smiod 	}
1423*3d8817e4Smiod     }
1424*3d8817e4Smiod 
1425*3d8817e4Smiod   /* Adjusting the internal symbols will not work if something has
1426*3d8817e4Smiod      already retrieved the generic symbols.  It would be possible to
1427*3d8817e4Smiod      make this work by adjusting the generic symbols at the same time.
1428*3d8817e4Smiod      However, this case should not arise in normal usage.  */
1429*3d8817e4Smiod   if (obj_symbols (abfd) != NULL
1430*3d8817e4Smiod       || obj_raw_syments (abfd) != NULL)
1431*3d8817e4Smiod     {
1432*3d8817e4Smiod       ((*_bfd_error_handler)
1433*3d8817e4Smiod        ("%B: fatal: generic symbols retrieved before relaxing", abfd));
1434*3d8817e4Smiod       bfd_set_error (bfd_error_invalid_operation);
1435*3d8817e4Smiod       return FALSE;
1436*3d8817e4Smiod     }
1437*3d8817e4Smiod 
1438*3d8817e4Smiod   /* Adjust all the symbols.  */
1439*3d8817e4Smiod   sym_hash = obj_coff_sym_hashes (abfd);
1440*3d8817e4Smiod   symesz = bfd_coff_symesz (abfd);
1441*3d8817e4Smiod   esym = (bfd_byte *) obj_coff_external_syms (abfd);
1442*3d8817e4Smiod   esymend = esym + obj_raw_syment_count (abfd) * symesz;
1443*3d8817e4Smiod   while (esym < esymend)
1444*3d8817e4Smiod     {
1445*3d8817e4Smiod       struct internal_syment isym;
1446*3d8817e4Smiod 
1447*3d8817e4Smiod       bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
1448*3d8817e4Smiod 
1449*3d8817e4Smiod       if (isym.n_scnum == sec->target_index
1450*3d8817e4Smiod 	  && (bfd_vma) isym.n_value > addr
1451*3d8817e4Smiod 	  && (bfd_vma) isym.n_value < toaddr)
1452*3d8817e4Smiod 	{
1453*3d8817e4Smiod 	  isym.n_value -= count;
1454*3d8817e4Smiod 
1455*3d8817e4Smiod 	  bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym);
1456*3d8817e4Smiod 
1457*3d8817e4Smiod 	  if (*sym_hash != NULL)
1458*3d8817e4Smiod 	    {
1459*3d8817e4Smiod 	      BFD_ASSERT ((*sym_hash)->root.type == bfd_link_hash_defined
1460*3d8817e4Smiod 			  || (*sym_hash)->root.type == bfd_link_hash_defweak);
1461*3d8817e4Smiod 	      BFD_ASSERT ((*sym_hash)->root.u.def.value >= addr
1462*3d8817e4Smiod 			  && (*sym_hash)->root.u.def.value < toaddr);
1463*3d8817e4Smiod 	      (*sym_hash)->root.u.def.value -= count;
1464*3d8817e4Smiod 	    }
1465*3d8817e4Smiod 	}
1466*3d8817e4Smiod 
1467*3d8817e4Smiod       esym += (isym.n_numaux + 1) * symesz;
1468*3d8817e4Smiod       sym_hash += isym.n_numaux + 1;
1469*3d8817e4Smiod     }
1470*3d8817e4Smiod 
1471*3d8817e4Smiod   /* See if we can move the ALIGN reloc forward.  We have adjusted
1472*3d8817e4Smiod      r_vaddr for it already.  */
1473*3d8817e4Smiod   if (irelalign != NULL)
1474*3d8817e4Smiod     {
1475*3d8817e4Smiod       bfd_vma alignto, alignaddr;
1476*3d8817e4Smiod 
1477*3d8817e4Smiod       alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_offset);
1478*3d8817e4Smiod       alignaddr = BFD_ALIGN (irelalign->r_vaddr - sec->vma,
1479*3d8817e4Smiod 			     1 << irelalign->r_offset);
1480*3d8817e4Smiod       if (alignto != alignaddr)
1481*3d8817e4Smiod 	{
1482*3d8817e4Smiod 	  /* Tail recursion.  */
1483*3d8817e4Smiod 	  return sh_relax_delete_bytes (abfd, sec, alignaddr,
1484*3d8817e4Smiod 					(int) (alignto - alignaddr));
1485*3d8817e4Smiod 	}
1486*3d8817e4Smiod     }
1487*3d8817e4Smiod 
1488*3d8817e4Smiod   return TRUE;
1489*3d8817e4Smiod }
1490*3d8817e4Smiod 
1491*3d8817e4Smiod /* This is yet another version of the SH opcode table, used to rapidly
1492*3d8817e4Smiod    get information about a particular instruction.  */
1493*3d8817e4Smiod 
1494*3d8817e4Smiod /* The opcode map is represented by an array of these structures.  The
1495*3d8817e4Smiod    array is indexed by the high order four bits in the instruction.  */
1496*3d8817e4Smiod 
1497*3d8817e4Smiod struct sh_major_opcode
1498*3d8817e4Smiod {
1499*3d8817e4Smiod   /* A pointer to the instruction list.  This is an array which
1500*3d8817e4Smiod      contains all the instructions with this major opcode.  */
1501*3d8817e4Smiod   const struct sh_minor_opcode *minor_opcodes;
1502*3d8817e4Smiod   /* The number of elements in minor_opcodes.  */
1503*3d8817e4Smiod   unsigned short count;
1504*3d8817e4Smiod };
1505*3d8817e4Smiod 
1506*3d8817e4Smiod /* This structure holds information for a set of SH opcodes.  The
1507*3d8817e4Smiod    instruction code is anded with the mask value, and the resulting
1508*3d8817e4Smiod    value is used to search the order opcode list.  */
1509*3d8817e4Smiod 
1510*3d8817e4Smiod struct sh_minor_opcode
1511*3d8817e4Smiod {
1512*3d8817e4Smiod   /* The sorted opcode list.  */
1513*3d8817e4Smiod   const struct sh_opcode *opcodes;
1514*3d8817e4Smiod   /* The number of elements in opcodes.  */
1515*3d8817e4Smiod   unsigned short count;
1516*3d8817e4Smiod   /* The mask value to use when searching the opcode list.  */
1517*3d8817e4Smiod   unsigned short mask;
1518*3d8817e4Smiod };
1519*3d8817e4Smiod 
1520*3d8817e4Smiod /* This structure holds information for an SH instruction.  An array
1521*3d8817e4Smiod    of these structures is sorted in order by opcode.  */
1522*3d8817e4Smiod 
1523*3d8817e4Smiod struct sh_opcode
1524*3d8817e4Smiod {
1525*3d8817e4Smiod   /* The code for this instruction, after it has been anded with the
1526*3d8817e4Smiod      mask value in the sh_major_opcode structure.  */
1527*3d8817e4Smiod   unsigned short opcode;
1528*3d8817e4Smiod   /* Flags for this instruction.  */
1529*3d8817e4Smiod   unsigned long flags;
1530*3d8817e4Smiod };
1531*3d8817e4Smiod 
1532*3d8817e4Smiod /* Flag which appear in the sh_opcode structure.  */
1533*3d8817e4Smiod 
1534*3d8817e4Smiod /* This instruction loads a value from memory.  */
1535*3d8817e4Smiod #define LOAD (0x1)
1536*3d8817e4Smiod 
1537*3d8817e4Smiod /* This instruction stores a value to memory.  */
1538*3d8817e4Smiod #define STORE (0x2)
1539*3d8817e4Smiod 
1540*3d8817e4Smiod /* This instruction is a branch.  */
1541*3d8817e4Smiod #define BRANCH (0x4)
1542*3d8817e4Smiod 
1543*3d8817e4Smiod /* This instruction has a delay slot.  */
1544*3d8817e4Smiod #define DELAY (0x8)
1545*3d8817e4Smiod 
1546*3d8817e4Smiod /* This instruction uses the value in the register in the field at
1547*3d8817e4Smiod    mask 0x0f00 of the instruction.  */
1548*3d8817e4Smiod #define USES1 (0x10)
1549*3d8817e4Smiod #define USES1_REG(x) ((x & 0x0f00) >> 8)
1550*3d8817e4Smiod 
1551*3d8817e4Smiod /* This instruction uses the value in the register in the field at
1552*3d8817e4Smiod    mask 0x00f0 of the instruction.  */
1553*3d8817e4Smiod #define USES2 (0x20)
1554*3d8817e4Smiod #define USES2_REG(x) ((x & 0x00f0) >> 4)
1555*3d8817e4Smiod 
1556*3d8817e4Smiod /* This instruction uses the value in register 0.  */
1557*3d8817e4Smiod #define USESR0 (0x40)
1558*3d8817e4Smiod 
1559*3d8817e4Smiod /* This instruction sets the value in the register in the field at
1560*3d8817e4Smiod    mask 0x0f00 of the instruction.  */
1561*3d8817e4Smiod #define SETS1 (0x80)
1562*3d8817e4Smiod #define SETS1_REG(x) ((x & 0x0f00) >> 8)
1563*3d8817e4Smiod 
1564*3d8817e4Smiod /* This instruction sets the value in the register in the field at
1565*3d8817e4Smiod    mask 0x00f0 of the instruction.  */
1566*3d8817e4Smiod #define SETS2 (0x100)
1567*3d8817e4Smiod #define SETS2_REG(x) ((x & 0x00f0) >> 4)
1568*3d8817e4Smiod 
1569*3d8817e4Smiod /* This instruction sets register 0.  */
1570*3d8817e4Smiod #define SETSR0 (0x200)
1571*3d8817e4Smiod 
1572*3d8817e4Smiod /* This instruction sets a special register.  */
1573*3d8817e4Smiod #define SETSSP (0x400)
1574*3d8817e4Smiod 
1575*3d8817e4Smiod /* This instruction uses a special register.  */
1576*3d8817e4Smiod #define USESSP (0x800)
1577*3d8817e4Smiod 
1578*3d8817e4Smiod /* This instruction uses the floating point register in the field at
1579*3d8817e4Smiod    mask 0x0f00 of the instruction.  */
1580*3d8817e4Smiod #define USESF1 (0x1000)
1581*3d8817e4Smiod #define USESF1_REG(x) ((x & 0x0f00) >> 8)
1582*3d8817e4Smiod 
1583*3d8817e4Smiod /* This instruction uses the floating point register in the field at
1584*3d8817e4Smiod    mask 0x00f0 of the instruction.  */
1585*3d8817e4Smiod #define USESF2 (0x2000)
1586*3d8817e4Smiod #define USESF2_REG(x) ((x & 0x00f0) >> 4)
1587*3d8817e4Smiod 
1588*3d8817e4Smiod /* This instruction uses floating point register 0.  */
1589*3d8817e4Smiod #define USESF0 (0x4000)
1590*3d8817e4Smiod 
1591*3d8817e4Smiod /* This instruction sets the floating point register in the field at
1592*3d8817e4Smiod    mask 0x0f00 of the instruction.  */
1593*3d8817e4Smiod #define SETSF1 (0x8000)
1594*3d8817e4Smiod #define SETSF1_REG(x) ((x & 0x0f00) >> 8)
1595*3d8817e4Smiod 
1596*3d8817e4Smiod #define USESAS (0x10000)
1597*3d8817e4Smiod #define USESAS_REG(x) (((((x) >> 8) - 2) & 3) + 2)
1598*3d8817e4Smiod #define USESR8 (0x20000)
1599*3d8817e4Smiod #define SETSAS (0x40000)
1600*3d8817e4Smiod #define SETSAS_REG(x) USESAS_REG (x)
1601*3d8817e4Smiod 
1602*3d8817e4Smiod #define MAP(a) a, sizeof a / sizeof a[0]
1603*3d8817e4Smiod 
1604*3d8817e4Smiod #ifndef COFF_IMAGE_WITH_PE
1605*3d8817e4Smiod static bfd_boolean sh_insn_uses_reg
1606*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1607*3d8817e4Smiod static bfd_boolean sh_insn_sets_reg
1608*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1609*3d8817e4Smiod static bfd_boolean sh_insn_uses_or_sets_reg
1610*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1611*3d8817e4Smiod static bfd_boolean sh_insn_uses_freg
1612*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1613*3d8817e4Smiod static bfd_boolean sh_insn_sets_freg
1614*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1615*3d8817e4Smiod static bfd_boolean sh_insn_uses_or_sets_freg
1616*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1617*3d8817e4Smiod static bfd_boolean sh_insns_conflict
1618*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int,
1619*3d8817e4Smiod 	   const struct sh_opcode *));
1620*3d8817e4Smiod static bfd_boolean sh_load_use
1621*3d8817e4Smiod   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int,
1622*3d8817e4Smiod 	   const struct sh_opcode *));
1623*3d8817e4Smiod 
1624*3d8817e4Smiod /* The opcode maps.  */
1625*3d8817e4Smiod 
1626*3d8817e4Smiod static const struct sh_opcode sh_opcode00[] =
1627*3d8817e4Smiod {
1628*3d8817e4Smiod   { 0x0008, SETSSP },			/* clrt */
1629*3d8817e4Smiod   { 0x0009, 0 },			/* nop */
1630*3d8817e4Smiod   { 0x000b, BRANCH | DELAY | USESSP },	/* rts */
1631*3d8817e4Smiod   { 0x0018, SETSSP },			/* sett */
1632*3d8817e4Smiod   { 0x0019, SETSSP },			/* div0u */
1633*3d8817e4Smiod   { 0x001b, 0 },			/* sleep */
1634*3d8817e4Smiod   { 0x0028, SETSSP },			/* clrmac */
1635*3d8817e4Smiod   { 0x002b, BRANCH | DELAY | SETSSP },	/* rte */
1636*3d8817e4Smiod   { 0x0038, USESSP | SETSSP },		/* ldtlb */
1637*3d8817e4Smiod   { 0x0048, SETSSP },			/* clrs */
1638*3d8817e4Smiod   { 0x0058, SETSSP }			/* sets */
1639*3d8817e4Smiod };
1640*3d8817e4Smiod 
1641*3d8817e4Smiod static const struct sh_opcode sh_opcode01[] =
1642*3d8817e4Smiod {
1643*3d8817e4Smiod   { 0x0003, BRANCH | DELAY | USES1 | SETSSP },	/* bsrf rn */
1644*3d8817e4Smiod   { 0x000a, SETS1 | USESSP },			/* sts mach,rn */
1645*3d8817e4Smiod   { 0x001a, SETS1 | USESSP },			/* sts macl,rn */
1646*3d8817e4Smiod   { 0x0023, BRANCH | DELAY | USES1 },		/* braf rn */
1647*3d8817e4Smiod   { 0x0029, SETS1 | USESSP },			/* movt rn */
1648*3d8817e4Smiod   { 0x002a, SETS1 | USESSP },			/* sts pr,rn */
1649*3d8817e4Smiod   { 0x005a, SETS1 | USESSP },			/* sts fpul,rn */
1650*3d8817e4Smiod   { 0x006a, SETS1 | USESSP },			/* sts fpscr,rn / sts dsr,rn */
1651*3d8817e4Smiod   { 0x0083, LOAD | USES1 },			/* pref @rn */
1652*3d8817e4Smiod   { 0x007a, SETS1 | USESSP },			/* sts a0,rn */
1653*3d8817e4Smiod   { 0x008a, SETS1 | USESSP },			/* sts x0,rn */
1654*3d8817e4Smiod   { 0x009a, SETS1 | USESSP },			/* sts x1,rn */
1655*3d8817e4Smiod   { 0x00aa, SETS1 | USESSP },			/* sts y0,rn */
1656*3d8817e4Smiod   { 0x00ba, SETS1 | USESSP }			/* sts y1,rn */
1657*3d8817e4Smiod };
1658*3d8817e4Smiod 
1659*3d8817e4Smiod static const struct sh_opcode sh_opcode02[] =
1660*3d8817e4Smiod {
1661*3d8817e4Smiod   { 0x0002, SETS1 | USESSP },			/* stc <special_reg>,rn */
1662*3d8817e4Smiod   { 0x0004, STORE | USES1 | USES2 | USESR0 },	/* mov.b rm,@(r0,rn) */
1663*3d8817e4Smiod   { 0x0005, STORE | USES1 | USES2 | USESR0 },	/* mov.w rm,@(r0,rn) */
1664*3d8817e4Smiod   { 0x0006, STORE | USES1 | USES2 | USESR0 },	/* mov.l rm,@(r0,rn) */
1665*3d8817e4Smiod   { 0x0007, SETSSP | USES1 | USES2 },		/* mul.l rm,rn */
1666*3d8817e4Smiod   { 0x000c, LOAD | SETS1 | USES2 | USESR0 },	/* mov.b @(r0,rm),rn */
1667*3d8817e4Smiod   { 0x000d, LOAD | SETS1 | USES2 | USESR0 },	/* mov.w @(r0,rm),rn */
1668*3d8817e4Smiod   { 0x000e, LOAD | SETS1 | USES2 | USESR0 },	/* mov.l @(r0,rm),rn */
1669*3d8817e4Smiod   { 0x000f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.l @rm+,@rn+ */
1670*3d8817e4Smiod };
1671*3d8817e4Smiod 
1672*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode0[] =
1673*3d8817e4Smiod {
1674*3d8817e4Smiod   { MAP (sh_opcode00), 0xffff },
1675*3d8817e4Smiod   { MAP (sh_opcode01), 0xf0ff },
1676*3d8817e4Smiod   { MAP (sh_opcode02), 0xf00f }
1677*3d8817e4Smiod };
1678*3d8817e4Smiod 
1679*3d8817e4Smiod static const struct sh_opcode sh_opcode10[] =
1680*3d8817e4Smiod {
1681*3d8817e4Smiod   { 0x1000, STORE | USES1 | USES2 }	/* mov.l rm,@(disp,rn) */
1682*3d8817e4Smiod };
1683*3d8817e4Smiod 
1684*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode1[] =
1685*3d8817e4Smiod {
1686*3d8817e4Smiod   { MAP (sh_opcode10), 0xf000 }
1687*3d8817e4Smiod };
1688*3d8817e4Smiod 
1689*3d8817e4Smiod static const struct sh_opcode sh_opcode20[] =
1690*3d8817e4Smiod {
1691*3d8817e4Smiod   { 0x2000, STORE | USES1 | USES2 },		/* mov.b rm,@rn */
1692*3d8817e4Smiod   { 0x2001, STORE | USES1 | USES2 },		/* mov.w rm,@rn */
1693*3d8817e4Smiod   { 0x2002, STORE | USES1 | USES2 },		/* mov.l rm,@rn */
1694*3d8817e4Smiod   { 0x2004, STORE | SETS1 | USES1 | USES2 },	/* mov.b rm,@-rn */
1695*3d8817e4Smiod   { 0x2005, STORE | SETS1 | USES1 | USES2 },	/* mov.w rm,@-rn */
1696*3d8817e4Smiod   { 0x2006, STORE | SETS1 | USES1 | USES2 },	/* mov.l rm,@-rn */
1697*3d8817e4Smiod   { 0x2007, SETSSP | USES1 | USES2 | USESSP },	/* div0s */
1698*3d8817e4Smiod   { 0x2008, SETSSP | USES1 | USES2 },		/* tst rm,rn */
1699*3d8817e4Smiod   { 0x2009, SETS1 | USES1 | USES2 },		/* and rm,rn */
1700*3d8817e4Smiod   { 0x200a, SETS1 | USES1 | USES2 },		/* xor rm,rn */
1701*3d8817e4Smiod   { 0x200b, SETS1 | USES1 | USES2 },		/* or rm,rn */
1702*3d8817e4Smiod   { 0x200c, SETSSP | USES1 | USES2 },		/* cmp/str rm,rn */
1703*3d8817e4Smiod   { 0x200d, SETS1 | USES1 | USES2 },		/* xtrct rm,rn */
1704*3d8817e4Smiod   { 0x200e, SETSSP | USES1 | USES2 },		/* mulu.w rm,rn */
1705*3d8817e4Smiod   { 0x200f, SETSSP | USES1 | USES2 }		/* muls.w rm,rn */
1706*3d8817e4Smiod };
1707*3d8817e4Smiod 
1708*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode2[] =
1709*3d8817e4Smiod {
1710*3d8817e4Smiod   { MAP (sh_opcode20), 0xf00f }
1711*3d8817e4Smiod };
1712*3d8817e4Smiod 
1713*3d8817e4Smiod static const struct sh_opcode sh_opcode30[] =
1714*3d8817e4Smiod {
1715*3d8817e4Smiod   { 0x3000, SETSSP | USES1 | USES2 },		/* cmp/eq rm,rn */
1716*3d8817e4Smiod   { 0x3002, SETSSP | USES1 | USES2 },		/* cmp/hs rm,rn */
1717*3d8817e4Smiod   { 0x3003, SETSSP | USES1 | USES2 },		/* cmp/ge rm,rn */
1718*3d8817e4Smiod   { 0x3004, SETSSP | USESSP | USES1 | USES2 },	/* div1 rm,rn */
1719*3d8817e4Smiod   { 0x3005, SETSSP | USES1 | USES2 },		/* dmulu.l rm,rn */
1720*3d8817e4Smiod   { 0x3006, SETSSP | USES1 | USES2 },		/* cmp/hi rm,rn */
1721*3d8817e4Smiod   { 0x3007, SETSSP | USES1 | USES2 },		/* cmp/gt rm,rn */
1722*3d8817e4Smiod   { 0x3008, SETS1 | USES1 | USES2 },		/* sub rm,rn */
1723*3d8817e4Smiod   { 0x300a, SETS1 | SETSSP | USES1 | USES2 | USESSP }, /* subc rm,rn */
1724*3d8817e4Smiod   { 0x300b, SETS1 | SETSSP | USES1 | USES2 },	/* subv rm,rn */
1725*3d8817e4Smiod   { 0x300c, SETS1 | USES1 | USES2 },		/* add rm,rn */
1726*3d8817e4Smiod   { 0x300d, SETSSP | USES1 | USES2 },		/* dmuls.l rm,rn */
1727*3d8817e4Smiod   { 0x300e, SETS1 | SETSSP | USES1 | USES2 | USESSP }, /* addc rm,rn */
1728*3d8817e4Smiod   { 0x300f, SETS1 | SETSSP | USES1 | USES2 }	/* addv rm,rn */
1729*3d8817e4Smiod };
1730*3d8817e4Smiod 
1731*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode3[] =
1732*3d8817e4Smiod {
1733*3d8817e4Smiod   { MAP (sh_opcode30), 0xf00f }
1734*3d8817e4Smiod };
1735*3d8817e4Smiod 
1736*3d8817e4Smiod static const struct sh_opcode sh_opcode40[] =
1737*3d8817e4Smiod {
1738*3d8817e4Smiod   { 0x4000, SETS1 | SETSSP | USES1 },		/* shll rn */
1739*3d8817e4Smiod   { 0x4001, SETS1 | SETSSP | USES1 },		/* shlr rn */
1740*3d8817e4Smiod   { 0x4002, STORE | SETS1 | USES1 | USESSP },	/* sts.l mach,@-rn */
1741*3d8817e4Smiod   { 0x4004, SETS1 | SETSSP | USES1 },		/* rotl rn */
1742*3d8817e4Smiod   { 0x4005, SETS1 | SETSSP | USES1 },		/* rotr rn */
1743*3d8817e4Smiod   { 0x4006, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,mach */
1744*3d8817e4Smiod   { 0x4008, SETS1 | USES1 },			/* shll2 rn */
1745*3d8817e4Smiod   { 0x4009, SETS1 | USES1 },			/* shlr2 rn */
1746*3d8817e4Smiod   { 0x400a, SETSSP | USES1 },			/* lds rm,mach */
1747*3d8817e4Smiod   { 0x400b, BRANCH | DELAY | USES1 },		/* jsr @rn */
1748*3d8817e4Smiod   { 0x4010, SETS1 | SETSSP | USES1 },		/* dt rn */
1749*3d8817e4Smiod   { 0x4011, SETSSP | USES1 },			/* cmp/pz rn */
1750*3d8817e4Smiod   { 0x4012, STORE | SETS1 | USES1 | USESSP },	/* sts.l macl,@-rn */
1751*3d8817e4Smiod   { 0x4014, SETSSP | USES1 },			/* setrc rm */
1752*3d8817e4Smiod   { 0x4015, SETSSP | USES1 },			/* cmp/pl rn */
1753*3d8817e4Smiod   { 0x4016, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,macl */
1754*3d8817e4Smiod   { 0x4018, SETS1 | USES1 },			/* shll8 rn */
1755*3d8817e4Smiod   { 0x4019, SETS1 | USES1 },			/* shlr8 rn */
1756*3d8817e4Smiod   { 0x401a, SETSSP | USES1 },			/* lds rm,macl */
1757*3d8817e4Smiod   { 0x401b, LOAD | SETSSP | USES1 },		/* tas.b @rn */
1758*3d8817e4Smiod   { 0x4020, SETS1 | SETSSP | USES1 },		/* shal rn */
1759*3d8817e4Smiod   { 0x4021, SETS1 | SETSSP | USES1 },		/* shar rn */
1760*3d8817e4Smiod   { 0x4022, STORE | SETS1 | USES1 | USESSP },	/* sts.l pr,@-rn */
1761*3d8817e4Smiod   { 0x4024, SETS1 | SETSSP | USES1 | USESSP },	/* rotcl rn */
1762*3d8817e4Smiod   { 0x4025, SETS1 | SETSSP | USES1 | USESSP },	/* rotcr rn */
1763*3d8817e4Smiod   { 0x4026, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,pr */
1764*3d8817e4Smiod   { 0x4028, SETS1 | USES1 },			/* shll16 rn */
1765*3d8817e4Smiod   { 0x4029, SETS1 | USES1 },			/* shlr16 rn */
1766*3d8817e4Smiod   { 0x402a, SETSSP | USES1 },			/* lds rm,pr */
1767*3d8817e4Smiod   { 0x402b, BRANCH | DELAY | USES1 },		/* jmp @rn */
1768*3d8817e4Smiod   { 0x4052, STORE | SETS1 | USES1 | USESSP },	/* sts.l fpul,@-rn */
1769*3d8817e4Smiod   { 0x4056, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,fpul */
1770*3d8817e4Smiod   { 0x405a, SETSSP | USES1 },			/* lds.l rm,fpul */
1771*3d8817e4Smiod   { 0x4062, STORE | SETS1 | USES1 | USESSP },	/* sts.l fpscr / dsr,@-rn */
1772*3d8817e4Smiod   { 0x4066, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,fpscr / dsr */
1773*3d8817e4Smiod   { 0x406a, SETSSP | USES1 },			/* lds rm,fpscr / lds rm,dsr */
1774*3d8817e4Smiod   { 0x4072, STORE | SETS1 | USES1 | USESSP },	/* sts.l a0,@-rn */
1775*3d8817e4Smiod   { 0x4076, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,a0 */
1776*3d8817e4Smiod   { 0x407a, SETSSP | USES1 },			/* lds.l rm,a0 */
1777*3d8817e4Smiod   { 0x4082, STORE | SETS1 | USES1 | USESSP },	/* sts.l x0,@-rn */
1778*3d8817e4Smiod   { 0x4086, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,x0 */
1779*3d8817e4Smiod   { 0x408a, SETSSP | USES1 },			/* lds.l rm,x0 */
1780*3d8817e4Smiod   { 0x4092, STORE | SETS1 | USES1 | USESSP },	/* sts.l x1,@-rn */
1781*3d8817e4Smiod   { 0x4096, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,x1 */
1782*3d8817e4Smiod   { 0x409a, SETSSP | USES1 },			/* lds.l rm,x1 */
1783*3d8817e4Smiod   { 0x40a2, STORE | SETS1 | USES1 | USESSP },	/* sts.l y0,@-rn */
1784*3d8817e4Smiod   { 0x40a6, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,y0 */
1785*3d8817e4Smiod   { 0x40aa, SETSSP | USES1 },			/* lds.l rm,y0 */
1786*3d8817e4Smiod   { 0x40b2, STORE | SETS1 | USES1 | USESSP },	/* sts.l y1,@-rn */
1787*3d8817e4Smiod   { 0x40b6, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,y1 */
1788*3d8817e4Smiod   { 0x40ba, SETSSP | USES1 }			/* lds.l rm,y1 */
1789*3d8817e4Smiod };
1790*3d8817e4Smiod 
1791*3d8817e4Smiod static const struct sh_opcode sh_opcode41[] =
1792*3d8817e4Smiod {
1793*3d8817e4Smiod   { 0x4003, STORE | SETS1 | USES1 | USESSP },	/* stc.l <special_reg>,@-rn */
1794*3d8817e4Smiod   { 0x4007, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,<special_reg> */
1795*3d8817e4Smiod   { 0x400c, SETS1 | USES1 | USES2 },		/* shad rm,rn */
1796*3d8817e4Smiod   { 0x400d, SETS1 | USES1 | USES2 },		/* shld rm,rn */
1797*3d8817e4Smiod   { 0x400e, SETSSP | USES1 },			/* ldc rm,<special_reg> */
1798*3d8817e4Smiod   { 0x400f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.w @rm+,@rn+ */
1799*3d8817e4Smiod };
1800*3d8817e4Smiod 
1801*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode4[] =
1802*3d8817e4Smiod {
1803*3d8817e4Smiod   { MAP (sh_opcode40), 0xf0ff },
1804*3d8817e4Smiod   { MAP (sh_opcode41), 0xf00f }
1805*3d8817e4Smiod };
1806*3d8817e4Smiod 
1807*3d8817e4Smiod static const struct sh_opcode sh_opcode50[] =
1808*3d8817e4Smiod {
1809*3d8817e4Smiod   { 0x5000, LOAD | SETS1 | USES2 }	/* mov.l @(disp,rm),rn */
1810*3d8817e4Smiod };
1811*3d8817e4Smiod 
1812*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode5[] =
1813*3d8817e4Smiod {
1814*3d8817e4Smiod   { MAP (sh_opcode50), 0xf000 }
1815*3d8817e4Smiod };
1816*3d8817e4Smiod 
1817*3d8817e4Smiod static const struct sh_opcode sh_opcode60[] =
1818*3d8817e4Smiod {
1819*3d8817e4Smiod   { 0x6000, LOAD | SETS1 | USES2 },		/* mov.b @rm,rn */
1820*3d8817e4Smiod   { 0x6001, LOAD | SETS1 | USES2 },		/* mov.w @rm,rn */
1821*3d8817e4Smiod   { 0x6002, LOAD | SETS1 | USES2 },		/* mov.l @rm,rn */
1822*3d8817e4Smiod   { 0x6003, SETS1 | USES2 },			/* mov rm,rn */
1823*3d8817e4Smiod   { 0x6004, LOAD | SETS1 | SETS2 | USES2 },	/* mov.b @rm+,rn */
1824*3d8817e4Smiod   { 0x6005, LOAD | SETS1 | SETS2 | USES2 },	/* mov.w @rm+,rn */
1825*3d8817e4Smiod   { 0x6006, LOAD | SETS1 | SETS2 | USES2 },	/* mov.l @rm+,rn */
1826*3d8817e4Smiod   { 0x6007, SETS1 | USES2 },			/* not rm,rn */
1827*3d8817e4Smiod   { 0x6008, SETS1 | USES2 },			/* swap.b rm,rn */
1828*3d8817e4Smiod   { 0x6009, SETS1 | USES2 },			/* swap.w rm,rn */
1829*3d8817e4Smiod   { 0x600a, SETS1 | SETSSP | USES2 | USESSP },	/* negc rm,rn */
1830*3d8817e4Smiod   { 0x600b, SETS1 | USES2 },			/* neg rm,rn */
1831*3d8817e4Smiod   { 0x600c, SETS1 | USES2 },			/* extu.b rm,rn */
1832*3d8817e4Smiod   { 0x600d, SETS1 | USES2 },			/* extu.w rm,rn */
1833*3d8817e4Smiod   { 0x600e, SETS1 | USES2 },			/* exts.b rm,rn */
1834*3d8817e4Smiod   { 0x600f, SETS1 | USES2 }			/* exts.w rm,rn */
1835*3d8817e4Smiod };
1836*3d8817e4Smiod 
1837*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode6[] =
1838*3d8817e4Smiod {
1839*3d8817e4Smiod   { MAP (sh_opcode60), 0xf00f }
1840*3d8817e4Smiod };
1841*3d8817e4Smiod 
1842*3d8817e4Smiod static const struct sh_opcode sh_opcode70[] =
1843*3d8817e4Smiod {
1844*3d8817e4Smiod   { 0x7000, SETS1 | USES1 }		/* add #imm,rn */
1845*3d8817e4Smiod };
1846*3d8817e4Smiod 
1847*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode7[] =
1848*3d8817e4Smiod {
1849*3d8817e4Smiod   { MAP (sh_opcode70), 0xf000 }
1850*3d8817e4Smiod };
1851*3d8817e4Smiod 
1852*3d8817e4Smiod static const struct sh_opcode sh_opcode80[] =
1853*3d8817e4Smiod {
1854*3d8817e4Smiod   { 0x8000, STORE | USES2 | USESR0 },	/* mov.b r0,@(disp,rn) */
1855*3d8817e4Smiod   { 0x8100, STORE | USES2 | USESR0 },	/* mov.w r0,@(disp,rn) */
1856*3d8817e4Smiod   { 0x8200, SETSSP },			/* setrc #imm */
1857*3d8817e4Smiod   { 0x8400, LOAD | SETSR0 | USES2 },	/* mov.b @(disp,rm),r0 */
1858*3d8817e4Smiod   { 0x8500, LOAD | SETSR0 | USES2 },	/* mov.w @(disp,rn),r0 */
1859*3d8817e4Smiod   { 0x8800, SETSSP | USESR0 },		/* cmp/eq #imm,r0 */
1860*3d8817e4Smiod   { 0x8900, BRANCH | USESSP },		/* bt label */
1861*3d8817e4Smiod   { 0x8b00, BRANCH | USESSP },		/* bf label */
1862*3d8817e4Smiod   { 0x8c00, SETSSP },			/* ldrs @(disp,pc) */
1863*3d8817e4Smiod   { 0x8d00, BRANCH | DELAY | USESSP },	/* bt/s label */
1864*3d8817e4Smiod   { 0x8e00, SETSSP },			/* ldre @(disp,pc) */
1865*3d8817e4Smiod   { 0x8f00, BRANCH | DELAY | USESSP }	/* bf/s label */
1866*3d8817e4Smiod };
1867*3d8817e4Smiod 
1868*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode8[] =
1869*3d8817e4Smiod {
1870*3d8817e4Smiod   { MAP (sh_opcode80), 0xff00 }
1871*3d8817e4Smiod };
1872*3d8817e4Smiod 
1873*3d8817e4Smiod static const struct sh_opcode sh_opcode90[] =
1874*3d8817e4Smiod {
1875*3d8817e4Smiod   { 0x9000, LOAD | SETS1 }	/* mov.w @(disp,pc),rn */
1876*3d8817e4Smiod };
1877*3d8817e4Smiod 
1878*3d8817e4Smiod static const struct sh_minor_opcode sh_opcode9[] =
1879*3d8817e4Smiod {
1880*3d8817e4Smiod   { MAP (sh_opcode90), 0xf000 }
1881*3d8817e4Smiod };
1882*3d8817e4Smiod 
1883*3d8817e4Smiod static const struct sh_opcode sh_opcodea0[] =
1884*3d8817e4Smiod {
1885*3d8817e4Smiod   { 0xa000, BRANCH | DELAY }	/* bra label */
1886*3d8817e4Smiod };
1887*3d8817e4Smiod 
1888*3d8817e4Smiod static const struct sh_minor_opcode sh_opcodea[] =
1889*3d8817e4Smiod {
1890*3d8817e4Smiod   { MAP (sh_opcodea0), 0xf000 }
1891*3d8817e4Smiod };
1892*3d8817e4Smiod 
1893*3d8817e4Smiod static const struct sh_opcode sh_opcodeb0[] =
1894*3d8817e4Smiod {
1895*3d8817e4Smiod   { 0xb000, BRANCH | DELAY }	/* bsr label */
1896*3d8817e4Smiod };
1897*3d8817e4Smiod 
1898*3d8817e4Smiod static const struct sh_minor_opcode sh_opcodeb[] =
1899*3d8817e4Smiod {
1900*3d8817e4Smiod   { MAP (sh_opcodeb0), 0xf000 }
1901*3d8817e4Smiod };
1902*3d8817e4Smiod 
1903*3d8817e4Smiod static const struct sh_opcode sh_opcodec0[] =
1904*3d8817e4Smiod {
1905*3d8817e4Smiod   { 0xc000, STORE | USESR0 | USESSP },		/* mov.b r0,@(disp,gbr) */
1906*3d8817e4Smiod   { 0xc100, STORE | USESR0 | USESSP },		/* mov.w r0,@(disp,gbr) */
1907*3d8817e4Smiod   { 0xc200, STORE | USESR0 | USESSP },		/* mov.l r0,@(disp,gbr) */
1908*3d8817e4Smiod   { 0xc300, BRANCH | USESSP },			/* trapa #imm */
1909*3d8817e4Smiod   { 0xc400, LOAD | SETSR0 | USESSP },		/* mov.b @(disp,gbr),r0 */
1910*3d8817e4Smiod   { 0xc500, LOAD | SETSR0 | USESSP },		/* mov.w @(disp,gbr),r0 */
1911*3d8817e4Smiod   { 0xc600, LOAD | SETSR0 | USESSP },		/* mov.l @(disp,gbr),r0 */
1912*3d8817e4Smiod   { 0xc700, SETSR0 },				/* mova @(disp,pc),r0 */
1913*3d8817e4Smiod   { 0xc800, SETSSP | USESR0 },			/* tst #imm,r0 */
1914*3d8817e4Smiod   { 0xc900, SETSR0 | USESR0 },			/* and #imm,r0 */
1915*3d8817e4Smiod   { 0xca00, SETSR0 | USESR0 },			/* xor #imm,r0 */
1916*3d8817e4Smiod   { 0xcb00, SETSR0 | USESR0 },			/* or #imm,r0 */
1917*3d8817e4Smiod   { 0xcc00, LOAD | SETSSP | USESR0 | USESSP },	/* tst.b #imm,@(r0,gbr) */
1918*3d8817e4Smiod   { 0xcd00, LOAD | STORE | USESR0 | USESSP },	/* and.b #imm,@(r0,gbr) */
1919*3d8817e4Smiod   { 0xce00, LOAD | STORE | USESR0 | USESSP },	/* xor.b #imm,@(r0,gbr) */
1920*3d8817e4Smiod   { 0xcf00, LOAD | STORE | USESR0 | USESSP }	/* or.b #imm,@(r0,gbr) */
1921*3d8817e4Smiod };
1922*3d8817e4Smiod 
1923*3d8817e4Smiod static const struct sh_minor_opcode sh_opcodec[] =
1924*3d8817e4Smiod {
1925*3d8817e4Smiod   { MAP (sh_opcodec0), 0xff00 }
1926*3d8817e4Smiod };
1927*3d8817e4Smiod 
1928*3d8817e4Smiod static const struct sh_opcode sh_opcoded0[] =
1929*3d8817e4Smiod {
1930*3d8817e4Smiod   { 0xd000, LOAD | SETS1 }		/* mov.l @(disp,pc),rn */
1931*3d8817e4Smiod };
1932*3d8817e4Smiod 
1933*3d8817e4Smiod static const struct sh_minor_opcode sh_opcoded[] =
1934*3d8817e4Smiod {
1935*3d8817e4Smiod   { MAP (sh_opcoded0), 0xf000 }
1936*3d8817e4Smiod };
1937*3d8817e4Smiod 
1938*3d8817e4Smiod static const struct sh_opcode sh_opcodee0[] =
1939*3d8817e4Smiod {
1940*3d8817e4Smiod   { 0xe000, SETS1 }		/* mov #imm,rn */
1941*3d8817e4Smiod };
1942*3d8817e4Smiod 
1943*3d8817e4Smiod static const struct sh_minor_opcode sh_opcodee[] =
1944*3d8817e4Smiod {
1945*3d8817e4Smiod   { MAP (sh_opcodee0), 0xf000 }
1946*3d8817e4Smiod };
1947*3d8817e4Smiod 
1948*3d8817e4Smiod static const struct sh_opcode sh_opcodef0[] =
1949*3d8817e4Smiod {
1950*3d8817e4Smiod   { 0xf000, SETSF1 | USESF1 | USESF2 },		/* fadd fm,fn */
1951*3d8817e4Smiod   { 0xf001, SETSF1 | USESF1 | USESF2 },		/* fsub fm,fn */
1952*3d8817e4Smiod   { 0xf002, SETSF1 | USESF1 | USESF2 },		/* fmul fm,fn */
1953*3d8817e4Smiod   { 0xf003, SETSF1 | USESF1 | USESF2 },		/* fdiv fm,fn */
1954*3d8817e4Smiod   { 0xf004, SETSSP | USESF1 | USESF2 },		/* fcmp/eq fm,fn */
1955*3d8817e4Smiod   { 0xf005, SETSSP | USESF1 | USESF2 },		/* fcmp/gt fm,fn */
1956*3d8817e4Smiod   { 0xf006, LOAD | SETSF1 | USES2 | USESR0 },	/* fmov.s @(r0,rm),fn */
1957*3d8817e4Smiod   { 0xf007, STORE | USES1 | USESF2 | USESR0 },	/* fmov.s fm,@(r0,rn) */
1958*3d8817e4Smiod   { 0xf008, LOAD | SETSF1 | USES2 },		/* fmov.s @rm,fn */
1959*3d8817e4Smiod   { 0xf009, LOAD | SETS2 | SETSF1 | USES2 },	/* fmov.s @rm+,fn */
1960*3d8817e4Smiod   { 0xf00a, STORE | USES1 | USESF2 },		/* fmov.s fm,@rn */
1961*3d8817e4Smiod   { 0xf00b, STORE | SETS1 | USES1 | USESF2 },	/* fmov.s fm,@-rn */
1962*3d8817e4Smiod   { 0xf00c, SETSF1 | USESF2 },			/* fmov fm,fn */
1963*3d8817e4Smiod   { 0xf00e, SETSF1 | USESF1 | USESF2 | USESF0 }	/* fmac f0,fm,fn */
1964*3d8817e4Smiod };
1965*3d8817e4Smiod 
1966*3d8817e4Smiod static const struct sh_opcode sh_opcodef1[] =
1967*3d8817e4Smiod {
1968*3d8817e4Smiod   { 0xf00d, SETSF1 | USESSP },	/* fsts fpul,fn */
1969*3d8817e4Smiod   { 0xf01d, SETSSP | USESF1 },	/* flds fn,fpul */
1970*3d8817e4Smiod   { 0xf02d, SETSF1 | USESSP },	/* float fpul,fn */
1971*3d8817e4Smiod   { 0xf03d, SETSSP | USESF1 },	/* ftrc fn,fpul */
1972*3d8817e4Smiod   { 0xf04d, SETSF1 | USESF1 },	/* fneg fn */
1973*3d8817e4Smiod   { 0xf05d, SETSF1 | USESF1 },	/* fabs fn */
1974*3d8817e4Smiod   { 0xf06d, SETSF1 | USESF1 },	/* fsqrt fn */
1975*3d8817e4Smiod   { 0xf07d, SETSSP | USESF1 },	/* ftst/nan fn */
1976*3d8817e4Smiod   { 0xf08d, SETSF1 },		/* fldi0 fn */
1977*3d8817e4Smiod   { 0xf09d, SETSF1 }		/* fldi1 fn */
1978*3d8817e4Smiod };
1979*3d8817e4Smiod 
1980*3d8817e4Smiod static const struct sh_minor_opcode sh_opcodef[] =
1981*3d8817e4Smiod {
1982*3d8817e4Smiod   { MAP (sh_opcodef0), 0xf00f },
1983*3d8817e4Smiod   { MAP (sh_opcodef1), 0xf0ff }
1984*3d8817e4Smiod };
1985*3d8817e4Smiod 
1986*3d8817e4Smiod static struct sh_major_opcode sh_opcodes[] =
1987*3d8817e4Smiod {
1988*3d8817e4Smiod   { MAP (sh_opcode0) },
1989*3d8817e4Smiod   { MAP (sh_opcode1) },
1990*3d8817e4Smiod   { MAP (sh_opcode2) },
1991*3d8817e4Smiod   { MAP (sh_opcode3) },
1992*3d8817e4Smiod   { MAP (sh_opcode4) },
1993*3d8817e4Smiod   { MAP (sh_opcode5) },
1994*3d8817e4Smiod   { MAP (sh_opcode6) },
1995*3d8817e4Smiod   { MAP (sh_opcode7) },
1996*3d8817e4Smiod   { MAP (sh_opcode8) },
1997*3d8817e4Smiod   { MAP (sh_opcode9) },
1998*3d8817e4Smiod   { MAP (sh_opcodea) },
1999*3d8817e4Smiod   { MAP (sh_opcodeb) },
2000*3d8817e4Smiod   { MAP (sh_opcodec) },
2001*3d8817e4Smiod   { MAP (sh_opcoded) },
2002*3d8817e4Smiod   { MAP (sh_opcodee) },
2003*3d8817e4Smiod   { MAP (sh_opcodef) }
2004*3d8817e4Smiod };
2005*3d8817e4Smiod 
2006*3d8817e4Smiod /* The double data transfer / parallel processing insns are not
2007*3d8817e4Smiod    described here.  This will cause sh_align_load_span to leave them alone.  */
2008*3d8817e4Smiod 
2009*3d8817e4Smiod static const struct sh_opcode sh_dsp_opcodef0[] =
2010*3d8817e4Smiod {
2011*3d8817e4Smiod   { 0xf400, USESAS | SETSAS | LOAD | SETSSP },	/* movs.x @-as,ds */
2012*3d8817e4Smiod   { 0xf401, USESAS | SETSAS | STORE | USESSP },	/* movs.x ds,@-as */
2013*3d8817e4Smiod   { 0xf404, USESAS | LOAD | SETSSP },		/* movs.x @as,ds */
2014*3d8817e4Smiod   { 0xf405, USESAS | STORE | USESSP },		/* movs.x ds,@as */
2015*3d8817e4Smiod   { 0xf408, USESAS | SETSAS | LOAD | SETSSP },	/* movs.x @as+,ds */
2016*3d8817e4Smiod   { 0xf409, USESAS | SETSAS | STORE | USESSP },	/* movs.x ds,@as+ */
2017*3d8817e4Smiod   { 0xf40c, USESAS | SETSAS | LOAD | SETSSP | USESR8 },	/* movs.x @as+r8,ds */
2018*3d8817e4Smiod   { 0xf40d, USESAS | SETSAS | STORE | USESSP | USESR8 }	/* movs.x ds,@as+r8 */
2019*3d8817e4Smiod };
2020*3d8817e4Smiod 
2021*3d8817e4Smiod static const struct sh_minor_opcode sh_dsp_opcodef[] =
2022*3d8817e4Smiod {
2023*3d8817e4Smiod   { MAP (sh_dsp_opcodef0), 0xfc0d }
2024*3d8817e4Smiod };
2025*3d8817e4Smiod 
2026*3d8817e4Smiod /* Given an instruction, return a pointer to the corresponding
2027*3d8817e4Smiod    sh_opcode structure.  Return NULL if the instruction is not
2028*3d8817e4Smiod    recognized.  */
2029*3d8817e4Smiod 
2030*3d8817e4Smiod static const struct sh_opcode *
sh_insn_info(insn)2031*3d8817e4Smiod sh_insn_info (insn)
2032*3d8817e4Smiod      unsigned int insn;
2033*3d8817e4Smiod {
2034*3d8817e4Smiod   const struct sh_major_opcode *maj;
2035*3d8817e4Smiod   const struct sh_minor_opcode *min, *minend;
2036*3d8817e4Smiod 
2037*3d8817e4Smiod   maj = &sh_opcodes[(insn & 0xf000) >> 12];
2038*3d8817e4Smiod   min = maj->minor_opcodes;
2039*3d8817e4Smiod   minend = min + maj->count;
2040*3d8817e4Smiod   for (; min < minend; min++)
2041*3d8817e4Smiod     {
2042*3d8817e4Smiod       unsigned int l;
2043*3d8817e4Smiod       const struct sh_opcode *op, *opend;
2044*3d8817e4Smiod 
2045*3d8817e4Smiod       l = insn & min->mask;
2046*3d8817e4Smiod       op = min->opcodes;
2047*3d8817e4Smiod       opend = op + min->count;
2048*3d8817e4Smiod 
2049*3d8817e4Smiod       /* Since the opcodes tables are sorted, we could use a binary
2050*3d8817e4Smiod          search here if the count were above some cutoff value.  */
2051*3d8817e4Smiod       for (; op < opend; op++)
2052*3d8817e4Smiod 	if (op->opcode == l)
2053*3d8817e4Smiod 	  return op;
2054*3d8817e4Smiod     }
2055*3d8817e4Smiod 
2056*3d8817e4Smiod   return NULL;
2057*3d8817e4Smiod }
2058*3d8817e4Smiod 
2059*3d8817e4Smiod /* See whether an instruction uses or sets a general purpose register */
2060*3d8817e4Smiod 
2061*3d8817e4Smiod static bfd_boolean
sh_insn_uses_or_sets_reg(insn,op,reg)2062*3d8817e4Smiod sh_insn_uses_or_sets_reg (insn, op, reg)
2063*3d8817e4Smiod      unsigned int insn;
2064*3d8817e4Smiod      const struct sh_opcode *op;
2065*3d8817e4Smiod      unsigned int reg;
2066*3d8817e4Smiod {
2067*3d8817e4Smiod   if (sh_insn_uses_reg (insn, op, reg))
2068*3d8817e4Smiod     return TRUE;
2069*3d8817e4Smiod 
2070*3d8817e4Smiod   return sh_insn_sets_reg (insn, op, reg);
2071*3d8817e4Smiod }
2072*3d8817e4Smiod 
2073*3d8817e4Smiod /* See whether an instruction uses a general purpose register.  */
2074*3d8817e4Smiod 
2075*3d8817e4Smiod static bfd_boolean
sh_insn_uses_reg(insn,op,reg)2076*3d8817e4Smiod sh_insn_uses_reg (insn, op, reg)
2077*3d8817e4Smiod      unsigned int insn;
2078*3d8817e4Smiod      const struct sh_opcode *op;
2079*3d8817e4Smiod      unsigned int reg;
2080*3d8817e4Smiod {
2081*3d8817e4Smiod   unsigned int f;
2082*3d8817e4Smiod 
2083*3d8817e4Smiod   f = op->flags;
2084*3d8817e4Smiod 
2085*3d8817e4Smiod   if ((f & USES1) != 0
2086*3d8817e4Smiod       && USES1_REG (insn) == reg)
2087*3d8817e4Smiod     return TRUE;
2088*3d8817e4Smiod   if ((f & USES2) != 0
2089*3d8817e4Smiod       && USES2_REG (insn) == reg)
2090*3d8817e4Smiod     return TRUE;
2091*3d8817e4Smiod   if ((f & USESR0) != 0
2092*3d8817e4Smiod       && reg == 0)
2093*3d8817e4Smiod     return TRUE;
2094*3d8817e4Smiod   if ((f & USESAS) && reg == USESAS_REG (insn))
2095*3d8817e4Smiod     return TRUE;
2096*3d8817e4Smiod   if ((f & USESR8) && reg == 8)
2097*3d8817e4Smiod     return TRUE;
2098*3d8817e4Smiod 
2099*3d8817e4Smiod   return FALSE;
2100*3d8817e4Smiod }
2101*3d8817e4Smiod 
2102*3d8817e4Smiod /* See whether an instruction sets a general purpose register.  */
2103*3d8817e4Smiod 
2104*3d8817e4Smiod static bfd_boolean
sh_insn_sets_reg(insn,op,reg)2105*3d8817e4Smiod sh_insn_sets_reg (insn, op, reg)
2106*3d8817e4Smiod      unsigned int insn;
2107*3d8817e4Smiod      const struct sh_opcode *op;
2108*3d8817e4Smiod      unsigned int reg;
2109*3d8817e4Smiod {
2110*3d8817e4Smiod   unsigned int f;
2111*3d8817e4Smiod 
2112*3d8817e4Smiod   f = op->flags;
2113*3d8817e4Smiod 
2114*3d8817e4Smiod   if ((f & SETS1) != 0
2115*3d8817e4Smiod       && SETS1_REG (insn) == reg)
2116*3d8817e4Smiod     return TRUE;
2117*3d8817e4Smiod   if ((f & SETS2) != 0
2118*3d8817e4Smiod       && SETS2_REG (insn) == reg)
2119*3d8817e4Smiod     return TRUE;
2120*3d8817e4Smiod   if ((f & SETSR0) != 0
2121*3d8817e4Smiod       && reg == 0)
2122*3d8817e4Smiod     return TRUE;
2123*3d8817e4Smiod   if ((f & SETSAS) && reg == SETSAS_REG (insn))
2124*3d8817e4Smiod     return TRUE;
2125*3d8817e4Smiod 
2126*3d8817e4Smiod   return FALSE;
2127*3d8817e4Smiod }
2128*3d8817e4Smiod 
2129*3d8817e4Smiod /* See whether an instruction uses or sets a floating point register */
2130*3d8817e4Smiod 
2131*3d8817e4Smiod static bfd_boolean
sh_insn_uses_or_sets_freg(insn,op,reg)2132*3d8817e4Smiod sh_insn_uses_or_sets_freg (insn, op, reg)
2133*3d8817e4Smiod      unsigned int insn;
2134*3d8817e4Smiod      const struct sh_opcode *op;
2135*3d8817e4Smiod      unsigned int reg;
2136*3d8817e4Smiod {
2137*3d8817e4Smiod   if (sh_insn_uses_freg (insn, op, reg))
2138*3d8817e4Smiod     return TRUE;
2139*3d8817e4Smiod 
2140*3d8817e4Smiod   return sh_insn_sets_freg (insn, op, reg);
2141*3d8817e4Smiod }
2142*3d8817e4Smiod 
2143*3d8817e4Smiod /* See whether an instruction uses a floating point register.  */
2144*3d8817e4Smiod 
2145*3d8817e4Smiod static bfd_boolean
sh_insn_uses_freg(insn,op,freg)2146*3d8817e4Smiod sh_insn_uses_freg (insn, op, freg)
2147*3d8817e4Smiod      unsigned int insn;
2148*3d8817e4Smiod      const struct sh_opcode *op;
2149*3d8817e4Smiod      unsigned int freg;
2150*3d8817e4Smiod {
2151*3d8817e4Smiod   unsigned int f;
2152*3d8817e4Smiod 
2153*3d8817e4Smiod   f = op->flags;
2154*3d8817e4Smiod 
2155*3d8817e4Smiod   /* We can't tell if this is a double-precision insn, so just play safe
2156*3d8817e4Smiod      and assume that it might be.  So not only have we test FREG against
2157*3d8817e4Smiod      itself, but also even FREG against FREG+1 - if the using insn uses
2158*3d8817e4Smiod      just the low part of a double precision value - but also an odd
2159*3d8817e4Smiod      FREG against FREG-1 -  if the setting insn sets just the low part
2160*3d8817e4Smiod      of a double precision value.
2161*3d8817e4Smiod      So what this all boils down to is that we have to ignore the lowest
2162*3d8817e4Smiod      bit of the register number.  */
2163*3d8817e4Smiod 
2164*3d8817e4Smiod   if ((f & USESF1) != 0
2165*3d8817e4Smiod       && (USESF1_REG (insn) & 0xe) == (freg & 0xe))
2166*3d8817e4Smiod     return TRUE;
2167*3d8817e4Smiod   if ((f & USESF2) != 0
2168*3d8817e4Smiod       && (USESF2_REG (insn) & 0xe) == (freg & 0xe))
2169*3d8817e4Smiod     return TRUE;
2170*3d8817e4Smiod   if ((f & USESF0) != 0
2171*3d8817e4Smiod       && freg == 0)
2172*3d8817e4Smiod     return TRUE;
2173*3d8817e4Smiod 
2174*3d8817e4Smiod   return FALSE;
2175*3d8817e4Smiod }
2176*3d8817e4Smiod 
2177*3d8817e4Smiod /* See whether an instruction sets a floating point register.  */
2178*3d8817e4Smiod 
2179*3d8817e4Smiod static bfd_boolean
sh_insn_sets_freg(insn,op,freg)2180*3d8817e4Smiod sh_insn_sets_freg (insn, op, freg)
2181*3d8817e4Smiod      unsigned int insn;
2182*3d8817e4Smiod      const struct sh_opcode *op;
2183*3d8817e4Smiod      unsigned int freg;
2184*3d8817e4Smiod {
2185*3d8817e4Smiod   unsigned int f;
2186*3d8817e4Smiod 
2187*3d8817e4Smiod   f = op->flags;
2188*3d8817e4Smiod 
2189*3d8817e4Smiod   /* We can't tell if this is a double-precision insn, so just play safe
2190*3d8817e4Smiod      and assume that it might be.  So not only have we test FREG against
2191*3d8817e4Smiod      itself, but also even FREG against FREG+1 - if the using insn uses
2192*3d8817e4Smiod      just the low part of a double precision value - but also an odd
2193*3d8817e4Smiod      FREG against FREG-1 -  if the setting insn sets just the low part
2194*3d8817e4Smiod      of a double precision value.
2195*3d8817e4Smiod      So what this all boils down to is that we have to ignore the lowest
2196*3d8817e4Smiod      bit of the register number.  */
2197*3d8817e4Smiod 
2198*3d8817e4Smiod   if ((f & SETSF1) != 0
2199*3d8817e4Smiod       && (SETSF1_REG (insn) & 0xe) == (freg & 0xe))
2200*3d8817e4Smiod     return TRUE;
2201*3d8817e4Smiod 
2202*3d8817e4Smiod   return FALSE;
2203*3d8817e4Smiod }
2204*3d8817e4Smiod 
2205*3d8817e4Smiod /* See whether instructions I1 and I2 conflict, assuming I1 comes
2206*3d8817e4Smiod    before I2.  OP1 and OP2 are the corresponding sh_opcode structures.
2207*3d8817e4Smiod    This should return TRUE if there is a conflict, or FALSE if the
2208*3d8817e4Smiod    instructions can be swapped safely.  */
2209*3d8817e4Smiod 
2210*3d8817e4Smiod static bfd_boolean
sh_insns_conflict(i1,op1,i2,op2)2211*3d8817e4Smiod sh_insns_conflict (i1, op1, i2, op2)
2212*3d8817e4Smiod      unsigned int i1;
2213*3d8817e4Smiod      const struct sh_opcode *op1;
2214*3d8817e4Smiod      unsigned int i2;
2215*3d8817e4Smiod      const struct sh_opcode *op2;
2216*3d8817e4Smiod {
2217*3d8817e4Smiod   unsigned int f1, f2;
2218*3d8817e4Smiod 
2219*3d8817e4Smiod   f1 = op1->flags;
2220*3d8817e4Smiod   f2 = op2->flags;
2221*3d8817e4Smiod 
2222*3d8817e4Smiod   /* Load of fpscr conflicts with floating point operations.
2223*3d8817e4Smiod      FIXME: shouldn't test raw opcodes here.  */
2224*3d8817e4Smiod   if (((i1 & 0xf0ff) == 0x4066 && (i2 & 0xf000) == 0xf000)
2225*3d8817e4Smiod       || ((i2 & 0xf0ff) == 0x4066 && (i1 & 0xf000) == 0xf000))
2226*3d8817e4Smiod     return TRUE;
2227*3d8817e4Smiod 
2228*3d8817e4Smiod   if ((f1 & (BRANCH | DELAY)) != 0
2229*3d8817e4Smiod       || (f2 & (BRANCH | DELAY)) != 0)
2230*3d8817e4Smiod     return TRUE;
2231*3d8817e4Smiod 
2232*3d8817e4Smiod   if (((f1 | f2) & SETSSP)
2233*3d8817e4Smiod       && (f1 & (SETSSP | USESSP))
2234*3d8817e4Smiod       && (f2 & (SETSSP | USESSP)))
2235*3d8817e4Smiod     return TRUE;
2236*3d8817e4Smiod 
2237*3d8817e4Smiod   if ((f1 & SETS1) != 0
2238*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i2, op2, SETS1_REG (i1)))
2239*3d8817e4Smiod     return TRUE;
2240*3d8817e4Smiod   if ((f1 & SETS2) != 0
2241*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i2, op2, SETS2_REG (i1)))
2242*3d8817e4Smiod     return TRUE;
2243*3d8817e4Smiod   if ((f1 & SETSR0) != 0
2244*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i2, op2, 0))
2245*3d8817e4Smiod     return TRUE;
2246*3d8817e4Smiod   if ((f1 & SETSAS)
2247*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i2, op2, SETSAS_REG (i1)))
2248*3d8817e4Smiod     return TRUE;
2249*3d8817e4Smiod   if ((f1 & SETSF1) != 0
2250*3d8817e4Smiod       && sh_insn_uses_or_sets_freg (i2, op2, SETSF1_REG (i1)))
2251*3d8817e4Smiod     return TRUE;
2252*3d8817e4Smiod 
2253*3d8817e4Smiod   if ((f2 & SETS1) != 0
2254*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i1, op1, SETS1_REG (i2)))
2255*3d8817e4Smiod     return TRUE;
2256*3d8817e4Smiod   if ((f2 & SETS2) != 0
2257*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i1, op1, SETS2_REG (i2)))
2258*3d8817e4Smiod     return TRUE;
2259*3d8817e4Smiod   if ((f2 & SETSR0) != 0
2260*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i1, op1, 0))
2261*3d8817e4Smiod     return TRUE;
2262*3d8817e4Smiod   if ((f2 & SETSAS)
2263*3d8817e4Smiod       && sh_insn_uses_or_sets_reg (i1, op1, SETSAS_REG (i2)))
2264*3d8817e4Smiod     return TRUE;
2265*3d8817e4Smiod   if ((f2 & SETSF1) != 0
2266*3d8817e4Smiod       && sh_insn_uses_or_sets_freg (i1, op1, SETSF1_REG (i2)))
2267*3d8817e4Smiod     return TRUE;
2268*3d8817e4Smiod 
2269*3d8817e4Smiod   /* The instructions do not conflict.  */
2270*3d8817e4Smiod   return FALSE;
2271*3d8817e4Smiod }
2272*3d8817e4Smiod 
2273*3d8817e4Smiod /* I1 is a load instruction, and I2 is some other instruction.  Return
2274*3d8817e4Smiod    TRUE if I1 loads a register which I2 uses.  */
2275*3d8817e4Smiod 
2276*3d8817e4Smiod static bfd_boolean
sh_load_use(i1,op1,i2,op2)2277*3d8817e4Smiod sh_load_use (i1, op1, i2, op2)
2278*3d8817e4Smiod      unsigned int i1;
2279*3d8817e4Smiod      const struct sh_opcode *op1;
2280*3d8817e4Smiod      unsigned int i2;
2281*3d8817e4Smiod      const struct sh_opcode *op2;
2282*3d8817e4Smiod {
2283*3d8817e4Smiod   unsigned int f1;
2284*3d8817e4Smiod 
2285*3d8817e4Smiod   f1 = op1->flags;
2286*3d8817e4Smiod 
2287*3d8817e4Smiod   if ((f1 & LOAD) == 0)
2288*3d8817e4Smiod     return FALSE;
2289*3d8817e4Smiod 
2290*3d8817e4Smiod   /* If both SETS1 and SETSSP are set, that means a load to a special
2291*3d8817e4Smiod      register using postincrement addressing mode, which we don't care
2292*3d8817e4Smiod      about here.  */
2293*3d8817e4Smiod   if ((f1 & SETS1) != 0
2294*3d8817e4Smiod       && (f1 & SETSSP) == 0
2295*3d8817e4Smiod       && sh_insn_uses_reg (i2, op2, (i1 & 0x0f00) >> 8))
2296*3d8817e4Smiod     return TRUE;
2297*3d8817e4Smiod 
2298*3d8817e4Smiod   if ((f1 & SETSR0) != 0
2299*3d8817e4Smiod       && sh_insn_uses_reg (i2, op2, 0))
2300*3d8817e4Smiod     return TRUE;
2301*3d8817e4Smiod 
2302*3d8817e4Smiod   if ((f1 & SETSF1) != 0
2303*3d8817e4Smiod       && sh_insn_uses_freg (i2, op2, (i1 & 0x0f00) >> 8))
2304*3d8817e4Smiod     return TRUE;
2305*3d8817e4Smiod 
2306*3d8817e4Smiod   return FALSE;
2307*3d8817e4Smiod }
2308*3d8817e4Smiod 
2309*3d8817e4Smiod /* Try to align loads and stores within a span of memory.  This is
2310*3d8817e4Smiod    called by both the ELF and the COFF sh targets.  ABFD and SEC are
2311*3d8817e4Smiod    the BFD and section we are examining.  CONTENTS is the contents of
2312*3d8817e4Smiod    the section.  SWAP is the routine to call to swap two instructions.
2313*3d8817e4Smiod    RELOCS is a pointer to the internal relocation information, to be
2314*3d8817e4Smiod    passed to SWAP.  PLABEL is a pointer to the current label in a
2315*3d8817e4Smiod    sorted list of labels; LABEL_END is the end of the list.  START and
2316*3d8817e4Smiod    STOP are the range of memory to examine.  If a swap is made,
2317*3d8817e4Smiod    *PSWAPPED is set to TRUE.  */
2318*3d8817e4Smiod 
2319*3d8817e4Smiod #ifdef COFF_WITH_PE
2320*3d8817e4Smiod static
2321*3d8817e4Smiod #endif
2322*3d8817e4Smiod bfd_boolean
_bfd_sh_align_load_span(abfd,sec,contents,swap,relocs,plabel,label_end,start,stop,pswapped)2323*3d8817e4Smiod _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs,
2324*3d8817e4Smiod 			 plabel, label_end, start, stop, pswapped)
2325*3d8817e4Smiod      bfd *abfd;
2326*3d8817e4Smiod      asection *sec;
2327*3d8817e4Smiod      bfd_byte *contents;
2328*3d8817e4Smiod      bfd_boolean (*swap) PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
2329*3d8817e4Smiod      PTR relocs;
2330*3d8817e4Smiod      bfd_vma **plabel;
2331*3d8817e4Smiod      bfd_vma *label_end;
2332*3d8817e4Smiod      bfd_vma start;
2333*3d8817e4Smiod      bfd_vma stop;
2334*3d8817e4Smiod      bfd_boolean *pswapped;
2335*3d8817e4Smiod {
2336*3d8817e4Smiod   int dsp = (abfd->arch_info->mach == bfd_mach_sh_dsp
2337*3d8817e4Smiod 	     || abfd->arch_info->mach == bfd_mach_sh3_dsp);
2338*3d8817e4Smiod   bfd_vma i;
2339*3d8817e4Smiod 
2340*3d8817e4Smiod   /* The SH4 has a Harvard architecture, hence aligning loads is not
2341*3d8817e4Smiod      desirable.  In fact, it is counter-productive, since it interferes
2342*3d8817e4Smiod      with the schedules generated by the compiler.  */
2343*3d8817e4Smiod   if (abfd->arch_info->mach == bfd_mach_sh4)
2344*3d8817e4Smiod     return TRUE;
2345*3d8817e4Smiod 
2346*3d8817e4Smiod   /* If we are linking sh[3]-dsp code, swap the FPU instructions for DSP
2347*3d8817e4Smiod      instructions.  */
2348*3d8817e4Smiod   if (dsp)
2349*3d8817e4Smiod     {
2350*3d8817e4Smiod       sh_opcodes[0xf].minor_opcodes = sh_dsp_opcodef;
2351*3d8817e4Smiod       sh_opcodes[0xf].count = sizeof sh_dsp_opcodef / sizeof sh_dsp_opcodef;
2352*3d8817e4Smiod     }
2353*3d8817e4Smiod 
2354*3d8817e4Smiod   /* Instructions should be aligned on 2 byte boundaries.  */
2355*3d8817e4Smiod   if ((start & 1) == 1)
2356*3d8817e4Smiod     ++start;
2357*3d8817e4Smiod 
2358*3d8817e4Smiod   /* Now look through the unaligned addresses.  */
2359*3d8817e4Smiod   i = start;
2360*3d8817e4Smiod   if ((i & 2) == 0)
2361*3d8817e4Smiod     i += 2;
2362*3d8817e4Smiod   for (; i < stop; i += 4)
2363*3d8817e4Smiod     {
2364*3d8817e4Smiod       unsigned int insn;
2365*3d8817e4Smiod       const struct sh_opcode *op;
2366*3d8817e4Smiod       unsigned int prev_insn = 0;
2367*3d8817e4Smiod       const struct sh_opcode *prev_op = NULL;
2368*3d8817e4Smiod 
2369*3d8817e4Smiod       insn = bfd_get_16 (abfd, contents + i);
2370*3d8817e4Smiod       op = sh_insn_info (insn);
2371*3d8817e4Smiod       if (op == NULL
2372*3d8817e4Smiod 	  || (op->flags & (LOAD | STORE)) == 0)
2373*3d8817e4Smiod 	continue;
2374*3d8817e4Smiod 
2375*3d8817e4Smiod       /* This is a load or store which is not on a four byte boundary.  */
2376*3d8817e4Smiod 
2377*3d8817e4Smiod       while (*plabel < label_end && **plabel < i)
2378*3d8817e4Smiod 	++*plabel;
2379*3d8817e4Smiod 
2380*3d8817e4Smiod       if (i > start)
2381*3d8817e4Smiod 	{
2382*3d8817e4Smiod 	  prev_insn = bfd_get_16 (abfd, contents + i - 2);
2383*3d8817e4Smiod 	  /* If INSN is the field b of a parallel processing insn, it is not
2384*3d8817e4Smiod 	     a load / store after all.  Note that the test here might mistake
2385*3d8817e4Smiod 	     the field_b of a pcopy insn for the starting code of a parallel
2386*3d8817e4Smiod 	     processing insn; this might miss a swapping opportunity, but at
2387*3d8817e4Smiod 	     least we're on the safe side.  */
2388*3d8817e4Smiod 	  if (dsp && (prev_insn & 0xfc00) == 0xf800)
2389*3d8817e4Smiod 	    continue;
2390*3d8817e4Smiod 
2391*3d8817e4Smiod 	  /* Check if prev_insn is actually the field b of a parallel
2392*3d8817e4Smiod 	     processing insn.  Again, this can give a spurious match
2393*3d8817e4Smiod 	     after a pcopy.  */
2394*3d8817e4Smiod 	  if (dsp && i - 2 > start)
2395*3d8817e4Smiod 	    {
2396*3d8817e4Smiod 	      unsigned pprev_insn = bfd_get_16 (abfd, contents + i - 4);
2397*3d8817e4Smiod 
2398*3d8817e4Smiod 	      if ((pprev_insn & 0xfc00) == 0xf800)
2399*3d8817e4Smiod 		prev_op = NULL;
2400*3d8817e4Smiod 	      else
2401*3d8817e4Smiod 		prev_op = sh_insn_info (prev_insn);
2402*3d8817e4Smiod 	    }
2403*3d8817e4Smiod 	  else
2404*3d8817e4Smiod 	    prev_op = sh_insn_info (prev_insn);
2405*3d8817e4Smiod 
2406*3d8817e4Smiod 	  /* If the load/store instruction is in a delay slot, we
2407*3d8817e4Smiod 	     can't swap.  */
2408*3d8817e4Smiod 	  if (prev_op == NULL
2409*3d8817e4Smiod 	      || (prev_op->flags & DELAY) != 0)
2410*3d8817e4Smiod 	    continue;
2411*3d8817e4Smiod 	}
2412*3d8817e4Smiod       if (i > start
2413*3d8817e4Smiod 	  && (*plabel >= label_end || **plabel != i)
2414*3d8817e4Smiod 	  && prev_op != NULL
2415*3d8817e4Smiod 	  && (prev_op->flags & (LOAD | STORE)) == 0
2416*3d8817e4Smiod 	  && ! sh_insns_conflict (prev_insn, prev_op, insn, op))
2417*3d8817e4Smiod 	{
2418*3d8817e4Smiod 	  bfd_boolean ok;
2419*3d8817e4Smiod 
2420*3d8817e4Smiod 	  /* The load/store instruction does not have a label, and
2421*3d8817e4Smiod 	     there is a previous instruction; PREV_INSN is not
2422*3d8817e4Smiod 	     itself a load/store instruction, and PREV_INSN and
2423*3d8817e4Smiod 	     INSN do not conflict.  */
2424*3d8817e4Smiod 
2425*3d8817e4Smiod 	  ok = TRUE;
2426*3d8817e4Smiod 
2427*3d8817e4Smiod 	  if (i >= start + 4)
2428*3d8817e4Smiod 	    {
2429*3d8817e4Smiod 	      unsigned int prev2_insn;
2430*3d8817e4Smiod 	      const struct sh_opcode *prev2_op;
2431*3d8817e4Smiod 
2432*3d8817e4Smiod 	      prev2_insn = bfd_get_16 (abfd, contents + i - 4);
2433*3d8817e4Smiod 	      prev2_op = sh_insn_info (prev2_insn);
2434*3d8817e4Smiod 
2435*3d8817e4Smiod 	      /* If the instruction before PREV_INSN has a delay
2436*3d8817e4Smiod 		 slot--that is, PREV_INSN is in a delay slot--we
2437*3d8817e4Smiod 		 can not swap.  */
2438*3d8817e4Smiod 	      if (prev2_op == NULL
2439*3d8817e4Smiod 		  || (prev2_op->flags & DELAY) != 0)
2440*3d8817e4Smiod 		ok = FALSE;
2441*3d8817e4Smiod 
2442*3d8817e4Smiod 	      /* If the instruction before PREV_INSN is a load,
2443*3d8817e4Smiod 		 and it sets a register which INSN uses, then
2444*3d8817e4Smiod 		 putting INSN immediately after PREV_INSN will
2445*3d8817e4Smiod 		 cause a pipeline bubble, so there is no point to
2446*3d8817e4Smiod 		 making the swap.  */
2447*3d8817e4Smiod 	      if (ok
2448*3d8817e4Smiod 		  && (prev2_op->flags & LOAD) != 0
2449*3d8817e4Smiod 		  && sh_load_use (prev2_insn, prev2_op, insn, op))
2450*3d8817e4Smiod 		ok = FALSE;
2451*3d8817e4Smiod 	    }
2452*3d8817e4Smiod 
2453*3d8817e4Smiod 	  if (ok)
2454*3d8817e4Smiod 	    {
2455*3d8817e4Smiod 	      if (! (*swap) (abfd, sec, relocs, contents, i - 2))
2456*3d8817e4Smiod 		return FALSE;
2457*3d8817e4Smiod 	      *pswapped = TRUE;
2458*3d8817e4Smiod 	      continue;
2459*3d8817e4Smiod 	    }
2460*3d8817e4Smiod 	}
2461*3d8817e4Smiod 
2462*3d8817e4Smiod       while (*plabel < label_end && **plabel < i + 2)
2463*3d8817e4Smiod 	++*plabel;
2464*3d8817e4Smiod 
2465*3d8817e4Smiod       if (i + 2 < stop
2466*3d8817e4Smiod 	  && (*plabel >= label_end || **plabel != i + 2))
2467*3d8817e4Smiod 	{
2468*3d8817e4Smiod 	  unsigned int next_insn;
2469*3d8817e4Smiod 	  const struct sh_opcode *next_op;
2470*3d8817e4Smiod 
2471*3d8817e4Smiod 	  /* There is an instruction after the load/store
2472*3d8817e4Smiod 	     instruction, and it does not have a label.  */
2473*3d8817e4Smiod 	  next_insn = bfd_get_16 (abfd, contents + i + 2);
2474*3d8817e4Smiod 	  next_op = sh_insn_info (next_insn);
2475*3d8817e4Smiod 	  if (next_op != NULL
2476*3d8817e4Smiod 	      && (next_op->flags & (LOAD | STORE)) == 0
2477*3d8817e4Smiod 	      && ! sh_insns_conflict (insn, op, next_insn, next_op))
2478*3d8817e4Smiod 	    {
2479*3d8817e4Smiod 	      bfd_boolean ok;
2480*3d8817e4Smiod 
2481*3d8817e4Smiod 	      /* NEXT_INSN is not itself a load/store instruction,
2482*3d8817e4Smiod 		 and it does not conflict with INSN.  */
2483*3d8817e4Smiod 
2484*3d8817e4Smiod 	      ok = TRUE;
2485*3d8817e4Smiod 
2486*3d8817e4Smiod 	      /* If PREV_INSN is a load, and it sets a register
2487*3d8817e4Smiod 		 which NEXT_INSN uses, then putting NEXT_INSN
2488*3d8817e4Smiod 		 immediately after PREV_INSN will cause a pipeline
2489*3d8817e4Smiod 		 bubble, so there is no reason to make this swap.  */
2490*3d8817e4Smiod 	      if (prev_op != NULL
2491*3d8817e4Smiod 		  && (prev_op->flags & LOAD) != 0
2492*3d8817e4Smiod 		  && sh_load_use (prev_insn, prev_op, next_insn, next_op))
2493*3d8817e4Smiod 		ok = FALSE;
2494*3d8817e4Smiod 
2495*3d8817e4Smiod 	      /* If INSN is a load, and it sets a register which
2496*3d8817e4Smiod 		 the insn after NEXT_INSN uses, then doing the
2497*3d8817e4Smiod 		 swap will cause a pipeline bubble, so there is no
2498*3d8817e4Smiod 		 reason to make the swap.  However, if the insn
2499*3d8817e4Smiod 		 after NEXT_INSN is itself a load or store
2500*3d8817e4Smiod 		 instruction, then it is misaligned, so
2501*3d8817e4Smiod 		 optimistically hope that it will be swapped
2502*3d8817e4Smiod 		 itself, and just live with the pipeline bubble if
2503*3d8817e4Smiod 		 it isn't.  */
2504*3d8817e4Smiod 	      if (ok
2505*3d8817e4Smiod 		  && i + 4 < stop
2506*3d8817e4Smiod 		  && (op->flags & LOAD) != 0)
2507*3d8817e4Smiod 		{
2508*3d8817e4Smiod 		  unsigned int next2_insn;
2509*3d8817e4Smiod 		  const struct sh_opcode *next2_op;
2510*3d8817e4Smiod 
2511*3d8817e4Smiod 		  next2_insn = bfd_get_16 (abfd, contents + i + 4);
2512*3d8817e4Smiod 		  next2_op = sh_insn_info (next2_insn);
2513*3d8817e4Smiod 		  if ((next2_op->flags & (LOAD | STORE)) == 0
2514*3d8817e4Smiod 		      && sh_load_use (insn, op, next2_insn, next2_op))
2515*3d8817e4Smiod 		    ok = FALSE;
2516*3d8817e4Smiod 		}
2517*3d8817e4Smiod 
2518*3d8817e4Smiod 	      if (ok)
2519*3d8817e4Smiod 		{
2520*3d8817e4Smiod 		  if (! (*swap) (abfd, sec, relocs, contents, i))
2521*3d8817e4Smiod 		    return FALSE;
2522*3d8817e4Smiod 		  *pswapped = TRUE;
2523*3d8817e4Smiod 		  continue;
2524*3d8817e4Smiod 		}
2525*3d8817e4Smiod 	    }
2526*3d8817e4Smiod 	}
2527*3d8817e4Smiod     }
2528*3d8817e4Smiod 
2529*3d8817e4Smiod   return TRUE;
2530*3d8817e4Smiod }
2531*3d8817e4Smiod #endif /* not COFF_IMAGE_WITH_PE */
2532*3d8817e4Smiod 
2533*3d8817e4Smiod /* Look for loads and stores which we can align to four byte
2534*3d8817e4Smiod    boundaries.  See the longer comment above sh_relax_section for why
2535*3d8817e4Smiod    this is desirable.  This sets *PSWAPPED if some instruction was
2536*3d8817e4Smiod    swapped.  */
2537*3d8817e4Smiod 
2538*3d8817e4Smiod static bfd_boolean
sh_align_loads(abfd,sec,internal_relocs,contents,pswapped)2539*3d8817e4Smiod sh_align_loads (abfd, sec, internal_relocs, contents, pswapped)
2540*3d8817e4Smiod      bfd *abfd;
2541*3d8817e4Smiod      asection *sec;
2542*3d8817e4Smiod      struct internal_reloc *internal_relocs;
2543*3d8817e4Smiod      bfd_byte *contents;
2544*3d8817e4Smiod      bfd_boolean *pswapped;
2545*3d8817e4Smiod {
2546*3d8817e4Smiod   struct internal_reloc *irel, *irelend;
2547*3d8817e4Smiod   bfd_vma *labels = NULL;
2548*3d8817e4Smiod   bfd_vma *label, *label_end;
2549*3d8817e4Smiod   bfd_size_type amt;
2550*3d8817e4Smiod 
2551*3d8817e4Smiod   *pswapped = FALSE;
2552*3d8817e4Smiod 
2553*3d8817e4Smiod   irelend = internal_relocs + sec->reloc_count;
2554*3d8817e4Smiod 
2555*3d8817e4Smiod   /* Get all the addresses with labels on them.  */
2556*3d8817e4Smiod   amt = (bfd_size_type) sec->reloc_count * sizeof (bfd_vma);
2557*3d8817e4Smiod   labels = (bfd_vma *) bfd_malloc (amt);
2558*3d8817e4Smiod   if (labels == NULL)
2559*3d8817e4Smiod     goto error_return;
2560*3d8817e4Smiod   label_end = labels;
2561*3d8817e4Smiod   for (irel = internal_relocs; irel < irelend; irel++)
2562*3d8817e4Smiod     {
2563*3d8817e4Smiod       if (irel->r_type == R_SH_LABEL)
2564*3d8817e4Smiod 	{
2565*3d8817e4Smiod 	  *label_end = irel->r_vaddr - sec->vma;
2566*3d8817e4Smiod 	  ++label_end;
2567*3d8817e4Smiod 	}
2568*3d8817e4Smiod     }
2569*3d8817e4Smiod 
2570*3d8817e4Smiod   /* Note that the assembler currently always outputs relocs in
2571*3d8817e4Smiod      address order.  If that ever changes, this code will need to sort
2572*3d8817e4Smiod      the label values and the relocs.  */
2573*3d8817e4Smiod 
2574*3d8817e4Smiod   label = labels;
2575*3d8817e4Smiod 
2576*3d8817e4Smiod   for (irel = internal_relocs; irel < irelend; irel++)
2577*3d8817e4Smiod     {
2578*3d8817e4Smiod       bfd_vma start, stop;
2579*3d8817e4Smiod 
2580*3d8817e4Smiod       if (irel->r_type != R_SH_CODE)
2581*3d8817e4Smiod 	continue;
2582*3d8817e4Smiod 
2583*3d8817e4Smiod       start = irel->r_vaddr - sec->vma;
2584*3d8817e4Smiod 
2585*3d8817e4Smiod       for (irel++; irel < irelend; irel++)
2586*3d8817e4Smiod 	if (irel->r_type == R_SH_DATA)
2587*3d8817e4Smiod 	  break;
2588*3d8817e4Smiod       if (irel < irelend)
2589*3d8817e4Smiod 	stop = irel->r_vaddr - sec->vma;
2590*3d8817e4Smiod       else
2591*3d8817e4Smiod 	stop = sec->size;
2592*3d8817e4Smiod 
2593*3d8817e4Smiod       if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_swap_insns,
2594*3d8817e4Smiod 				     (PTR) internal_relocs, &label,
2595*3d8817e4Smiod 				     label_end, start, stop, pswapped))
2596*3d8817e4Smiod 	goto error_return;
2597*3d8817e4Smiod     }
2598*3d8817e4Smiod 
2599*3d8817e4Smiod   free (labels);
2600*3d8817e4Smiod 
2601*3d8817e4Smiod   return TRUE;
2602*3d8817e4Smiod 
2603*3d8817e4Smiod  error_return:
2604*3d8817e4Smiod   if (labels != NULL)
2605*3d8817e4Smiod     free (labels);
2606*3d8817e4Smiod   return FALSE;
2607*3d8817e4Smiod }
2608*3d8817e4Smiod 
2609*3d8817e4Smiod /* Swap two SH instructions.  */
2610*3d8817e4Smiod 
2611*3d8817e4Smiod static bfd_boolean
sh_swap_insns(abfd,sec,relocs,contents,addr)2612*3d8817e4Smiod sh_swap_insns (abfd, sec, relocs, contents, addr)
2613*3d8817e4Smiod      bfd *abfd;
2614*3d8817e4Smiod      asection *sec;
2615*3d8817e4Smiod      PTR relocs;
2616*3d8817e4Smiod      bfd_byte *contents;
2617*3d8817e4Smiod      bfd_vma addr;
2618*3d8817e4Smiod {
2619*3d8817e4Smiod   struct internal_reloc *internal_relocs = (struct internal_reloc *) relocs;
2620*3d8817e4Smiod   unsigned short i1, i2;
2621*3d8817e4Smiod   struct internal_reloc *irel, *irelend;
2622*3d8817e4Smiod 
2623*3d8817e4Smiod   /* Swap the instructions themselves.  */
2624*3d8817e4Smiod   i1 = bfd_get_16 (abfd, contents + addr);
2625*3d8817e4Smiod   i2 = bfd_get_16 (abfd, contents + addr + 2);
2626*3d8817e4Smiod   bfd_put_16 (abfd, (bfd_vma) i2, contents + addr);
2627*3d8817e4Smiod   bfd_put_16 (abfd, (bfd_vma) i1, contents + addr + 2);
2628*3d8817e4Smiod 
2629*3d8817e4Smiod   /* Adjust all reloc addresses.  */
2630*3d8817e4Smiod   irelend = internal_relocs + sec->reloc_count;
2631*3d8817e4Smiod   for (irel = internal_relocs; irel < irelend; irel++)
2632*3d8817e4Smiod     {
2633*3d8817e4Smiod       int type, add;
2634*3d8817e4Smiod 
2635*3d8817e4Smiod       /* There are a few special types of relocs that we don't want to
2636*3d8817e4Smiod          adjust.  These relocs do not apply to the instruction itself,
2637*3d8817e4Smiod          but are only associated with the address.  */
2638*3d8817e4Smiod       type = irel->r_type;
2639*3d8817e4Smiod       if (type == R_SH_ALIGN
2640*3d8817e4Smiod 	  || type == R_SH_CODE
2641*3d8817e4Smiod 	  || type == R_SH_DATA
2642*3d8817e4Smiod 	  || type == R_SH_LABEL)
2643*3d8817e4Smiod 	continue;
2644*3d8817e4Smiod 
2645*3d8817e4Smiod       /* If an R_SH_USES reloc points to one of the addresses being
2646*3d8817e4Smiod          swapped, we must adjust it.  It would be incorrect to do this
2647*3d8817e4Smiod          for a jump, though, since we want to execute both
2648*3d8817e4Smiod          instructions after the jump.  (We have avoided swapping
2649*3d8817e4Smiod          around a label, so the jump will not wind up executing an
2650*3d8817e4Smiod          instruction it shouldn't).  */
2651*3d8817e4Smiod       if (type == R_SH_USES)
2652*3d8817e4Smiod 	{
2653*3d8817e4Smiod 	  bfd_vma off;
2654*3d8817e4Smiod 
2655*3d8817e4Smiod 	  off = irel->r_vaddr - sec->vma + 4 + irel->r_offset;
2656*3d8817e4Smiod 	  if (off == addr)
2657*3d8817e4Smiod 	    irel->r_offset += 2;
2658*3d8817e4Smiod 	  else if (off == addr + 2)
2659*3d8817e4Smiod 	    irel->r_offset -= 2;
2660*3d8817e4Smiod 	}
2661*3d8817e4Smiod 
2662*3d8817e4Smiod       if (irel->r_vaddr - sec->vma == addr)
2663*3d8817e4Smiod 	{
2664*3d8817e4Smiod 	  irel->r_vaddr += 2;
2665*3d8817e4Smiod 	  add = -2;
2666*3d8817e4Smiod 	}
2667*3d8817e4Smiod       else if (irel->r_vaddr - sec->vma == addr + 2)
2668*3d8817e4Smiod 	{
2669*3d8817e4Smiod 	  irel->r_vaddr -= 2;
2670*3d8817e4Smiod 	  add = 2;
2671*3d8817e4Smiod 	}
2672*3d8817e4Smiod       else
2673*3d8817e4Smiod 	add = 0;
2674*3d8817e4Smiod 
2675*3d8817e4Smiod       if (add != 0)
2676*3d8817e4Smiod 	{
2677*3d8817e4Smiod 	  bfd_byte *loc;
2678*3d8817e4Smiod 	  unsigned short insn, oinsn;
2679*3d8817e4Smiod 	  bfd_boolean overflow;
2680*3d8817e4Smiod 
2681*3d8817e4Smiod 	  loc = contents + irel->r_vaddr - sec->vma;
2682*3d8817e4Smiod 	  overflow = FALSE;
2683*3d8817e4Smiod 	  switch (type)
2684*3d8817e4Smiod 	    {
2685*3d8817e4Smiod 	    default:
2686*3d8817e4Smiod 	      break;
2687*3d8817e4Smiod 
2688*3d8817e4Smiod 	    case R_SH_PCDISP8BY2:
2689*3d8817e4Smiod 	    case R_SH_PCRELIMM8BY2:
2690*3d8817e4Smiod 	      insn = bfd_get_16 (abfd, loc);
2691*3d8817e4Smiod 	      oinsn = insn;
2692*3d8817e4Smiod 	      insn += add / 2;
2693*3d8817e4Smiod 	      if ((oinsn & 0xff00) != (insn & 0xff00))
2694*3d8817e4Smiod 		overflow = TRUE;
2695*3d8817e4Smiod 	      bfd_put_16 (abfd, (bfd_vma) insn, loc);
2696*3d8817e4Smiod 	      break;
2697*3d8817e4Smiod 
2698*3d8817e4Smiod 	    case R_SH_PCDISP:
2699*3d8817e4Smiod 	      insn = bfd_get_16 (abfd, loc);
2700*3d8817e4Smiod 	      oinsn = insn;
2701*3d8817e4Smiod 	      insn += add / 2;
2702*3d8817e4Smiod 	      if ((oinsn & 0xf000) != (insn & 0xf000))
2703*3d8817e4Smiod 		overflow = TRUE;
2704*3d8817e4Smiod 	      bfd_put_16 (abfd, (bfd_vma) insn, loc);
2705*3d8817e4Smiod 	      break;
2706*3d8817e4Smiod 
2707*3d8817e4Smiod 	    case R_SH_PCRELIMM8BY4:
2708*3d8817e4Smiod 	      /* This reloc ignores the least significant 3 bits of
2709*3d8817e4Smiod                  the program counter before adding in the offset.
2710*3d8817e4Smiod                  This means that if ADDR is at an even address, the
2711*3d8817e4Smiod                  swap will not affect the offset.  If ADDR is an at an
2712*3d8817e4Smiod                  odd address, then the instruction will be crossing a
2713*3d8817e4Smiod                  four byte boundary, and must be adjusted.  */
2714*3d8817e4Smiod 	      if ((addr & 3) != 0)
2715*3d8817e4Smiod 		{
2716*3d8817e4Smiod 		  insn = bfd_get_16 (abfd, loc);
2717*3d8817e4Smiod 		  oinsn = insn;
2718*3d8817e4Smiod 		  insn += add / 2;
2719*3d8817e4Smiod 		  if ((oinsn & 0xff00) != (insn & 0xff00))
2720*3d8817e4Smiod 		    overflow = TRUE;
2721*3d8817e4Smiod 		  bfd_put_16 (abfd, (bfd_vma) insn, loc);
2722*3d8817e4Smiod 		}
2723*3d8817e4Smiod 
2724*3d8817e4Smiod 	      break;
2725*3d8817e4Smiod 	    }
2726*3d8817e4Smiod 
2727*3d8817e4Smiod 	  if (overflow)
2728*3d8817e4Smiod 	    {
2729*3d8817e4Smiod 	      ((*_bfd_error_handler)
2730*3d8817e4Smiod 	       ("%B: 0x%lx: fatal: reloc overflow while relaxing",
2731*3d8817e4Smiod 		abfd, (unsigned long) irel->r_vaddr));
2732*3d8817e4Smiod 	      bfd_set_error (bfd_error_bad_value);
2733*3d8817e4Smiod 	      return FALSE;
2734*3d8817e4Smiod 	    }
2735*3d8817e4Smiod 	}
2736*3d8817e4Smiod     }
2737*3d8817e4Smiod 
2738*3d8817e4Smiod   return TRUE;
2739*3d8817e4Smiod }
2740*3d8817e4Smiod 
2741*3d8817e4Smiod /* This is a modification of _bfd_coff_generic_relocate_section, which
2742*3d8817e4Smiod    will handle SH relaxing.  */
2743*3d8817e4Smiod 
2744*3d8817e4Smiod static bfd_boolean
sh_relocate_section(output_bfd,info,input_bfd,input_section,contents,relocs,syms,sections)2745*3d8817e4Smiod sh_relocate_section (output_bfd, info, input_bfd, input_section, contents,
2746*3d8817e4Smiod 		     relocs, syms, sections)
2747*3d8817e4Smiod      bfd *output_bfd ATTRIBUTE_UNUSED;
2748*3d8817e4Smiod      struct bfd_link_info *info;
2749*3d8817e4Smiod      bfd *input_bfd;
2750*3d8817e4Smiod      asection *input_section;
2751*3d8817e4Smiod      bfd_byte *contents;
2752*3d8817e4Smiod      struct internal_reloc *relocs;
2753*3d8817e4Smiod      struct internal_syment *syms;
2754*3d8817e4Smiod      asection **sections;
2755*3d8817e4Smiod {
2756*3d8817e4Smiod   struct internal_reloc *rel;
2757*3d8817e4Smiod   struct internal_reloc *relend;
2758*3d8817e4Smiod 
2759*3d8817e4Smiod   rel = relocs;
2760*3d8817e4Smiod   relend = rel + input_section->reloc_count;
2761*3d8817e4Smiod   for (; rel < relend; rel++)
2762*3d8817e4Smiod     {
2763*3d8817e4Smiod       long symndx;
2764*3d8817e4Smiod       struct coff_link_hash_entry *h;
2765*3d8817e4Smiod       struct internal_syment *sym;
2766*3d8817e4Smiod       bfd_vma addend;
2767*3d8817e4Smiod       bfd_vma val;
2768*3d8817e4Smiod       reloc_howto_type *howto;
2769*3d8817e4Smiod       bfd_reloc_status_type rstat;
2770*3d8817e4Smiod 
2771*3d8817e4Smiod       /* Almost all relocs have to do with relaxing.  If any work must
2772*3d8817e4Smiod          be done for them, it has been done in sh_relax_section.  */
2773*3d8817e4Smiod       if (rel->r_type != R_SH_IMM32
2774*3d8817e4Smiod #ifdef COFF_WITH_PE
2775*3d8817e4Smiod 	  && rel->r_type != R_SH_IMM32CE
2776*3d8817e4Smiod 	  && rel->r_type != R_SH_IMAGEBASE
2777*3d8817e4Smiod #endif
2778*3d8817e4Smiod 	  && rel->r_type != R_SH_PCDISP)
2779*3d8817e4Smiod 	continue;
2780*3d8817e4Smiod 
2781*3d8817e4Smiod       symndx = rel->r_symndx;
2782*3d8817e4Smiod 
2783*3d8817e4Smiod       if (symndx == -1)
2784*3d8817e4Smiod 	{
2785*3d8817e4Smiod 	  h = NULL;
2786*3d8817e4Smiod 	  sym = NULL;
2787*3d8817e4Smiod 	}
2788*3d8817e4Smiod       else
2789*3d8817e4Smiod 	{
2790*3d8817e4Smiod 	  if (symndx < 0
2791*3d8817e4Smiod 	      || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
2792*3d8817e4Smiod 	    {
2793*3d8817e4Smiod 	      (*_bfd_error_handler)
2794*3d8817e4Smiod 		("%B: illegal symbol index %ld in relocs",
2795*3d8817e4Smiod 		 input_bfd, symndx);
2796*3d8817e4Smiod 	      bfd_set_error (bfd_error_bad_value);
2797*3d8817e4Smiod 	      return FALSE;
2798*3d8817e4Smiod 	    }
2799*3d8817e4Smiod 	  h = obj_coff_sym_hashes (input_bfd)[symndx];
2800*3d8817e4Smiod 	  sym = syms + symndx;
2801*3d8817e4Smiod 	}
2802*3d8817e4Smiod 
2803*3d8817e4Smiod       if (sym != NULL && sym->n_scnum != 0)
2804*3d8817e4Smiod 	addend = - sym->n_value;
2805*3d8817e4Smiod       else
2806*3d8817e4Smiod 	addend = 0;
2807*3d8817e4Smiod 
2808*3d8817e4Smiod       if (rel->r_type == R_SH_PCDISP)
2809*3d8817e4Smiod 	addend -= 4;
2810*3d8817e4Smiod 
2811*3d8817e4Smiod       if (rel->r_type >= SH_COFF_HOWTO_COUNT)
2812*3d8817e4Smiod 	howto = NULL;
2813*3d8817e4Smiod       else
2814*3d8817e4Smiod 	howto = &sh_coff_howtos[rel->r_type];
2815*3d8817e4Smiod 
2816*3d8817e4Smiod       if (howto == NULL)
2817*3d8817e4Smiod 	{
2818*3d8817e4Smiod 	  bfd_set_error (bfd_error_bad_value);
2819*3d8817e4Smiod 	  return FALSE;
2820*3d8817e4Smiod 	}
2821*3d8817e4Smiod 
2822*3d8817e4Smiod #ifdef COFF_WITH_PE
2823*3d8817e4Smiod       if (rel->r_type == R_SH_IMAGEBASE)
2824*3d8817e4Smiod 	addend -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
2825*3d8817e4Smiod #endif
2826*3d8817e4Smiod 
2827*3d8817e4Smiod       val = 0;
2828*3d8817e4Smiod 
2829*3d8817e4Smiod       if (h == NULL)
2830*3d8817e4Smiod 	{
2831*3d8817e4Smiod 	  asection *sec;
2832*3d8817e4Smiod 
2833*3d8817e4Smiod 	  /* There is nothing to do for an internal PCDISP reloc.  */
2834*3d8817e4Smiod 	  if (rel->r_type == R_SH_PCDISP)
2835*3d8817e4Smiod 	    continue;
2836*3d8817e4Smiod 
2837*3d8817e4Smiod 	  if (symndx == -1)
2838*3d8817e4Smiod 	    {
2839*3d8817e4Smiod 	      sec = bfd_abs_section_ptr;
2840*3d8817e4Smiod 	      val = 0;
2841*3d8817e4Smiod 	    }
2842*3d8817e4Smiod 	  else
2843*3d8817e4Smiod 	    {
2844*3d8817e4Smiod 	      sec = sections[symndx];
2845*3d8817e4Smiod               val = (sec->output_section->vma
2846*3d8817e4Smiod 		     + sec->output_offset
2847*3d8817e4Smiod 		     + sym->n_value
2848*3d8817e4Smiod 		     - sec->vma);
2849*3d8817e4Smiod 	    }
2850*3d8817e4Smiod 	}
2851*3d8817e4Smiod       else
2852*3d8817e4Smiod 	{
2853*3d8817e4Smiod 	  if (h->root.type == bfd_link_hash_defined
2854*3d8817e4Smiod 	      || h->root.type == bfd_link_hash_defweak)
2855*3d8817e4Smiod 	    {
2856*3d8817e4Smiod 	      asection *sec;
2857*3d8817e4Smiod 
2858*3d8817e4Smiod 	      sec = h->root.u.def.section;
2859*3d8817e4Smiod 	      val = (h->root.u.def.value
2860*3d8817e4Smiod 		     + sec->output_section->vma
2861*3d8817e4Smiod 		     + sec->output_offset);
2862*3d8817e4Smiod 	    }
2863*3d8817e4Smiod 	  else if (! info->relocatable)
2864*3d8817e4Smiod 	    {
2865*3d8817e4Smiod 	      if (! ((*info->callbacks->undefined_symbol)
2866*3d8817e4Smiod 		     (info, h->root.root.string, input_bfd, input_section,
2867*3d8817e4Smiod 		      rel->r_vaddr - input_section->vma, TRUE)))
2868*3d8817e4Smiod 		return FALSE;
2869*3d8817e4Smiod 	    }
2870*3d8817e4Smiod 	}
2871*3d8817e4Smiod 
2872*3d8817e4Smiod       rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
2873*3d8817e4Smiod 					contents,
2874*3d8817e4Smiod 					rel->r_vaddr - input_section->vma,
2875*3d8817e4Smiod 					val, addend);
2876*3d8817e4Smiod 
2877*3d8817e4Smiod       switch (rstat)
2878*3d8817e4Smiod 	{
2879*3d8817e4Smiod 	default:
2880*3d8817e4Smiod 	  abort ();
2881*3d8817e4Smiod 	case bfd_reloc_ok:
2882*3d8817e4Smiod 	  break;
2883*3d8817e4Smiod 	case bfd_reloc_overflow:
2884*3d8817e4Smiod 	  {
2885*3d8817e4Smiod 	    const char *name;
2886*3d8817e4Smiod 	    char buf[SYMNMLEN + 1];
2887*3d8817e4Smiod 
2888*3d8817e4Smiod 	    if (symndx == -1)
2889*3d8817e4Smiod 	      name = "*ABS*";
2890*3d8817e4Smiod 	    else if (h != NULL)
2891*3d8817e4Smiod 	      name = NULL;
2892*3d8817e4Smiod 	    else if (sym->_n._n_n._n_zeroes == 0
2893*3d8817e4Smiod 		     && sym->_n._n_n._n_offset != 0)
2894*3d8817e4Smiod 	      name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
2895*3d8817e4Smiod 	    else
2896*3d8817e4Smiod 	      {
2897*3d8817e4Smiod  		strncpy (buf, sym->_n._n_name, SYMNMLEN);
2898*3d8817e4Smiod 		buf[SYMNMLEN] = '\0';
2899*3d8817e4Smiod 		name = buf;
2900*3d8817e4Smiod 	      }
2901*3d8817e4Smiod 
2902*3d8817e4Smiod 	    if (! ((*info->callbacks->reloc_overflow)
2903*3d8817e4Smiod 		   (info, (h ? &h->root : NULL), name, howto->name,
2904*3d8817e4Smiod 		    (bfd_vma) 0, input_bfd, input_section,
2905*3d8817e4Smiod 		    rel->r_vaddr - input_section->vma)))
2906*3d8817e4Smiod 	      return FALSE;
2907*3d8817e4Smiod 	  }
2908*3d8817e4Smiod 	}
2909*3d8817e4Smiod     }
2910*3d8817e4Smiod 
2911*3d8817e4Smiod   return TRUE;
2912*3d8817e4Smiod }
2913*3d8817e4Smiod 
2914*3d8817e4Smiod /* This is a version of bfd_generic_get_relocated_section_contents
2915*3d8817e4Smiod    which uses sh_relocate_section.  */
2916*3d8817e4Smiod 
2917*3d8817e4Smiod static bfd_byte *
sh_coff_get_relocated_section_contents(output_bfd,link_info,link_order,data,relocatable,symbols)2918*3d8817e4Smiod sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order,
2919*3d8817e4Smiod 					data, relocatable, symbols)
2920*3d8817e4Smiod      bfd *output_bfd;
2921*3d8817e4Smiod      struct bfd_link_info *link_info;
2922*3d8817e4Smiod      struct bfd_link_order *link_order;
2923*3d8817e4Smiod      bfd_byte *data;
2924*3d8817e4Smiod      bfd_boolean relocatable;
2925*3d8817e4Smiod      asymbol **symbols;
2926*3d8817e4Smiod {
2927*3d8817e4Smiod   asection *input_section = link_order->u.indirect.section;
2928*3d8817e4Smiod   bfd *input_bfd = input_section->owner;
2929*3d8817e4Smiod   asection **sections = NULL;
2930*3d8817e4Smiod   struct internal_reloc *internal_relocs = NULL;
2931*3d8817e4Smiod   struct internal_syment *internal_syms = NULL;
2932*3d8817e4Smiod 
2933*3d8817e4Smiod   /* We only need to handle the case of relaxing, or of having a
2934*3d8817e4Smiod      particular set of section contents, specially.  */
2935*3d8817e4Smiod   if (relocatable
2936*3d8817e4Smiod       || coff_section_data (input_bfd, input_section) == NULL
2937*3d8817e4Smiod       || coff_section_data (input_bfd, input_section)->contents == NULL)
2938*3d8817e4Smiod     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
2939*3d8817e4Smiod 						       link_order, data,
2940*3d8817e4Smiod 						       relocatable,
2941*3d8817e4Smiod 						       symbols);
2942*3d8817e4Smiod 
2943*3d8817e4Smiod   memcpy (data, coff_section_data (input_bfd, input_section)->contents,
2944*3d8817e4Smiod 	  (size_t) input_section->size);
2945*3d8817e4Smiod 
2946*3d8817e4Smiod   if ((input_section->flags & SEC_RELOC) != 0
2947*3d8817e4Smiod       && input_section->reloc_count > 0)
2948*3d8817e4Smiod     {
2949*3d8817e4Smiod       bfd_size_type symesz = bfd_coff_symesz (input_bfd);
2950*3d8817e4Smiod       bfd_byte *esym, *esymend;
2951*3d8817e4Smiod       struct internal_syment *isymp;
2952*3d8817e4Smiod       asection **secpp;
2953*3d8817e4Smiod       bfd_size_type amt;
2954*3d8817e4Smiod 
2955*3d8817e4Smiod       if (! _bfd_coff_get_external_symbols (input_bfd))
2956*3d8817e4Smiod 	goto error_return;
2957*3d8817e4Smiod 
2958*3d8817e4Smiod       internal_relocs = (_bfd_coff_read_internal_relocs
2959*3d8817e4Smiod 			 (input_bfd, input_section, FALSE, (bfd_byte *) NULL,
2960*3d8817e4Smiod 			  FALSE, (struct internal_reloc *) NULL));
2961*3d8817e4Smiod       if (internal_relocs == NULL)
2962*3d8817e4Smiod 	goto error_return;
2963*3d8817e4Smiod 
2964*3d8817e4Smiod       amt = obj_raw_syment_count (input_bfd);
2965*3d8817e4Smiod       amt *= sizeof (struct internal_syment);
2966*3d8817e4Smiod       internal_syms = (struct internal_syment *) bfd_malloc (amt);
2967*3d8817e4Smiod       if (internal_syms == NULL)
2968*3d8817e4Smiod 	goto error_return;
2969*3d8817e4Smiod 
2970*3d8817e4Smiod       amt = obj_raw_syment_count (input_bfd);
2971*3d8817e4Smiod       amt *= sizeof (asection *);
2972*3d8817e4Smiod       sections = (asection **) bfd_malloc (amt);
2973*3d8817e4Smiod       if (sections == NULL)
2974*3d8817e4Smiod 	goto error_return;
2975*3d8817e4Smiod 
2976*3d8817e4Smiod       isymp = internal_syms;
2977*3d8817e4Smiod       secpp = sections;
2978*3d8817e4Smiod       esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
2979*3d8817e4Smiod       esymend = esym + obj_raw_syment_count (input_bfd) * symesz;
2980*3d8817e4Smiod       while (esym < esymend)
2981*3d8817e4Smiod 	{
2982*3d8817e4Smiod 	  bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
2983*3d8817e4Smiod 
2984*3d8817e4Smiod 	  if (isymp->n_scnum != 0)
2985*3d8817e4Smiod 	    *secpp = coff_section_from_bfd_index (input_bfd, isymp->n_scnum);
2986*3d8817e4Smiod 	  else
2987*3d8817e4Smiod 	    {
2988*3d8817e4Smiod 	      if (isymp->n_value == 0)
2989*3d8817e4Smiod 		*secpp = bfd_und_section_ptr;
2990*3d8817e4Smiod 	      else
2991*3d8817e4Smiod 		*secpp = bfd_com_section_ptr;
2992*3d8817e4Smiod 	    }
2993*3d8817e4Smiod 
2994*3d8817e4Smiod 	  esym += (isymp->n_numaux + 1) * symesz;
2995*3d8817e4Smiod 	  secpp += isymp->n_numaux + 1;
2996*3d8817e4Smiod 	  isymp += isymp->n_numaux + 1;
2997*3d8817e4Smiod 	}
2998*3d8817e4Smiod 
2999*3d8817e4Smiod       if (! sh_relocate_section (output_bfd, link_info, input_bfd,
3000*3d8817e4Smiod 				 input_section, data, internal_relocs,
3001*3d8817e4Smiod 				 internal_syms, sections))
3002*3d8817e4Smiod 	goto error_return;
3003*3d8817e4Smiod 
3004*3d8817e4Smiod       free (sections);
3005*3d8817e4Smiod       sections = NULL;
3006*3d8817e4Smiod       free (internal_syms);
3007*3d8817e4Smiod       internal_syms = NULL;
3008*3d8817e4Smiod       free (internal_relocs);
3009*3d8817e4Smiod       internal_relocs = NULL;
3010*3d8817e4Smiod     }
3011*3d8817e4Smiod 
3012*3d8817e4Smiod   return data;
3013*3d8817e4Smiod 
3014*3d8817e4Smiod  error_return:
3015*3d8817e4Smiod   if (internal_relocs != NULL)
3016*3d8817e4Smiod     free (internal_relocs);
3017*3d8817e4Smiod   if (internal_syms != NULL)
3018*3d8817e4Smiod     free (internal_syms);
3019*3d8817e4Smiod   if (sections != NULL)
3020*3d8817e4Smiod     free (sections);
3021*3d8817e4Smiod   return NULL;
3022*3d8817e4Smiod }
3023*3d8817e4Smiod 
3024*3d8817e4Smiod /* The target vectors.  */
3025*3d8817e4Smiod 
3026*3d8817e4Smiod #ifndef TARGET_SHL_SYM
3027*3d8817e4Smiod CREATE_BIG_COFF_TARGET_VEC (shcoff_vec, "coff-sh", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)
3028*3d8817e4Smiod #endif
3029*3d8817e4Smiod 
3030*3d8817e4Smiod #ifdef TARGET_SHL_SYM
3031*3d8817e4Smiod #define TARGET_SYM TARGET_SHL_SYM
3032*3d8817e4Smiod #else
3033*3d8817e4Smiod #define TARGET_SYM shlcoff_vec
3034*3d8817e4Smiod #endif
3035*3d8817e4Smiod 
3036*3d8817e4Smiod #ifndef TARGET_SHL_NAME
3037*3d8817e4Smiod #define TARGET_SHL_NAME "coff-shl"
3038*3d8817e4Smiod #endif
3039*3d8817e4Smiod 
3040*3d8817e4Smiod #ifdef COFF_WITH_PE
3041*3d8817e4Smiod CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE,
3042*3d8817e4Smiod 			       SEC_CODE | SEC_DATA, '_', NULL, COFF_SWAP_TABLE);
3043*3d8817e4Smiod #else
3044*3d8817e4Smiod CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE,
3045*3d8817e4Smiod 			       0, '_', NULL, COFF_SWAP_TABLE)
3046*3d8817e4Smiod #endif
3047*3d8817e4Smiod 
3048*3d8817e4Smiod #ifndef TARGET_SHL_SYM
3049*3d8817e4Smiod static const bfd_target * coff_small_object_p PARAMS ((bfd *));
3050*3d8817e4Smiod static bfd_boolean coff_small_new_section_hook PARAMS ((bfd *, asection *));
3051*3d8817e4Smiod /* Some people want versions of the SH COFF target which do not align
3052*3d8817e4Smiod    to 16 byte boundaries.  We implement that by adding a couple of new
3053*3d8817e4Smiod    target vectors.  These are just like the ones above, but they
3054*3d8817e4Smiod    change the default section alignment.  To generate them in the
3055*3d8817e4Smiod    assembler, use -small.  To use them in the linker, use -b
3056*3d8817e4Smiod    coff-sh{l}-small and -oformat coff-sh{l}-small.
3057*3d8817e4Smiod 
3058*3d8817e4Smiod    Yes, this is a horrible hack.  A general solution for setting
3059*3d8817e4Smiod    section alignment in COFF is rather complex.  ELF handles this
3060*3d8817e4Smiod    correctly.  */
3061*3d8817e4Smiod 
3062*3d8817e4Smiod /* Only recognize the small versions if the target was not defaulted.
3063*3d8817e4Smiod    Otherwise we won't recognize the non default endianness.  */
3064*3d8817e4Smiod 
3065*3d8817e4Smiod static const bfd_target *
coff_small_object_p(abfd)3066*3d8817e4Smiod coff_small_object_p (abfd)
3067*3d8817e4Smiod      bfd *abfd;
3068*3d8817e4Smiod {
3069*3d8817e4Smiod   if (abfd->target_defaulted)
3070*3d8817e4Smiod     {
3071*3d8817e4Smiod       bfd_set_error (bfd_error_wrong_format);
3072*3d8817e4Smiod       return NULL;
3073*3d8817e4Smiod     }
3074*3d8817e4Smiod   return coff_object_p (abfd);
3075*3d8817e4Smiod }
3076*3d8817e4Smiod 
3077*3d8817e4Smiod /* Set the section alignment for the small versions.  */
3078*3d8817e4Smiod 
3079*3d8817e4Smiod static bfd_boolean
coff_small_new_section_hook(abfd,section)3080*3d8817e4Smiod coff_small_new_section_hook (abfd, section)
3081*3d8817e4Smiod      bfd *abfd;
3082*3d8817e4Smiod      asection *section;
3083*3d8817e4Smiod {
3084*3d8817e4Smiod   if (! coff_new_section_hook (abfd, section))
3085*3d8817e4Smiod     return FALSE;
3086*3d8817e4Smiod 
3087*3d8817e4Smiod   /* We must align to at least a four byte boundary, because longword
3088*3d8817e4Smiod      accesses must be on a four byte boundary.  */
3089*3d8817e4Smiod   if (section->alignment_power == COFF_DEFAULT_SECTION_ALIGNMENT_POWER)
3090*3d8817e4Smiod     section->alignment_power = 2;
3091*3d8817e4Smiod 
3092*3d8817e4Smiod   return TRUE;
3093*3d8817e4Smiod }
3094*3d8817e4Smiod 
3095*3d8817e4Smiod /* This is copied from bfd_coff_std_swap_table so that we can change
3096*3d8817e4Smiod    the default section alignment power.  */
3097*3d8817e4Smiod 
3098*3d8817e4Smiod static const bfd_coff_backend_data bfd_coff_small_swap_table =
3099*3d8817e4Smiod {
3100*3d8817e4Smiod   coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in,
3101*3d8817e4Smiod   coff_swap_aux_out, coff_swap_sym_out,
3102*3d8817e4Smiod   coff_swap_lineno_out, coff_swap_reloc_out,
3103*3d8817e4Smiod   coff_swap_filehdr_out, coff_swap_aouthdr_out,
3104*3d8817e4Smiod   coff_swap_scnhdr_out,
3105*3d8817e4Smiod   FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN,
3106*3d8817e4Smiod #ifdef COFF_LONG_FILENAMES
3107*3d8817e4Smiod   TRUE,
3108*3d8817e4Smiod #else
3109*3d8817e4Smiod   FALSE,
3110*3d8817e4Smiod #endif
3111*3d8817e4Smiod #ifdef COFF_LONG_SECTION_NAMES
3112*3d8817e4Smiod   TRUE,
3113*3d8817e4Smiod #else
3114*3d8817e4Smiod   FALSE,
3115*3d8817e4Smiod #endif
3116*3d8817e4Smiod   2,
3117*3d8817e4Smiod #ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
3118*3d8817e4Smiod   TRUE,
3119*3d8817e4Smiod #else
3120*3d8817e4Smiod   FALSE,
3121*3d8817e4Smiod #endif
3122*3d8817e4Smiod #ifdef COFF_DEBUG_STRING_WIDE_PREFIX
3123*3d8817e4Smiod   4,
3124*3d8817e4Smiod #else
3125*3d8817e4Smiod   2,
3126*3d8817e4Smiod #endif
3127*3d8817e4Smiod   coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in,
3128*3d8817e4Smiod   coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
3129*3d8817e4Smiod   coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
3130*3d8817e4Smiod   coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
3131*3d8817e4Smiod   coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
3132*3d8817e4Smiod   coff_classify_symbol, coff_compute_section_file_positions,
3133*3d8817e4Smiod   coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
3134*3d8817e4Smiod   coff_adjust_symndx, coff_link_add_one_symbol,
3135*3d8817e4Smiod   coff_link_output_has_begun, coff_final_link_postscript
3136*3d8817e4Smiod };
3137*3d8817e4Smiod 
3138*3d8817e4Smiod #define coff_small_close_and_cleanup \
3139*3d8817e4Smiod   coff_close_and_cleanup
3140*3d8817e4Smiod #define coff_small_bfd_free_cached_info \
3141*3d8817e4Smiod   coff_bfd_free_cached_info
3142*3d8817e4Smiod #define coff_small_get_section_contents \
3143*3d8817e4Smiod   coff_get_section_contents
3144*3d8817e4Smiod #define coff_small_get_section_contents_in_window \
3145*3d8817e4Smiod   coff_get_section_contents_in_window
3146*3d8817e4Smiod 
3147*3d8817e4Smiod extern const bfd_target shlcoff_small_vec;
3148*3d8817e4Smiod 
3149*3d8817e4Smiod const bfd_target shcoff_small_vec =
3150*3d8817e4Smiod {
3151*3d8817e4Smiod   "coff-sh-small",		/* name */
3152*3d8817e4Smiod   bfd_target_coff_flavour,
3153*3d8817e4Smiod   BFD_ENDIAN_BIG,		/* data byte order is big */
3154*3d8817e4Smiod   BFD_ENDIAN_BIG,		/* header byte order is big */
3155*3d8817e4Smiod 
3156*3d8817e4Smiod   (HAS_RELOC | EXEC_P |		/* object flags */
3157*3d8817e4Smiod    HAS_LINENO | HAS_DEBUG |
3158*3d8817e4Smiod    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
3159*3d8817e4Smiod 
3160*3d8817e4Smiod   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
3161*3d8817e4Smiod   '_',				/* leading symbol underscore */
3162*3d8817e4Smiod   '/',				/* ar_pad_char */
3163*3d8817e4Smiod   15,				/* ar_max_namelen */
3164*3d8817e4Smiod   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3165*3d8817e4Smiod   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3166*3d8817e4Smiod   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
3167*3d8817e4Smiod   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3168*3d8817e4Smiod   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3169*3d8817e4Smiod   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
3170*3d8817e4Smiod 
3171*3d8817e4Smiod   {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */
3172*3d8817e4Smiod      bfd_generic_archive_p, _bfd_dummy_target},
3173*3d8817e4Smiod   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
3174*3d8817e4Smiod      bfd_false},
3175*3d8817e4Smiod   {bfd_false, coff_write_object_contents, /* bfd_write_contents */
3176*3d8817e4Smiod      _bfd_write_archive_contents, bfd_false},
3177*3d8817e4Smiod 
3178*3d8817e4Smiod   BFD_JUMP_TABLE_GENERIC (coff_small),
3179*3d8817e4Smiod   BFD_JUMP_TABLE_COPY (coff),
3180*3d8817e4Smiod   BFD_JUMP_TABLE_CORE (_bfd_nocore),
3181*3d8817e4Smiod   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
3182*3d8817e4Smiod   BFD_JUMP_TABLE_SYMBOLS (coff),
3183*3d8817e4Smiod   BFD_JUMP_TABLE_RELOCS (coff),
3184*3d8817e4Smiod   BFD_JUMP_TABLE_WRITE (coff),
3185*3d8817e4Smiod   BFD_JUMP_TABLE_LINK (coff),
3186*3d8817e4Smiod   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3187*3d8817e4Smiod 
3188*3d8817e4Smiod   & shlcoff_small_vec,
3189*3d8817e4Smiod 
3190*3d8817e4Smiod   (PTR) &bfd_coff_small_swap_table
3191*3d8817e4Smiod };
3192*3d8817e4Smiod 
3193*3d8817e4Smiod const bfd_target shlcoff_small_vec =
3194*3d8817e4Smiod {
3195*3d8817e4Smiod   "coff-shl-small",		/* name */
3196*3d8817e4Smiod   bfd_target_coff_flavour,
3197*3d8817e4Smiod   BFD_ENDIAN_LITTLE,		/* data byte order is little */
3198*3d8817e4Smiod   BFD_ENDIAN_LITTLE,		/* header byte order is little endian too*/
3199*3d8817e4Smiod 
3200*3d8817e4Smiod   (HAS_RELOC | EXEC_P |		/* object flags */
3201*3d8817e4Smiod    HAS_LINENO | HAS_DEBUG |
3202*3d8817e4Smiod    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
3203*3d8817e4Smiod 
3204*3d8817e4Smiod   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
3205*3d8817e4Smiod   '_',				/* leading symbol underscore */
3206*3d8817e4Smiod   '/',				/* ar_pad_char */
3207*3d8817e4Smiod   15,				/* ar_max_namelen */
3208*3d8817e4Smiod   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
3209*3d8817e4Smiod   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
3210*3d8817e4Smiod   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
3211*3d8817e4Smiod   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
3212*3d8817e4Smiod   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
3213*3d8817e4Smiod   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
3214*3d8817e4Smiod 
3215*3d8817e4Smiod   {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */
3216*3d8817e4Smiod      bfd_generic_archive_p, _bfd_dummy_target},
3217*3d8817e4Smiod   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
3218*3d8817e4Smiod      bfd_false},
3219*3d8817e4Smiod   {bfd_false, coff_write_object_contents, /* bfd_write_contents */
3220*3d8817e4Smiod      _bfd_write_archive_contents, bfd_false},
3221*3d8817e4Smiod 
3222*3d8817e4Smiod   BFD_JUMP_TABLE_GENERIC (coff_small),
3223*3d8817e4Smiod   BFD_JUMP_TABLE_COPY (coff),
3224*3d8817e4Smiod   BFD_JUMP_TABLE_CORE (_bfd_nocore),
3225*3d8817e4Smiod   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
3226*3d8817e4Smiod   BFD_JUMP_TABLE_SYMBOLS (coff),
3227*3d8817e4Smiod   BFD_JUMP_TABLE_RELOCS (coff),
3228*3d8817e4Smiod   BFD_JUMP_TABLE_WRITE (coff),
3229*3d8817e4Smiod   BFD_JUMP_TABLE_LINK (coff),
3230*3d8817e4Smiod   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3231*3d8817e4Smiod 
3232*3d8817e4Smiod   & shcoff_small_vec,
3233*3d8817e4Smiod 
3234*3d8817e4Smiod   (PTR) &bfd_coff_small_swap_table
3235*3d8817e4Smiod };
3236*3d8817e4Smiod #endif
3237