xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/elf32-m32c.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* M16C/M32C specific support for 32-bit ELF.
2*3d8817e4Smiod    Copyright (C) 2005, 2006
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod    This file is part of BFD, the Binary File Descriptor library.
6*3d8817e4Smiod 
7*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
8*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
9*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
10*3d8817e4Smiod    (at your option) any later version.
11*3d8817e4Smiod 
12*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
13*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3d8817e4Smiod    GNU General Public License for more details.
16*3d8817e4Smiod 
17*3d8817e4Smiod    You should have received a copy of the GNU General Public License
18*3d8817e4Smiod    along with this program; if not, write to the Free Software
19*3d8817e4Smiod    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20*3d8817e4Smiod 
21*3d8817e4Smiod #include "bfd.h"
22*3d8817e4Smiod #include "sysdep.h"
23*3d8817e4Smiod #include "libbfd.h"
24*3d8817e4Smiod #include "elf-bfd.h"
25*3d8817e4Smiod #include "elf/m32c.h"
26*3d8817e4Smiod #include "libiberty.h"
27*3d8817e4Smiod 
28*3d8817e4Smiod /* Forward declarations.  */
29*3d8817e4Smiod static reloc_howto_type * m32c_reloc_type_lookup
30*3d8817e4Smiod   (bfd *, bfd_reloc_code_real_type);
31*3d8817e4Smiod static void m32c_info_to_howto_rela
32*3d8817e4Smiod   (bfd *, arelent *, Elf_Internal_Rela *);
33*3d8817e4Smiod static bfd_boolean m32c_elf_relocate_section
34*3d8817e4Smiod   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
35*3d8817e4Smiod static bfd_boolean m32c_elf_gc_sweep_hook
36*3d8817e4Smiod   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
37*3d8817e4Smiod static asection * m32c_elf_gc_mark_hook
38*3d8817e4Smiod   (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *);
39*3d8817e4Smiod static bfd_boolean m32c_elf_check_relocs
40*3d8817e4Smiod   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
41*3d8817e4Smiod static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
42*3d8817e4Smiod #ifdef DEBUG
43*3d8817e4Smiod static char * m32c_get_reloc (long reloc);
44*3d8817e4Smiod #endif
45*3d8817e4Smiod static bfd_boolean m32c_elf_relax_section
46*3d8817e4Smiod (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
47*3d8817e4Smiod 
48*3d8817e4Smiod 
49*3d8817e4Smiod static reloc_howto_type m32c_elf_howto_table [] =
50*3d8817e4Smiod {
51*3d8817e4Smiod   /* This reloc does nothing.  */
52*3d8817e4Smiod   HOWTO (R_M32C_NONE,		/* type */
53*3d8817e4Smiod 	 0,			/* rightshift */
54*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
55*3d8817e4Smiod 	 32,			/* bitsize */
56*3d8817e4Smiod 	 FALSE,			/* pc_relative */
57*3d8817e4Smiod 	 0,			/* bitpos */
58*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
59*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
60*3d8817e4Smiod 	 "R_M32C_NONE",		/* name */
61*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
62*3d8817e4Smiod 	 0,			/* src_mask */
63*3d8817e4Smiod 	 0,			/* dst_mask */
64*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
65*3d8817e4Smiod 
66*3d8817e4Smiod   HOWTO (R_M32C_16,		/* type */
67*3d8817e4Smiod 	 0,			/* rightshift */
68*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
69*3d8817e4Smiod 	 16,			/* bitsize */
70*3d8817e4Smiod 	 FALSE,			/* pc_relative */
71*3d8817e4Smiod 	 0,			/* bitpos */
72*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
73*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
74*3d8817e4Smiod 	 "R_M32C_16",		/* name */
75*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
76*3d8817e4Smiod 	 0,			/* src_mask */
77*3d8817e4Smiod 	 0xffff,		/* dst_mask */
78*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
79*3d8817e4Smiod 
80*3d8817e4Smiod   HOWTO (R_M32C_24,		/* type */
81*3d8817e4Smiod 	 0,			/* rightshift */
82*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
83*3d8817e4Smiod 	 24,			/* bitsize */
84*3d8817e4Smiod 	 FALSE,			/* pc_relative */
85*3d8817e4Smiod 	 0,			/* bitpos */
86*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
87*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
88*3d8817e4Smiod 	 "R_M32C_24",		/* name */
89*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
90*3d8817e4Smiod 	 0,			/* src_mask */
91*3d8817e4Smiod 	 0xffffff,		/* dst_mask */
92*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
93*3d8817e4Smiod 
94*3d8817e4Smiod   HOWTO (R_M32C_32,		/* type */
95*3d8817e4Smiod 	 0,			/* rightshift */
96*3d8817e4Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
97*3d8817e4Smiod 	 32,			/* bitsize */
98*3d8817e4Smiod 	 FALSE,			/* pc_relative */
99*3d8817e4Smiod 	 0,			/* bitpos */
100*3d8817e4Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
101*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
102*3d8817e4Smiod 	 "R_M32C_32",		/* name */
103*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
104*3d8817e4Smiod 	 0,			/* src_mask */
105*3d8817e4Smiod 	 0xffffffff,		/* dst_mask */
106*3d8817e4Smiod 	 FALSE),		/* pcrel_offset */
107*3d8817e4Smiod 
108*3d8817e4Smiod   HOWTO (R_M32C_8_PCREL,	/* type */
109*3d8817e4Smiod 	 0,			/* rightshift */
110*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
111*3d8817e4Smiod 	 8,			/* bitsize */
112*3d8817e4Smiod 	 TRUE,			/* pc_relative */
113*3d8817e4Smiod 	 0,			/* bitpos */
114*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
115*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
116*3d8817e4Smiod 	 "R_M32C_8_PCREL",	/* name */
117*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
118*3d8817e4Smiod 	 0,     		/* src_mask */
119*3d8817e4Smiod 	 0xff,   		/* dst_mask */
120*3d8817e4Smiod 	 TRUE), 		/* pcrel_offset */
121*3d8817e4Smiod 
122*3d8817e4Smiod   HOWTO (R_M32C_16_PCREL,	/* type */
123*3d8817e4Smiod 	 0,			/* rightshift */
124*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
125*3d8817e4Smiod 	 16,			/* bitsize */
126*3d8817e4Smiod 	 TRUE,			/* pc_relative */
127*3d8817e4Smiod 	 0,			/* bitpos */
128*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
129*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
130*3d8817e4Smiod 	 "R_M32C_16_PCREL",	/* name */
131*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
132*3d8817e4Smiod 	 0,     		/* src_mask */
133*3d8817e4Smiod 	 0xffff,             	/* dst_mask */
134*3d8817e4Smiod 	 TRUE), 		/* pcrel_offset */
135*3d8817e4Smiod 
136*3d8817e4Smiod   HOWTO (R_M32C_8,		/* type */
137*3d8817e4Smiod 	 0,			/* rightshift */
138*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
139*3d8817e4Smiod 	 8,			/* bitsize */
140*3d8817e4Smiod 	 FALSE,			/* pc_relative */
141*3d8817e4Smiod 	 0,			/* bitpos */
142*3d8817e4Smiod 	 complain_overflow_unsigned, /* complain_on_overflow */
143*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
144*3d8817e4Smiod 	 "R_M32C_8",		/* name */
145*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
146*3d8817e4Smiod 	 0,     		/* src_mask */
147*3d8817e4Smiod 	 0xff,			/* dst_mask */
148*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
149*3d8817e4Smiod 
150*3d8817e4Smiod   HOWTO (R_M32C_LO16,		/* type */
151*3d8817e4Smiod 	 0,			/* rightshift */
152*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
153*3d8817e4Smiod 	 16,			/* bitsize */
154*3d8817e4Smiod 	 FALSE,			/* pc_relative */
155*3d8817e4Smiod 	 0,			/* bitpos */
156*3d8817e4Smiod 	 complain_overflow_dont, /* complain_on_overflow */
157*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
158*3d8817e4Smiod 	 "R_M32C_LO16",		/* name */
159*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
160*3d8817e4Smiod 	 0,     		/* src_mask */
161*3d8817e4Smiod 	 0xffff,		/* dst_mask */
162*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
163*3d8817e4Smiod 
164*3d8817e4Smiod   HOWTO (R_M32C_HI8,		/* type */
165*3d8817e4Smiod 	 0,			/* rightshift */
166*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
167*3d8817e4Smiod 	 8,			/* bitsize */
168*3d8817e4Smiod 	 FALSE,			/* pc_relative */
169*3d8817e4Smiod 	 0,			/* bitpos */
170*3d8817e4Smiod 	 complain_overflow_dont, /* complain_on_overflow */
171*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
172*3d8817e4Smiod 	 "R_M32C_HI8",		/* name */
173*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
174*3d8817e4Smiod 	 0,     		/* src_mask */
175*3d8817e4Smiod 	 0xff,			/* dst_mask */
176*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
177*3d8817e4Smiod 
178*3d8817e4Smiod   HOWTO (R_M32C_HI16,		/* type */
179*3d8817e4Smiod 	 0,			/* rightshift */
180*3d8817e4Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
181*3d8817e4Smiod 	 16,			/* bitsize */
182*3d8817e4Smiod 	 FALSE,			/* pc_relative */
183*3d8817e4Smiod 	 0,			/* bitpos */
184*3d8817e4Smiod 	 complain_overflow_dont, /* complain_on_overflow */
185*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
186*3d8817e4Smiod 	 "R_M32C_HI16",		/* name */
187*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
188*3d8817e4Smiod 	 0,     		/* src_mask */
189*3d8817e4Smiod 	 0xffff,		/* dst_mask */
190*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
191*3d8817e4Smiod 
192*3d8817e4Smiod   HOWTO (R_M32C_RL_JUMP,	/* type */
193*3d8817e4Smiod 	 0,			/* rightshift */
194*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
195*3d8817e4Smiod 	 0,			/* bitsize */
196*3d8817e4Smiod 	 FALSE,			/* pc_relative */
197*3d8817e4Smiod 	 0,			/* bitpos */
198*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
199*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
200*3d8817e4Smiod 	 "R_M32C_RL_JUMP",	/* name */
201*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
202*3d8817e4Smiod 	 0,     		/* src_mask */
203*3d8817e4Smiod 	 0,   			/* dst_mask */
204*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
205*3d8817e4Smiod 
206*3d8817e4Smiod   HOWTO (R_M32C_RL_1ADDR,	/* type */
207*3d8817e4Smiod 	 0,			/* rightshift */
208*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
209*3d8817e4Smiod 	 0,			/* bitsize */
210*3d8817e4Smiod 	 FALSE,			/* pc_relative */
211*3d8817e4Smiod 	 0,			/* bitpos */
212*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
213*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
214*3d8817e4Smiod 	 "R_M32C_RL_1ADDR",	/* name */
215*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
216*3d8817e4Smiod 	 0,     		/* src_mask */
217*3d8817e4Smiod 	 0,   			/* dst_mask */
218*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
219*3d8817e4Smiod 
220*3d8817e4Smiod   HOWTO (R_M32C_RL_2ADDR,	/* type */
221*3d8817e4Smiod 	 0,			/* rightshift */
222*3d8817e4Smiod 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
223*3d8817e4Smiod 	 0,			/* bitsize */
224*3d8817e4Smiod 	 FALSE,			/* pc_relative */
225*3d8817e4Smiod 	 0,			/* bitpos */
226*3d8817e4Smiod 	 complain_overflow_signed, /* complain_on_overflow */
227*3d8817e4Smiod 	 bfd_elf_generic_reloc,	/* special_function */
228*3d8817e4Smiod 	 "R_M32C_RL_2ADDR",	/* name */
229*3d8817e4Smiod 	 FALSE,			/* partial_inplace */
230*3d8817e4Smiod 	 0,     		/* src_mask */
231*3d8817e4Smiod 	 0,   			/* dst_mask */
232*3d8817e4Smiod 	 FALSE), 		/* pcrel_offset */
233*3d8817e4Smiod 
234*3d8817e4Smiod };
235*3d8817e4Smiod 
236*3d8817e4Smiod /* Map BFD reloc types to M32C ELF reloc types.  */
237*3d8817e4Smiod 
238*3d8817e4Smiod struct m32c_reloc_map
239*3d8817e4Smiod {
240*3d8817e4Smiod   bfd_reloc_code_real_type bfd_reloc_val;
241*3d8817e4Smiod   unsigned int m32c_reloc_val;
242*3d8817e4Smiod };
243*3d8817e4Smiod 
244*3d8817e4Smiod static const struct m32c_reloc_map m32c_reloc_map [] =
245*3d8817e4Smiod {
246*3d8817e4Smiod   { BFD_RELOC_NONE,		R_M32C_NONE },
247*3d8817e4Smiod   { BFD_RELOC_16,		R_M32C_16 },
248*3d8817e4Smiod   { BFD_RELOC_24,               R_M32C_24 },
249*3d8817e4Smiod   { BFD_RELOC_32,		R_M32C_32 },
250*3d8817e4Smiod   { BFD_RELOC_8_PCREL,          R_M32C_8_PCREL },
251*3d8817e4Smiod   { BFD_RELOC_16_PCREL,         R_M32C_16_PCREL },
252*3d8817e4Smiod   { BFD_RELOC_8,		R_M32C_8 },
253*3d8817e4Smiod   { BFD_RELOC_LO16,		R_M32C_LO16 },
254*3d8817e4Smiod   { BFD_RELOC_HI16,		R_M32C_HI16 },
255*3d8817e4Smiod   { BFD_RELOC_M32C_HI8,		R_M32C_HI8 },
256*3d8817e4Smiod   { BFD_RELOC_M32C_RL_JUMP,	R_M32C_RL_JUMP },
257*3d8817e4Smiod   { BFD_RELOC_M32C_RL_1ADDR,	R_M32C_RL_1ADDR },
258*3d8817e4Smiod   { BFD_RELOC_M32C_RL_2ADDR,	R_M32C_RL_2ADDR }
259*3d8817e4Smiod };
260*3d8817e4Smiod 
261*3d8817e4Smiod static reloc_howto_type *
m32c_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)262*3d8817e4Smiod m32c_reloc_type_lookup
263*3d8817e4Smiod     (bfd *                    abfd ATTRIBUTE_UNUSED,
264*3d8817e4Smiod      bfd_reloc_code_real_type code)
265*3d8817e4Smiod {
266*3d8817e4Smiod   unsigned int i;
267*3d8817e4Smiod 
268*3d8817e4Smiod   for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
269*3d8817e4Smiod     if (m32c_reloc_map [i].bfd_reloc_val == code)
270*3d8817e4Smiod       return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
271*3d8817e4Smiod 
272*3d8817e4Smiod   return NULL;
273*3d8817e4Smiod }
274*3d8817e4Smiod 
275*3d8817e4Smiod /* Set the howto pointer for an M32C ELF reloc.  */
276*3d8817e4Smiod 
277*3d8817e4Smiod static void
m32c_info_to_howto_rela(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)278*3d8817e4Smiod m32c_info_to_howto_rela
279*3d8817e4Smiod     (bfd *               abfd ATTRIBUTE_UNUSED,
280*3d8817e4Smiod      arelent *           cache_ptr,
281*3d8817e4Smiod      Elf_Internal_Rela * dst)
282*3d8817e4Smiod {
283*3d8817e4Smiod   unsigned int r_type;
284*3d8817e4Smiod 
285*3d8817e4Smiod   r_type = ELF32_R_TYPE (dst->r_info);
286*3d8817e4Smiod   BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
287*3d8817e4Smiod   cache_ptr->howto = & m32c_elf_howto_table [r_type];
288*3d8817e4Smiod }
289*3d8817e4Smiod 
290*3d8817e4Smiod 
291*3d8817e4Smiod 
292*3d8817e4Smiod /* Relocate an M32C ELF section.
293*3d8817e4Smiod    There is some attempt to make this function usable for many architectures,
294*3d8817e4Smiod    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
295*3d8817e4Smiod    if only to serve as a learning tool.
296*3d8817e4Smiod 
297*3d8817e4Smiod    The RELOCATE_SECTION function is called by the new ELF backend linker
298*3d8817e4Smiod    to handle the relocations for a section.
299*3d8817e4Smiod 
300*3d8817e4Smiod    The relocs are always passed as Rela structures; if the section
301*3d8817e4Smiod    actually uses Rel structures, the r_addend field will always be
302*3d8817e4Smiod    zero.
303*3d8817e4Smiod 
304*3d8817e4Smiod    This function is responsible for adjusting the section contents as
305*3d8817e4Smiod    necessary, and (if using Rela relocs and generating a relocatable
306*3d8817e4Smiod    output file) adjusting the reloc addend as necessary.
307*3d8817e4Smiod 
308*3d8817e4Smiod    This function does not have to worry about setting the reloc
309*3d8817e4Smiod    address or the reloc symbol index.
310*3d8817e4Smiod 
311*3d8817e4Smiod    LOCAL_SYMS is a pointer to the swapped in local symbols.
312*3d8817e4Smiod 
313*3d8817e4Smiod    LOCAL_SECTIONS is an array giving the section in the input file
314*3d8817e4Smiod    corresponding to the st_shndx field of each local symbol.
315*3d8817e4Smiod 
316*3d8817e4Smiod    The global hash table entry for the global symbols can be found
317*3d8817e4Smiod    via elf_sym_hashes (input_bfd).
318*3d8817e4Smiod 
319*3d8817e4Smiod    When generating relocatable output, this function must handle
320*3d8817e4Smiod    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
321*3d8817e4Smiod    going to be the section symbol corresponding to the output
322*3d8817e4Smiod    section, which means that the addend must be adjusted
323*3d8817e4Smiod    accordingly.  */
324*3d8817e4Smiod 
325*3d8817e4Smiod static bfd_boolean
m32c_elf_relocate_section(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)326*3d8817e4Smiod m32c_elf_relocate_section
327*3d8817e4Smiod     (bfd *                   output_bfd ATTRIBUTE_UNUSED,
328*3d8817e4Smiod      struct bfd_link_info *  info,
329*3d8817e4Smiod      bfd *                   input_bfd,
330*3d8817e4Smiod      asection *              input_section,
331*3d8817e4Smiod      bfd_byte *              contents,
332*3d8817e4Smiod      Elf_Internal_Rela *     relocs,
333*3d8817e4Smiod      Elf_Internal_Sym *      local_syms,
334*3d8817e4Smiod      asection **             local_sections)
335*3d8817e4Smiod {
336*3d8817e4Smiod   Elf_Internal_Shdr *           symtab_hdr;
337*3d8817e4Smiod   struct elf_link_hash_entry ** sym_hashes;
338*3d8817e4Smiod   Elf_Internal_Rela *           rel;
339*3d8817e4Smiod   Elf_Internal_Rela *           relend;
340*3d8817e4Smiod   bfd *dynobj;
341*3d8817e4Smiod   asection *splt;
342*3d8817e4Smiod 
343*3d8817e4Smiod   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
344*3d8817e4Smiod   sym_hashes = elf_sym_hashes (input_bfd);
345*3d8817e4Smiod   relend     = relocs + input_section->reloc_count;
346*3d8817e4Smiod 
347*3d8817e4Smiod   dynobj = elf_hash_table (info)->dynobj;
348*3d8817e4Smiod   splt = NULL;
349*3d8817e4Smiod   if (dynobj != NULL)
350*3d8817e4Smiod     splt = bfd_get_section_by_name (dynobj, ".plt");
351*3d8817e4Smiod 
352*3d8817e4Smiod   for (rel = relocs; rel < relend; rel ++)
353*3d8817e4Smiod     {
354*3d8817e4Smiod       reloc_howto_type *           howto;
355*3d8817e4Smiod       unsigned long                r_symndx;
356*3d8817e4Smiod       Elf_Internal_Sym *           sym;
357*3d8817e4Smiod       asection *                   sec;
358*3d8817e4Smiod       struct elf_link_hash_entry * h;
359*3d8817e4Smiod       bfd_vma                      relocation;
360*3d8817e4Smiod       bfd_reloc_status_type        r;
361*3d8817e4Smiod       const char *                 name = NULL;
362*3d8817e4Smiod       int                          r_type;
363*3d8817e4Smiod 
364*3d8817e4Smiod       r_type = ELF32_R_TYPE (rel->r_info);
365*3d8817e4Smiod 
366*3d8817e4Smiod       /* These are only used for relaxing; we don't actually relocate
367*3d8817e4Smiod 	 anything with them, so skip them.  */
368*3d8817e4Smiod       if (r_type == R_M32C_RL_JUMP
369*3d8817e4Smiod 	  || r_type == R_M32C_RL_1ADDR
370*3d8817e4Smiod 	  || r_type == R_M32C_RL_2ADDR)
371*3d8817e4Smiod 	continue;
372*3d8817e4Smiod 
373*3d8817e4Smiod       r_symndx = ELF32_R_SYM (rel->r_info);
374*3d8817e4Smiod 
375*3d8817e4Smiod       if (info->relocatable)
376*3d8817e4Smiod 	{
377*3d8817e4Smiod 	  /* This is a relocatable link.  We don't have to change
378*3d8817e4Smiod              anything, unless the reloc is against a section symbol,
379*3d8817e4Smiod              in which case we have to adjust according to where the
380*3d8817e4Smiod              section symbol winds up in the output section.  */
381*3d8817e4Smiod 	  if (r_symndx < symtab_hdr->sh_info)
382*3d8817e4Smiod 	    {
383*3d8817e4Smiod 	      sym = local_syms + r_symndx;
384*3d8817e4Smiod 
385*3d8817e4Smiod 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
386*3d8817e4Smiod 		{
387*3d8817e4Smiod 		  sec = local_sections [r_symndx];
388*3d8817e4Smiod 		  rel->r_addend += sec->output_offset + sym->st_value;
389*3d8817e4Smiod 		}
390*3d8817e4Smiod 	    }
391*3d8817e4Smiod 
392*3d8817e4Smiod 	  continue;
393*3d8817e4Smiod 	}
394*3d8817e4Smiod 
395*3d8817e4Smiod       /* This is a final link.  */
396*3d8817e4Smiod       howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
397*3d8817e4Smiod       h      = NULL;
398*3d8817e4Smiod       sym    = NULL;
399*3d8817e4Smiod       sec    = NULL;
400*3d8817e4Smiod 
401*3d8817e4Smiod       if (r_symndx < symtab_hdr->sh_info)
402*3d8817e4Smiod 	{
403*3d8817e4Smiod 	  sym = local_syms + r_symndx;
404*3d8817e4Smiod 	  sec = local_sections [r_symndx];
405*3d8817e4Smiod 	  relocation = (sec->output_section->vma
406*3d8817e4Smiod 			+ sec->output_offset
407*3d8817e4Smiod 			+ sym->st_value);
408*3d8817e4Smiod 
409*3d8817e4Smiod 	  name = bfd_elf_string_from_elf_section
410*3d8817e4Smiod 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
411*3d8817e4Smiod 	  name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
412*3d8817e4Smiod 	}
413*3d8817e4Smiod       else
414*3d8817e4Smiod 	{
415*3d8817e4Smiod 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
416*3d8817e4Smiod 
417*3d8817e4Smiod 	  while (h->root.type == bfd_link_hash_indirect
418*3d8817e4Smiod 		 || h->root.type == bfd_link_hash_warning)
419*3d8817e4Smiod 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
420*3d8817e4Smiod 
421*3d8817e4Smiod 	  name = h->root.root.string;
422*3d8817e4Smiod 
423*3d8817e4Smiod 	  if (h->root.type == bfd_link_hash_defined
424*3d8817e4Smiod 	      || h->root.type == bfd_link_hash_defweak)
425*3d8817e4Smiod 	    {
426*3d8817e4Smiod 	      sec = h->root.u.def.section;
427*3d8817e4Smiod 	      relocation = (h->root.u.def.value
428*3d8817e4Smiod 			    + sec->output_section->vma
429*3d8817e4Smiod 			    + sec->output_offset);
430*3d8817e4Smiod 	    }
431*3d8817e4Smiod 	  else if (h->root.type == bfd_link_hash_undefweak)
432*3d8817e4Smiod 	    {
433*3d8817e4Smiod 	      relocation = 0;
434*3d8817e4Smiod 	    }
435*3d8817e4Smiod 	  else
436*3d8817e4Smiod 	    {
437*3d8817e4Smiod 	      if (! ((*info->callbacks->undefined_symbol)
438*3d8817e4Smiod 		     (info, h->root.root.string, input_bfd,
439*3d8817e4Smiod 		      input_section, rel->r_offset, TRUE)))
440*3d8817e4Smiod 		return FALSE;
441*3d8817e4Smiod 	      relocation = 0;
442*3d8817e4Smiod 	    }
443*3d8817e4Smiod 	}
444*3d8817e4Smiod 
445*3d8817e4Smiod       switch (ELF32_R_TYPE (rel->r_info))
446*3d8817e4Smiod 	{
447*3d8817e4Smiod 	case R_M32C_16:
448*3d8817e4Smiod 	  {
449*3d8817e4Smiod 	    bfd_vma *plt_offset;
450*3d8817e4Smiod 
451*3d8817e4Smiod 	    if (h != NULL)
452*3d8817e4Smiod 	      plt_offset = &h->plt.offset;
453*3d8817e4Smiod 	    else
454*3d8817e4Smiod 	      plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
455*3d8817e4Smiod 
456*3d8817e4Smiod 	    /*	    printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
457*3d8817e4Smiod 		    relocation, *plt_offset);*/
458*3d8817e4Smiod 	    if (relocation <= 0xffff)
459*3d8817e4Smiod 	      {
460*3d8817e4Smiod 	        /* If the symbol is in range for a 16-bit address, we should
461*3d8817e4Smiod 		   have deallocated the plt entry in relax_section.  */
462*3d8817e4Smiod 	        BFD_ASSERT (*plt_offset == (bfd_vma) -1);
463*3d8817e4Smiod 	      }
464*3d8817e4Smiod 	    else
465*3d8817e4Smiod 	      {
466*3d8817e4Smiod 		/* If the symbol is out of range for a 16-bit address,
467*3d8817e4Smiod 		   we must have allocated a plt entry.  */
468*3d8817e4Smiod 		BFD_ASSERT (*plt_offset != (bfd_vma) -1);
469*3d8817e4Smiod 
470*3d8817e4Smiod 		/* If this is the first time we've processed this symbol,
471*3d8817e4Smiod 		   fill in the plt entry with the correct symbol address.  */
472*3d8817e4Smiod 		if ((*plt_offset & 1) == 0)
473*3d8817e4Smiod 		  {
474*3d8817e4Smiod 		    unsigned int x;
475*3d8817e4Smiod 
476*3d8817e4Smiod 		    x = 0x000000fc;  /* jmpf */
477*3d8817e4Smiod 		    x |= (relocation << 8) & 0xffffff00;
478*3d8817e4Smiod 		    bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
479*3d8817e4Smiod 		    *plt_offset |= 1;
480*3d8817e4Smiod 		  }
481*3d8817e4Smiod 
482*3d8817e4Smiod 		relocation = (splt->output_section->vma
483*3d8817e4Smiod 			      + splt->output_offset
484*3d8817e4Smiod 			      + (*plt_offset & -2));
485*3d8817e4Smiod 		if (name)
486*3d8817e4Smiod 		{
487*3d8817e4Smiod 		  char *newname = bfd_malloc (strlen(name)+5);
488*3d8817e4Smiod 		  strcpy (newname, name);
489*3d8817e4Smiod 		  strcat(newname, ".plt");
490*3d8817e4Smiod 		  _bfd_generic_link_add_one_symbol (info,
491*3d8817e4Smiod 						    input_bfd,
492*3d8817e4Smiod 						    newname,
493*3d8817e4Smiod 						    BSF_FUNCTION | BSF_WEAK,
494*3d8817e4Smiod 						    splt,
495*3d8817e4Smiod 						    (*plt_offset & -2),
496*3d8817e4Smiod 						    0,
497*3d8817e4Smiod 						    1,
498*3d8817e4Smiod 						    0,
499*3d8817e4Smiod 						    0);
500*3d8817e4Smiod 		}
501*3d8817e4Smiod 	      }
502*3d8817e4Smiod 	  }
503*3d8817e4Smiod 	  break;
504*3d8817e4Smiod 
505*3d8817e4Smiod 	case R_M32C_HI8:
506*3d8817e4Smiod 	case R_M32C_HI16:
507*3d8817e4Smiod 	  relocation >>= 16;
508*3d8817e4Smiod 	  break;
509*3d8817e4Smiod 	}
510*3d8817e4Smiod 
511*3d8817e4Smiod #if 0
512*3d8817e4Smiod       printf ("relocate %s at %06lx relocation %06lx addend %ld  ",
513*3d8817e4Smiod 	      m32c_elf_howto_table[ELF32_R_TYPE(rel->r_info)].name,
514*3d8817e4Smiod 	      rel->r_offset + input_section->output_section->vma + input_section->output_offset,
515*3d8817e4Smiod 	      relocation, rel->r_addend);
516*3d8817e4Smiod       {
517*3d8817e4Smiod 	int i;
518*3d8817e4Smiod 	for (i=0; i<4; i++)
519*3d8817e4Smiod 	  printf (" %02x", contents[rel->r_offset+i]);
520*3d8817e4Smiod 	printf ("\n");
521*3d8817e4Smiod       }
522*3d8817e4Smiod #endif
523*3d8817e4Smiod       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
524*3d8817e4Smiod                                     contents, rel->r_offset, relocation,
525*3d8817e4Smiod                                     rel->r_addend);
526*3d8817e4Smiod 
527*3d8817e4Smiod       if (r != bfd_reloc_ok)
528*3d8817e4Smiod 	{
529*3d8817e4Smiod 	  const char * msg = (const char *) NULL;
530*3d8817e4Smiod 
531*3d8817e4Smiod 	  switch (r)
532*3d8817e4Smiod 	    {
533*3d8817e4Smiod 	    case bfd_reloc_overflow:
534*3d8817e4Smiod 	      r = info->callbacks->reloc_overflow
535*3d8817e4Smiod 		(info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
536*3d8817e4Smiod 		 input_bfd, input_section, rel->r_offset);
537*3d8817e4Smiod 	      break;
538*3d8817e4Smiod 
539*3d8817e4Smiod 	    case bfd_reloc_undefined:
540*3d8817e4Smiod 	      r = info->callbacks->undefined_symbol
541*3d8817e4Smiod 		(info, name, input_bfd, input_section, rel->r_offset,
542*3d8817e4Smiod 		 TRUE);
543*3d8817e4Smiod 	      break;
544*3d8817e4Smiod 
545*3d8817e4Smiod 	    case bfd_reloc_outofrange:
546*3d8817e4Smiod 	      msg = _("internal error: out of range error");
547*3d8817e4Smiod 	      break;
548*3d8817e4Smiod 
549*3d8817e4Smiod 	    case bfd_reloc_notsupported:
550*3d8817e4Smiod 	      msg = _("internal error: unsupported relocation error");
551*3d8817e4Smiod 	      break;
552*3d8817e4Smiod 
553*3d8817e4Smiod 	    case bfd_reloc_dangerous:
554*3d8817e4Smiod 	      msg = _("internal error: dangerous relocation");
555*3d8817e4Smiod 	      break;
556*3d8817e4Smiod 
557*3d8817e4Smiod 	    default:
558*3d8817e4Smiod 	      msg = _("internal error: unknown error");
559*3d8817e4Smiod 	      break;
560*3d8817e4Smiod 	    }
561*3d8817e4Smiod 
562*3d8817e4Smiod 	  if (msg)
563*3d8817e4Smiod 	    r = info->callbacks->warning
564*3d8817e4Smiod 	      (info, msg, name, input_bfd, input_section, rel->r_offset);
565*3d8817e4Smiod 
566*3d8817e4Smiod 	  if (! r)
567*3d8817e4Smiod 	    return FALSE;
568*3d8817e4Smiod 	}
569*3d8817e4Smiod     }
570*3d8817e4Smiod 
571*3d8817e4Smiod   return TRUE;
572*3d8817e4Smiod }
573*3d8817e4Smiod 
574*3d8817e4Smiod /* Return the section that should be marked against GC for a given
575*3d8817e4Smiod    relocation.  */
576*3d8817e4Smiod 
577*3d8817e4Smiod static asection *
m32c_elf_gc_mark_hook(asection * sec,struct bfd_link_info * info ATTRIBUTE_UNUSED,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)578*3d8817e4Smiod m32c_elf_gc_mark_hook
579*3d8817e4Smiod     (asection *                   sec,
580*3d8817e4Smiod      struct bfd_link_info *       info ATTRIBUTE_UNUSED,
581*3d8817e4Smiod      Elf_Internal_Rela *          rel,
582*3d8817e4Smiod      struct elf_link_hash_entry * h,
583*3d8817e4Smiod      Elf_Internal_Sym *           sym)
584*3d8817e4Smiod {
585*3d8817e4Smiod   if (h != NULL)
586*3d8817e4Smiod     {
587*3d8817e4Smiod       switch (ELF32_R_TYPE (rel->r_info))
588*3d8817e4Smiod 	{
589*3d8817e4Smiod 	default:
590*3d8817e4Smiod 	  switch (h->root.type)
591*3d8817e4Smiod 	    {
592*3d8817e4Smiod 	    case bfd_link_hash_defined:
593*3d8817e4Smiod 	    case bfd_link_hash_defweak:
594*3d8817e4Smiod 	      return h->root.u.def.section;
595*3d8817e4Smiod 
596*3d8817e4Smiod 	    case bfd_link_hash_common:
597*3d8817e4Smiod 	      return h->root.u.c.p->section;
598*3d8817e4Smiod 
599*3d8817e4Smiod 	    default:
600*3d8817e4Smiod 	      break;
601*3d8817e4Smiod 	    }
602*3d8817e4Smiod 	}
603*3d8817e4Smiod     }
604*3d8817e4Smiod   else
605*3d8817e4Smiod     {
606*3d8817e4Smiod       if (!(elf_bad_symtab (sec->owner)
607*3d8817e4Smiod 	    && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
608*3d8817e4Smiod 	  && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
609*3d8817e4Smiod 		&& sym->st_shndx != SHN_COMMON))
610*3d8817e4Smiod 	{
611*3d8817e4Smiod 	  return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
612*3d8817e4Smiod 	}
613*3d8817e4Smiod     }
614*3d8817e4Smiod 
615*3d8817e4Smiod   return NULL;
616*3d8817e4Smiod }
617*3d8817e4Smiod 
618*3d8817e4Smiod /* Update the got entry reference counts for the section being removed.  */
619*3d8817e4Smiod 
620*3d8817e4Smiod static bfd_boolean
m32c_elf_gc_sweep_hook(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_link_info * info ATTRIBUTE_UNUSED,asection * sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)621*3d8817e4Smiod m32c_elf_gc_sweep_hook
622*3d8817e4Smiod     (bfd *                     abfd ATTRIBUTE_UNUSED,
623*3d8817e4Smiod      struct bfd_link_info *    info ATTRIBUTE_UNUSED,
624*3d8817e4Smiod      asection *                sec ATTRIBUTE_UNUSED,
625*3d8817e4Smiod      const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
626*3d8817e4Smiod {
627*3d8817e4Smiod   return TRUE;
628*3d8817e4Smiod }
629*3d8817e4Smiod 
630*3d8817e4Smiod /* We support 16-bit pointers to code above 64k by generating a thunk
631*3d8817e4Smiod    below 64k containing a JMP instruction to the final address.  */
632*3d8817e4Smiod 
633*3d8817e4Smiod static bfd_boolean
m32c_elf_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)634*3d8817e4Smiod m32c_elf_check_relocs
635*3d8817e4Smiod     (bfd *                     abfd,
636*3d8817e4Smiod      struct bfd_link_info *    info,
637*3d8817e4Smiod      asection *                sec,
638*3d8817e4Smiod      const Elf_Internal_Rela * relocs)
639*3d8817e4Smiod {
640*3d8817e4Smiod   Elf_Internal_Shdr *           symtab_hdr;
641*3d8817e4Smiod   struct elf_link_hash_entry ** sym_hashes;
642*3d8817e4Smiod   struct elf_link_hash_entry ** sym_hashes_end;
643*3d8817e4Smiod   const Elf_Internal_Rela *     rel;
644*3d8817e4Smiod   const Elf_Internal_Rela *     rel_end;
645*3d8817e4Smiod   bfd_vma *local_plt_offsets;
646*3d8817e4Smiod   asection *splt;
647*3d8817e4Smiod   bfd *dynobj;
648*3d8817e4Smiod 
649*3d8817e4Smiod   if (info->relocatable)
650*3d8817e4Smiod     return TRUE;
651*3d8817e4Smiod 
652*3d8817e4Smiod   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
653*3d8817e4Smiod   sym_hashes = elf_sym_hashes (abfd);
654*3d8817e4Smiod   local_plt_offsets = elf_local_got_offsets (abfd);
655*3d8817e4Smiod   splt = NULL;
656*3d8817e4Smiod   dynobj = elf_hash_table(info)->dynobj;
657*3d8817e4Smiod 
658*3d8817e4Smiod   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
659*3d8817e4Smiod   if (!elf_bad_symtab (abfd))
660*3d8817e4Smiod     sym_hashes_end -= symtab_hdr->sh_info;
661*3d8817e4Smiod 
662*3d8817e4Smiod   rel_end = relocs + sec->reloc_count;
663*3d8817e4Smiod   for (rel = relocs; rel < rel_end; rel++)
664*3d8817e4Smiod     {
665*3d8817e4Smiod       struct elf_link_hash_entry *h;
666*3d8817e4Smiod       unsigned long r_symndx;
667*3d8817e4Smiod       bfd_vma *offset;
668*3d8817e4Smiod 
669*3d8817e4Smiod       r_symndx = ELF32_R_SYM (rel->r_info);
670*3d8817e4Smiod       if (r_symndx < symtab_hdr->sh_info)
671*3d8817e4Smiod         h = NULL;
672*3d8817e4Smiod       else
673*3d8817e4Smiod 	{
674*3d8817e4Smiod 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
675*3d8817e4Smiod 	  while (h->root.type == bfd_link_hash_indirect
676*3d8817e4Smiod 		 || h->root.type == bfd_link_hash_warning)
677*3d8817e4Smiod 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
678*3d8817e4Smiod 	}
679*3d8817e4Smiod 
680*3d8817e4Smiod       switch (ELF32_R_TYPE (rel->r_info))
681*3d8817e4Smiod         {
682*3d8817e4Smiod 	  /* This relocation describes a 16-bit pointer to a function.
683*3d8817e4Smiod 	     We may need to allocate a thunk in low memory; reserve memory
684*3d8817e4Smiod 	     for it now.  */
685*3d8817e4Smiod 	case R_M32C_16:
686*3d8817e4Smiod 	  if (dynobj == NULL)
687*3d8817e4Smiod 	    elf_hash_table (info)->dynobj = dynobj = abfd;
688*3d8817e4Smiod 	  if (splt == NULL)
689*3d8817e4Smiod 	    {
690*3d8817e4Smiod 	      splt = bfd_get_section_by_name (dynobj, ".plt");
691*3d8817e4Smiod 	      if (splt == NULL)
692*3d8817e4Smiod 		{
693*3d8817e4Smiod 		  splt = bfd_make_section (dynobj, ".plt");
694*3d8817e4Smiod 		  if (splt == NULL
695*3d8817e4Smiod 		      || ! bfd_set_section_flags (dynobj, splt,
696*3d8817e4Smiod 						  (SEC_ALLOC
697*3d8817e4Smiod 						   | SEC_LOAD
698*3d8817e4Smiod 						   | SEC_HAS_CONTENTS
699*3d8817e4Smiod 						   | SEC_IN_MEMORY
700*3d8817e4Smiod 						   | SEC_LINKER_CREATED
701*3d8817e4Smiod 						   | SEC_READONLY
702*3d8817e4Smiod 						   | SEC_CODE))
703*3d8817e4Smiod 		      || ! bfd_set_section_alignment (dynobj, splt, 1))
704*3d8817e4Smiod 		    return FALSE;
705*3d8817e4Smiod 		}
706*3d8817e4Smiod 	    }
707*3d8817e4Smiod 
708*3d8817e4Smiod 	  if (h != NULL)
709*3d8817e4Smiod 	    offset = &h->plt.offset;
710*3d8817e4Smiod 	  else
711*3d8817e4Smiod 	    {
712*3d8817e4Smiod 	      if (local_plt_offsets == NULL)
713*3d8817e4Smiod 		{
714*3d8817e4Smiod 		  size_t size;
715*3d8817e4Smiod 		  unsigned int i;
716*3d8817e4Smiod 
717*3d8817e4Smiod 		  size = symtab_hdr->sh_info * sizeof (bfd_vma);
718*3d8817e4Smiod 		  local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
719*3d8817e4Smiod 		  if (local_plt_offsets == NULL)
720*3d8817e4Smiod 		    return FALSE;
721*3d8817e4Smiod 		  elf_local_got_offsets (abfd) = local_plt_offsets;
722*3d8817e4Smiod 
723*3d8817e4Smiod 		  for (i = 0; i < symtab_hdr->sh_info; i++)
724*3d8817e4Smiod 		    local_plt_offsets[i] = (bfd_vma) -1;
725*3d8817e4Smiod 		}
726*3d8817e4Smiod 	      offset = &local_plt_offsets[r_symndx];
727*3d8817e4Smiod 	    }
728*3d8817e4Smiod 
729*3d8817e4Smiod 	  if (*offset == (bfd_vma) -1)
730*3d8817e4Smiod 	    {
731*3d8817e4Smiod 	      *offset = splt->size;
732*3d8817e4Smiod 	      splt->size += 4;
733*3d8817e4Smiod 	    }
734*3d8817e4Smiod 	  break;
735*3d8817e4Smiod         }
736*3d8817e4Smiod     }
737*3d8817e4Smiod 
738*3d8817e4Smiod   return TRUE;
739*3d8817e4Smiod }
740*3d8817e4Smiod 
741*3d8817e4Smiod /* This must exist if dynobj is ever set.  */
742*3d8817e4Smiod 
743*3d8817e4Smiod static bfd_boolean
m32c_elf_finish_dynamic_sections(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)744*3d8817e4Smiod m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
745*3d8817e4Smiod                                   struct bfd_link_info *info)
746*3d8817e4Smiod {
747*3d8817e4Smiod   bfd *dynobj;
748*3d8817e4Smiod   asection *splt;
749*3d8817e4Smiod 
750*3d8817e4Smiod   /* As an extra sanity check, verify that all plt entries have
751*3d8817e4Smiod      been filled in.  */
752*3d8817e4Smiod 
753*3d8817e4Smiod   if ((dynobj = elf_hash_table (info)->dynobj) != NULL
754*3d8817e4Smiod       && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
755*3d8817e4Smiod     {
756*3d8817e4Smiod       bfd_byte *contents = splt->contents;
757*3d8817e4Smiod       unsigned int i, size = splt->size;
758*3d8817e4Smiod       for (i = 0; i < size; i += 4)
759*3d8817e4Smiod 	{
760*3d8817e4Smiod 	  unsigned int x = bfd_get_32 (dynobj, contents + i);
761*3d8817e4Smiod 	  BFD_ASSERT (x != 0);
762*3d8817e4Smiod 	}
763*3d8817e4Smiod     }
764*3d8817e4Smiod 
765*3d8817e4Smiod   return TRUE;
766*3d8817e4Smiod }
767*3d8817e4Smiod 
768*3d8817e4Smiod static bfd_boolean
m32c_elf_always_size_sections(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)769*3d8817e4Smiod m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
770*3d8817e4Smiod                                struct bfd_link_info *info)
771*3d8817e4Smiod {
772*3d8817e4Smiod   bfd *dynobj;
773*3d8817e4Smiod   asection *splt;
774*3d8817e4Smiod 
775*3d8817e4Smiod   if (info->relocatable)
776*3d8817e4Smiod     return TRUE;
777*3d8817e4Smiod 
778*3d8817e4Smiod   dynobj = elf_hash_table (info)->dynobj;
779*3d8817e4Smiod   if (dynobj == NULL)
780*3d8817e4Smiod     return TRUE;
781*3d8817e4Smiod 
782*3d8817e4Smiod   splt = bfd_get_section_by_name (dynobj, ".plt");
783*3d8817e4Smiod   BFD_ASSERT (splt != NULL);
784*3d8817e4Smiod 
785*3d8817e4Smiod   splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
786*3d8817e4Smiod   if (splt->contents == NULL)
787*3d8817e4Smiod     return FALSE;
788*3d8817e4Smiod 
789*3d8817e4Smiod   return TRUE;
790*3d8817e4Smiod }
791*3d8817e4Smiod 
792*3d8817e4Smiod /* Function to set the ELF flag bits.  */
793*3d8817e4Smiod 
794*3d8817e4Smiod static bfd_boolean
m32c_elf_set_private_flags(bfd * abfd,flagword flags)795*3d8817e4Smiod m32c_elf_set_private_flags (bfd *abfd, flagword flags)
796*3d8817e4Smiod {
797*3d8817e4Smiod   elf_elfheader (abfd)->e_flags = flags;
798*3d8817e4Smiod   elf_flags_init (abfd) = TRUE;
799*3d8817e4Smiod   return TRUE;
800*3d8817e4Smiod }
801*3d8817e4Smiod 
802*3d8817e4Smiod /* Merge backend specific data from an object file to the output
803*3d8817e4Smiod    object file when linking.  */
804*3d8817e4Smiod 
805*3d8817e4Smiod static bfd_boolean
m32c_elf_merge_private_bfd_data(bfd * ibfd,bfd * obfd)806*3d8817e4Smiod m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
807*3d8817e4Smiod {
808*3d8817e4Smiod   flagword old_flags, old_partial;
809*3d8817e4Smiod   flagword new_flags, new_partial;
810*3d8817e4Smiod   bfd_boolean error = FALSE;
811*3d8817e4Smiod   char new_opt[80];
812*3d8817e4Smiod   char old_opt[80];
813*3d8817e4Smiod 
814*3d8817e4Smiod   new_opt[0] = old_opt[0] = '\0';
815*3d8817e4Smiod   new_flags = elf_elfheader (ibfd)->e_flags;
816*3d8817e4Smiod   old_flags = elf_elfheader (obfd)->e_flags;
817*3d8817e4Smiod 
818*3d8817e4Smiod #ifdef DEBUG
819*3d8817e4Smiod   (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
820*3d8817e4Smiod 			 old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
821*3d8817e4Smiod 			 bfd_get_filename (ibfd));
822*3d8817e4Smiod #endif
823*3d8817e4Smiod 
824*3d8817e4Smiod   if (!elf_flags_init (obfd))
825*3d8817e4Smiod     {
826*3d8817e4Smiod       /* First call, no flags set.  */
827*3d8817e4Smiod       elf_flags_init (obfd) = TRUE;
828*3d8817e4Smiod       elf_elfheader (obfd)->e_flags = new_flags;
829*3d8817e4Smiod     }
830*3d8817e4Smiod 
831*3d8817e4Smiod   else if (new_flags == old_flags)
832*3d8817e4Smiod     /* Compatible flags are ok.	 */
833*3d8817e4Smiod     ;
834*3d8817e4Smiod 
835*3d8817e4Smiod   else		/* Possibly incompatible flags.	 */
836*3d8817e4Smiod     {
837*3d8817e4Smiod       /* Warn if different cpu is used (allow a specific cpu to override
838*3d8817e4Smiod 	 the generic cpu).  */
839*3d8817e4Smiod       new_partial = (new_flags & EF_M32C_CPU_MASK);
840*3d8817e4Smiod       old_partial = (old_flags & EF_M32C_CPU_MASK);
841*3d8817e4Smiod       if (new_partial == old_partial)
842*3d8817e4Smiod 	;
843*3d8817e4Smiod 
844*3d8817e4Smiod       else
845*3d8817e4Smiod 	{
846*3d8817e4Smiod 	  switch (new_partial)
847*3d8817e4Smiod 	    {
848*3d8817e4Smiod 	    default:		  strcat (new_opt, " -m16c");	break;
849*3d8817e4Smiod 	    case EF_M32C_CPU_M16C:	strcat (new_opt, " -m16c");  break;
850*3d8817e4Smiod 	    case EF_M32C_CPU_M32C:  strcat (new_opt, " -m32c");  break;
851*3d8817e4Smiod 	    }
852*3d8817e4Smiod 
853*3d8817e4Smiod 	  switch (old_partial)
854*3d8817e4Smiod 	    {
855*3d8817e4Smiod 	    default:		  strcat (old_opt, " -m16c");	break;
856*3d8817e4Smiod 	    case EF_M32C_CPU_M16C:	strcat (old_opt, " -m16c");  break;
857*3d8817e4Smiod 	    case EF_M32C_CPU_M32C:  strcat (old_opt, " -m32c");  break;
858*3d8817e4Smiod 	    }
859*3d8817e4Smiod 	}
860*3d8817e4Smiod 
861*3d8817e4Smiod       /* Print out any mismatches from above.  */
862*3d8817e4Smiod       if (new_opt[0])
863*3d8817e4Smiod 	{
864*3d8817e4Smiod 	  error = TRUE;
865*3d8817e4Smiod 	  (*_bfd_error_handler)
866*3d8817e4Smiod 	    (_("%s: compiled with %s and linked with modules compiled with %s"),
867*3d8817e4Smiod 	     bfd_get_filename (ibfd), new_opt, old_opt);
868*3d8817e4Smiod 	}
869*3d8817e4Smiod 
870*3d8817e4Smiod       new_flags &= ~ EF_M32C_ALL_FLAGS;
871*3d8817e4Smiod       old_flags &= ~ EF_M32C_ALL_FLAGS;
872*3d8817e4Smiod 
873*3d8817e4Smiod       /* Warn about any other mismatches.  */
874*3d8817e4Smiod       if (new_flags != old_flags)
875*3d8817e4Smiod 	{
876*3d8817e4Smiod 	  error = TRUE;
877*3d8817e4Smiod 	  (*_bfd_error_handler)
878*3d8817e4Smiod 	    (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
879*3d8817e4Smiod 	     bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
880*3d8817e4Smiod 	}
881*3d8817e4Smiod     }
882*3d8817e4Smiod 
883*3d8817e4Smiod   if (error)
884*3d8817e4Smiod     bfd_set_error (bfd_error_bad_value);
885*3d8817e4Smiod 
886*3d8817e4Smiod   return !error;
887*3d8817e4Smiod }
888*3d8817e4Smiod 
889*3d8817e4Smiod 
890*3d8817e4Smiod static bfd_boolean
m32c_elf_print_private_bfd_data(bfd * abfd,PTR ptr)891*3d8817e4Smiod m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
892*3d8817e4Smiod {
893*3d8817e4Smiod   FILE *file = (FILE *) ptr;
894*3d8817e4Smiod   flagword flags;
895*3d8817e4Smiod 
896*3d8817e4Smiod   BFD_ASSERT (abfd != NULL && ptr != NULL);
897*3d8817e4Smiod 
898*3d8817e4Smiod   /* Print normal ELF private data.  */
899*3d8817e4Smiod   _bfd_elf_print_private_bfd_data (abfd, ptr);
900*3d8817e4Smiod 
901*3d8817e4Smiod   flags = elf_elfheader (abfd)->e_flags;
902*3d8817e4Smiod   fprintf (file, _("private flags = 0x%lx:"), (long)flags);
903*3d8817e4Smiod 
904*3d8817e4Smiod   switch (flags & EF_M32C_CPU_MASK)
905*3d8817e4Smiod     {
906*3d8817e4Smiod     default:							break;
907*3d8817e4Smiod     case EF_M32C_CPU_M16C:	fprintf (file, " -m16c");	break;
908*3d8817e4Smiod     case EF_M32C_CPU_M32C:  fprintf (file, " -m32c");	break;
909*3d8817e4Smiod     }
910*3d8817e4Smiod 
911*3d8817e4Smiod   fputc ('\n', file);
912*3d8817e4Smiod   return TRUE;
913*3d8817e4Smiod }
914*3d8817e4Smiod 
915*3d8817e4Smiod /* Return the MACH for an e_flags value.  */
916*3d8817e4Smiod 
917*3d8817e4Smiod static int
elf32_m32c_machine(bfd * abfd)918*3d8817e4Smiod elf32_m32c_machine (bfd *abfd)
919*3d8817e4Smiod {
920*3d8817e4Smiod   switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
921*3d8817e4Smiod     {
922*3d8817e4Smiod     case EF_M32C_CPU_M16C:	return bfd_mach_m16c;
923*3d8817e4Smiod     case EF_M32C_CPU_M32C:  	return bfd_mach_m32c;
924*3d8817e4Smiod     }
925*3d8817e4Smiod 
926*3d8817e4Smiod   return bfd_mach_m16c;
927*3d8817e4Smiod }
928*3d8817e4Smiod 
929*3d8817e4Smiod static bfd_boolean
m32c_elf_object_p(bfd * abfd)930*3d8817e4Smiod m32c_elf_object_p (bfd *abfd)
931*3d8817e4Smiod {
932*3d8817e4Smiod   bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
933*3d8817e4Smiod 			     elf32_m32c_machine (abfd));
934*3d8817e4Smiod   return TRUE;
935*3d8817e4Smiod }
936*3d8817e4Smiod 
937*3d8817e4Smiod 
938*3d8817e4Smiod #ifdef DEBUG
939*3d8817e4Smiod static void
dump_symtab(bfd * abfd,void * internal_syms,void * external_syms)940*3d8817e4Smiod dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
941*3d8817e4Smiod {
942*3d8817e4Smiod   size_t locsymcount;
943*3d8817e4Smiod   Elf_Internal_Sym *isymbuf;
944*3d8817e4Smiod   Elf_Internal_Sym *isymend;
945*3d8817e4Smiod   Elf_Internal_Sym *isym;
946*3d8817e4Smiod   Elf_Internal_Shdr *symtab_hdr;
947*3d8817e4Smiod   bfd_boolean free_internal = 0, free_external = 0;
948*3d8817e4Smiod   char * st_info_str;
949*3d8817e4Smiod   char * st_info_stb_str;
950*3d8817e4Smiod   char * st_other_str;
951*3d8817e4Smiod   char * st_shndx_str;
952*3d8817e4Smiod 
953*3d8817e4Smiod   if (! internal_syms)
954*3d8817e4Smiod     {
955*3d8817e4Smiod       internal_syms = bfd_malloc (1000);
956*3d8817e4Smiod       free_internal = 1;
957*3d8817e4Smiod     }
958*3d8817e4Smiod   if (! external_syms)
959*3d8817e4Smiod     {
960*3d8817e4Smiod       external_syms = bfd_malloc (1000);
961*3d8817e4Smiod       free_external = 1;
962*3d8817e4Smiod     }
963*3d8817e4Smiod 
964*3d8817e4Smiod   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
965*3d8817e4Smiod   locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
966*3d8817e4Smiod   if (free_internal)
967*3d8817e4Smiod     isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
968*3d8817e4Smiod 				    symtab_hdr->sh_info, 0,
969*3d8817e4Smiod 				    internal_syms, external_syms, NULL);
970*3d8817e4Smiod   else
971*3d8817e4Smiod     isymbuf = internal_syms;
972*3d8817e4Smiod   isymend = isymbuf + locsymcount;
973*3d8817e4Smiod 
974*3d8817e4Smiod   for (isym = isymbuf ; isym < isymend ; isym++)
975*3d8817e4Smiod     {
976*3d8817e4Smiod       switch (ELF_ST_TYPE (isym->st_info))
977*3d8817e4Smiod 	{
978*3d8817e4Smiod 	case STT_FUNC: st_info_str = "STT_FUNC";
979*3d8817e4Smiod 	case STT_SECTION: st_info_str = "STT_SECTION";
980*3d8817e4Smiod 	case STT_SRELC: st_info_str = "STT_SRELC";
981*3d8817e4Smiod 	case STT_FILE: st_info_str = "STT_FILE";
982*3d8817e4Smiod 	case STT_OBJECT: st_info_str = "STT_OBJECT";
983*3d8817e4Smiod 	case STT_TLS: st_info_str = "STT_TLS";
984*3d8817e4Smiod 	default: st_info_str = "";
985*3d8817e4Smiod 	}
986*3d8817e4Smiod       switch (ELF_ST_BIND (isym->st_info))
987*3d8817e4Smiod 	{
988*3d8817e4Smiod 	case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
989*3d8817e4Smiod 	case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
990*3d8817e4Smiod 	default: st_info_stb_str = "";
991*3d8817e4Smiod 	}
992*3d8817e4Smiod       switch (ELF_ST_VISIBILITY (isym->st_other))
993*3d8817e4Smiod 	{
994*3d8817e4Smiod 	case STV_DEFAULT: st_other_str = "STV_DEFAULT";
995*3d8817e4Smiod 	case STV_INTERNAL: st_other_str = "STV_INTERNAL";
996*3d8817e4Smiod 	case STV_PROTECTED: st_other_str = "STV_PROTECTED";
997*3d8817e4Smiod 	default: st_other_str = "";
998*3d8817e4Smiod 	}
999*3d8817e4Smiod       switch (isym->st_shndx)
1000*3d8817e4Smiod 	{
1001*3d8817e4Smiod 	case SHN_ABS: st_shndx_str = "SHN_ABS";
1002*3d8817e4Smiod 	case SHN_COMMON: st_shndx_str = "SHN_COMMON";
1003*3d8817e4Smiod 	case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
1004*3d8817e4Smiod 	default: st_shndx_str = "";
1005*3d8817e4Smiod 	}
1006*3d8817e4Smiod 
1007*3d8817e4Smiod       printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
1008*3d8817e4Smiod 	      "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
1009*3d8817e4Smiod 	      isym,
1010*3d8817e4Smiod 	      (unsigned long) isym->st_value,
1011*3d8817e4Smiod 	      (unsigned long) isym->st_size,
1012*3d8817e4Smiod 	      isym->st_name,
1013*3d8817e4Smiod 	      bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
1014*3d8817e4Smiod 					       isym->st_name),
1015*3d8817e4Smiod 	      isym->st_info, st_info_str, st_info_stb_str,
1016*3d8817e4Smiod 	      isym->st_other, st_other_str,
1017*3d8817e4Smiod 	      isym->st_shndx, st_shndx_str);
1018*3d8817e4Smiod     }
1019*3d8817e4Smiod   if (free_internal)
1020*3d8817e4Smiod     free (internal_syms);
1021*3d8817e4Smiod   if (free_external)
1022*3d8817e4Smiod     free (external_syms);
1023*3d8817e4Smiod }
1024*3d8817e4Smiod 
1025*3d8817e4Smiod static char *
m32c_get_reloc(long reloc)1026*3d8817e4Smiod m32c_get_reloc (long reloc)
1027*3d8817e4Smiod {
1028*3d8817e4Smiod   if (0 <= reloc && reloc < R_M32C_max)
1029*3d8817e4Smiod     return m32c_elf_howto_table[reloc].name;
1030*3d8817e4Smiod   else
1031*3d8817e4Smiod     return "";
1032*3d8817e4Smiod }
1033*3d8817e4Smiod #endif /* DEBUG */
1034*3d8817e4Smiod 
1035*3d8817e4Smiod /* Handle relaxing.  */
1036*3d8817e4Smiod 
1037*3d8817e4Smiod /* A subroutine of m32c_elf_relax_section.  If the global symbol H
1038*3d8817e4Smiod    is within the low 64k, remove any entry for it in the plt.  */
1039*3d8817e4Smiod 
1040*3d8817e4Smiod struct relax_plt_data
1041*3d8817e4Smiod {
1042*3d8817e4Smiod   asection *splt;
1043*3d8817e4Smiod   bfd_boolean *again;
1044*3d8817e4Smiod };
1045*3d8817e4Smiod 
1046*3d8817e4Smiod static bfd_boolean
m32c_relax_plt_check(struct elf_link_hash_entry * h,PTR xdata)1047*3d8817e4Smiod m32c_relax_plt_check (struct elf_link_hash_entry *h,
1048*3d8817e4Smiod                       PTR xdata)
1049*3d8817e4Smiod {
1050*3d8817e4Smiod   struct relax_plt_data *data = (struct relax_plt_data *) xdata;
1051*3d8817e4Smiod 
1052*3d8817e4Smiod   if (h->root.type == bfd_link_hash_warning)
1053*3d8817e4Smiod     h = (struct elf_link_hash_entry *) h->root.u.i.link;
1054*3d8817e4Smiod 
1055*3d8817e4Smiod   if (h->plt.offset != (bfd_vma) -1)
1056*3d8817e4Smiod     {
1057*3d8817e4Smiod       bfd_vma address;
1058*3d8817e4Smiod 
1059*3d8817e4Smiod       if (h->root.type == bfd_link_hash_undefined
1060*3d8817e4Smiod 	  || h->root.type == bfd_link_hash_undefweak)
1061*3d8817e4Smiod 	address = 0;
1062*3d8817e4Smiod       else
1063*3d8817e4Smiod 	address = (h->root.u.def.section->output_section->vma
1064*3d8817e4Smiod 		   + h->root.u.def.section->output_offset
1065*3d8817e4Smiod 		   + h->root.u.def.value);
1066*3d8817e4Smiod 
1067*3d8817e4Smiod       if (address <= 0xffff)
1068*3d8817e4Smiod 	{
1069*3d8817e4Smiod 	  h->plt.offset = -1;
1070*3d8817e4Smiod 	  data->splt->size -= 4;
1071*3d8817e4Smiod 	  *data->again = TRUE;
1072*3d8817e4Smiod 	}
1073*3d8817e4Smiod     }
1074*3d8817e4Smiod 
1075*3d8817e4Smiod   return TRUE;
1076*3d8817e4Smiod }
1077*3d8817e4Smiod 
1078*3d8817e4Smiod /* A subroutine of m32c_elf_relax_section.  If the global symbol H
1079*3d8817e4Smiod    previously had a plt entry, give it a new entry offset.  */
1080*3d8817e4Smiod 
1081*3d8817e4Smiod static bfd_boolean
m32c_relax_plt_realloc(struct elf_link_hash_entry * h,PTR xdata)1082*3d8817e4Smiod m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
1083*3d8817e4Smiod                         PTR xdata)
1084*3d8817e4Smiod {
1085*3d8817e4Smiod   bfd_vma *entry = (bfd_vma *) xdata;
1086*3d8817e4Smiod 
1087*3d8817e4Smiod   if (h->root.type == bfd_link_hash_warning)
1088*3d8817e4Smiod     h = (struct elf_link_hash_entry *) h->root.u.i.link;
1089*3d8817e4Smiod 
1090*3d8817e4Smiod   if (h->plt.offset != (bfd_vma) -1)
1091*3d8817e4Smiod     {
1092*3d8817e4Smiod       h->plt.offset = *entry;
1093*3d8817e4Smiod       *entry += 4;
1094*3d8817e4Smiod     }
1095*3d8817e4Smiod 
1096*3d8817e4Smiod   return TRUE;
1097*3d8817e4Smiod }
1098*3d8817e4Smiod 
1099*3d8817e4Smiod static bfd_boolean
m32c_elf_relax_plt_section(bfd * dynobj,asection * splt,struct bfd_link_info * info,bfd_boolean * again)1100*3d8817e4Smiod m32c_elf_relax_plt_section (bfd *dynobj,
1101*3d8817e4Smiod                             asection *splt,
1102*3d8817e4Smiod                             struct bfd_link_info *info,
1103*3d8817e4Smiod                             bfd_boolean *again)
1104*3d8817e4Smiod {
1105*3d8817e4Smiod   struct relax_plt_data relax_plt_data;
1106*3d8817e4Smiod   bfd *ibfd;
1107*3d8817e4Smiod 
1108*3d8817e4Smiod   /* Assume nothing changes.  */
1109*3d8817e4Smiod   *again = FALSE;
1110*3d8817e4Smiod 
1111*3d8817e4Smiod   if (info->relocatable)
1112*3d8817e4Smiod     return TRUE;
1113*3d8817e4Smiod 
1114*3d8817e4Smiod   /* We only relax the .plt section at the moment.  */
1115*3d8817e4Smiod   if (dynobj != elf_hash_table (info)->dynobj
1116*3d8817e4Smiod       || strcmp (splt->name, ".plt") != 0)
1117*3d8817e4Smiod     return TRUE;
1118*3d8817e4Smiod 
1119*3d8817e4Smiod   /* Quick check for an empty plt.  */
1120*3d8817e4Smiod   if (splt->size == 0)
1121*3d8817e4Smiod     return TRUE;
1122*3d8817e4Smiod 
1123*3d8817e4Smiod   /* Map across all global symbols; see which ones happen to
1124*3d8817e4Smiod      fall in the low 64k.  */
1125*3d8817e4Smiod   relax_plt_data.splt = splt;
1126*3d8817e4Smiod   relax_plt_data.again = again;
1127*3d8817e4Smiod   elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
1128*3d8817e4Smiod 			  &relax_plt_data);
1129*3d8817e4Smiod 
1130*3d8817e4Smiod   /* Likewise for local symbols, though that's somewhat less convenient
1131*3d8817e4Smiod      as we have to walk the list of input bfds and swap in symbol data.  */
1132*3d8817e4Smiod   for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1133*3d8817e4Smiod     {
1134*3d8817e4Smiod       bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1135*3d8817e4Smiod       Elf_Internal_Shdr *symtab_hdr;
1136*3d8817e4Smiod       Elf_Internal_Sym *isymbuf = NULL;
1137*3d8817e4Smiod       unsigned int idx;
1138*3d8817e4Smiod 
1139*3d8817e4Smiod       if (! local_plt_offsets)
1140*3d8817e4Smiod 	continue;
1141*3d8817e4Smiod 
1142*3d8817e4Smiod       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1143*3d8817e4Smiod       if (symtab_hdr->sh_info != 0)
1144*3d8817e4Smiod 	{
1145*3d8817e4Smiod 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1146*3d8817e4Smiod 	  if (isymbuf == NULL)
1147*3d8817e4Smiod 	    isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1148*3d8817e4Smiod 					    symtab_hdr->sh_info, 0,
1149*3d8817e4Smiod 					    NULL, NULL, NULL);
1150*3d8817e4Smiod 	  if (isymbuf == NULL)
1151*3d8817e4Smiod 	    return FALSE;
1152*3d8817e4Smiod 	}
1153*3d8817e4Smiod 
1154*3d8817e4Smiod       for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1155*3d8817e4Smiod 	{
1156*3d8817e4Smiod 	  Elf_Internal_Sym *isym;
1157*3d8817e4Smiod 	  asection *tsec;
1158*3d8817e4Smiod 	  bfd_vma address;
1159*3d8817e4Smiod 
1160*3d8817e4Smiod 	  if (local_plt_offsets[idx] == (bfd_vma) -1)
1161*3d8817e4Smiod 	    continue;
1162*3d8817e4Smiod 
1163*3d8817e4Smiod 	  isym = &isymbuf[idx];
1164*3d8817e4Smiod 	  if (isym->st_shndx == SHN_UNDEF)
1165*3d8817e4Smiod 	    continue;
1166*3d8817e4Smiod 	  else if (isym->st_shndx == SHN_ABS)
1167*3d8817e4Smiod 	    tsec = bfd_abs_section_ptr;
1168*3d8817e4Smiod 	  else if (isym->st_shndx == SHN_COMMON)
1169*3d8817e4Smiod 	    tsec = bfd_com_section_ptr;
1170*3d8817e4Smiod 	  else
1171*3d8817e4Smiod 	    tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1172*3d8817e4Smiod 
1173*3d8817e4Smiod 	  address = (tsec->output_section->vma
1174*3d8817e4Smiod 		     + tsec->output_offset
1175*3d8817e4Smiod 		     + isym->st_value);
1176*3d8817e4Smiod 	  if (address <= 0xffff)
1177*3d8817e4Smiod 	    {
1178*3d8817e4Smiod 	      local_plt_offsets[idx] = -1;
1179*3d8817e4Smiod 	      splt->size -= 4;
1180*3d8817e4Smiod 	      *again = TRUE;
1181*3d8817e4Smiod 	    }
1182*3d8817e4Smiod 	}
1183*3d8817e4Smiod 
1184*3d8817e4Smiod       if (isymbuf != NULL
1185*3d8817e4Smiod 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
1186*3d8817e4Smiod 	{
1187*3d8817e4Smiod 	  if (! info->keep_memory)
1188*3d8817e4Smiod 	    free (isymbuf);
1189*3d8817e4Smiod 	  else
1190*3d8817e4Smiod 	    {
1191*3d8817e4Smiod 	      /* Cache the symbols for elf_link_input_bfd.  */
1192*3d8817e4Smiod 	      symtab_hdr->contents = (unsigned char *) isymbuf;
1193*3d8817e4Smiod 	    }
1194*3d8817e4Smiod 	}
1195*3d8817e4Smiod     }
1196*3d8817e4Smiod 
1197*3d8817e4Smiod   /* If we changed anything, walk the symbols again to reallocate
1198*3d8817e4Smiod      .plt entry addresses.  */
1199*3d8817e4Smiod   if (*again && splt->size > 0)
1200*3d8817e4Smiod     {
1201*3d8817e4Smiod       bfd_vma entry = 0;
1202*3d8817e4Smiod 
1203*3d8817e4Smiod       elf_link_hash_traverse (elf_hash_table (info),
1204*3d8817e4Smiod 			      m32c_relax_plt_realloc, &entry);
1205*3d8817e4Smiod 
1206*3d8817e4Smiod       for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1207*3d8817e4Smiod 	{
1208*3d8817e4Smiod 	  bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1209*3d8817e4Smiod 	  unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1210*3d8817e4Smiod 	  unsigned int idx;
1211*3d8817e4Smiod 
1212*3d8817e4Smiod 	  if (! local_plt_offsets)
1213*3d8817e4Smiod 	    continue;
1214*3d8817e4Smiod 
1215*3d8817e4Smiod 	  for (idx = 0; idx < nlocals; ++idx)
1216*3d8817e4Smiod 	    if (local_plt_offsets[idx] != (bfd_vma) -1)
1217*3d8817e4Smiod 	      {
1218*3d8817e4Smiod 	        local_plt_offsets[idx] = entry;
1219*3d8817e4Smiod 		entry += 4;
1220*3d8817e4Smiod 	      }
1221*3d8817e4Smiod 	}
1222*3d8817e4Smiod     }
1223*3d8817e4Smiod 
1224*3d8817e4Smiod   return TRUE;
1225*3d8817e4Smiod }
1226*3d8817e4Smiod 
1227*3d8817e4Smiod static int
compare_reloc(const void * e1,const void * e2)1228*3d8817e4Smiod compare_reloc (const void *e1, const void *e2)
1229*3d8817e4Smiod {
1230*3d8817e4Smiod   const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
1231*3d8817e4Smiod   const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
1232*3d8817e4Smiod 
1233*3d8817e4Smiod   if (i1->r_offset == i2->r_offset)
1234*3d8817e4Smiod     return 0;
1235*3d8817e4Smiod   else
1236*3d8817e4Smiod     return i1->r_offset < i2->r_offset ? -1 : 1;
1237*3d8817e4Smiod }
1238*3d8817e4Smiod 
1239*3d8817e4Smiod #define OFFSET_FOR_RELOC(rel) m32c_offset_for_reloc (abfd, rel, symtab_hdr, shndx_buf, intsyms)
1240*3d8817e4Smiod static bfd_vma
m32c_offset_for_reloc(bfd * abfd,Elf_Internal_Rela * rel,Elf_Internal_Shdr * symtab_hdr,Elf_External_Sym_Shndx * shndx_buf,Elf_Internal_Sym * intsyms)1241*3d8817e4Smiod m32c_offset_for_reloc (bfd *abfd,
1242*3d8817e4Smiod 		       Elf_Internal_Rela *rel,
1243*3d8817e4Smiod 		       Elf_Internal_Shdr *symtab_hdr,
1244*3d8817e4Smiod 		       Elf_External_Sym_Shndx *shndx_buf,
1245*3d8817e4Smiod 		       Elf_Internal_Sym *intsyms)
1246*3d8817e4Smiod {
1247*3d8817e4Smiod   bfd_vma symval;
1248*3d8817e4Smiod 
1249*3d8817e4Smiod   /* Get the value of the symbol referred to by the reloc.  */
1250*3d8817e4Smiod   if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
1251*3d8817e4Smiod     {
1252*3d8817e4Smiod       /* A local symbol.  */
1253*3d8817e4Smiod       Elf_Internal_Sym *isym;
1254*3d8817e4Smiod       Elf_External_Sym_Shndx *shndx;
1255*3d8817e4Smiod       asection *ssec;
1256*3d8817e4Smiod 
1257*3d8817e4Smiod 
1258*3d8817e4Smiod       isym = intsyms + ELF32_R_SYM (rel->r_info);
1259*3d8817e4Smiod       ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1260*3d8817e4Smiod       shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (rel->r_info) : 0);
1261*3d8817e4Smiod 
1262*3d8817e4Smiod       symval = isym->st_value;
1263*3d8817e4Smiod       if (ssec)
1264*3d8817e4Smiod 	symval += ssec->output_section->vma
1265*3d8817e4Smiod 	  + ssec->output_offset;
1266*3d8817e4Smiod     }
1267*3d8817e4Smiod   else
1268*3d8817e4Smiod     {
1269*3d8817e4Smiod       unsigned long indx;
1270*3d8817e4Smiod       struct elf_link_hash_entry *h;
1271*3d8817e4Smiod 
1272*3d8817e4Smiod       /* An external symbol.  */
1273*3d8817e4Smiod       indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
1274*3d8817e4Smiod       h = elf_sym_hashes (abfd)[indx];
1275*3d8817e4Smiod       BFD_ASSERT (h != NULL);
1276*3d8817e4Smiod 
1277*3d8817e4Smiod       if (h->root.type != bfd_link_hash_defined
1278*3d8817e4Smiod 	  && h->root.type != bfd_link_hash_defweak)
1279*3d8817e4Smiod 	/* This appears to be a reference to an undefined
1280*3d8817e4Smiod 	   symbol.  Just ignore it--it will be caught by the
1281*3d8817e4Smiod 	   regular reloc processing.  */
1282*3d8817e4Smiod 	return 0;
1283*3d8817e4Smiod 
1284*3d8817e4Smiod       symval = (h->root.u.def.value
1285*3d8817e4Smiod 		+ h->root.u.def.section->output_section->vma
1286*3d8817e4Smiod 		+ h->root.u.def.section->output_offset);
1287*3d8817e4Smiod     }
1288*3d8817e4Smiod   return symval;
1289*3d8817e4Smiod }
1290*3d8817e4Smiod 
1291*3d8817e4Smiod static int bytes_saved = 0;
1292*3d8817e4Smiod 
1293*3d8817e4Smiod static int bytes_to_reloc[] = {
1294*3d8817e4Smiod   R_M32C_NONE,
1295*3d8817e4Smiod   R_M32C_8,
1296*3d8817e4Smiod   R_M32C_16,
1297*3d8817e4Smiod   R_M32C_24,
1298*3d8817e4Smiod   R_M32C_32
1299*3d8817e4Smiod };
1300*3d8817e4Smiod 
1301*3d8817e4Smiod /* What we use the bits in a relax reloc addend (R_M32C_RL_*) for.  */
1302*3d8817e4Smiod 
1303*3d8817e4Smiod /* Mask for the number of relocs associated with this insn.  */
1304*3d8817e4Smiod #define RLA_RELOCS		0x0000000f
1305*3d8817e4Smiod /* Number of bytes gas emitted (before gas's relaxing) */
1306*3d8817e4Smiod #define RLA_NBYTES		0x00000ff0
1307*3d8817e4Smiod 
1308*3d8817e4Smiod /* If the displacement is within the given range and the new encoding
1309*3d8817e4Smiod    differs from the old encoding (the index), then the insn can be
1310*3d8817e4Smiod    relaxed to the new encoding.  */
1311*3d8817e4Smiod typedef struct {
1312*3d8817e4Smiod   int bytes;
1313*3d8817e4Smiod   unsigned int max_disp;
1314*3d8817e4Smiod   unsigned char new_encoding;
1315*3d8817e4Smiod } EncodingTable;
1316*3d8817e4Smiod 
1317*3d8817e4Smiod static EncodingTable m16c_addr_encodings[] = {
1318*3d8817e4Smiod   { 0,   0,  0 }, /* R0 */
1319*3d8817e4Smiod   { 0,   0,  1 }, /* R1 */
1320*3d8817e4Smiod   { 0,   0,  2 }, /* R2 */
1321*3d8817e4Smiod   { 0,   0,  3 }, /* R3 */
1322*3d8817e4Smiod   { 0,   0,  4 }, /* A0 */
1323*3d8817e4Smiod   { 0,   0,  5 }, /* A1 */
1324*3d8817e4Smiod   { 0,   0,  6 }, /* [A0] */
1325*3d8817e4Smiod   { 0,   0,  7 }, /* [A1] */
1326*3d8817e4Smiod   { 1,   0,  6 }, /* udsp:8[A0] */
1327*3d8817e4Smiod   { 1,   0,  7 }, /* udsp:8[A1] */
1328*3d8817e4Smiod   { 1,   0, 10 }, /* udsp:8[SB] */
1329*3d8817e4Smiod   { 1,   0, 11 }, /* sdsp:8[FB] */
1330*3d8817e4Smiod   { 2, 255,  8 }, /* udsp:16[A0] */
1331*3d8817e4Smiod   { 2, 255,  9 }, /* udsp:16[A1] */
1332*3d8817e4Smiod   { 2, 255, 10 }, /* udsp:16[SB] */
1333*3d8817e4Smiod   { 2,   0, 15 }, /* abs:16 */
1334*3d8817e4Smiod };
1335*3d8817e4Smiod 
1336*3d8817e4Smiod static EncodingTable m16c_jmpaddr_encodings[] = {
1337*3d8817e4Smiod   { 0,   0,  0 }, /* R0 */
1338*3d8817e4Smiod   { 0,   0,  1 }, /* R1 */
1339*3d8817e4Smiod   { 0,   0,  2 }, /* R2 */
1340*3d8817e4Smiod   { 0,   0,  3 }, /* R3 */
1341*3d8817e4Smiod   { 0,   0,  4 }, /* A0 */
1342*3d8817e4Smiod   { 0,   0,  5 }, /* A1 */
1343*3d8817e4Smiod   { 0,   0,  6 }, /* [A0] */
1344*3d8817e4Smiod   { 0,   0,  7 }, /* [A1] */
1345*3d8817e4Smiod   { 1,   0,  6 }, /* udsp:8[A0] */
1346*3d8817e4Smiod   { 1,   0,  7 }, /* udsp:8[A1] */
1347*3d8817e4Smiod   { 1,   0, 10 }, /* udsp:8[SB] */
1348*3d8817e4Smiod   { 1,   0, 11 }, /* sdsp:8[FB] */
1349*3d8817e4Smiod   { 3, 255,  8 }, /* udsp:20[A0] */
1350*3d8817e4Smiod   { 3, 255,  9 }, /* udsp:20[A1] */
1351*3d8817e4Smiod   { 2, 255, 10 }, /* udsp:16[SB] */
1352*3d8817e4Smiod   { 2,   0, 15 }, /* abs:16 */
1353*3d8817e4Smiod };
1354*3d8817e4Smiod 
1355*3d8817e4Smiod static EncodingTable m32c_addr_encodings[] = {
1356*3d8817e4Smiod   { 0,     0,  0 }, /* [A0] */
1357*3d8817e4Smiod   { 0,     0,  1 }, /* [A1] */
1358*3d8817e4Smiod   { 0,     0,  2 }, /* A0 */
1359*3d8817e4Smiod   { 0,     0,  3 }, /* A1 */
1360*3d8817e4Smiod   { 1,     0,  0 }, /* udsp:8[A0] */
1361*3d8817e4Smiod   { 1,     0,  1 }, /* udsp:8[A1] */
1362*3d8817e4Smiod   { 1,     0,  6 }, /* udsp:8[SB] */
1363*3d8817e4Smiod   { 1,     0,  7 }, /* sdsp:8[FB] */
1364*3d8817e4Smiod   { 2,   255,  4 }, /* udsp:16[A0] */
1365*3d8817e4Smiod   { 2,   255,  5 }, /* udsp:16[A1] */
1366*3d8817e4Smiod   { 2,   255,  6 }, /* udsp:16[SB] */
1367*3d8817e4Smiod   { 2,   127,  7 }, /* sdsp:16[FB] */
1368*3d8817e4Smiod   { 3, 65535, 8 }, /* udsp:24[A0] */
1369*3d8817e4Smiod   { 3, 65535, 9 }, /* udsp:24[A1] */
1370*3d8817e4Smiod   { 3, 65535, 15 }, /* abs24 */
1371*3d8817e4Smiod   { 2,     0, 15 }, /* abs16 */
1372*3d8817e4Smiod   { 0,     0, 16 }, /* R2 */
1373*3d8817e4Smiod   { 0,     0, 17 }, /* R3 */
1374*3d8817e4Smiod   { 0,     0, 18 }, /* R0 */
1375*3d8817e4Smiod   { 0,     0, 19 }, /* R1 */
1376*3d8817e4Smiod   { 0,     0, 20 }, /*  */
1377*3d8817e4Smiod   { 0,     0, 21 }, /*  */
1378*3d8817e4Smiod   { 0,     0, 22 }, /*  */
1379*3d8817e4Smiod   { 0,     0, 23 }, /*  */
1380*3d8817e4Smiod   { 0,     0, 24 }, /*  */
1381*3d8817e4Smiod   { 0,     0, 25 }, /*  */
1382*3d8817e4Smiod   { 0,     0, 26 }, /*  */
1383*3d8817e4Smiod   { 0,     0, 27 }, /*  */
1384*3d8817e4Smiod   { 0,     0, 28 }, /*  */
1385*3d8817e4Smiod   { 0,     0, 29 }, /*  */
1386*3d8817e4Smiod   { 0,     0, 30 }, /*  */
1387*3d8817e4Smiod   { 0,     0, 31 }, /*  */
1388*3d8817e4Smiod };
1389*3d8817e4Smiod 
1390*3d8817e4Smiod static bfd_boolean
m32c_elf_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bfd_boolean * again)1391*3d8817e4Smiod m32c_elf_relax_section
1392*3d8817e4Smiod     (bfd *                  abfd,
1393*3d8817e4Smiod      asection *             sec,
1394*3d8817e4Smiod      struct bfd_link_info * link_info,
1395*3d8817e4Smiod      bfd_boolean *          again)
1396*3d8817e4Smiod {
1397*3d8817e4Smiod   Elf_Internal_Shdr *symtab_hdr;
1398*3d8817e4Smiod   Elf_Internal_Shdr *shndx_hdr;
1399*3d8817e4Smiod   Elf_Internal_Rela *internal_relocs;
1400*3d8817e4Smiod   Elf_Internal_Rela *free_relocs = NULL;
1401*3d8817e4Smiod   Elf_Internal_Rela *irel, *irelend, *srel;
1402*3d8817e4Smiod   bfd_byte * contents = NULL;
1403*3d8817e4Smiod   bfd_byte * free_contents = NULL;
1404*3d8817e4Smiod   Elf_Internal_Sym *intsyms = NULL;
1405*3d8817e4Smiod   Elf_Internal_Sym *free_intsyms = NULL;
1406*3d8817e4Smiod   Elf_External_Sym_Shndx *shndx_buf = NULL;
1407*3d8817e4Smiod   int machine;
1408*3d8817e4Smiod 
1409*3d8817e4Smiod   if (abfd == elf_hash_table (link_info)->dynobj
1410*3d8817e4Smiod       && strcmp (sec->name, ".plt") == 0)
1411*3d8817e4Smiod     return m32c_elf_relax_plt_section (abfd, sec, link_info, again);
1412*3d8817e4Smiod 
1413*3d8817e4Smiod   /* Assume nothing changes.  */
1414*3d8817e4Smiod   *again = FALSE;
1415*3d8817e4Smiod 
1416*3d8817e4Smiod   machine = elf32_m32c_machine (abfd);
1417*3d8817e4Smiod 
1418*3d8817e4Smiod   /* We don't have to do anything for a relocatable link, if
1419*3d8817e4Smiod      this section does not have relocs, or if this is not a
1420*3d8817e4Smiod      code section.  */
1421*3d8817e4Smiod   if (link_info->relocatable
1422*3d8817e4Smiod       || (sec->flags & SEC_RELOC) == 0
1423*3d8817e4Smiod       || sec->reloc_count == 0
1424*3d8817e4Smiod       || (sec->flags & SEC_CODE) == 0)
1425*3d8817e4Smiod     return TRUE;
1426*3d8817e4Smiod 
1427*3d8817e4Smiod   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1428*3d8817e4Smiod   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1429*3d8817e4Smiod 
1430*3d8817e4Smiod   /* Get the section contents.  */
1431*3d8817e4Smiod   if (elf_section_data (sec)->this_hdr.contents != NULL)
1432*3d8817e4Smiod     contents = elf_section_data (sec)->this_hdr.contents;
1433*3d8817e4Smiod   /* Go get them off disk.  */
1434*3d8817e4Smiod   else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1435*3d8817e4Smiod     goto error_return;
1436*3d8817e4Smiod 
1437*3d8817e4Smiod   /* Read this BFD's symbols.  */
1438*3d8817e4Smiod   /* Get cached copy if it exists.  */
1439*3d8817e4Smiod   if (symtab_hdr->contents != NULL)
1440*3d8817e4Smiod     {
1441*3d8817e4Smiod       intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
1442*3d8817e4Smiod     }
1443*3d8817e4Smiod   else
1444*3d8817e4Smiod     {
1445*3d8817e4Smiod       intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
1446*3d8817e4Smiod       symtab_hdr->contents = (bfd_byte *) intsyms;
1447*3d8817e4Smiod     }
1448*3d8817e4Smiod 
1449*3d8817e4Smiod   if (shndx_hdr->sh_size != 0)
1450*3d8817e4Smiod     {
1451*3d8817e4Smiod       bfd_size_type amt;
1452*3d8817e4Smiod 
1453*3d8817e4Smiod       amt = symtab_hdr->sh_info;
1454*3d8817e4Smiod       amt *= sizeof (Elf_External_Sym_Shndx);
1455*3d8817e4Smiod       shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
1456*3d8817e4Smiod       if (shndx_buf == NULL)
1457*3d8817e4Smiod 	goto error_return;
1458*3d8817e4Smiod       if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
1459*3d8817e4Smiod 	  || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
1460*3d8817e4Smiod 	goto error_return;
1461*3d8817e4Smiod       shndx_hdr->contents = (bfd_byte *) shndx_buf;
1462*3d8817e4Smiod     }
1463*3d8817e4Smiod 
1464*3d8817e4Smiod   /* Get a copy of the native relocations.  */
1465*3d8817e4Smiod   internal_relocs = (_bfd_elf_link_read_relocs
1466*3d8817e4Smiod 		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
1467*3d8817e4Smiod 		      link_info->keep_memory));
1468*3d8817e4Smiod   if (internal_relocs == NULL)
1469*3d8817e4Smiod     goto error_return;
1470*3d8817e4Smiod   if (! link_info->keep_memory)
1471*3d8817e4Smiod     free_relocs = internal_relocs;
1472*3d8817e4Smiod 
1473*3d8817e4Smiod   /* The RL_ relocs must be just before the operand relocs they go
1474*3d8817e4Smiod      with, so we must sort them to guarantee this.  */
1475*3d8817e4Smiod   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
1476*3d8817e4Smiod          compare_reloc);
1477*3d8817e4Smiod 
1478*3d8817e4Smiod   /* Walk through them looking for relaxing opportunities.  */
1479*3d8817e4Smiod   irelend = internal_relocs + sec->reloc_count;
1480*3d8817e4Smiod 
1481*3d8817e4Smiod   for (irel = internal_relocs; irel < irelend; irel++)
1482*3d8817e4Smiod     {
1483*3d8817e4Smiod       bfd_vma symval;
1484*3d8817e4Smiod       unsigned char *insn, *gap, *einsn;
1485*3d8817e4Smiod       bfd_vma pc;
1486*3d8817e4Smiod       bfd_signed_vma pcrel;
1487*3d8817e4Smiod       int relax_relocs;
1488*3d8817e4Smiod       int gap_size;
1489*3d8817e4Smiod       int new_type;
1490*3d8817e4Smiod       int posn;
1491*3d8817e4Smiod       int enc;
1492*3d8817e4Smiod       EncodingTable *enctbl;
1493*3d8817e4Smiod       EncodingTable *e;
1494*3d8817e4Smiod 
1495*3d8817e4Smiod       if (ELF32_R_TYPE(irel->r_info) != R_M32C_RL_JUMP
1496*3d8817e4Smiod 	  && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_1ADDR
1497*3d8817e4Smiod 	  && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_2ADDR)
1498*3d8817e4Smiod 	continue;
1499*3d8817e4Smiod 
1500*3d8817e4Smiod       srel = irel;
1501*3d8817e4Smiod 
1502*3d8817e4Smiod       /* There will always be room for the relaxed insn, since it is smaller
1503*3d8817e4Smiod 	 than the one it would replace.  */
1504*3d8817e4Smiod       BFD_ASSERT (irel->r_offset < sec->size);
1505*3d8817e4Smiod 
1506*3d8817e4Smiod       insn = contents + irel->r_offset;
1507*3d8817e4Smiod       relax_relocs = irel->r_addend % 16;
1508*3d8817e4Smiod 
1509*3d8817e4Smiod       /* Ok, we only have three relocs we care about, and they're all
1510*3d8817e4Smiod 	 fake.  The lower four bits of the addend is always the number
1511*3d8817e4Smiod 	 of following relocs (hence the qsort above) that are assigned
1512*3d8817e4Smiod 	 to this opcode.  The next 8 bits of the addend indicates the
1513*3d8817e4Smiod 	 number of bytes in the insn.  We use the rest of them
1514*3d8817e4Smiod 	 ourselves as flags for the more expensive operations (defines
1515*3d8817e4Smiod 	 above).  The three relocs are:
1516*3d8817e4Smiod 
1517*3d8817e4Smiod 	 RL_JUMP: This marks all direct jump insns.  We check the
1518*3d8817e4Smiod 		displacement and replace them with shorter jumps if
1519*3d8817e4Smiod 		they're in range.  We also use this to find JMP.S
1520*3d8817e4Smiod 		insns and manually shorten them when we delete bytes.
1521*3d8817e4Smiod 		We have to decode these insns to figure out what to
1522*3d8817e4Smiod 		do.
1523*3d8817e4Smiod 
1524*3d8817e4Smiod 	 RL_1ADDR: This is a :G or :Q insn, which has a single
1525*3d8817e4Smiod 		"standard" operand.  We have to extract the type
1526*3d8817e4Smiod 		field, see if it's a wide displacement, then figure
1527*3d8817e4Smiod 		out if we can replace it with a narrow displacement.
1528*3d8817e4Smiod 		We don't have to decode these insns.
1529*3d8817e4Smiod 
1530*3d8817e4Smiod 	 RL_2ADDR: Similarly, but two "standard" operands.  Note that
1531*3d8817e4Smiod 		r_addend may still be 1, as standard operands don't
1532*3d8817e4Smiod 		always have displacements.  Gas shouldn't give us one
1533*3d8817e4Smiod 		with zero operands, but since we don't know which one
1534*3d8817e4Smiod 		has the displacement, we check them both anyway.
1535*3d8817e4Smiod 
1536*3d8817e4Smiod 	 These all point to the beginning of the insn itself, not the
1537*3d8817e4Smiod 	 operands.
1538*3d8817e4Smiod 
1539*3d8817e4Smiod 	 Note that we only relax one step at a time, relying on the
1540*3d8817e4Smiod 	 linker to call us repeatedly.  Thus, there is no code for
1541*3d8817e4Smiod 	 JMP.A->JMP.B although that will happen in two steps.
1542*3d8817e4Smiod 	 Likewise, for 2ADDR relaxes, we do one operand per cycle.
1543*3d8817e4Smiod       */
1544*3d8817e4Smiod 
1545*3d8817e4Smiod       /* Get the value of the symbol referred to by the reloc.  Just
1546*3d8817e4Smiod          in case this is the last reloc in the list, use the RL's
1547*3d8817e4Smiod          addend to choose between this reloc (no addend) or the next
1548*3d8817e4Smiod          (yes addend, which means at least one following reloc).  */
1549*3d8817e4Smiod       srel = irel + (relax_relocs ? 1 : 0);
1550*3d8817e4Smiod       symval = OFFSET_FOR_RELOC (srel);
1551*3d8817e4Smiod 
1552*3d8817e4Smiod       /* Setting gap_size nonzero is the flag which means "something
1553*3d8817e4Smiod 	 shrunk".  */
1554*3d8817e4Smiod       gap_size = 0;
1555*3d8817e4Smiod       gap = NULL;
1556*3d8817e4Smiod       new_type = ELF32_R_TYPE(srel->r_info);
1557*3d8817e4Smiod 
1558*3d8817e4Smiod       pc = sec->output_section->vma + sec->output_offset
1559*3d8817e4Smiod 	+ srel->r_offset;
1560*3d8817e4Smiod       pcrel = symval - pc + srel->r_addend;
1561*3d8817e4Smiod 
1562*3d8817e4Smiod       if (machine == bfd_mach_m16c)
1563*3d8817e4Smiod 	{
1564*3d8817e4Smiod 	  /* R8C / M16C */
1565*3d8817e4Smiod 
1566*3d8817e4Smiod 	  switch (ELF32_R_TYPE(irel->r_info))
1567*3d8817e4Smiod 	    {
1568*3d8817e4Smiod 
1569*3d8817e4Smiod 	    case R_M32C_RL_JUMP:
1570*3d8817e4Smiod 	      switch (insn[0])
1571*3d8817e4Smiod 		{
1572*3d8817e4Smiod 		case 0xfe: /* jmp.b */
1573*3d8817e4Smiod 		  if (pcrel >= 2 && pcrel <= 9)
1574*3d8817e4Smiod 		    {
1575*3d8817e4Smiod 		      /* Relax JMP.B -> JMP.S.  We need to get rid of
1576*3d8817e4Smiod 			 the following reloc though. */
1577*3d8817e4Smiod 		      insn[0] = 0x60 | (pcrel - 2);
1578*3d8817e4Smiod 		      new_type = R_M32C_NONE;
1579*3d8817e4Smiod 		      irel->r_addend = 0x10;
1580*3d8817e4Smiod 		      gap_size = 1;
1581*3d8817e4Smiod 		      gap = insn + 1;
1582*3d8817e4Smiod 		    }
1583*3d8817e4Smiod 		  break;
1584*3d8817e4Smiod 
1585*3d8817e4Smiod 		case 0xf4: /* jmp.w */
1586*3d8817e4Smiod 		  /* 128 is allowed because it will be one byte closer
1587*3d8817e4Smiod 		     after relaxing.  Likewise for all other pc-rel
1588*3d8817e4Smiod 		     jumps.  */
1589*3d8817e4Smiod 		  if (pcrel <= 128 && pcrel >= -128)
1590*3d8817e4Smiod 		    {
1591*3d8817e4Smiod 		      /* Relax JMP.W -> JMP.B */
1592*3d8817e4Smiod 		      insn[0] = 0xfe;
1593*3d8817e4Smiod 		      insn[1] = 0;
1594*3d8817e4Smiod 		      new_type = R_M32C_8_PCREL;
1595*3d8817e4Smiod 		      gap_size = 1;
1596*3d8817e4Smiod 		      gap = insn + 2;
1597*3d8817e4Smiod 		    }
1598*3d8817e4Smiod 		  break;
1599*3d8817e4Smiod 
1600*3d8817e4Smiod 		case 0xfc: /* jmp.a */
1601*3d8817e4Smiod 		  if (pcrel <= 32768 && pcrel >= -32768)
1602*3d8817e4Smiod 		    {
1603*3d8817e4Smiod 		      /* Relax JMP.A -> JMP.W */
1604*3d8817e4Smiod 		      insn[0] = 0xf4;
1605*3d8817e4Smiod 		      insn[1] = 0;
1606*3d8817e4Smiod 		      insn[2] = 0;
1607*3d8817e4Smiod 		      new_type = R_M32C_16_PCREL;
1608*3d8817e4Smiod 		      gap_size = 1;
1609*3d8817e4Smiod 		      gap = insn + 3;
1610*3d8817e4Smiod 		    }
1611*3d8817e4Smiod 		  break;
1612*3d8817e4Smiod 
1613*3d8817e4Smiod 		case 0xfd: /* jsr.a */
1614*3d8817e4Smiod 		  if (pcrel <= 32768 && pcrel >= -32768)
1615*3d8817e4Smiod 		    {
1616*3d8817e4Smiod 		      /* Relax JSR.A -> JSR.W */
1617*3d8817e4Smiod 		      insn[0] = 0xf5;
1618*3d8817e4Smiod 		      insn[1] = 0;
1619*3d8817e4Smiod 		      insn[2] = 0;
1620*3d8817e4Smiod 		      new_type = R_M32C_16_PCREL;
1621*3d8817e4Smiod 		      gap_size = 1;
1622*3d8817e4Smiod 		      gap = insn + 3;
1623*3d8817e4Smiod 		    }
1624*3d8817e4Smiod 		  break;
1625*3d8817e4Smiod 		}
1626*3d8817e4Smiod 	      break;
1627*3d8817e4Smiod 
1628*3d8817e4Smiod 	    case R_M32C_RL_2ADDR:
1629*3d8817e4Smiod 	      /* xxxx xxxx srce dest [src-disp] [dest-disp]*/
1630*3d8817e4Smiod 
1631*3d8817e4Smiod 	      enctbl = m16c_addr_encodings;
1632*3d8817e4Smiod 	      posn = 2;
1633*3d8817e4Smiod 	      enc = (insn[1] >> 4) & 0x0f;
1634*3d8817e4Smiod 	      e = & enctbl[enc];
1635*3d8817e4Smiod 
1636*3d8817e4Smiod 	      if (srel->r_offset == irel->r_offset + posn
1637*3d8817e4Smiod 		  && e->new_encoding != enc
1638*3d8817e4Smiod 		  && symval <= e->max_disp)
1639*3d8817e4Smiod 		{
1640*3d8817e4Smiod 		  insn[1] &= 0x0f;
1641*3d8817e4Smiod 		  insn[1] |= e->new_encoding << 4;
1642*3d8817e4Smiod 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1643*3d8817e4Smiod 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
1644*3d8817e4Smiod 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1645*3d8817e4Smiod 		  break;
1646*3d8817e4Smiod 		}
1647*3d8817e4Smiod 	      if (relax_relocs == 2)
1648*3d8817e4Smiod 		srel ++;
1649*3d8817e4Smiod 	      posn += e->bytes;
1650*3d8817e4Smiod 
1651*3d8817e4Smiod 	      goto try_1addr_16;
1652*3d8817e4Smiod 
1653*3d8817e4Smiod 	    case R_M32C_RL_1ADDR:
1654*3d8817e4Smiod 	      /* xxxx xxxx xxxx dest [disp] */
1655*3d8817e4Smiod 
1656*3d8817e4Smiod 	      enctbl = m16c_addr_encodings;
1657*3d8817e4Smiod 	      posn = 2;
1658*3d8817e4Smiod 
1659*3d8817e4Smiod 	      /* Check the opcode for jumps.  We know it's safe to
1660*3d8817e4Smiod 		 do this because all 2ADDR insns are at least two
1661*3d8817e4Smiod 		 bytes long.  */
1662*3d8817e4Smiod 	      enc = insn[0] * 256 + insn[1];
1663*3d8817e4Smiod 	      enc &= 0xfff0;
1664*3d8817e4Smiod 	      if (enc == 0x7d20
1665*3d8817e4Smiod 		  || enc == 0x7d00
1666*3d8817e4Smiod 		  || enc == 0x7d30
1667*3d8817e4Smiod 		  || enc == 0x7d10)
1668*3d8817e4Smiod 		{
1669*3d8817e4Smiod 		  enctbl = m16c_jmpaddr_encodings;
1670*3d8817e4Smiod 		}
1671*3d8817e4Smiod 
1672*3d8817e4Smiod 	    try_1addr_16:
1673*3d8817e4Smiod 	      /* srel, posn, and enc must be set here.  */
1674*3d8817e4Smiod 
1675*3d8817e4Smiod 	      symval = OFFSET_FOR_RELOC (srel);
1676*3d8817e4Smiod 	      enc = insn[1] & 0x0f;
1677*3d8817e4Smiod 	      e = & enctbl[enc];
1678*3d8817e4Smiod 
1679*3d8817e4Smiod 	      if (srel->r_offset == irel->r_offset + posn
1680*3d8817e4Smiod 		  && e->new_encoding != enc
1681*3d8817e4Smiod 		  && symval <= e->max_disp)
1682*3d8817e4Smiod 		{
1683*3d8817e4Smiod 		  insn[1] &= 0xf0;
1684*3d8817e4Smiod 		  insn[1] |= e->new_encoding;
1685*3d8817e4Smiod 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1686*3d8817e4Smiod 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
1687*3d8817e4Smiod 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1688*3d8817e4Smiod 		  break;
1689*3d8817e4Smiod 		}
1690*3d8817e4Smiod 
1691*3d8817e4Smiod 	      break;
1692*3d8817e4Smiod 
1693*3d8817e4Smiod 	    } /* Ends switch (reloc type) for m16c.  */
1694*3d8817e4Smiod 	}
1695*3d8817e4Smiod       else /* machine == bfd_mach_m32c */
1696*3d8817e4Smiod 	{
1697*3d8817e4Smiod 	  /* M32CM / M32C */
1698*3d8817e4Smiod 
1699*3d8817e4Smiod 	  switch (ELF32_R_TYPE(irel->r_info))
1700*3d8817e4Smiod 	    {
1701*3d8817e4Smiod 
1702*3d8817e4Smiod 	    case R_M32C_RL_JUMP:
1703*3d8817e4Smiod 	      switch (insn[0])
1704*3d8817e4Smiod 		{
1705*3d8817e4Smiod 		case 0xbb: /* jmp.b */
1706*3d8817e4Smiod 		  if (pcrel >= 2 && pcrel <= 9)
1707*3d8817e4Smiod 		    {
1708*3d8817e4Smiod 		      int p = pcrel - 2;
1709*3d8817e4Smiod 		      /* Relax JMP.B -> JMP.S.  We need to get rid of
1710*3d8817e4Smiod 			 the following reloc though. */
1711*3d8817e4Smiod 		      insn[0] = 0x4a | ((p << 3) & 0x30) | (p & 1);
1712*3d8817e4Smiod 		      new_type = R_M32C_NONE;
1713*3d8817e4Smiod 		      irel->r_addend = 0x10;
1714*3d8817e4Smiod 		      gap_size = 1;
1715*3d8817e4Smiod 		      gap = insn + 1;
1716*3d8817e4Smiod 		    }
1717*3d8817e4Smiod 		  break;
1718*3d8817e4Smiod 
1719*3d8817e4Smiod 		case 0xce: /* jmp.w */
1720*3d8817e4Smiod 		  if (pcrel <= 128 && pcrel >= -128)
1721*3d8817e4Smiod 		    {
1722*3d8817e4Smiod 		      /* Relax JMP.W -> JMP.B */
1723*3d8817e4Smiod 		      insn[0] = 0xbb;
1724*3d8817e4Smiod 		      insn[1] = 0;
1725*3d8817e4Smiod 		      new_type = R_M32C_8_PCREL;
1726*3d8817e4Smiod 		      gap_size = 1;
1727*3d8817e4Smiod 		      gap = insn + 2;
1728*3d8817e4Smiod 		    }
1729*3d8817e4Smiod 		  break;
1730*3d8817e4Smiod 
1731*3d8817e4Smiod 		case 0xcc: /* jmp.a */
1732*3d8817e4Smiod 		  if (pcrel <= 32768 && pcrel >= -32768)
1733*3d8817e4Smiod 		    {
1734*3d8817e4Smiod 		      /* Relax JMP.A -> JMP.W */
1735*3d8817e4Smiod 		      insn[0] = 0xce;
1736*3d8817e4Smiod 		      insn[1] = 0;
1737*3d8817e4Smiod 		      insn[2] = 0;
1738*3d8817e4Smiod 		      new_type = R_M32C_16_PCREL;
1739*3d8817e4Smiod 		      gap_size = 1;
1740*3d8817e4Smiod 		      gap = insn + 3;
1741*3d8817e4Smiod 		    }
1742*3d8817e4Smiod 		  break;
1743*3d8817e4Smiod 
1744*3d8817e4Smiod 		case 0xcd: /* jsr.a */
1745*3d8817e4Smiod 		  if (pcrel <= 32768 && pcrel >= -32768)
1746*3d8817e4Smiod 		    {
1747*3d8817e4Smiod 		      /* Relax JSR.A -> JSR.W */
1748*3d8817e4Smiod 		      insn[0] = 0xcf;
1749*3d8817e4Smiod 		      insn[1] = 0;
1750*3d8817e4Smiod 		      insn[2] = 0;
1751*3d8817e4Smiod 		      new_type = R_M32C_16_PCREL;
1752*3d8817e4Smiod 		      gap_size = 1;
1753*3d8817e4Smiod 		      gap = insn + 3;
1754*3d8817e4Smiod 		    }
1755*3d8817e4Smiod 		  break;
1756*3d8817e4Smiod 		}
1757*3d8817e4Smiod 	      break;
1758*3d8817e4Smiod 
1759*3d8817e4Smiod 	    case R_M32C_RL_2ADDR:
1760*3d8817e4Smiod 	      /* xSSS DDDx DDSS xxxx [src-disp] [dest-disp]*/
1761*3d8817e4Smiod 
1762*3d8817e4Smiod 	      einsn = insn;
1763*3d8817e4Smiod 	      posn = 2;
1764*3d8817e4Smiod 	      if (einsn[0] == 1)
1765*3d8817e4Smiod 		{
1766*3d8817e4Smiod 		  /* prefix; remove it as far as the RL reloc is concerned.  */
1767*3d8817e4Smiod 		  einsn ++;
1768*3d8817e4Smiod 		  posn ++;
1769*3d8817e4Smiod 		}
1770*3d8817e4Smiod 
1771*3d8817e4Smiod 	      enctbl = m32c_addr_encodings;
1772*3d8817e4Smiod 	      enc = ((einsn[0] & 0x70) >> 2) | ((einsn[1] & 0x30) >> 4);
1773*3d8817e4Smiod 	      e = & enctbl[enc];
1774*3d8817e4Smiod 
1775*3d8817e4Smiod 	      if (srel->r_offset == irel->r_offset + posn
1776*3d8817e4Smiod 		  && e->new_encoding != enc
1777*3d8817e4Smiod 		  && symval <= e->max_disp)
1778*3d8817e4Smiod 		{
1779*3d8817e4Smiod 		  einsn[0] &= 0x8f;
1780*3d8817e4Smiod 		  einsn[0] |= (e->new_encoding & 0x1c) << 2;
1781*3d8817e4Smiod 		  einsn[1] &= 0xcf;
1782*3d8817e4Smiod 		  einsn[1] |= (e->new_encoding & 0x03) << 4;
1783*3d8817e4Smiod 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1784*3d8817e4Smiod 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
1785*3d8817e4Smiod 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1786*3d8817e4Smiod 		  break;
1787*3d8817e4Smiod 		}
1788*3d8817e4Smiod 	      if (relax_relocs == 2)
1789*3d8817e4Smiod 		  srel ++;
1790*3d8817e4Smiod 	      posn += e->bytes;
1791*3d8817e4Smiod 
1792*3d8817e4Smiod 	      goto try_1addr_32;
1793*3d8817e4Smiod 
1794*3d8817e4Smiod 	    case R_M32C_RL_1ADDR:
1795*3d8817e4Smiod 	      /* xxxx DDDx DDxx xxxx [disp] */
1796*3d8817e4Smiod 
1797*3d8817e4Smiod 	      einsn = insn;
1798*3d8817e4Smiod 	      posn = 2;
1799*3d8817e4Smiod 	      if (einsn[0] == 1)
1800*3d8817e4Smiod 		{
1801*3d8817e4Smiod 		  /* prefix; remove it as far as the RL reloc is concerned.  */
1802*3d8817e4Smiod 		  einsn ++;
1803*3d8817e4Smiod 		  posn ++;
1804*3d8817e4Smiod 		}
1805*3d8817e4Smiod 
1806*3d8817e4Smiod 	      enctbl = m32c_addr_encodings;
1807*3d8817e4Smiod 
1808*3d8817e4Smiod 	    try_1addr_32:
1809*3d8817e4Smiod 	      /* srel, posn, and enc must be set here.  */
1810*3d8817e4Smiod 
1811*3d8817e4Smiod 	      symval = OFFSET_FOR_RELOC (srel);
1812*3d8817e4Smiod 	      enc = ((einsn[0] & 0x0e) << 1) |  ((einsn[1] & 0xc0) >> 6);
1813*3d8817e4Smiod 	      e = & enctbl[enc];
1814*3d8817e4Smiod 
1815*3d8817e4Smiod 	      if (srel->r_offset == irel->r_offset + posn
1816*3d8817e4Smiod 		  && e->new_encoding != enc
1817*3d8817e4Smiod 		  && symval <= e->max_disp)
1818*3d8817e4Smiod 		{
1819*3d8817e4Smiod 		  einsn[0] &= 0xf1;
1820*3d8817e4Smiod 		  einsn[0] |= (e->new_encoding & 0x1c) >> 1;
1821*3d8817e4Smiod 		  einsn[1] &= 0x3f;
1822*3d8817e4Smiod 		  einsn[1] |= (e->new_encoding & 0x03) << 6;
1823*3d8817e4Smiod 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1824*3d8817e4Smiod 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
1825*3d8817e4Smiod 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1826*3d8817e4Smiod 		  break;
1827*3d8817e4Smiod 		}
1828*3d8817e4Smiod 
1829*3d8817e4Smiod 	      break;
1830*3d8817e4Smiod 
1831*3d8817e4Smiod 	    } /* Ends switch (reloc type) for m32c.  */
1832*3d8817e4Smiod 	}
1833*3d8817e4Smiod 
1834*3d8817e4Smiod       if (gap_size == 0)
1835*3d8817e4Smiod 	continue;
1836*3d8817e4Smiod 
1837*3d8817e4Smiod       *again = TRUE;
1838*3d8817e4Smiod 
1839*3d8817e4Smiod       srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), new_type);
1840*3d8817e4Smiod 
1841*3d8817e4Smiod       /* Note that we've changed the relocs, section contents, etc.  */
1842*3d8817e4Smiod       elf_section_data (sec)->relocs = internal_relocs;
1843*3d8817e4Smiod       free_relocs = NULL;
1844*3d8817e4Smiod 
1845*3d8817e4Smiod       elf_section_data (sec)->this_hdr.contents = contents;
1846*3d8817e4Smiod       free_contents = NULL;
1847*3d8817e4Smiod 
1848*3d8817e4Smiod       symtab_hdr->contents = (bfd_byte *) intsyms;
1849*3d8817e4Smiod       free_intsyms = NULL;
1850*3d8817e4Smiod 
1851*3d8817e4Smiod       bytes_saved += gap_size;
1852*3d8817e4Smiod 
1853*3d8817e4Smiod       if (! m32c_elf_relax_delete_bytes(abfd, sec, gap - contents, gap_size))
1854*3d8817e4Smiod 	goto error_return;
1855*3d8817e4Smiod 
1856*3d8817e4Smiod     } /* next relocation */
1857*3d8817e4Smiod 
1858*3d8817e4Smiod   if (free_relocs != NULL)
1859*3d8817e4Smiod     {
1860*3d8817e4Smiod       free (free_relocs);
1861*3d8817e4Smiod       free_relocs = NULL;
1862*3d8817e4Smiod     }
1863*3d8817e4Smiod 
1864*3d8817e4Smiod   if (free_contents != NULL)
1865*3d8817e4Smiod     {
1866*3d8817e4Smiod       if (! link_info->keep_memory)
1867*3d8817e4Smiod 	free (free_contents);
1868*3d8817e4Smiod       /* Cache the section contents for elf_link_input_bfd.  */
1869*3d8817e4Smiod       else
1870*3d8817e4Smiod 	elf_section_data (sec)->this_hdr.contents = contents;
1871*3d8817e4Smiod 
1872*3d8817e4Smiod       free_contents = NULL;
1873*3d8817e4Smiod     }
1874*3d8817e4Smiod 
1875*3d8817e4Smiod   if (shndx_buf != NULL)
1876*3d8817e4Smiod     {
1877*3d8817e4Smiod       shndx_hdr->contents = NULL;
1878*3d8817e4Smiod       free (shndx_buf);
1879*3d8817e4Smiod     }
1880*3d8817e4Smiod 
1881*3d8817e4Smiod   if (free_intsyms != NULL)
1882*3d8817e4Smiod     {
1883*3d8817e4Smiod       if (! link_info->keep_memory)
1884*3d8817e4Smiod 	free (free_intsyms);
1885*3d8817e4Smiod       /* Cache the symbols for elf_link_input_bfd.  */
1886*3d8817e4Smiod       else
1887*3d8817e4Smiod 	{
1888*3d8817e4Smiod 	symtab_hdr->contents = NULL /* (unsigned char *) intsyms*/;
1889*3d8817e4Smiod 	}
1890*3d8817e4Smiod 
1891*3d8817e4Smiod       free_intsyms = NULL;
1892*3d8817e4Smiod     }
1893*3d8817e4Smiod 
1894*3d8817e4Smiod   return TRUE;
1895*3d8817e4Smiod 
1896*3d8817e4Smiod  error_return:
1897*3d8817e4Smiod   if (free_relocs != NULL)
1898*3d8817e4Smiod     free (free_relocs);
1899*3d8817e4Smiod   if (free_contents != NULL)
1900*3d8817e4Smiod     free (free_contents);
1901*3d8817e4Smiod   if (shndx_buf != NULL)
1902*3d8817e4Smiod     {
1903*3d8817e4Smiod       shndx_hdr->contents = NULL;
1904*3d8817e4Smiod       free (shndx_buf);
1905*3d8817e4Smiod     }
1906*3d8817e4Smiod   if (free_intsyms != NULL)
1907*3d8817e4Smiod     free (free_intsyms);
1908*3d8817e4Smiod   return FALSE;
1909*3d8817e4Smiod }
1910*3d8817e4Smiod 
1911*3d8817e4Smiod /* Delete some bytes from a section while relaxing.  */
1912*3d8817e4Smiod 
1913*3d8817e4Smiod static bfd_boolean
m32c_elf_relax_delete_bytes(bfd * abfd,asection * sec,bfd_vma addr,int count)1914*3d8817e4Smiod m32c_elf_relax_delete_bytes
1915*3d8817e4Smiod  (bfd *      abfd,
1916*3d8817e4Smiod   asection * sec,
1917*3d8817e4Smiod   bfd_vma    addr,
1918*3d8817e4Smiod   int        count)
1919*3d8817e4Smiod {
1920*3d8817e4Smiod   Elf_Internal_Shdr *symtab_hdr;
1921*3d8817e4Smiod   Elf_Internal_Shdr *shndx_hdr;
1922*3d8817e4Smiod   int sec_shndx;
1923*3d8817e4Smiod   bfd_byte *contents;
1924*3d8817e4Smiod   Elf_Internal_Rela *irel;
1925*3d8817e4Smiod   Elf_Internal_Rela *irelend;
1926*3d8817e4Smiod   Elf_Internal_Rela *irelalign;
1927*3d8817e4Smiod   bfd_vma toaddr;
1928*3d8817e4Smiod   Elf_Internal_Sym *isym;
1929*3d8817e4Smiod   Elf_Internal_Sym *isymend;
1930*3d8817e4Smiod   Elf_Internal_Sym *intsyms;
1931*3d8817e4Smiod   Elf_External_Sym_Shndx *shndx_buf;
1932*3d8817e4Smiod   Elf_External_Sym_Shndx *shndx;
1933*3d8817e4Smiod   struct elf_link_hash_entry ** sym_hashes;
1934*3d8817e4Smiod   struct elf_link_hash_entry ** end_hashes;
1935*3d8817e4Smiod   unsigned int                  symcount;
1936*3d8817e4Smiod 
1937*3d8817e4Smiod   contents   = elf_section_data (sec)->this_hdr.contents;
1938*3d8817e4Smiod 
1939*3d8817e4Smiod   /* The deletion must stop at the next ALIGN reloc for an aligment
1940*3d8817e4Smiod      power larger than the number of bytes we are deleting.  */
1941*3d8817e4Smiod   irelalign = NULL;
1942*3d8817e4Smiod   toaddr = sec->size;
1943*3d8817e4Smiod 
1944*3d8817e4Smiod   irel = elf_section_data (sec)->relocs;
1945*3d8817e4Smiod   irelend = irel + sec->reloc_count;
1946*3d8817e4Smiod 
1947*3d8817e4Smiod   /* Actually delete the bytes.  */
1948*3d8817e4Smiod   memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
1949*3d8817e4Smiod   sec->size -= count;
1950*3d8817e4Smiod 
1951*3d8817e4Smiod   /* Adjust all the relocs.  */
1952*3d8817e4Smiod   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
1953*3d8817e4Smiod     {
1954*3d8817e4Smiod       /* Get the new reloc address.  */
1955*3d8817e4Smiod       if (irel->r_offset > addr && irel->r_offset < toaddr)
1956*3d8817e4Smiod 	irel->r_offset -= count;
1957*3d8817e4Smiod 
1958*3d8817e4Smiod       if (ELF32_R_TYPE(irel->r_info) == R_M32C_RL_JUMP
1959*3d8817e4Smiod 	  && irel->r_addend == 0x10 /* one byte insn, no relocs */
1960*3d8817e4Smiod 	  && irel->r_offset + 1 < addr
1961*3d8817e4Smiod 	  && irel->r_offset + 7 > addr)
1962*3d8817e4Smiod 	{
1963*3d8817e4Smiod 	  bfd_vma disp;
1964*3d8817e4Smiod 	  unsigned char *insn = &contents[irel->r_offset];
1965*3d8817e4Smiod 	  disp = *insn;
1966*3d8817e4Smiod 	  /* This is a JMP.S, which we have to manually update. */
1967*3d8817e4Smiod 	  if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
1968*3d8817e4Smiod 	    {
1969*3d8817e4Smiod 	      if ((*insn & 0xf8) != 0x60)
1970*3d8817e4Smiod 		continue;
1971*3d8817e4Smiod 	      disp = (disp & 7);
1972*3d8817e4Smiod 	    }
1973*3d8817e4Smiod 	  else
1974*3d8817e4Smiod 	    {
1975*3d8817e4Smiod 	      if ((*insn & 0xce) != 0x4a)
1976*3d8817e4Smiod 		continue;
1977*3d8817e4Smiod 	      disp = ((disp & 0x30) >> 3) | (disp & 1);
1978*3d8817e4Smiod 	    }
1979*3d8817e4Smiod 	  if (irel->r_offset + disp + 2 >= addr+count)
1980*3d8817e4Smiod 	    {
1981*3d8817e4Smiod 	      disp -= count;
1982*3d8817e4Smiod 	      if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
1983*3d8817e4Smiod 		{
1984*3d8817e4Smiod 		  *insn = (*insn & 0xf8) | disp;
1985*3d8817e4Smiod 		}
1986*3d8817e4Smiod 	      else
1987*3d8817e4Smiod 		{
1988*3d8817e4Smiod 		  *insn = (*insn & 0xce) | ((disp & 6) << 3) | (disp & 1);
1989*3d8817e4Smiod 		}
1990*3d8817e4Smiod 	    }
1991*3d8817e4Smiod 	}
1992*3d8817e4Smiod     }
1993*3d8817e4Smiod 
1994*3d8817e4Smiod   /* Adjust the local symbols defined in this section.  */
1995*3d8817e4Smiod   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1996*3d8817e4Smiod   intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
1997*3d8817e4Smiod   isym = intsyms;
1998*3d8817e4Smiod   isymend = isym + symtab_hdr->sh_info;
1999*3d8817e4Smiod 
2000*3d8817e4Smiod   sec_shndx  = _bfd_elf_section_from_bfd_section (abfd, sec);
2001*3d8817e4Smiod   shndx_hdr  = & elf_tdata (abfd)->symtab_shndx_hdr;
2002*3d8817e4Smiod   shndx_buf  = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
2003*3d8817e4Smiod   shndx = shndx_buf;
2004*3d8817e4Smiod 
2005*3d8817e4Smiod   for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
2006*3d8817e4Smiod     {
2007*3d8817e4Smiod 
2008*3d8817e4Smiod       if ((int) isym->st_shndx == sec_shndx
2009*3d8817e4Smiod 	  && isym->st_value > addr
2010*3d8817e4Smiod 	  && isym->st_value < toaddr)
2011*3d8817e4Smiod 	{
2012*3d8817e4Smiod 	  isym->st_value -= count;
2013*3d8817e4Smiod 	}
2014*3d8817e4Smiod     }
2015*3d8817e4Smiod 
2016*3d8817e4Smiod   /* Now adjust the global symbols defined in this section.  */
2017*3d8817e4Smiod   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
2018*3d8817e4Smiod 	      - symtab_hdr->sh_info);
2019*3d8817e4Smiod   sym_hashes = elf_sym_hashes (abfd);
2020*3d8817e4Smiod   //  sym_hashes += symtab_hdr->sh_info;
2021*3d8817e4Smiod   end_hashes = sym_hashes + symcount;
2022*3d8817e4Smiod 
2023*3d8817e4Smiod   for (; sym_hashes < end_hashes; sym_hashes ++)
2024*3d8817e4Smiod     {
2025*3d8817e4Smiod       struct elf_link_hash_entry * sym_hash = * sym_hashes;
2026*3d8817e4Smiod 
2027*3d8817e4Smiod       if (sym_hash &&
2028*3d8817e4Smiod 	  (   sym_hash->root.type == bfd_link_hash_defined
2029*3d8817e4Smiod 	   || sym_hash->root.type == bfd_link_hash_defweak)
2030*3d8817e4Smiod 	  && sym_hash->root.u.def.section == sec
2031*3d8817e4Smiod 	  && sym_hash->root.u.def.value > addr
2032*3d8817e4Smiod 	  && sym_hash->root.u.def.value < toaddr)
2033*3d8817e4Smiod 	{
2034*3d8817e4Smiod 	  sym_hash->root.u.def.value -= count;
2035*3d8817e4Smiod 	}
2036*3d8817e4Smiod     }
2037*3d8817e4Smiod 
2038*3d8817e4Smiod   return TRUE;
2039*3d8817e4Smiod }
2040*3d8817e4Smiod 
2041*3d8817e4Smiod 
2042*3d8817e4Smiod #define ELF_ARCH		bfd_arch_m32c
2043*3d8817e4Smiod #define ELF_MACHINE_CODE	EM_M32C
2044*3d8817e4Smiod #define ELF_MAXPAGESIZE		0x1000
2045*3d8817e4Smiod 
2046*3d8817e4Smiod #if 0
2047*3d8817e4Smiod #define TARGET_BIG_SYM		bfd_elf32_m32c_vec
2048*3d8817e4Smiod #define TARGET_BIG_NAME		"elf32-m32c"
2049*3d8817e4Smiod #else
2050*3d8817e4Smiod #define TARGET_LITTLE_SYM		bfd_elf32_m32c_vec
2051*3d8817e4Smiod #define TARGET_LITTLE_NAME		"elf32-m32c"
2052*3d8817e4Smiod #endif
2053*3d8817e4Smiod 
2054*3d8817e4Smiod #define elf_info_to_howto_rel			NULL
2055*3d8817e4Smiod #define elf_info_to_howto			m32c_info_to_howto_rela
2056*3d8817e4Smiod #define elf_backend_object_p			m32c_elf_object_p
2057*3d8817e4Smiod #define elf_backend_relocate_section		m32c_elf_relocate_section
2058*3d8817e4Smiod #define elf_backend_gc_mark_hook		m32c_elf_gc_mark_hook
2059*3d8817e4Smiod #define elf_backend_gc_sweep_hook		m32c_elf_gc_sweep_hook
2060*3d8817e4Smiod #define elf_backend_check_relocs                m32c_elf_check_relocs
2061*3d8817e4Smiod #define elf_backend_object_p			m32c_elf_object_p
2062*3d8817e4Smiod #define elf_symbol_leading_char                 ('_')
2063*3d8817e4Smiod #define elf_backend_always_size_sections \
2064*3d8817e4Smiod   m32c_elf_always_size_sections
2065*3d8817e4Smiod #define elf_backend_finish_dynamic_sections \
2066*3d8817e4Smiod   m32c_elf_finish_dynamic_sections
2067*3d8817e4Smiod 
2068*3d8817e4Smiod #define elf_backend_can_gc_sections		1
2069*3d8817e4Smiod 
2070*3d8817e4Smiod #define bfd_elf32_bfd_reloc_type_lookup		m32c_reloc_type_lookup
2071*3d8817e4Smiod #define bfd_elf32_bfd_relax_section		m32c_elf_relax_section
2072*3d8817e4Smiod #define bfd_elf32_bfd_set_private_flags		m32c_elf_set_private_flags
2073*3d8817e4Smiod #define bfd_elf32_bfd_merge_private_bfd_data	m32c_elf_merge_private_bfd_data
2074*3d8817e4Smiod #define bfd_elf32_bfd_print_private_bfd_data	m32c_elf_print_private_bfd_data
2075*3d8817e4Smiod 
2076*3d8817e4Smiod #include "elf32-target.h"
2077