xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/elf32-m32c.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* M16C/M32C specific support for 32-bit ELF.
2*e992f068Schristos    Copyright (C) 2005-2022 Free Software Foundation, Inc.
375fd0b74Schristos 
475fd0b74Schristos    This file is part of BFD, the Binary File Descriptor library.
575fd0b74Schristos 
675fd0b74Schristos    This program is free software; you can redistribute it and/or modify
775fd0b74Schristos    it under the terms of the GNU General Public License as published by
875fd0b74Schristos    the Free Software Foundation; either version 3 of the License, or
975fd0b74Schristos    (at your option) any later version.
1075fd0b74Schristos 
1175fd0b74Schristos    This program is distributed in the hope that it will be useful,
1275fd0b74Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1375fd0b74Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1475fd0b74Schristos    GNU General Public License for more details.
1575fd0b74Schristos 
1675fd0b74Schristos    You should have received a copy of the GNU General Public License
1775fd0b74Schristos    along with this program; if not, write to the Free Software
18ede78133Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19ede78133Schristos    MA 02110-1301, USA.  */
2075fd0b74Schristos 
2175fd0b74Schristos #include "sysdep.h"
2275fd0b74Schristos #include "bfd.h"
2375fd0b74Schristos #include "libbfd.h"
2475fd0b74Schristos #include "elf-bfd.h"
2575fd0b74Schristos #include "elf/m32c.h"
2675fd0b74Schristos #include "libiberty.h"
2775fd0b74Schristos 
2875fd0b74Schristos /* Forward declarations.  */
2975fd0b74Schristos static reloc_howto_type * m32c_reloc_type_lookup
3075fd0b74Schristos   (bfd *, bfd_reloc_code_real_type);
31*e992f068Schristos static bool m32c_info_to_howto_rela
3275fd0b74Schristos   (bfd *, arelent *, Elf_Internal_Rela *);
33*e992f068Schristos static int m32c_elf_relocate_section
3475fd0b74Schristos   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
35*e992f068Schristos static bool m32c_elf_check_relocs
3675fd0b74Schristos   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
37*e992f068Schristos static bool m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
3875fd0b74Schristos #ifdef DEBUG
3975fd0b74Schristos char * m32c_get_reloc (long reloc);
4075fd0b74Schristos void dump_symtab (bfd *, void *, void *);
4175fd0b74Schristos #endif
42*e992f068Schristos static bool m32c_elf_relax_section
43*e992f068Schristos (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bool *again);
4475fd0b74Schristos static bfd_reloc_status_type m32c_apply_reloc_24
4575fd0b74Schristos   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4675fd0b74Schristos 
4775fd0b74Schristos 
4875fd0b74Schristos static reloc_howto_type m32c_elf_howto_table [] =
4975fd0b74Schristos {
5075fd0b74Schristos   /* This reloc does nothing.  */
5175fd0b74Schristos   HOWTO (R_M32C_NONE,		/* type */
5275fd0b74Schristos 	 0,			/* rightshift */
53*e992f068Schristos 	 0,			/* size */
5475fd0b74Schristos 	 0,			/* bitsize */
55*e992f068Schristos 	 false,			/* pc_relative */
5675fd0b74Schristos 	 0,			/* bitpos */
5775fd0b74Schristos 	 complain_overflow_dont, /* complain_on_overflow */
5875fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
5975fd0b74Schristos 	 "R_M32C_NONE",		/* name */
60*e992f068Schristos 	 false,			/* partial_inplace */
6175fd0b74Schristos 	 0,			/* src_mask */
6275fd0b74Schristos 	 0,			/* dst_mask */
63*e992f068Schristos 	 false),		/* pcrel_offset */
6475fd0b74Schristos 
6575fd0b74Schristos   /* GCC intentionally overflows these next two in order to work
6675fd0b74Schristos      around limitations in the addressing modes, so don't complain
6775fd0b74Schristos      about overflow.  */
6875fd0b74Schristos   HOWTO (R_M32C_16,		/* type */
6975fd0b74Schristos 	 0,			/* rightshift */
70*e992f068Schristos 	 2,			/* size */
7175fd0b74Schristos 	 16,			/* bitsize */
72*e992f068Schristos 	 false,			/* pc_relative */
7375fd0b74Schristos 	 0,			/* bitpos */
7475fd0b74Schristos 	 complain_overflow_dont, /* complain_on_overflow */
7575fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
7675fd0b74Schristos 	 "R_M32C_16",		/* name */
77*e992f068Schristos 	 false,			/* partial_inplace */
7875fd0b74Schristos 	 0,			/* src_mask */
7975fd0b74Schristos 	 0xffff,		/* dst_mask */
80*e992f068Schristos 	 false),		/* pcrel_offset */
8175fd0b74Schristos 
8275fd0b74Schristos   HOWTO (R_M32C_24,		/* type */
8375fd0b74Schristos 	 0,			/* rightshift */
84*e992f068Schristos 	 4,			/* size */
8575fd0b74Schristos 	 24,			/* bitsize */
86*e992f068Schristos 	 false,			/* pc_relative */
8775fd0b74Schristos 	 0,			/* bitpos */
8875fd0b74Schristos 	 complain_overflow_dont, /* complain_on_overflow */
8975fd0b74Schristos 	 m32c_apply_reloc_24,	/* special_function */
9075fd0b74Schristos 	 "R_M32C_24",		/* name */
91*e992f068Schristos 	 false,			/* partial_inplace */
9275fd0b74Schristos 	 0,			/* src_mask */
9375fd0b74Schristos 	 0xffffff,		/* dst_mask */
94*e992f068Schristos 	 false),		/* pcrel_offset */
9575fd0b74Schristos 
9675fd0b74Schristos   HOWTO (R_M32C_32,		/* type */
9775fd0b74Schristos 	 0,			/* rightshift */
98*e992f068Schristos 	 4,			/* size */
9975fd0b74Schristos 	 32,			/* bitsize */
100*e992f068Schristos 	 false,			/* pc_relative */
10175fd0b74Schristos 	 0,			/* bitpos */
10275fd0b74Schristos 	 complain_overflow_bitfield, /* complain_on_overflow */
10375fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
10475fd0b74Schristos 	 "R_M32C_32",		/* name */
105*e992f068Schristos 	 false,			/* partial_inplace */
10675fd0b74Schristos 	 0,			/* src_mask */
10775fd0b74Schristos 	 0xffffffff,		/* dst_mask */
108*e992f068Schristos 	 false),		/* pcrel_offset */
10975fd0b74Schristos 
11075fd0b74Schristos   HOWTO (R_M32C_8_PCREL,	/* type */
11175fd0b74Schristos 	 0,			/* rightshift */
112*e992f068Schristos 	 1,			/* size */
11375fd0b74Schristos 	 8,			/* bitsize */
114*e992f068Schristos 	 true,			/* pc_relative */
11575fd0b74Schristos 	 0,			/* bitpos */
11675fd0b74Schristos 	 complain_overflow_signed, /* complain_on_overflow */
11775fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
11875fd0b74Schristos 	 "R_M32C_8_PCREL",	/* name */
119*e992f068Schristos 	 false,			/* partial_inplace */
12075fd0b74Schristos 	 0,			/* src_mask */
12175fd0b74Schristos 	 0xff,			/* dst_mask */
122*e992f068Schristos 	 true),			/* pcrel_offset */
12375fd0b74Schristos 
12475fd0b74Schristos   HOWTO (R_M32C_16_PCREL,	/* type */
12575fd0b74Schristos 	 0,			/* rightshift */
126*e992f068Schristos 	 2,			/* size */
12775fd0b74Schristos 	 16,			/* bitsize */
128*e992f068Schristos 	 true,			/* pc_relative */
12975fd0b74Schristos 	 0,			/* bitpos */
13075fd0b74Schristos 	 complain_overflow_signed, /* complain_on_overflow */
13175fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
13275fd0b74Schristos 	 "R_M32C_16_PCREL",	/* name */
133*e992f068Schristos 	 false,			/* partial_inplace */
13475fd0b74Schristos 	 0,			/* src_mask */
13575fd0b74Schristos 	 0xffff,		/* dst_mask */
136*e992f068Schristos 	 true),			/* pcrel_offset */
13775fd0b74Schristos 
13875fd0b74Schristos   HOWTO (R_M32C_8,		/* type */
13975fd0b74Schristos 	 0,			/* rightshift */
140*e992f068Schristos 	 1,			/* size */
14175fd0b74Schristos 	 8,			/* bitsize */
142*e992f068Schristos 	 false,			/* pc_relative */
14375fd0b74Schristos 	 0,			/* bitpos */
14475fd0b74Schristos 	 complain_overflow_unsigned, /* complain_on_overflow */
14575fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
14675fd0b74Schristos 	 "R_M32C_8",		/* name */
147*e992f068Schristos 	 false,			/* partial_inplace */
14875fd0b74Schristos 	 0,			/* src_mask */
14975fd0b74Schristos 	 0xff,			/* dst_mask */
150*e992f068Schristos 	 false),		/* pcrel_offset */
15175fd0b74Schristos 
15275fd0b74Schristos   HOWTO (R_M32C_LO16,		/* type */
15375fd0b74Schristos 	 0,			/* rightshift */
154*e992f068Schristos 	 2,			/* size */
15575fd0b74Schristos 	 16,			/* bitsize */
156*e992f068Schristos 	 false,			/* pc_relative */
15775fd0b74Schristos 	 0,			/* bitpos */
15875fd0b74Schristos 	 complain_overflow_dont, /* complain_on_overflow */
15975fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
16075fd0b74Schristos 	 "R_M32C_LO16",		/* name */
161*e992f068Schristos 	 false,			/* partial_inplace */
16275fd0b74Schristos 	 0,			/* src_mask */
16375fd0b74Schristos 	 0xffff,		/* dst_mask */
164*e992f068Schristos 	 false),		/* pcrel_offset */
16575fd0b74Schristos 
16675fd0b74Schristos   HOWTO (R_M32C_HI8,		/* type */
16775fd0b74Schristos 	 0,			/* rightshift */
168*e992f068Schristos 	 1,			/* size */
16975fd0b74Schristos 	 8,			/* bitsize */
170*e992f068Schristos 	 false,			/* pc_relative */
17175fd0b74Schristos 	 0,			/* bitpos */
17275fd0b74Schristos 	 complain_overflow_dont, /* complain_on_overflow */
17375fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
17475fd0b74Schristos 	 "R_M32C_HI8",		/* name */
175*e992f068Schristos 	 false,			/* partial_inplace */
17675fd0b74Schristos 	 0,			/* src_mask */
17775fd0b74Schristos 	 0xff,			/* dst_mask */
178*e992f068Schristos 	 false),		/* pcrel_offset */
17975fd0b74Schristos 
18075fd0b74Schristos   HOWTO (R_M32C_HI16,		/* type */
18175fd0b74Schristos 	 0,			/* rightshift */
182*e992f068Schristos 	 2,			/* size */
18375fd0b74Schristos 	 16,			/* bitsize */
184*e992f068Schristos 	 false,			/* pc_relative */
18575fd0b74Schristos 	 0,			/* bitpos */
18675fd0b74Schristos 	 complain_overflow_dont, /* complain_on_overflow */
18775fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
18875fd0b74Schristos 	 "R_M32C_HI16",		/* name */
189*e992f068Schristos 	 false,			/* partial_inplace */
19075fd0b74Schristos 	 0,			/* src_mask */
19175fd0b74Schristos 	 0xffff,		/* dst_mask */
192*e992f068Schristos 	 false),		/* pcrel_offset */
19375fd0b74Schristos 
19475fd0b74Schristos   HOWTO (R_M32C_RL_JUMP,	/* type */
19575fd0b74Schristos 	 0,			/* rightshift */
196*e992f068Schristos 	 0,			/* size */
19775fd0b74Schristos 	 0,			/* bitsize */
198*e992f068Schristos 	 false,			/* pc_relative */
19975fd0b74Schristos 	 0,			/* bitpos */
20075fd0b74Schristos 	 complain_overflow_signed, /* complain_on_overflow */
20175fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
20275fd0b74Schristos 	 "R_M32C_RL_JUMP",	/* name */
203*e992f068Schristos 	 false,			/* partial_inplace */
20475fd0b74Schristos 	 0,			/* src_mask */
20575fd0b74Schristos 	 0,			/* dst_mask */
206*e992f068Schristos 	 false),		/* pcrel_offset */
20775fd0b74Schristos 
20875fd0b74Schristos   HOWTO (R_M32C_RL_1ADDR,	/* type */
20975fd0b74Schristos 	 0,			/* rightshift */
210*e992f068Schristos 	 0,			/* size */
21175fd0b74Schristos 	 0,			/* bitsize */
212*e992f068Schristos 	 false,			/* pc_relative */
21375fd0b74Schristos 	 0,			/* bitpos */
21475fd0b74Schristos 	 complain_overflow_signed, /* complain_on_overflow */
21575fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
21675fd0b74Schristos 	 "R_M32C_RL_1ADDR",	/* name */
217*e992f068Schristos 	 false,			/* partial_inplace */
21875fd0b74Schristos 	 0,			/* src_mask */
21975fd0b74Schristos 	 0,			/* dst_mask */
220*e992f068Schristos 	 false),		/* pcrel_offset */
22175fd0b74Schristos 
22275fd0b74Schristos   HOWTO (R_M32C_RL_2ADDR,	/* type */
22375fd0b74Schristos 	 0,			/* rightshift */
224*e992f068Schristos 	 0,			/* size */
22575fd0b74Schristos 	 0,			/* bitsize */
226*e992f068Schristos 	 false,			/* pc_relative */
22775fd0b74Schristos 	 0,			/* bitpos */
22875fd0b74Schristos 	 complain_overflow_signed, /* complain_on_overflow */
22975fd0b74Schristos 	 bfd_elf_generic_reloc,	/* special_function */
23075fd0b74Schristos 	 "R_M32C_RL_2ADDR",	/* name */
231*e992f068Schristos 	 false,			/* partial_inplace */
23275fd0b74Schristos 	 0,			/* src_mask */
23375fd0b74Schristos 	 0,			/* dst_mask */
234*e992f068Schristos 	 false),		/* pcrel_offset */
23575fd0b74Schristos 
23675fd0b74Schristos };
23775fd0b74Schristos 
23875fd0b74Schristos /* Map BFD reloc types to M32C ELF reloc types.  */
23975fd0b74Schristos 
24075fd0b74Schristos struct m32c_reloc_map
24175fd0b74Schristos {
24275fd0b74Schristos   bfd_reloc_code_real_type bfd_reloc_val;
24375fd0b74Schristos   unsigned int m32c_reloc_val;
24475fd0b74Schristos };
24575fd0b74Schristos 
24675fd0b74Schristos static const struct m32c_reloc_map m32c_reloc_map [] =
24775fd0b74Schristos {
24875fd0b74Schristos   { BFD_RELOC_NONE,		R_M32C_NONE },
24975fd0b74Schristos   { BFD_RELOC_16,		R_M32C_16 },
25075fd0b74Schristos   { BFD_RELOC_24,		R_M32C_24 },
25175fd0b74Schristos   { BFD_RELOC_32,		R_M32C_32 },
25275fd0b74Schristos   { BFD_RELOC_8_PCREL,		R_M32C_8_PCREL },
25375fd0b74Schristos   { BFD_RELOC_16_PCREL,		R_M32C_16_PCREL },
25475fd0b74Schristos   { BFD_RELOC_8,		R_M32C_8 },
25575fd0b74Schristos   { BFD_RELOC_LO16,		R_M32C_LO16 },
25675fd0b74Schristos   { BFD_RELOC_HI16,		R_M32C_HI16 },
25775fd0b74Schristos   { BFD_RELOC_M32C_HI8,		R_M32C_HI8 },
25875fd0b74Schristos   { BFD_RELOC_M32C_RL_JUMP,	R_M32C_RL_JUMP },
25975fd0b74Schristos   { BFD_RELOC_M32C_RL_1ADDR,	R_M32C_RL_1ADDR },
26075fd0b74Schristos   { BFD_RELOC_M32C_RL_2ADDR,	R_M32C_RL_2ADDR }
26175fd0b74Schristos };
26275fd0b74Schristos 
26375fd0b74Schristos static reloc_howto_type *
m32c_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)26475fd0b74Schristos m32c_reloc_type_lookup
26575fd0b74Schristos     (bfd *		      abfd ATTRIBUTE_UNUSED,
26675fd0b74Schristos      bfd_reloc_code_real_type code)
26775fd0b74Schristos {
26875fd0b74Schristos   unsigned int i;
26975fd0b74Schristos 
27075fd0b74Schristos   for (i = ARRAY_SIZE (m32c_reloc_map); i--;)
27175fd0b74Schristos     if (m32c_reloc_map [i].bfd_reloc_val == code)
27275fd0b74Schristos       return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
27375fd0b74Schristos 
27475fd0b74Schristos   return NULL;
27575fd0b74Schristos }
27675fd0b74Schristos 
27775fd0b74Schristos static reloc_howto_type *
m32c_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)27875fd0b74Schristos m32c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
27975fd0b74Schristos {
28075fd0b74Schristos   unsigned int i;
28175fd0b74Schristos 
28275fd0b74Schristos   for (i = 0;
28375fd0b74Schristos        i < sizeof (m32c_elf_howto_table) / sizeof (m32c_elf_howto_table[0]);
28475fd0b74Schristos        i++)
28575fd0b74Schristos     if (m32c_elf_howto_table[i].name != NULL
28675fd0b74Schristos 	&& strcasecmp (m32c_elf_howto_table[i].name, r_name) == 0)
28775fd0b74Schristos       return &m32c_elf_howto_table[i];
28875fd0b74Schristos 
28975fd0b74Schristos   return NULL;
29075fd0b74Schristos }
29175fd0b74Schristos 
29275fd0b74Schristos /* Set the howto pointer for an M32C ELF reloc.  */
29375fd0b74Schristos 
294*e992f068Schristos static bool
m32c_info_to_howto_rela(bfd * abfd,arelent * cache_ptr,Elf_Internal_Rela * dst)295ede78133Schristos m32c_info_to_howto_rela (bfd *               abfd,
29675fd0b74Schristos 			 arelent *           cache_ptr,
29775fd0b74Schristos 			 Elf_Internal_Rela * dst)
29875fd0b74Schristos {
29975fd0b74Schristos   unsigned int r_type;
30075fd0b74Schristos 
30175fd0b74Schristos   r_type = ELF32_R_TYPE (dst->r_info);
30275fd0b74Schristos   if (r_type >= (unsigned int) R_M32C_max)
30375fd0b74Schristos     {
304ede78133Schristos       /* xgettext:c-format */
305ede78133Schristos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
306ede78133Schristos 			  abfd, r_type);
307ede78133Schristos       bfd_set_error (bfd_error_bad_value);
308*e992f068Schristos       return false;
30975fd0b74Schristos     }
31075fd0b74Schristos   cache_ptr->howto = & m32c_elf_howto_table [r_type];
311*e992f068Schristos   return true;
31275fd0b74Schristos }
31375fd0b74Schristos 
31475fd0b74Schristos 
31575fd0b74Schristos 
31675fd0b74Schristos /* Apply R_M32C_24 relocations.  We have to do this because it's not a
31775fd0b74Schristos    power-of-two size, and the generic code may think it overruns the
31875fd0b74Schristos    section if it's right at the end.
31975fd0b74Schristos 
32075fd0b74Schristos    Must return something other than bfd_reloc_continue to avoid the
32175fd0b74Schristos    above problem.  Typical return values include bfd_reloc_ok or
32275fd0b74Schristos    bfd_reloc_overflow.
32375fd0b74Schristos */
32475fd0b74Schristos 
m32c_apply_reloc_24(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol,void * vdata_start ATTRIBUTE_UNUSED,asection * input_section,bfd * ibfd ATTRIBUTE_UNUSED,char ** error_msg ATTRIBUTE_UNUSED)32575fd0b74Schristos static bfd_reloc_status_type m32c_apply_reloc_24 (bfd *abfd ATTRIBUTE_UNUSED,
32675fd0b74Schristos 						  arelent *reloc_entry,
32775fd0b74Schristos 						  asymbol *symbol,
32875fd0b74Schristos 						  void *vdata_start ATTRIBUTE_UNUSED,
32975fd0b74Schristos 						  asection *input_section,
33075fd0b74Schristos 						  bfd *ibfd ATTRIBUTE_UNUSED,
33175fd0b74Schristos 						  char **error_msg ATTRIBUTE_UNUSED)
33275fd0b74Schristos {
33375fd0b74Schristos   bfd_vma relocation;
33475fd0b74Schristos   bfd_reloc_status_type s;
33575fd0b74Schristos 
33675fd0b74Schristos   s = bfd_elf_generic_reloc (abfd, reloc_entry, symbol,
33775fd0b74Schristos 			     vdata_start,
33875fd0b74Schristos 			     input_section, ibfd, error_msg);
33975fd0b74Schristos   if (s != bfd_reloc_continue)
34075fd0b74Schristos     return s;
34175fd0b74Schristos 
34275fd0b74Schristos   /* Get symbol value.  (Common symbols are special.)  */
34375fd0b74Schristos   if (bfd_is_com_section (symbol->section))
34475fd0b74Schristos     relocation = 0;
34575fd0b74Schristos   else
34675fd0b74Schristos     relocation = symbol->value;
34775fd0b74Schristos 
34875fd0b74Schristos   relocation += symbol->section->output_offset;
34975fd0b74Schristos 
35075fd0b74Schristos   /* Add in supplied addend.  */
35175fd0b74Schristos   relocation += reloc_entry->addend;
35275fd0b74Schristos 
35375fd0b74Schristos   reloc_entry->addend = relocation;
35475fd0b74Schristos   reloc_entry->address += input_section->output_offset;
35575fd0b74Schristos   return bfd_reloc_ok;
35675fd0b74Schristos }
35775fd0b74Schristos 
35875fd0b74Schristos /* Relocate an M32C ELF section.
35975fd0b74Schristos    There is some attempt to make this function usable for many architectures,
36075fd0b74Schristos    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
36175fd0b74Schristos    if only to serve as a learning tool.
36275fd0b74Schristos 
36375fd0b74Schristos    The RELOCATE_SECTION function is called by the new ELF backend linker
36475fd0b74Schristos    to handle the relocations for a section.
36575fd0b74Schristos 
36675fd0b74Schristos    The relocs are always passed as Rela structures; if the section
36775fd0b74Schristos    actually uses Rel structures, the r_addend field will always be
36875fd0b74Schristos    zero.
36975fd0b74Schristos 
37075fd0b74Schristos    This function is responsible for adjusting the section contents as
37175fd0b74Schristos    necessary, and (if using Rela relocs and generating a relocatable
37275fd0b74Schristos    output file) adjusting the reloc addend as necessary.
37375fd0b74Schristos 
37475fd0b74Schristos    This function does not have to worry about setting the reloc
37575fd0b74Schristos    address or the reloc symbol index.
37675fd0b74Schristos 
37775fd0b74Schristos    LOCAL_SYMS is a pointer to the swapped in local symbols.
37875fd0b74Schristos 
37975fd0b74Schristos    LOCAL_SECTIONS is an array giving the section in the input file
38075fd0b74Schristos    corresponding to the st_shndx field of each local symbol.
38175fd0b74Schristos 
38275fd0b74Schristos    The global hash table entry for the global symbols can be found
38375fd0b74Schristos    via elf_sym_hashes (input_bfd).
38475fd0b74Schristos 
38575fd0b74Schristos    When generating relocatable output, this function must handle
38675fd0b74Schristos    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
38775fd0b74Schristos    going to be the section symbol corresponding to the output
38875fd0b74Schristos    section, which means that the addend must be adjusted
38975fd0b74Schristos    accordingly.  */
39075fd0b74Schristos 
391*e992f068Schristos static int
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)39275fd0b74Schristos m32c_elf_relocate_section
39375fd0b74Schristos     (bfd *		     output_bfd ATTRIBUTE_UNUSED,
39475fd0b74Schristos      struct bfd_link_info *  info,
39575fd0b74Schristos      bfd *		     input_bfd,
39675fd0b74Schristos      asection *		     input_section,
39775fd0b74Schristos      bfd_byte *		     contents,
39875fd0b74Schristos      Elf_Internal_Rela *     relocs,
39975fd0b74Schristos      Elf_Internal_Sym *	     local_syms,
40075fd0b74Schristos      asection **	     local_sections)
40175fd0b74Schristos {
40275fd0b74Schristos   Elf_Internal_Shdr *		symtab_hdr;
40375fd0b74Schristos   struct elf_link_hash_entry ** sym_hashes;
40475fd0b74Schristos   Elf_Internal_Rela *		rel;
40575fd0b74Schristos   Elf_Internal_Rela *		relend;
40675fd0b74Schristos   asection *splt;
40775fd0b74Schristos 
40875fd0b74Schristos   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
40975fd0b74Schristos   sym_hashes = elf_sym_hashes (input_bfd);
41075fd0b74Schristos   relend     = relocs + input_section->reloc_count;
41175fd0b74Schristos 
412ede78133Schristos   splt = elf_hash_table (info)->splt;
41375fd0b74Schristos 
41475fd0b74Schristos   for (rel = relocs; rel < relend; rel ++)
41575fd0b74Schristos     {
41675fd0b74Schristos       reloc_howto_type *	   howto;
41775fd0b74Schristos       unsigned long		   r_symndx;
41875fd0b74Schristos       Elf_Internal_Sym *	   sym;
41975fd0b74Schristos       asection *		   sec;
42075fd0b74Schristos       struct elf_link_hash_entry * h;
42175fd0b74Schristos       bfd_vma			   relocation;
42275fd0b74Schristos       bfd_reloc_status_type	   r;
42375fd0b74Schristos       const char *		   name = NULL;
42475fd0b74Schristos       int			   r_type;
42575fd0b74Schristos 
42675fd0b74Schristos       r_type = ELF32_R_TYPE (rel->r_info);
42775fd0b74Schristos 
42875fd0b74Schristos       /* These are only used for relaxing; we don't actually relocate
42975fd0b74Schristos 	 anything with them, so skip them.  */
43075fd0b74Schristos       if (r_type == R_M32C_RL_JUMP
43175fd0b74Schristos 	  || r_type == R_M32C_RL_1ADDR
43275fd0b74Schristos 	  || r_type == R_M32C_RL_2ADDR)
43375fd0b74Schristos 	continue;
43475fd0b74Schristos 
43575fd0b74Schristos       r_symndx = ELF32_R_SYM (rel->r_info);
43675fd0b74Schristos 
43775fd0b74Schristos       howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
43875fd0b74Schristos       h      = NULL;
43975fd0b74Schristos       sym    = NULL;
44075fd0b74Schristos       sec    = NULL;
44175fd0b74Schristos       relocation = 0;
44275fd0b74Schristos 
44375fd0b74Schristos       if (r_symndx < symtab_hdr->sh_info)
44475fd0b74Schristos 	{
44575fd0b74Schristos 	  sym = local_syms + r_symndx;
44675fd0b74Schristos 	  sec = local_sections [r_symndx];
44775fd0b74Schristos 	  relocation = (sec->output_section->vma
44875fd0b74Schristos 			+ sec->output_offset
44975fd0b74Schristos 			+ sym->st_value);
45075fd0b74Schristos 
45175fd0b74Schristos 	  name = bfd_elf_string_from_elf_section
45275fd0b74Schristos 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
453012573ebSchristos 	  name = sym->st_name == 0 ? bfd_section_name (sec) : name;
45475fd0b74Schristos 	}
45575fd0b74Schristos       else
45675fd0b74Schristos 	{
45775fd0b74Schristos 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
45875fd0b74Schristos 
45975fd0b74Schristos 	  if (info->wrap_hash != NULL
46075fd0b74Schristos 	      && (input_section->flags & SEC_DEBUGGING) != 0)
46175fd0b74Schristos 	    h = ((struct elf_link_hash_entry *)
46275fd0b74Schristos 		 unwrap_hash_lookup (info, input_bfd, &h->root));
46375fd0b74Schristos 
46475fd0b74Schristos 	  while (h->root.type == bfd_link_hash_indirect
46575fd0b74Schristos 		 || h->root.type == bfd_link_hash_warning)
46675fd0b74Schristos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
46775fd0b74Schristos 
46875fd0b74Schristos 	  name = h->root.root.string;
46975fd0b74Schristos 
47075fd0b74Schristos 	  if (h->root.type == bfd_link_hash_defined
47175fd0b74Schristos 	      || h->root.type == bfd_link_hash_defweak)
47275fd0b74Schristos 	    {
47375fd0b74Schristos 	      sec = h->root.u.def.section;
47475fd0b74Schristos 	      relocation = (h->root.u.def.value
47575fd0b74Schristos 			    + sec->output_section->vma
47675fd0b74Schristos 			    + sec->output_offset);
47775fd0b74Schristos 	    }
47875fd0b74Schristos 	  else if (h->root.type == bfd_link_hash_undefweak)
47975fd0b74Schristos 	    ;
48075fd0b74Schristos 	  else if (!bfd_link_relocatable (info))
48175fd0b74Schristos 	    (*info->callbacks->undefined_symbol) (info, h->root.root.string,
48275fd0b74Schristos 						  input_bfd, input_section,
483*e992f068Schristos 						  rel->r_offset, true);
48475fd0b74Schristos 	}
48575fd0b74Schristos 
48675fd0b74Schristos       if (sec != NULL && discarded_section (sec))
48775fd0b74Schristos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
48875fd0b74Schristos 					 rel, 1, relend, howto, 0, contents);
48975fd0b74Schristos 
49075fd0b74Schristos       if (bfd_link_relocatable (info))
49175fd0b74Schristos 	{
49275fd0b74Schristos 	  /* This is a relocatable link.  We don't have to change
49375fd0b74Schristos 	     anything, unless the reloc is against a section symbol,
49475fd0b74Schristos 	     in which case we have to adjust according to where the
49575fd0b74Schristos 	     section symbol winds up in the output section.  */
49675fd0b74Schristos 	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
49775fd0b74Schristos 	    rel->r_addend += sec->output_offset;
49875fd0b74Schristos 	  continue;
49975fd0b74Schristos 	}
50075fd0b74Schristos 
50175fd0b74Schristos       switch (ELF32_R_TYPE (rel->r_info))
50275fd0b74Schristos 	{
50375fd0b74Schristos 	case R_M32C_16:
50475fd0b74Schristos 	  {
50575fd0b74Schristos 	    bfd_vma *plt_offset;
50675fd0b74Schristos 
50775fd0b74Schristos 	    if (h != NULL)
50875fd0b74Schristos 	      plt_offset = &h->plt.offset;
50975fd0b74Schristos 	    else
51075fd0b74Schristos 	      plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
51175fd0b74Schristos 
51275fd0b74Schristos 	    /*	    printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
51375fd0b74Schristos 		    relocation, *plt_offset);*/
51475fd0b74Schristos 	    if (relocation <= 0xffff)
51575fd0b74Schristos 	      {
51675fd0b74Schristos 		/* If the symbol is in range for a 16-bit address, we should
51775fd0b74Schristos 		   have deallocated the plt entry in relax_section.  */
51875fd0b74Schristos 		BFD_ASSERT (*plt_offset == (bfd_vma) -1);
51975fd0b74Schristos 	      }
52075fd0b74Schristos 	    else
52175fd0b74Schristos 	      {
52275fd0b74Schristos 		/* If the symbol is out of range for a 16-bit address,
52375fd0b74Schristos 		   we must have allocated a plt entry.  */
52475fd0b74Schristos 		BFD_ASSERT (*plt_offset != (bfd_vma) -1);
52575fd0b74Schristos 
52675fd0b74Schristos 		/* If this is the first time we've processed this symbol,
52775fd0b74Schristos 		   fill in the plt entry with the correct symbol address.  */
52875fd0b74Schristos 		if ((*plt_offset & 1) == 0)
52975fd0b74Schristos 		  {
53075fd0b74Schristos 		    unsigned int x;
53175fd0b74Schristos 
53275fd0b74Schristos 		    x = 0x000000fc;  /* jmpf */
53375fd0b74Schristos 		    x |= (relocation << 8) & 0xffffff00;
53475fd0b74Schristos 		    bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
53575fd0b74Schristos 		    *plt_offset |= 1;
53675fd0b74Schristos 		  }
53775fd0b74Schristos 
53875fd0b74Schristos 		relocation = (splt->output_section->vma
53975fd0b74Schristos 			      + splt->output_offset
54075fd0b74Schristos 			      + (*plt_offset & -2));
54175fd0b74Schristos 		if (name)
54275fd0b74Schristos 		{
54375fd0b74Schristos 		  char *newname = bfd_malloc (strlen(name)+5);
54475fd0b74Schristos 		  strcpy (newname, name);
54575fd0b74Schristos 		  strcat(newname, ".plt");
54675fd0b74Schristos 		  _bfd_generic_link_add_one_symbol (info,
54775fd0b74Schristos 						    input_bfd,
54875fd0b74Schristos 						    newname,
54975fd0b74Schristos 						    BSF_FUNCTION | BSF_WEAK,
55075fd0b74Schristos 						    splt,
55175fd0b74Schristos 						    (*plt_offset & -2),
55275fd0b74Schristos 						    0,
55375fd0b74Schristos 						    1,
55475fd0b74Schristos 						    0,
55575fd0b74Schristos 						    0);
55675fd0b74Schristos 		}
55775fd0b74Schristos 	      }
55875fd0b74Schristos 	  }
55975fd0b74Schristos 	  break;
56075fd0b74Schristos 
56175fd0b74Schristos 	case R_M32C_HI8:
56275fd0b74Schristos 	case R_M32C_HI16:
56375fd0b74Schristos 	  relocation >>= 16;
56475fd0b74Schristos 	  break;
56575fd0b74Schristos 	}
56675fd0b74Schristos 
56775fd0b74Schristos #if 0
56875fd0b74Schristos       printf ("relocate %s at %06lx relocation %06lx addend %ld  ",
56975fd0b74Schristos 	      m32c_elf_howto_table[ELF32_R_TYPE(rel->r_info)].name,
57075fd0b74Schristos 	      rel->r_offset + input_section->output_section->vma + input_section->output_offset,
57175fd0b74Schristos 	      relocation, rel->r_addend);
57275fd0b74Schristos       {
57375fd0b74Schristos 	int i;
57475fd0b74Schristos 	for (i=0; i<4; i++)
57575fd0b74Schristos 	  printf (" %02x", contents[rel->r_offset+i]);
57675fd0b74Schristos 	printf ("\n");
57775fd0b74Schristos       }
57875fd0b74Schristos #endif
57975fd0b74Schristos       switch (ELF32_R_TYPE(rel->r_info))
58075fd0b74Schristos 	{
58175fd0b74Schristos 	case R_M32C_24:
58275fd0b74Schristos 	  /* Like m32c_apply_reloc_24, we must handle this one separately.  */
58375fd0b74Schristos 	  relocation += rel->r_addend;
58475fd0b74Schristos 
58575fd0b74Schristos 	  /* Sanity check the address.  */
58675fd0b74Schristos 	  if (rel->r_offset + 3
58775fd0b74Schristos 	      > bfd_get_section_limit_octets (input_bfd, input_section))
58875fd0b74Schristos 	    r = bfd_reloc_outofrange;
58975fd0b74Schristos 	  else
59075fd0b74Schristos 	    {
59175fd0b74Schristos 	      bfd_put_8 (input_bfd, relocation & 0xff, contents + rel->r_offset);
59275fd0b74Schristos 	      bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, contents + rel->r_offset + 1);
59375fd0b74Schristos 	      bfd_put_8 (input_bfd, (relocation >> 16) & 0xff, contents + rel->r_offset + 2);
59475fd0b74Schristos 	      r = bfd_reloc_ok;
59575fd0b74Schristos 	    }
59675fd0b74Schristos 
59775fd0b74Schristos 	  break;
59875fd0b74Schristos 
59975fd0b74Schristos 	default:
60075fd0b74Schristos 	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
60175fd0b74Schristos 					contents, rel->r_offset, relocation,
60275fd0b74Schristos 					rel->r_addend);
60375fd0b74Schristos 	  break;
60475fd0b74Schristos 	}
60575fd0b74Schristos 
60675fd0b74Schristos       if (r != bfd_reloc_ok)
60775fd0b74Schristos 	{
60875fd0b74Schristos 	  const char * msg = (const char *) NULL;
60975fd0b74Schristos 
61075fd0b74Schristos 	  switch (r)
61175fd0b74Schristos 	    {
61275fd0b74Schristos 	    case bfd_reloc_overflow:
61375fd0b74Schristos 	      (*info->callbacks->reloc_overflow)
61475fd0b74Schristos 		(info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
61575fd0b74Schristos 		 input_bfd, input_section, rel->r_offset);
61675fd0b74Schristos 	      break;
61775fd0b74Schristos 
61875fd0b74Schristos 	    case bfd_reloc_undefined:
61975fd0b74Schristos 	      (*info->callbacks->undefined_symbol)
620*e992f068Schristos 		(info, name, input_bfd, input_section, rel->r_offset, true);
62175fd0b74Schristos 	      break;
62275fd0b74Schristos 
62375fd0b74Schristos 	    case bfd_reloc_outofrange:
62475fd0b74Schristos 	      msg = _("internal error: out of range error");
62575fd0b74Schristos 	      break;
62675fd0b74Schristos 
62775fd0b74Schristos 	    case bfd_reloc_notsupported:
62875fd0b74Schristos 	      msg = _("internal error: unsupported relocation error");
62975fd0b74Schristos 	      break;
63075fd0b74Schristos 
63175fd0b74Schristos 	    case bfd_reloc_dangerous:
63275fd0b74Schristos 	      msg = _("internal error: dangerous relocation");
63375fd0b74Schristos 	      break;
63475fd0b74Schristos 
63575fd0b74Schristos 	    default:
63675fd0b74Schristos 	      msg = _("internal error: unknown error");
63775fd0b74Schristos 	      break;
63875fd0b74Schristos 	    }
63975fd0b74Schristos 
64075fd0b74Schristos 	  if (msg)
64175fd0b74Schristos 	    (*info->callbacks->warning) (info, msg, name, input_bfd,
64275fd0b74Schristos 					 input_section, rel->r_offset);
64375fd0b74Schristos 	}
64475fd0b74Schristos     }
64575fd0b74Schristos 
646*e992f068Schristos   return true;
64775fd0b74Schristos }
64875fd0b74Schristos 
64975fd0b74Schristos /* We support 16-bit pointers to code above 64k by generating a thunk
65075fd0b74Schristos    below 64k containing a JMP instruction to the final address.  */
65175fd0b74Schristos 
652*e992f068Schristos static bool
m32c_elf_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)65375fd0b74Schristos m32c_elf_check_relocs
65475fd0b74Schristos     (bfd *		       abfd,
65575fd0b74Schristos      struct bfd_link_info *    info,
65675fd0b74Schristos      asection *		       sec,
65775fd0b74Schristos      const Elf_Internal_Rela * relocs)
65875fd0b74Schristos {
65975fd0b74Schristos   Elf_Internal_Shdr *		symtab_hdr;
66075fd0b74Schristos   struct elf_link_hash_entry ** sym_hashes;
66175fd0b74Schristos   const Elf_Internal_Rela *	rel;
66275fd0b74Schristos   const Elf_Internal_Rela *	rel_end;
66375fd0b74Schristos   bfd_vma *local_plt_offsets;
66475fd0b74Schristos   asection *splt;
66575fd0b74Schristos   bfd *dynobj;
66675fd0b74Schristos 
66775fd0b74Schristos   if (bfd_link_relocatable (info))
668*e992f068Schristos     return true;
66975fd0b74Schristos 
67075fd0b74Schristos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
67175fd0b74Schristos   sym_hashes = elf_sym_hashes (abfd);
67275fd0b74Schristos   local_plt_offsets = elf_local_got_offsets (abfd);
67375fd0b74Schristos   splt = NULL;
67475fd0b74Schristos   dynobj = elf_hash_table(info)->dynobj;
67575fd0b74Schristos 
67675fd0b74Schristos   rel_end = relocs + sec->reloc_count;
67775fd0b74Schristos   for (rel = relocs; rel < rel_end; rel++)
67875fd0b74Schristos     {
67975fd0b74Schristos       struct elf_link_hash_entry *h;
68075fd0b74Schristos       unsigned long r_symndx;
68175fd0b74Schristos       bfd_vma *offset;
68275fd0b74Schristos 
68375fd0b74Schristos       r_symndx = ELF32_R_SYM (rel->r_info);
68475fd0b74Schristos       if (r_symndx < symtab_hdr->sh_info)
68575fd0b74Schristos 	h = NULL;
68675fd0b74Schristos       else
68775fd0b74Schristos 	{
68875fd0b74Schristos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
68975fd0b74Schristos 	  while (h->root.type == bfd_link_hash_indirect
69075fd0b74Schristos 		 || h->root.type == bfd_link_hash_warning)
69175fd0b74Schristos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
69275fd0b74Schristos 	}
69375fd0b74Schristos 
69475fd0b74Schristos       switch (ELF32_R_TYPE (rel->r_info))
69575fd0b74Schristos 	{
69675fd0b74Schristos 	  /* This relocation describes a 16-bit pointer to a function.
69775fd0b74Schristos 	     We may need to allocate a thunk in low memory; reserve memory
69875fd0b74Schristos 	     for it now.  */
69975fd0b74Schristos 	case R_M32C_16:
70075fd0b74Schristos 	  if (dynobj == NULL)
70175fd0b74Schristos 	    elf_hash_table (info)->dynobj = dynobj = abfd;
702ede78133Schristos 	  splt = elf_hash_table (info)->splt;
70375fd0b74Schristos 	  if (splt == NULL)
70475fd0b74Schristos 	    {
70575fd0b74Schristos 	      flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
70675fd0b74Schristos 				| SEC_IN_MEMORY | SEC_LINKER_CREATED
70775fd0b74Schristos 				| SEC_READONLY | SEC_CODE);
70875fd0b74Schristos 	      splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
70975fd0b74Schristos 							 flags);
710ede78133Schristos 	      elf_hash_table (info)->splt = splt;
71175fd0b74Schristos 	      if (splt == NULL
712012573ebSchristos 		  || !bfd_set_section_alignment (splt, 1))
713*e992f068Schristos 		return false;
71475fd0b74Schristos 	    }
71575fd0b74Schristos 
71675fd0b74Schristos 	  if (h != NULL)
71775fd0b74Schristos 	    offset = &h->plt.offset;
71875fd0b74Schristos 	  else
71975fd0b74Schristos 	    {
72075fd0b74Schristos 	      if (local_plt_offsets == NULL)
72175fd0b74Schristos 		{
72275fd0b74Schristos 		  size_t size;
72375fd0b74Schristos 		  unsigned int i;
72475fd0b74Schristos 
72575fd0b74Schristos 		  size = symtab_hdr->sh_info * sizeof (bfd_vma);
72675fd0b74Schristos 		  local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
72775fd0b74Schristos 		  if (local_plt_offsets == NULL)
728*e992f068Schristos 		    return false;
72975fd0b74Schristos 		  elf_local_got_offsets (abfd) = local_plt_offsets;
73075fd0b74Schristos 
73175fd0b74Schristos 		  for (i = 0; i < symtab_hdr->sh_info; i++)
73275fd0b74Schristos 		    local_plt_offsets[i] = (bfd_vma) -1;
73375fd0b74Schristos 		}
73475fd0b74Schristos 	      offset = &local_plt_offsets[r_symndx];
73575fd0b74Schristos 	    }
73675fd0b74Schristos 
73775fd0b74Schristos 	  if (*offset == (bfd_vma) -1)
73875fd0b74Schristos 	    {
73975fd0b74Schristos 	      *offset = splt->size;
74075fd0b74Schristos 	      splt->size += 4;
74175fd0b74Schristos 	    }
74275fd0b74Schristos 	  break;
74375fd0b74Schristos 	}
74475fd0b74Schristos     }
74575fd0b74Schristos 
746*e992f068Schristos   return true;
74775fd0b74Schristos }
74875fd0b74Schristos 
74975fd0b74Schristos /* This must exist if dynobj is ever set.  */
75075fd0b74Schristos 
751*e992f068Schristos static bool
m32c_elf_finish_dynamic_sections(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)75275fd0b74Schristos m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
75375fd0b74Schristos 				  struct bfd_link_info *info)
75475fd0b74Schristos {
755ede78133Schristos   bfd *dynobj = elf_hash_table (info)->dynobj;
756ede78133Schristos   asection *splt = elf_hash_table (info)->splt;
75775fd0b74Schristos 
75875fd0b74Schristos   /* As an extra sanity check, verify that all plt entries have
75975fd0b74Schristos      been filled in.  */
76075fd0b74Schristos 
761ede78133Schristos   if (dynobj != NULL && splt != NULL)
76275fd0b74Schristos     {
76375fd0b74Schristos       bfd_byte *contents = splt->contents;
76475fd0b74Schristos       unsigned int i, size = splt->size;
76575fd0b74Schristos       for (i = 0; i < size; i += 4)
76675fd0b74Schristos 	{
76775fd0b74Schristos 	  unsigned int x = bfd_get_32 (dynobj, contents + i);
76875fd0b74Schristos 	  BFD_ASSERT (x != 0);
76975fd0b74Schristos 	}
77075fd0b74Schristos     }
77175fd0b74Schristos 
772*e992f068Schristos   return true;
77375fd0b74Schristos }
77475fd0b74Schristos 
775*e992f068Schristos static bool
m32c_elf_always_size_sections(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)77675fd0b74Schristos m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
77775fd0b74Schristos 			       struct bfd_link_info *info)
77875fd0b74Schristos {
77975fd0b74Schristos   bfd *dynobj;
78075fd0b74Schristos   asection *splt;
78175fd0b74Schristos 
78275fd0b74Schristos   if (bfd_link_relocatable (info))
783*e992f068Schristos     return true;
78475fd0b74Schristos 
78575fd0b74Schristos   dynobj = elf_hash_table (info)->dynobj;
78675fd0b74Schristos   if (dynobj == NULL)
787*e992f068Schristos     return true;
78875fd0b74Schristos 
789ede78133Schristos   splt = elf_hash_table (info)->splt;
79075fd0b74Schristos   BFD_ASSERT (splt != NULL);
79175fd0b74Schristos 
79275fd0b74Schristos   splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
79375fd0b74Schristos   if (splt->contents == NULL)
794*e992f068Schristos     return false;
79575fd0b74Schristos 
796*e992f068Schristos   return true;
79775fd0b74Schristos }
79875fd0b74Schristos 
79975fd0b74Schristos /* Function to set the ELF flag bits.  */
80075fd0b74Schristos 
801*e992f068Schristos static bool
m32c_elf_set_private_flags(bfd * abfd,flagword flags)80275fd0b74Schristos m32c_elf_set_private_flags (bfd *abfd, flagword flags)
80375fd0b74Schristos {
80475fd0b74Schristos   elf_elfheader (abfd)->e_flags = flags;
805*e992f068Schristos   elf_flags_init (abfd) = true;
806*e992f068Schristos   return true;
80775fd0b74Schristos }
80875fd0b74Schristos 
80975fd0b74Schristos /* Merge backend specific data from an object file to the output
81075fd0b74Schristos    object file when linking.  */
81175fd0b74Schristos 
812*e992f068Schristos static bool
m32c_elf_merge_private_bfd_data(bfd * ibfd,struct bfd_link_info * info)813ede78133Schristos m32c_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
81475fd0b74Schristos {
815ede78133Schristos   bfd *obfd = info->output_bfd;
81675fd0b74Schristos   flagword old_flags, old_partial;
81775fd0b74Schristos   flagword new_flags, new_partial;
818*e992f068Schristos   bool error = false;
81975fd0b74Schristos   char new_opt[80];
82075fd0b74Schristos   char old_opt[80];
82175fd0b74Schristos 
82275fd0b74Schristos   new_opt[0] = old_opt[0] = '\0';
82375fd0b74Schristos   new_flags = elf_elfheader (ibfd)->e_flags;
82475fd0b74Schristos   old_flags = elf_elfheader (obfd)->e_flags;
82575fd0b74Schristos 
82675fd0b74Schristos #ifdef DEBUG
827ede78133Schristos   _bfd_error_handler
828ede78133Schristos     ("old_flags = 0x%.8x, new_flags = 0x%.8x, init = %s, filename = %s",
82975fd0b74Schristos      old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
83075fd0b74Schristos      bfd_get_filename (ibfd));
83175fd0b74Schristos #endif
83275fd0b74Schristos 
83375fd0b74Schristos   if (!elf_flags_init (obfd))
83475fd0b74Schristos     {
83575fd0b74Schristos       /* First call, no flags set.  */
836*e992f068Schristos       elf_flags_init (obfd) = true;
83775fd0b74Schristos       elf_elfheader (obfd)->e_flags = new_flags;
83875fd0b74Schristos     }
83975fd0b74Schristos 
84075fd0b74Schristos   else if (new_flags == old_flags)
84175fd0b74Schristos     /* Compatible flags are ok.	 */
84275fd0b74Schristos     ;
84375fd0b74Schristos 
84475fd0b74Schristos   else		/* Possibly incompatible flags.	 */
84575fd0b74Schristos     {
84675fd0b74Schristos       /* Warn if different cpu is used (allow a specific cpu to override
84775fd0b74Schristos 	 the generic cpu).  */
84875fd0b74Schristos       new_partial = (new_flags & EF_M32C_CPU_MASK);
84975fd0b74Schristos       old_partial = (old_flags & EF_M32C_CPU_MASK);
85075fd0b74Schristos       if (new_partial == old_partial)
85175fd0b74Schristos 	;
85275fd0b74Schristos 
85375fd0b74Schristos       else
85475fd0b74Schristos 	{
85575fd0b74Schristos 	  switch (new_partial)
85675fd0b74Schristos 	    {
85775fd0b74Schristos 	    default:		  strcat (new_opt, " -m16c");	break;
85875fd0b74Schristos 	    case EF_M32C_CPU_M16C:	strcat (new_opt, " -m16c");  break;
85975fd0b74Schristos 	    case EF_M32C_CPU_M32C:  strcat (new_opt, " -m32c");  break;
86075fd0b74Schristos 	    }
86175fd0b74Schristos 
86275fd0b74Schristos 	  switch (old_partial)
86375fd0b74Schristos 	    {
86475fd0b74Schristos 	    default:		  strcat (old_opt, " -m16c");	break;
86575fd0b74Schristos 	    case EF_M32C_CPU_M16C:	strcat (old_opt, " -m16c");  break;
86675fd0b74Schristos 	    case EF_M32C_CPU_M32C:  strcat (old_opt, " -m32c");  break;
86775fd0b74Schristos 	    }
86875fd0b74Schristos 	}
86975fd0b74Schristos 
87075fd0b74Schristos       /* Print out any mismatches from above.  */
87175fd0b74Schristos       if (new_opt[0])
87275fd0b74Schristos 	{
873*e992f068Schristos 	  error = true;
874ede78133Schristos 	  _bfd_error_handler
875ede78133Schristos 	    /* xgettext:c-format */
876ede78133Schristos 	    (_("%pB: compiled with %s and linked with modules compiled with %s"),
877ede78133Schristos 	     ibfd, new_opt, old_opt);
87875fd0b74Schristos 	}
87975fd0b74Schristos 
88075fd0b74Schristos       new_flags &= ~ EF_M32C_ALL_FLAGS;
88175fd0b74Schristos       old_flags &= ~ EF_M32C_ALL_FLAGS;
88275fd0b74Schristos 
88375fd0b74Schristos       /* Warn about any other mismatches.  */
88475fd0b74Schristos       if (new_flags != old_flags)
88575fd0b74Schristos 	{
886*e992f068Schristos 	  error = true;
887ede78133Schristos 	  _bfd_error_handler
888ede78133Schristos 	    /* xgettext:c-format */
889ede78133Schristos 	    (_("%pB: uses different e_flags (%#x) fields"
890ede78133Schristos 	       " than previous modules (%#x)"),
891ede78133Schristos 	     ibfd, new_flags, old_flags);
89275fd0b74Schristos 	}
89375fd0b74Schristos     }
89475fd0b74Schristos 
89575fd0b74Schristos   if (error)
89675fd0b74Schristos     bfd_set_error (bfd_error_bad_value);
89775fd0b74Schristos 
89875fd0b74Schristos   return !error;
89975fd0b74Schristos }
90075fd0b74Schristos 
90175fd0b74Schristos 
902*e992f068Schristos static bool
m32c_elf_print_private_bfd_data(bfd * abfd,void * ptr)90375fd0b74Schristos m32c_elf_print_private_bfd_data (bfd *abfd, void *ptr)
90475fd0b74Schristos {
90575fd0b74Schristos   FILE *file = (FILE *) ptr;
90675fd0b74Schristos   flagword flags;
90775fd0b74Schristos 
90875fd0b74Schristos   BFD_ASSERT (abfd != NULL && ptr != NULL);
90975fd0b74Schristos 
91075fd0b74Schristos   /* Print normal ELF private data.  */
91175fd0b74Schristos   _bfd_elf_print_private_bfd_data (abfd, ptr);
91275fd0b74Schristos 
91375fd0b74Schristos   flags = elf_elfheader (abfd)->e_flags;
91475fd0b74Schristos   fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
91575fd0b74Schristos 
91675fd0b74Schristos   switch (flags & EF_M32C_CPU_MASK)
91775fd0b74Schristos     {
91875fd0b74Schristos     default:							break;
91975fd0b74Schristos     case EF_M32C_CPU_M16C:	fprintf (file, " -m16c");	break;
92075fd0b74Schristos     case EF_M32C_CPU_M32C:  fprintf (file, " -m32c");	break;
92175fd0b74Schristos     }
92275fd0b74Schristos 
92375fd0b74Schristos   fputc ('\n', file);
924*e992f068Schristos   return true;
92575fd0b74Schristos }
92675fd0b74Schristos 
92775fd0b74Schristos /* Return the MACH for an e_flags value.  */
92875fd0b74Schristos 
92975fd0b74Schristos static int
elf32_m32c_machine(bfd * abfd)93075fd0b74Schristos elf32_m32c_machine (bfd *abfd)
93175fd0b74Schristos {
93275fd0b74Schristos   switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
93375fd0b74Schristos     {
93475fd0b74Schristos     case EF_M32C_CPU_M16C:	return bfd_mach_m16c;
93575fd0b74Schristos     case EF_M32C_CPU_M32C:	return bfd_mach_m32c;
93675fd0b74Schristos     }
93775fd0b74Schristos 
93875fd0b74Schristos   return bfd_mach_m16c;
93975fd0b74Schristos }
94075fd0b74Schristos 
941*e992f068Schristos static bool
m32c_elf_object_p(bfd * abfd)94275fd0b74Schristos m32c_elf_object_p (bfd *abfd)
94375fd0b74Schristos {
94475fd0b74Schristos   bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
94575fd0b74Schristos 			     elf32_m32c_machine (abfd));
946*e992f068Schristos   return true;
94775fd0b74Schristos }
94875fd0b74Schristos 
94975fd0b74Schristos 
95075fd0b74Schristos #ifdef DEBUG
95175fd0b74Schristos void
dump_symtab(bfd * abfd,void * internal_syms,void * external_syms)95275fd0b74Schristos dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
95375fd0b74Schristos {
95475fd0b74Schristos   size_t locsymcount;
95575fd0b74Schristos   Elf_Internal_Sym *isymbuf;
95675fd0b74Schristos   Elf_Internal_Sym *isymend;
95775fd0b74Schristos   Elf_Internal_Sym *isym;
95875fd0b74Schristos   Elf_Internal_Shdr *symtab_hdr;
959*e992f068Schristos   bool free_internal = 0, free_external = 0;
96075fd0b74Schristos   char * st_info_str;
96175fd0b74Schristos   char * st_info_stb_str;
96275fd0b74Schristos   char * st_other_str;
96375fd0b74Schristos   char * st_shndx_str;
96475fd0b74Schristos 
96575fd0b74Schristos   if (! internal_syms)
96675fd0b74Schristos     {
96775fd0b74Schristos       internal_syms = bfd_malloc (1000);
96875fd0b74Schristos       free_internal = 1;
96975fd0b74Schristos     }
97075fd0b74Schristos   if (! external_syms)
97175fd0b74Schristos     {
97275fd0b74Schristos       external_syms = bfd_malloc (1000);
97375fd0b74Schristos       free_external = 1;
97475fd0b74Schristos     }
97575fd0b74Schristos 
97675fd0b74Schristos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
97775fd0b74Schristos   locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
97875fd0b74Schristos   if (free_internal)
97975fd0b74Schristos     isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
98075fd0b74Schristos 				    symtab_hdr->sh_info, 0,
98175fd0b74Schristos 				    internal_syms, external_syms, NULL);
98275fd0b74Schristos   else
98375fd0b74Schristos     isymbuf = internal_syms;
98475fd0b74Schristos   isymend = isymbuf + locsymcount;
98575fd0b74Schristos 
98675fd0b74Schristos   for (isym = isymbuf ; isym < isymend ; isym++)
98775fd0b74Schristos     {
98875fd0b74Schristos       switch (ELF_ST_TYPE (isym->st_info))
98975fd0b74Schristos 	{
99075fd0b74Schristos 	case STT_FUNC:
99175fd0b74Schristos 	  st_info_str = "STT_FUNC";
99275fd0b74Schristos 	  break;
99375fd0b74Schristos 
99475fd0b74Schristos 	case STT_SECTION:
99575fd0b74Schristos 	  st_info_str = "STT_SECTION";
99675fd0b74Schristos 	  break;
99775fd0b74Schristos 
99875fd0b74Schristos 	case STT_FILE:
99975fd0b74Schristos 	  st_info_str = "STT_FILE";
100075fd0b74Schristos 	  break;
100175fd0b74Schristos 
100275fd0b74Schristos 	case STT_OBJECT:
100375fd0b74Schristos 	  st_info_str = "STT_OBJECT";
100475fd0b74Schristos 	  break;
100575fd0b74Schristos 
100675fd0b74Schristos 	case STT_TLS:
100775fd0b74Schristos 	  st_info_str = "STT_TLS";
100875fd0b74Schristos 	  break;
100975fd0b74Schristos 
101075fd0b74Schristos 	default:
101175fd0b74Schristos 	  st_info_str = "";
101275fd0b74Schristos 	}
101375fd0b74Schristos 
101475fd0b74Schristos       switch (ELF_ST_BIND (isym->st_info))
101575fd0b74Schristos 	{
101675fd0b74Schristos 	case STB_LOCAL:
101775fd0b74Schristos 	  st_info_stb_str = "STB_LOCAL";
101875fd0b74Schristos 	  break;
101975fd0b74Schristos 
102075fd0b74Schristos 	case STB_GLOBAL:
102175fd0b74Schristos 	  st_info_stb_str = "STB_GLOBAL";
102275fd0b74Schristos 	  break;
102375fd0b74Schristos 
102475fd0b74Schristos 	default:
102575fd0b74Schristos 	  st_info_stb_str = "";
102675fd0b74Schristos 	}
102775fd0b74Schristos 
102875fd0b74Schristos       switch (ELF_ST_VISIBILITY (isym->st_other))
102975fd0b74Schristos 	{
103075fd0b74Schristos 	case STV_DEFAULT:
103175fd0b74Schristos 	  st_other_str = "STV_DEFAULT";
103275fd0b74Schristos 	  break;
103375fd0b74Schristos 
103475fd0b74Schristos 	case STV_INTERNAL:
103575fd0b74Schristos 	  st_other_str = "STV_INTERNAL";
103675fd0b74Schristos 	  break;
103775fd0b74Schristos 
103875fd0b74Schristos 	case STV_PROTECTED:
103975fd0b74Schristos 	  st_other_str = "STV_PROTECTED";
104075fd0b74Schristos 	  break;
104175fd0b74Schristos 
104275fd0b74Schristos 	default:
104375fd0b74Schristos 	  st_other_str = "";
104475fd0b74Schristos 	}
104575fd0b74Schristos 
104675fd0b74Schristos       switch (isym->st_shndx)
104775fd0b74Schristos 	{
104875fd0b74Schristos 	case SHN_ABS:
104975fd0b74Schristos 	  st_shndx_str = "SHN_ABS";
105075fd0b74Schristos 	  break;
105175fd0b74Schristos 
105275fd0b74Schristos 	case SHN_COMMON:
105375fd0b74Schristos 	  st_shndx_str = "SHN_COMMON";
105475fd0b74Schristos 	  break;
105575fd0b74Schristos 
105675fd0b74Schristos 	case SHN_UNDEF:
105775fd0b74Schristos 	  st_shndx_str = "SHN_UNDEF";
105875fd0b74Schristos 	  break;
105975fd0b74Schristos 
106075fd0b74Schristos 	default:
106175fd0b74Schristos 	  st_shndx_str = "";
106275fd0b74Schristos 	}
106375fd0b74Schristos 
106475fd0b74Schristos       printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
106575fd0b74Schristos 	      "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
106675fd0b74Schristos 	      isym,
106775fd0b74Schristos 	      (unsigned long) isym->st_value,
106875fd0b74Schristos 	      (unsigned long) isym->st_size,
106975fd0b74Schristos 	      isym->st_name,
107075fd0b74Schristos 	      bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
107175fd0b74Schristos 					       isym->st_name),
107275fd0b74Schristos 	      isym->st_info, st_info_str, st_info_stb_str,
107375fd0b74Schristos 	      isym->st_other, st_other_str,
107475fd0b74Schristos 	      isym->st_shndx, st_shndx_str);
107575fd0b74Schristos     }
107675fd0b74Schristos   if (free_internal)
107775fd0b74Schristos     free (internal_syms);
107875fd0b74Schristos   if (free_external)
107975fd0b74Schristos     free (external_syms);
108075fd0b74Schristos }
108175fd0b74Schristos 
108275fd0b74Schristos char *
m32c_get_reloc(long reloc)108375fd0b74Schristos m32c_get_reloc (long reloc)
108475fd0b74Schristos {
108575fd0b74Schristos   if (0 <= reloc && reloc < R_M32C_max)
108675fd0b74Schristos     return m32c_elf_howto_table[reloc].name;
108775fd0b74Schristos   else
108875fd0b74Schristos     return "";
108975fd0b74Schristos }
109075fd0b74Schristos #endif /* DEBUG */
109175fd0b74Schristos 
109275fd0b74Schristos /* Handle relaxing.  */
109375fd0b74Schristos 
109475fd0b74Schristos /* A subroutine of m32c_elf_relax_section.  If the global symbol H
109575fd0b74Schristos    is within the low 64k, remove any entry for it in the plt.  */
109675fd0b74Schristos 
109775fd0b74Schristos struct relax_plt_data
109875fd0b74Schristos {
109975fd0b74Schristos   asection *splt;
1100*e992f068Schristos   bool *again;
110175fd0b74Schristos };
110275fd0b74Schristos 
1103*e992f068Schristos static bool
m32c_relax_plt_check(struct elf_link_hash_entry * h,void * xdata)110475fd0b74Schristos m32c_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
110575fd0b74Schristos {
110675fd0b74Schristos   struct relax_plt_data *data = (struct relax_plt_data *) xdata;
110775fd0b74Schristos 
110875fd0b74Schristos   if (h->plt.offset != (bfd_vma) -1)
110975fd0b74Schristos     {
111075fd0b74Schristos       bfd_vma address;
111175fd0b74Schristos 
111275fd0b74Schristos       if (h->root.type == bfd_link_hash_undefined
111375fd0b74Schristos 	  || h->root.type == bfd_link_hash_undefweak)
111475fd0b74Schristos 	address = 0;
111575fd0b74Schristos       else
111675fd0b74Schristos 	address = (h->root.u.def.section->output_section->vma
111775fd0b74Schristos 		   + h->root.u.def.section->output_offset
111875fd0b74Schristos 		   + h->root.u.def.value);
111975fd0b74Schristos 
112075fd0b74Schristos       if (address <= 0xffff)
112175fd0b74Schristos 	{
112275fd0b74Schristos 	  h->plt.offset = -1;
112375fd0b74Schristos 	  data->splt->size -= 4;
1124*e992f068Schristos 	  *data->again = true;
112575fd0b74Schristos 	}
112675fd0b74Schristos     }
112775fd0b74Schristos 
1128*e992f068Schristos   return true;
112975fd0b74Schristos }
113075fd0b74Schristos 
113175fd0b74Schristos /* A subroutine of m32c_elf_relax_section.  If the global symbol H
113275fd0b74Schristos    previously had a plt entry, give it a new entry offset.  */
113375fd0b74Schristos 
1134*e992f068Schristos static bool
m32c_relax_plt_realloc(struct elf_link_hash_entry * h,void * xdata)113575fd0b74Schristos m32c_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
113675fd0b74Schristos {
113775fd0b74Schristos   bfd_vma *entry = (bfd_vma *) xdata;
113875fd0b74Schristos 
113975fd0b74Schristos   if (h->plt.offset != (bfd_vma) -1)
114075fd0b74Schristos     {
114175fd0b74Schristos       h->plt.offset = *entry;
114275fd0b74Schristos       *entry += 4;
114375fd0b74Schristos     }
114475fd0b74Schristos 
1145*e992f068Schristos   return true;
114675fd0b74Schristos }
114775fd0b74Schristos 
1148*e992f068Schristos static bool
m32c_elf_relax_plt_section(asection * splt,struct bfd_link_info * info,bool * again)114975fd0b74Schristos m32c_elf_relax_plt_section (asection *splt,
115075fd0b74Schristos 			    struct bfd_link_info *info,
1151*e992f068Schristos 			    bool *again)
115275fd0b74Schristos {
115375fd0b74Schristos   struct relax_plt_data relax_plt_data;
115475fd0b74Schristos   bfd *ibfd;
115575fd0b74Schristos 
115675fd0b74Schristos   /* Assume nothing changes.  */
1157*e992f068Schristos   *again = false;
115875fd0b74Schristos 
115975fd0b74Schristos   if (bfd_link_relocatable (info))
1160*e992f068Schristos     return true;
116175fd0b74Schristos 
116275fd0b74Schristos   /* Quick check for an empty plt.  */
116375fd0b74Schristos   if (splt->size == 0)
1164*e992f068Schristos     return true;
116575fd0b74Schristos 
116675fd0b74Schristos   /* Map across all global symbols; see which ones happen to
116775fd0b74Schristos      fall in the low 64k.  */
116875fd0b74Schristos   relax_plt_data.splt = splt;
116975fd0b74Schristos   relax_plt_data.again = again;
117075fd0b74Schristos   elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
117175fd0b74Schristos 			  &relax_plt_data);
117275fd0b74Schristos 
117375fd0b74Schristos   /* Likewise for local symbols, though that's somewhat less convenient
117475fd0b74Schristos      as we have to walk the list of input bfds and swap in symbol data.  */
117575fd0b74Schristos   for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
117675fd0b74Schristos     {
117775fd0b74Schristos       bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
117875fd0b74Schristos       Elf_Internal_Shdr *symtab_hdr;
117975fd0b74Schristos       Elf_Internal_Sym *isymbuf = NULL;
118075fd0b74Schristos       unsigned int idx;
118175fd0b74Schristos 
118275fd0b74Schristos       if (! local_plt_offsets)
118375fd0b74Schristos 	continue;
118475fd0b74Schristos 
118575fd0b74Schristos       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
118675fd0b74Schristos       if (symtab_hdr->sh_info != 0)
118775fd0b74Schristos 	{
118875fd0b74Schristos 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
118975fd0b74Schristos 	  if (isymbuf == NULL)
119075fd0b74Schristos 	    isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
119175fd0b74Schristos 					    symtab_hdr->sh_info, 0,
119275fd0b74Schristos 					    NULL, NULL, NULL);
119375fd0b74Schristos 	  if (isymbuf == NULL)
1194*e992f068Schristos 	    return false;
119575fd0b74Schristos 	}
119675fd0b74Schristos 
119775fd0b74Schristos       for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
119875fd0b74Schristos 	{
119975fd0b74Schristos 	  Elf_Internal_Sym *isym;
120075fd0b74Schristos 	  asection *tsec;
120175fd0b74Schristos 	  bfd_vma address;
120275fd0b74Schristos 
120375fd0b74Schristos 	  if (local_plt_offsets[idx] == (bfd_vma) -1)
120475fd0b74Schristos 	    continue;
120575fd0b74Schristos 
120675fd0b74Schristos 	  isym = &isymbuf[idx];
120775fd0b74Schristos 	  if (isym->st_shndx == SHN_UNDEF)
120875fd0b74Schristos 	    continue;
120975fd0b74Schristos 	  else if (isym->st_shndx == SHN_ABS)
121075fd0b74Schristos 	    tsec = bfd_abs_section_ptr;
121175fd0b74Schristos 	  else if (isym->st_shndx == SHN_COMMON)
121275fd0b74Schristos 	    tsec = bfd_com_section_ptr;
121375fd0b74Schristos 	  else
121475fd0b74Schristos 	    tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
121575fd0b74Schristos 
121675fd0b74Schristos 	  address = (tsec->output_section->vma
121775fd0b74Schristos 		     + tsec->output_offset
121875fd0b74Schristos 		     + isym->st_value);
121975fd0b74Schristos 	  if (address <= 0xffff)
122075fd0b74Schristos 	    {
122175fd0b74Schristos 	      local_plt_offsets[idx] = -1;
122275fd0b74Schristos 	      splt->size -= 4;
1223*e992f068Schristos 	      *again = true;
122475fd0b74Schristos 	    }
122575fd0b74Schristos 	}
122675fd0b74Schristos 
122775fd0b74Schristos       if (isymbuf != NULL
122875fd0b74Schristos 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
122975fd0b74Schristos 	{
123075fd0b74Schristos 	  if (! info->keep_memory)
123175fd0b74Schristos 	    free (isymbuf);
123275fd0b74Schristos 	  else
123375fd0b74Schristos 	    {
123475fd0b74Schristos 	      /* Cache the symbols for elf_link_input_bfd.  */
123575fd0b74Schristos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
123675fd0b74Schristos 	    }
123775fd0b74Schristos 	}
123875fd0b74Schristos     }
123975fd0b74Schristos 
124075fd0b74Schristos   /* If we changed anything, walk the symbols again to reallocate
124175fd0b74Schristos      .plt entry addresses.  */
124275fd0b74Schristos   if (*again && splt->size > 0)
124375fd0b74Schristos     {
124475fd0b74Schristos       bfd_vma entry = 0;
124575fd0b74Schristos 
124675fd0b74Schristos       elf_link_hash_traverse (elf_hash_table (info),
124775fd0b74Schristos 			      m32c_relax_plt_realloc, &entry);
124875fd0b74Schristos 
124975fd0b74Schristos       for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
125075fd0b74Schristos 	{
125175fd0b74Schristos 	  bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
125275fd0b74Schristos 	  unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
125375fd0b74Schristos 	  unsigned int idx;
125475fd0b74Schristos 
125575fd0b74Schristos 	  if (! local_plt_offsets)
125675fd0b74Schristos 	    continue;
125775fd0b74Schristos 
125875fd0b74Schristos 	  for (idx = 0; idx < nlocals; ++idx)
125975fd0b74Schristos 	    if (local_plt_offsets[idx] != (bfd_vma) -1)
126075fd0b74Schristos 	      {
126175fd0b74Schristos 		local_plt_offsets[idx] = entry;
126275fd0b74Schristos 		entry += 4;
126375fd0b74Schristos 	      }
126475fd0b74Schristos 	}
126575fd0b74Schristos     }
126675fd0b74Schristos 
1267*e992f068Schristos   return true;
126875fd0b74Schristos }
126975fd0b74Schristos 
127075fd0b74Schristos static int
compare_reloc(const void * e1,const void * e2)127175fd0b74Schristos compare_reloc (const void *e1, const void *e2)
127275fd0b74Schristos {
127375fd0b74Schristos   const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
127475fd0b74Schristos   const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
127575fd0b74Schristos 
127675fd0b74Schristos   if (i1->r_offset == i2->r_offset)
127775fd0b74Schristos     return 0;
127875fd0b74Schristos   else
127975fd0b74Schristos     return i1->r_offset < i2->r_offset ? -1 : 1;
128075fd0b74Schristos }
128175fd0b74Schristos 
128275fd0b74Schristos #define OFFSET_FOR_RELOC(rel) m32c_offset_for_reloc (abfd, rel, symtab_hdr, shndx_buf, intsyms)
128375fd0b74Schristos static bfd_vma
m32c_offset_for_reloc(bfd * abfd,Elf_Internal_Rela * rel,Elf_Internal_Shdr * symtab_hdr,bfd_byte * shndx_buf ATTRIBUTE_UNUSED,Elf_Internal_Sym * intsyms)128475fd0b74Schristos m32c_offset_for_reloc (bfd *abfd,
128575fd0b74Schristos 		       Elf_Internal_Rela *rel,
128675fd0b74Schristos 		       Elf_Internal_Shdr *symtab_hdr,
1287*e992f068Schristos 		       bfd_byte *shndx_buf ATTRIBUTE_UNUSED,
128875fd0b74Schristos 		       Elf_Internal_Sym *intsyms)
128975fd0b74Schristos {
129075fd0b74Schristos   bfd_vma symval;
129175fd0b74Schristos 
129275fd0b74Schristos   /* Get the value of the symbol referred to by the reloc.  */
129375fd0b74Schristos   if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
129475fd0b74Schristos     {
129575fd0b74Schristos       /* A local symbol.  */
129675fd0b74Schristos       Elf_Internal_Sym *isym;
129775fd0b74Schristos       asection *ssec;
129875fd0b74Schristos 
129975fd0b74Schristos       isym = intsyms + ELF32_R_SYM (rel->r_info);
130075fd0b74Schristos       ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
130175fd0b74Schristos       symval = isym->st_value;
130275fd0b74Schristos       if (ssec)
130375fd0b74Schristos 	symval += ssec->output_section->vma
130475fd0b74Schristos 	  + ssec->output_offset;
130575fd0b74Schristos     }
130675fd0b74Schristos   else
130775fd0b74Schristos     {
130875fd0b74Schristos       unsigned long indx;
130975fd0b74Schristos       struct elf_link_hash_entry *h;
131075fd0b74Schristos 
131175fd0b74Schristos       /* An external symbol.  */
131275fd0b74Schristos       indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
131375fd0b74Schristos       h = elf_sym_hashes (abfd)[indx];
131475fd0b74Schristos       BFD_ASSERT (h != NULL);
131575fd0b74Schristos 
131675fd0b74Schristos       if (h->root.type != bfd_link_hash_defined
131775fd0b74Schristos 	  && h->root.type != bfd_link_hash_defweak)
131875fd0b74Schristos 	/* This appears to be a reference to an undefined
131975fd0b74Schristos 	   symbol.  Just ignore it--it will be caught by the
132075fd0b74Schristos 	   regular reloc processing.  */
132175fd0b74Schristos 	return 0;
132275fd0b74Schristos 
132375fd0b74Schristos       symval = (h->root.u.def.value
132475fd0b74Schristos 		+ h->root.u.def.section->output_section->vma
132575fd0b74Schristos 		+ h->root.u.def.section->output_offset);
132675fd0b74Schristos     }
132775fd0b74Schristos   return symval;
132875fd0b74Schristos }
132975fd0b74Schristos 
133075fd0b74Schristos static int bytes_saved = 0;
133175fd0b74Schristos 
133275fd0b74Schristos static int bytes_to_reloc[] = {
133375fd0b74Schristos   R_M32C_NONE,
133475fd0b74Schristos   R_M32C_8,
133575fd0b74Schristos   R_M32C_16,
133675fd0b74Schristos   R_M32C_24,
133775fd0b74Schristos   R_M32C_32
133875fd0b74Schristos };
133975fd0b74Schristos 
134075fd0b74Schristos /* What we use the bits in a relax reloc addend (R_M32C_RL_*) for.  */
134175fd0b74Schristos 
134275fd0b74Schristos /* Mask for the number of relocs associated with this insn.  */
134375fd0b74Schristos #define RLA_RELOCS		0x0000000f
134475fd0b74Schristos /* Number of bytes gas emitted (before gas's relaxing) */
134575fd0b74Schristos #define RLA_NBYTES		0x00000ff0
134675fd0b74Schristos 
134775fd0b74Schristos /* If the displacement is within the given range and the new encoding
134875fd0b74Schristos    differs from the old encoding (the index), then the insn can be
134975fd0b74Schristos    relaxed to the new encoding.  */
1350*e992f068Schristos typedef const struct {
135175fd0b74Schristos   int bytes;
135275fd0b74Schristos   unsigned int max_disp;
135375fd0b74Schristos   unsigned char new_encoding;
135475fd0b74Schristos } EncodingTable;
135575fd0b74Schristos 
135675fd0b74Schristos static EncodingTable m16c_addr_encodings[] = {
135775fd0b74Schristos   { 0,   0,  0 }, /* R0 */
135875fd0b74Schristos   { 0,   0,  1 }, /* R1 */
135975fd0b74Schristos   { 0,   0,  2 }, /* R2 */
136075fd0b74Schristos   { 0,   0,  3 }, /* R3 */
136175fd0b74Schristos   { 0,   0,  4 }, /* A0 */
136275fd0b74Schristos   { 0,   0,  5 }, /* A1 */
136375fd0b74Schristos   { 0,   0,  6 }, /* [A0] */
136475fd0b74Schristos   { 0,   0,  7 }, /* [A1] */
136575fd0b74Schristos   { 1,   0,  6 }, /* udsp:8[A0] */
136675fd0b74Schristos   { 1,   0,  7 }, /* udsp:8[A1] */
136775fd0b74Schristos   { 1,   0, 10 }, /* udsp:8[SB] */
136875fd0b74Schristos   { 1,   0, 11 }, /* sdsp:8[FB] */
136975fd0b74Schristos   { 2, 255,  8 }, /* udsp:16[A0] */
137075fd0b74Schristos   { 2, 255,  9 }, /* udsp:16[A1] */
137175fd0b74Schristos   { 2, 255, 10 }, /* udsp:16[SB] */
137275fd0b74Schristos   { 2,   0, 15 }, /* abs:16 */
137375fd0b74Schristos };
137475fd0b74Schristos 
137575fd0b74Schristos static EncodingTable m16c_jmpaddr_encodings[] = {
137675fd0b74Schristos   { 0,   0,  0 }, /* R0 */
137775fd0b74Schristos   { 0,   0,  1 }, /* R1 */
137875fd0b74Schristos   { 0,   0,  2 }, /* R2 */
137975fd0b74Schristos   { 0,   0,  3 }, /* R3 */
138075fd0b74Schristos   { 0,   0,  4 }, /* A0 */
138175fd0b74Schristos   { 0,   0,  5 }, /* A1 */
138275fd0b74Schristos   { 0,   0,  6 }, /* [A0] */
138375fd0b74Schristos   { 0,   0,  7 }, /* [A1] */
138475fd0b74Schristos   { 1,   0,  6 }, /* udsp:8[A0] */
138575fd0b74Schristos   { 1,   0,  7 }, /* udsp:8[A1] */
138675fd0b74Schristos   { 1,   0, 10 }, /* udsp:8[SB] */
138775fd0b74Schristos   { 1,   0, 11 }, /* sdsp:8[FB] */
138875fd0b74Schristos   { 3, 255,  8 }, /* udsp:20[A0] */
138975fd0b74Schristos   { 3, 255,  9 }, /* udsp:20[A1] */
139075fd0b74Schristos   { 2, 255, 10 }, /* udsp:16[SB] */
139175fd0b74Schristos   { 2,   0, 15 }, /* abs:16 */
139275fd0b74Schristos };
139375fd0b74Schristos 
139475fd0b74Schristos static EncodingTable m32c_addr_encodings[] = {
139575fd0b74Schristos   { 0,     0,  0 }, /* [A0] */
139675fd0b74Schristos   { 0,     0,  1 }, /* [A1] */
139775fd0b74Schristos   { 0,     0,  2 }, /* A0 */
139875fd0b74Schristos   { 0,     0,  3 }, /* A1 */
139975fd0b74Schristos   { 1,     0,  0 }, /* udsp:8[A0] */
140075fd0b74Schristos   { 1,     0,  1 }, /* udsp:8[A1] */
140175fd0b74Schristos   { 1,     0,  6 }, /* udsp:8[SB] */
140275fd0b74Schristos   { 1,     0,  7 }, /* sdsp:8[FB] */
140375fd0b74Schristos   { 2,   255,  4 }, /* udsp:16[A0] */
140475fd0b74Schristos   { 2,   255,  5 }, /* udsp:16[A1] */
140575fd0b74Schristos   { 2,   255,  6 }, /* udsp:16[SB] */
140675fd0b74Schristos   { 2,   127,  7 }, /* sdsp:16[FB] */
140775fd0b74Schristos   { 3, 65535, 8 }, /* udsp:24[A0] */
140875fd0b74Schristos   { 3, 65535, 9 }, /* udsp:24[A1] */
140975fd0b74Schristos   { 3, 65535, 15 }, /* abs24 */
141075fd0b74Schristos   { 2,     0, 15 }, /* abs16 */
141175fd0b74Schristos   { 0,     0, 16 }, /* R2 */
141275fd0b74Schristos   { 0,     0, 17 }, /* R3 */
141375fd0b74Schristos   { 0,     0, 18 }, /* R0 */
141475fd0b74Schristos   { 0,     0, 19 }, /* R1 */
141575fd0b74Schristos   { 0,     0, 20 }, /*  */
141675fd0b74Schristos   { 0,     0, 21 }, /*  */
141775fd0b74Schristos   { 0,     0, 22 }, /*  */
141875fd0b74Schristos   { 0,     0, 23 }, /*  */
141975fd0b74Schristos   { 0,     0, 24 }, /*  */
142075fd0b74Schristos   { 0,     0, 25 }, /*  */
142175fd0b74Schristos   { 0,     0, 26 }, /*  */
142275fd0b74Schristos   { 0,     0, 27 }, /*  */
142375fd0b74Schristos   { 0,     0, 28 }, /*  */
142475fd0b74Schristos   { 0,     0, 29 }, /*  */
142575fd0b74Schristos   { 0,     0, 30 }, /*  */
142675fd0b74Schristos   { 0,     0, 31 }, /*  */
142775fd0b74Schristos };
142875fd0b74Schristos 
1429*e992f068Schristos static bool
m32c_elf_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bool * again)1430*e992f068Schristos m32c_elf_relax_section (bfd *abfd,
143175fd0b74Schristos 			asection *sec,
143275fd0b74Schristos 			struct bfd_link_info *link_info,
1433*e992f068Schristos 			bool *again)
143475fd0b74Schristos {
143575fd0b74Schristos   Elf_Internal_Shdr *symtab_hdr;
143675fd0b74Schristos   Elf_Internal_Shdr *shndx_hdr;
143775fd0b74Schristos   Elf_Internal_Rela *internal_relocs;
143875fd0b74Schristos   Elf_Internal_Rela *free_relocs = NULL;
143975fd0b74Schristos   Elf_Internal_Rela *irel, *irelend, *srel;
144075fd0b74Schristos   bfd_byte * contents = NULL;
144175fd0b74Schristos   bfd_byte * free_contents = NULL;
144275fd0b74Schristos   Elf_Internal_Sym *intsyms = NULL;
144375fd0b74Schristos   Elf_Internal_Sym *free_intsyms = NULL;
1444*e992f068Schristos   bfd_byte *shndx_buf = NULL;
144575fd0b74Schristos   int machine;
144675fd0b74Schristos 
1447*e992f068Schristos   if (is_elf_hash_table (link_info->hash)
1448*e992f068Schristos       && abfd == elf_hash_table (link_info)->dynobj
144975fd0b74Schristos       && (sec->flags & SEC_LINKER_CREATED) != 0
145075fd0b74Schristos       && strcmp (sec->name, ".plt") == 0)
145175fd0b74Schristos     return m32c_elf_relax_plt_section (sec, link_info, again);
145275fd0b74Schristos 
145375fd0b74Schristos   /* Assume nothing changes.  */
1454*e992f068Schristos   *again = false;
145575fd0b74Schristos 
145675fd0b74Schristos   machine = elf32_m32c_machine (abfd);
145775fd0b74Schristos 
145875fd0b74Schristos   /* We don't have to do anything for a relocatable link, if
145975fd0b74Schristos      this section does not have relocs, or if this is not a
146075fd0b74Schristos      code section.  */
146175fd0b74Schristos   if (bfd_link_relocatable (link_info)
146275fd0b74Schristos       || (sec->flags & SEC_RELOC) == 0
146375fd0b74Schristos       || sec->reloc_count == 0
146475fd0b74Schristos       || (sec->flags & SEC_CODE) == 0)
1465*e992f068Schristos     return true;
146675fd0b74Schristos 
146775fd0b74Schristos   symtab_hdr = & elf_symtab_hdr (abfd);
146875fd0b74Schristos   if (elf_symtab_shndx_list (abfd))
146975fd0b74Schristos     shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
147075fd0b74Schristos   else
147175fd0b74Schristos     shndx_hdr = NULL;
147275fd0b74Schristos 
147375fd0b74Schristos   /* Get the section contents.  */
147475fd0b74Schristos   if (elf_section_data (sec)->this_hdr.contents != NULL)
147575fd0b74Schristos     contents = elf_section_data (sec)->this_hdr.contents;
147675fd0b74Schristos   /* Go get them off disk.  */
147775fd0b74Schristos   else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
147875fd0b74Schristos     goto error_return;
147975fd0b74Schristos 
148075fd0b74Schristos   /* Read this BFD's symbols.  */
148175fd0b74Schristos   /* Get cached copy if it exists.  */
148275fd0b74Schristos   if (symtab_hdr->contents != NULL)
148375fd0b74Schristos     {
148475fd0b74Schristos       intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
148575fd0b74Schristos     }
148675fd0b74Schristos   else
148775fd0b74Schristos     {
148875fd0b74Schristos       intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
148975fd0b74Schristos       symtab_hdr->contents = (bfd_byte *) intsyms;
149075fd0b74Schristos     }
149175fd0b74Schristos 
149275fd0b74Schristos   if (shndx_hdr && shndx_hdr->sh_size != 0)
149375fd0b74Schristos     {
1494*e992f068Schristos       size_t amt;
149575fd0b74Schristos 
1496*e992f068Schristos       if (_bfd_mul_overflow (symtab_hdr->sh_info,
1497*e992f068Schristos 			     sizeof (Elf_External_Sym_Shndx), &amt))
1498*e992f068Schristos 	{
1499*e992f068Schristos 	  bfd_set_error (bfd_error_file_too_big);
1500*e992f068Schristos 	  goto error_return;
1501*e992f068Schristos 	}
1502*e992f068Schristos       if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0)
1503*e992f068Schristos 	goto error_return;
1504*e992f068Schristos       shndx_buf = _bfd_malloc_and_read (abfd, amt, amt);
150575fd0b74Schristos       if (shndx_buf == NULL)
150675fd0b74Schristos 	goto error_return;
1507*e992f068Schristos       shndx_hdr->contents = shndx_buf;
150875fd0b74Schristos     }
150975fd0b74Schristos 
151075fd0b74Schristos   /* Get a copy of the native relocations.  */
151175fd0b74Schristos   internal_relocs = (_bfd_elf_link_read_relocs
151275fd0b74Schristos 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
151375fd0b74Schristos 		      link_info->keep_memory));
151475fd0b74Schristos   if (internal_relocs == NULL)
151575fd0b74Schristos     goto error_return;
151675fd0b74Schristos   if (! link_info->keep_memory)
151775fd0b74Schristos     free_relocs = internal_relocs;
151875fd0b74Schristos 
151975fd0b74Schristos   /* The RL_ relocs must be just before the operand relocs they go
152075fd0b74Schristos      with, so we must sort them to guarantee this.  */
152175fd0b74Schristos   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
152275fd0b74Schristos 	 compare_reloc);
152375fd0b74Schristos 
152475fd0b74Schristos   /* Walk through them looking for relaxing opportunities.  */
152575fd0b74Schristos   irelend = internal_relocs + sec->reloc_count;
152675fd0b74Schristos 
152775fd0b74Schristos   for (irel = internal_relocs; irel < irelend; irel++)
152875fd0b74Schristos     {
152975fd0b74Schristos       bfd_vma symval;
153075fd0b74Schristos       unsigned char *insn, *gap, *einsn;
153175fd0b74Schristos       bfd_vma pc;
153275fd0b74Schristos       bfd_signed_vma pcrel;
153375fd0b74Schristos       int relax_relocs;
153475fd0b74Schristos       int gap_size;
153575fd0b74Schristos       int new_type;
153675fd0b74Schristos       int posn;
153775fd0b74Schristos       int enc;
153875fd0b74Schristos       EncodingTable *enctbl;
153975fd0b74Schristos       EncodingTable *e;
154075fd0b74Schristos 
154175fd0b74Schristos       if (ELF32_R_TYPE(irel->r_info) != R_M32C_RL_JUMP
154275fd0b74Schristos 	  && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_1ADDR
154375fd0b74Schristos 	  && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_2ADDR)
154475fd0b74Schristos 	continue;
154575fd0b74Schristos 
154675fd0b74Schristos       srel = irel;
154775fd0b74Schristos 
154875fd0b74Schristos       /* There will always be room for the relaxed insn, since it is smaller
154975fd0b74Schristos 	 than the one it would replace.  */
155075fd0b74Schristos       BFD_ASSERT (irel->r_offset < sec->size);
155175fd0b74Schristos 
155275fd0b74Schristos       insn = contents + irel->r_offset;
155375fd0b74Schristos       relax_relocs = irel->r_addend % 16;
155475fd0b74Schristos 
155575fd0b74Schristos       /* Ok, we only have three relocs we care about, and they're all
155675fd0b74Schristos 	 fake.  The lower four bits of the addend is always the number
155775fd0b74Schristos 	 of following relocs (hence the qsort above) that are assigned
155875fd0b74Schristos 	 to this opcode.  The next 8 bits of the addend indicates the
155975fd0b74Schristos 	 number of bytes in the insn.  We use the rest of them
156075fd0b74Schristos 	 ourselves as flags for the more expensive operations (defines
156175fd0b74Schristos 	 above).  The three relocs are:
156275fd0b74Schristos 
156375fd0b74Schristos 	 RL_JUMP: This marks all direct jump insns.  We check the
156475fd0b74Schristos 		displacement and replace them with shorter jumps if
156575fd0b74Schristos 		they're in range.  We also use this to find JMP.S
156675fd0b74Schristos 		insns and manually shorten them when we delete bytes.
156775fd0b74Schristos 		We have to decode these insns to figure out what to
156875fd0b74Schristos 		do.
156975fd0b74Schristos 
157075fd0b74Schristos 	 RL_1ADDR: This is a :G or :Q insn, which has a single
157175fd0b74Schristos 		"standard" operand.  We have to extract the type
157275fd0b74Schristos 		field, see if it's a wide displacement, then figure
157375fd0b74Schristos 		out if we can replace it with a narrow displacement.
157475fd0b74Schristos 		We don't have to decode these insns.
157575fd0b74Schristos 
157675fd0b74Schristos 	 RL_2ADDR: Similarly, but two "standard" operands.  Note that
157775fd0b74Schristos 		r_addend may still be 1, as standard operands don't
157875fd0b74Schristos 		always have displacements.  Gas shouldn't give us one
157975fd0b74Schristos 		with zero operands, but since we don't know which one
158075fd0b74Schristos 		has the displacement, we check them both anyway.
158175fd0b74Schristos 
158275fd0b74Schristos 	 These all point to the beginning of the insn itself, not the
158375fd0b74Schristos 	 operands.
158475fd0b74Schristos 
158575fd0b74Schristos 	 Note that we only relax one step at a time, relying on the
158675fd0b74Schristos 	 linker to call us repeatedly.  Thus, there is no code for
158775fd0b74Schristos 	 JMP.A->JMP.B although that will happen in two steps.
158875fd0b74Schristos 	 Likewise, for 2ADDR relaxes, we do one operand per cycle.
158975fd0b74Schristos       */
159075fd0b74Schristos 
159175fd0b74Schristos       /* Get the value of the symbol referred to by the reloc.  Just
159275fd0b74Schristos 	 in case this is the last reloc in the list, use the RL's
159375fd0b74Schristos 	 addend to choose between this reloc (no addend) or the next
159475fd0b74Schristos 	 (yes addend, which means at least one following reloc).  */
159575fd0b74Schristos       srel = irel + (relax_relocs ? 1 : 0);
159675fd0b74Schristos       symval = OFFSET_FOR_RELOC (srel);
159775fd0b74Schristos 
159875fd0b74Schristos       /* Setting gap_size nonzero is the flag which means "something
159975fd0b74Schristos 	 shrunk".  */
160075fd0b74Schristos       gap_size = 0;
160175fd0b74Schristos       gap = NULL;
160275fd0b74Schristos       new_type = ELF32_R_TYPE(srel->r_info);
160375fd0b74Schristos 
160475fd0b74Schristos       pc = sec->output_section->vma + sec->output_offset
160575fd0b74Schristos 	+ srel->r_offset;
160675fd0b74Schristos       pcrel = symval - pc + srel->r_addend;
160775fd0b74Schristos 
160875fd0b74Schristos       if (machine == bfd_mach_m16c)
160975fd0b74Schristos 	{
161075fd0b74Schristos 	  /* R8C / M16C */
161175fd0b74Schristos 
161275fd0b74Schristos 	  switch (ELF32_R_TYPE(irel->r_info))
161375fd0b74Schristos 	    {
161475fd0b74Schristos 
161575fd0b74Schristos 	    case R_M32C_RL_JUMP:
161675fd0b74Schristos 	      switch (insn[0])
161775fd0b74Schristos 		{
161875fd0b74Schristos 		case 0xfe: /* jmp.b */
161975fd0b74Schristos 		  if (pcrel >= 2 && pcrel <= 9)
162075fd0b74Schristos 		    {
162175fd0b74Schristos 		      /* Relax JMP.B -> JMP.S.  We need to get rid of
162275fd0b74Schristos 			 the following reloc though. */
162375fd0b74Schristos 		      insn[0] = 0x60 | (pcrel - 2);
162475fd0b74Schristos 		      new_type = R_M32C_NONE;
162575fd0b74Schristos 		      irel->r_addend = 0x10;
162675fd0b74Schristos 		      gap_size = 1;
162775fd0b74Schristos 		      gap = insn + 1;
162875fd0b74Schristos 		    }
162975fd0b74Schristos 		  break;
163075fd0b74Schristos 
163175fd0b74Schristos 		case 0xf4: /* jmp.w */
163275fd0b74Schristos 		  /* 128 is allowed because it will be one byte closer
163375fd0b74Schristos 		     after relaxing.  Likewise for all other pc-rel
163475fd0b74Schristos 		     jumps.  */
163575fd0b74Schristos 		  if (pcrel <= 128 && pcrel >= -128)
163675fd0b74Schristos 		    {
163775fd0b74Schristos 		      /* Relax JMP.W -> JMP.B */
163875fd0b74Schristos 		      insn[0] = 0xfe;
163975fd0b74Schristos 		      insn[1] = 0;
164075fd0b74Schristos 		      new_type = R_M32C_8_PCREL;
164175fd0b74Schristos 		      gap_size = 1;
164275fd0b74Schristos 		      gap = insn + 2;
164375fd0b74Schristos 		    }
164475fd0b74Schristos 		  break;
164575fd0b74Schristos 
164675fd0b74Schristos 		case 0xfc: /* jmp.a */
164775fd0b74Schristos 		  if (pcrel <= 32768 && pcrel >= -32768)
164875fd0b74Schristos 		    {
164975fd0b74Schristos 		      /* Relax JMP.A -> JMP.W */
165075fd0b74Schristos 		      insn[0] = 0xf4;
165175fd0b74Schristos 		      insn[1] = 0;
165275fd0b74Schristos 		      insn[2] = 0;
165375fd0b74Schristos 		      new_type = R_M32C_16_PCREL;
165475fd0b74Schristos 		      gap_size = 1;
165575fd0b74Schristos 		      gap = insn + 3;
165675fd0b74Schristos 		    }
165775fd0b74Schristos 		  break;
165875fd0b74Schristos 
165975fd0b74Schristos 		case 0xfd: /* jsr.a */
166075fd0b74Schristos 		  if (pcrel <= 32768 && pcrel >= -32768)
166175fd0b74Schristos 		    {
166275fd0b74Schristos 		      /* Relax JSR.A -> JSR.W */
166375fd0b74Schristos 		      insn[0] = 0xf5;
166475fd0b74Schristos 		      insn[1] = 0;
166575fd0b74Schristos 		      insn[2] = 0;
166675fd0b74Schristos 		      new_type = R_M32C_16_PCREL;
166775fd0b74Schristos 		      gap_size = 1;
166875fd0b74Schristos 		      gap = insn + 3;
166975fd0b74Schristos 		    }
167075fd0b74Schristos 		  break;
167175fd0b74Schristos 		}
167275fd0b74Schristos 	      break;
167375fd0b74Schristos 
167475fd0b74Schristos 	    case R_M32C_RL_2ADDR:
167575fd0b74Schristos 	      /* xxxx xxxx srce dest [src-disp] [dest-disp]*/
167675fd0b74Schristos 
167775fd0b74Schristos 	      enctbl = m16c_addr_encodings;
167875fd0b74Schristos 	      posn = 2;
167975fd0b74Schristos 	      enc = (insn[1] >> 4) & 0x0f;
168075fd0b74Schristos 	      e = & enctbl[enc];
168175fd0b74Schristos 
168275fd0b74Schristos 	      if (srel->r_offset == irel->r_offset + posn
168375fd0b74Schristos 		  && e->new_encoding != enc
168475fd0b74Schristos 		  && symval <= e->max_disp)
168575fd0b74Schristos 		{
168675fd0b74Schristos 		  insn[1] &= 0x0f;
168775fd0b74Schristos 		  insn[1] |= e->new_encoding << 4;
168875fd0b74Schristos 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
168975fd0b74Schristos 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
169075fd0b74Schristos 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
169175fd0b74Schristos 		  break;
169275fd0b74Schristos 		}
169375fd0b74Schristos 	      if (relax_relocs == 2)
169475fd0b74Schristos 		srel ++;
169575fd0b74Schristos 	      posn += e->bytes;
169675fd0b74Schristos 
169775fd0b74Schristos 	      goto try_1addr_16;
169875fd0b74Schristos 
169975fd0b74Schristos 	    case R_M32C_RL_1ADDR:
170075fd0b74Schristos 	      /* xxxx xxxx xxxx dest [disp] */
170175fd0b74Schristos 
170275fd0b74Schristos 	      enctbl = m16c_addr_encodings;
170375fd0b74Schristos 	      posn = 2;
170475fd0b74Schristos 
170575fd0b74Schristos 	      /* Check the opcode for jumps.  We know it's safe to
170675fd0b74Schristos 		 do this because all 2ADDR insns are at least two
170775fd0b74Schristos 		 bytes long.  */
170875fd0b74Schristos 	      enc = insn[0] * 256 + insn[1];
170975fd0b74Schristos 	      enc &= 0xfff0;
171075fd0b74Schristos 	      if (enc == 0x7d20
171175fd0b74Schristos 		  || enc == 0x7d00
171275fd0b74Schristos 		  || enc == 0x7d30
171375fd0b74Schristos 		  || enc == 0x7d10)
171475fd0b74Schristos 		{
171575fd0b74Schristos 		  enctbl = m16c_jmpaddr_encodings;
171675fd0b74Schristos 		}
171775fd0b74Schristos 
171875fd0b74Schristos 	    try_1addr_16:
171975fd0b74Schristos 	      /* srel, posn, and enc must be set here.  */
172075fd0b74Schristos 
172175fd0b74Schristos 	      symval = OFFSET_FOR_RELOC (srel);
172275fd0b74Schristos 	      enc = insn[1] & 0x0f;
172375fd0b74Schristos 	      e = & enctbl[enc];
172475fd0b74Schristos 
172575fd0b74Schristos 	      if (srel->r_offset == irel->r_offset + posn
172675fd0b74Schristos 		  && e->new_encoding != enc
172775fd0b74Schristos 		  && symval <= e->max_disp)
172875fd0b74Schristos 		{
172975fd0b74Schristos 		  insn[1] &= 0xf0;
173075fd0b74Schristos 		  insn[1] |= e->new_encoding;
173175fd0b74Schristos 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
173275fd0b74Schristos 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
173375fd0b74Schristos 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
173475fd0b74Schristos 		  break;
173575fd0b74Schristos 		}
173675fd0b74Schristos 
173775fd0b74Schristos 	      break;
173875fd0b74Schristos 
173975fd0b74Schristos 	    } /* Ends switch (reloc type) for m16c.  */
174075fd0b74Schristos 	}
174175fd0b74Schristos       else /* machine == bfd_mach_m32c */
174275fd0b74Schristos 	{
174375fd0b74Schristos 	  /* M32CM / M32C */
174475fd0b74Schristos 
174575fd0b74Schristos 	  switch (ELF32_R_TYPE(irel->r_info))
174675fd0b74Schristos 	    {
174775fd0b74Schristos 
174875fd0b74Schristos 	    case R_M32C_RL_JUMP:
174975fd0b74Schristos 	      switch (insn[0])
175075fd0b74Schristos 		{
175175fd0b74Schristos 		case 0xbb: /* jmp.b */
175275fd0b74Schristos 		  if (pcrel >= 2 && pcrel <= 9)
175375fd0b74Schristos 		    {
175475fd0b74Schristos 		      int p = pcrel - 2;
175575fd0b74Schristos 		      /* Relax JMP.B -> JMP.S.  We need to get rid of
175675fd0b74Schristos 			 the following reloc though. */
175775fd0b74Schristos 		      insn[0] = 0x4a | ((p << 3) & 0x30) | (p & 1);
175875fd0b74Schristos 		      new_type = R_M32C_NONE;
175975fd0b74Schristos 		      irel->r_addend = 0x10;
176075fd0b74Schristos 		      gap_size = 1;
176175fd0b74Schristos 		      gap = insn + 1;
176275fd0b74Schristos 		    }
176375fd0b74Schristos 		  break;
176475fd0b74Schristos 
176575fd0b74Schristos 		case 0xce: /* jmp.w */
176675fd0b74Schristos 		  if (pcrel <= 128 && pcrel >= -128)
176775fd0b74Schristos 		    {
176875fd0b74Schristos 		      /* Relax JMP.W -> JMP.B */
176975fd0b74Schristos 		      insn[0] = 0xbb;
177075fd0b74Schristos 		      insn[1] = 0;
177175fd0b74Schristos 		      new_type = R_M32C_8_PCREL;
177275fd0b74Schristos 		      gap_size = 1;
177375fd0b74Schristos 		      gap = insn + 2;
177475fd0b74Schristos 		    }
177575fd0b74Schristos 		  break;
177675fd0b74Schristos 
177775fd0b74Schristos 		case 0xcc: /* jmp.a */
177875fd0b74Schristos 		  if (pcrel <= 32768 && pcrel >= -32768)
177975fd0b74Schristos 		    {
178075fd0b74Schristos 		      /* Relax JMP.A -> JMP.W */
178175fd0b74Schristos 		      insn[0] = 0xce;
178275fd0b74Schristos 		      insn[1] = 0;
178375fd0b74Schristos 		      insn[2] = 0;
178475fd0b74Schristos 		      new_type = R_M32C_16_PCREL;
178575fd0b74Schristos 		      gap_size = 1;
178675fd0b74Schristos 		      gap = insn + 3;
178775fd0b74Schristos 		    }
178875fd0b74Schristos 		  break;
178975fd0b74Schristos 
179075fd0b74Schristos 		case 0xcd: /* jsr.a */
179175fd0b74Schristos 		  if (pcrel <= 32768 && pcrel >= -32768)
179275fd0b74Schristos 		    {
179375fd0b74Schristos 		      /* Relax JSR.A -> JSR.W */
179475fd0b74Schristos 		      insn[0] = 0xcf;
179575fd0b74Schristos 		      insn[1] = 0;
179675fd0b74Schristos 		      insn[2] = 0;
179775fd0b74Schristos 		      new_type = R_M32C_16_PCREL;
179875fd0b74Schristos 		      gap_size = 1;
179975fd0b74Schristos 		      gap = insn + 3;
180075fd0b74Schristos 		    }
180175fd0b74Schristos 		  break;
180275fd0b74Schristos 		}
180375fd0b74Schristos 	      break;
180475fd0b74Schristos 
180575fd0b74Schristos 	    case R_M32C_RL_2ADDR:
180675fd0b74Schristos 	      /* xSSS DDDx DDSS xxxx [src-disp] [dest-disp]*/
180775fd0b74Schristos 
180875fd0b74Schristos 	      einsn = insn;
180975fd0b74Schristos 	      posn = 2;
181075fd0b74Schristos 	      if (einsn[0] == 1)
181175fd0b74Schristos 		{
181275fd0b74Schristos 		  /* prefix; remove it as far as the RL reloc is concerned.  */
181375fd0b74Schristos 		  einsn ++;
181475fd0b74Schristos 		  posn ++;
181575fd0b74Schristos 		}
181675fd0b74Schristos 
181775fd0b74Schristos 	      enctbl = m32c_addr_encodings;
181875fd0b74Schristos 	      enc = ((einsn[0] & 0x70) >> 2) | ((einsn[1] & 0x30) >> 4);
181975fd0b74Schristos 	      e = & enctbl[enc];
182075fd0b74Schristos 
182175fd0b74Schristos 	      if (srel->r_offset == irel->r_offset + posn
182275fd0b74Schristos 		  && e->new_encoding != enc
182375fd0b74Schristos 		  && symval <= e->max_disp)
182475fd0b74Schristos 		{
182575fd0b74Schristos 		  einsn[0] &= 0x8f;
182675fd0b74Schristos 		  einsn[0] |= (e->new_encoding & 0x1c) << 2;
182775fd0b74Schristos 		  einsn[1] &= 0xcf;
182875fd0b74Schristos 		  einsn[1] |= (e->new_encoding & 0x03) << 4;
182975fd0b74Schristos 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
183075fd0b74Schristos 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
183175fd0b74Schristos 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
183275fd0b74Schristos 		  break;
183375fd0b74Schristos 		}
183475fd0b74Schristos 	      if (relax_relocs == 2)
183575fd0b74Schristos 		  srel ++;
183675fd0b74Schristos 	      posn += e->bytes;
183775fd0b74Schristos 
183875fd0b74Schristos 	      goto try_1addr_32;
183975fd0b74Schristos 
184075fd0b74Schristos 	    case R_M32C_RL_1ADDR:
184175fd0b74Schristos 	      /* xxxx DDDx DDxx xxxx [disp] */
184275fd0b74Schristos 
184375fd0b74Schristos 	      einsn = insn;
184475fd0b74Schristos 	      posn = 2;
184575fd0b74Schristos 	      if (einsn[0] == 1)
184675fd0b74Schristos 		{
184775fd0b74Schristos 		  /* prefix; remove it as far as the RL reloc is concerned.  */
184875fd0b74Schristos 		  einsn ++;
184975fd0b74Schristos 		  posn ++;
185075fd0b74Schristos 		}
185175fd0b74Schristos 
185275fd0b74Schristos 	      enctbl = m32c_addr_encodings;
185375fd0b74Schristos 
185475fd0b74Schristos 	    try_1addr_32:
185575fd0b74Schristos 	      /* srel, posn, and enc must be set here.  */
185675fd0b74Schristos 
185775fd0b74Schristos 	      symval = OFFSET_FOR_RELOC (srel);
185875fd0b74Schristos 	      enc = ((einsn[0] & 0x0e) << 1) |  ((einsn[1] & 0xc0) >> 6);
185975fd0b74Schristos 	      e = & enctbl[enc];
186075fd0b74Schristos 
186175fd0b74Schristos 	      if (srel->r_offset == irel->r_offset + posn
186275fd0b74Schristos 		  && e->new_encoding != enc
186375fd0b74Schristos 		  && symval <= e->max_disp)
186475fd0b74Schristos 		{
186575fd0b74Schristos 		  einsn[0] &= 0xf1;
186675fd0b74Schristos 		  einsn[0] |= (e->new_encoding & 0x1c) >> 1;
186775fd0b74Schristos 		  einsn[1] &= 0x3f;
186875fd0b74Schristos 		  einsn[1] |= (e->new_encoding & 0x03) << 6;
186975fd0b74Schristos 		  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
187075fd0b74Schristos 		  gap = insn + posn + enctbl[e->new_encoding].bytes;
187175fd0b74Schristos 		  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
187275fd0b74Schristos 		  break;
187375fd0b74Schristos 		}
187475fd0b74Schristos 
187575fd0b74Schristos 	      break;
187675fd0b74Schristos 
187775fd0b74Schristos 	    } /* Ends switch (reloc type) for m32c.  */
187875fd0b74Schristos 	}
187975fd0b74Schristos 
188075fd0b74Schristos       if (gap_size == 0)
188175fd0b74Schristos 	continue;
188275fd0b74Schristos 
1883*e992f068Schristos       *again = true;
188475fd0b74Schristos 
188575fd0b74Schristos       srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), new_type);
188675fd0b74Schristos 
188775fd0b74Schristos       /* Note that we've changed the relocs, section contents, etc.  */
188875fd0b74Schristos       elf_section_data (sec)->relocs = internal_relocs;
188975fd0b74Schristos       free_relocs = NULL;
189075fd0b74Schristos 
189175fd0b74Schristos       elf_section_data (sec)->this_hdr.contents = contents;
189275fd0b74Schristos       free_contents = NULL;
189375fd0b74Schristos 
189475fd0b74Schristos       symtab_hdr->contents = (bfd_byte *) intsyms;
189575fd0b74Schristos       free_intsyms = NULL;
189675fd0b74Schristos 
189775fd0b74Schristos       bytes_saved += gap_size;
189875fd0b74Schristos 
189975fd0b74Schristos       if (! m32c_elf_relax_delete_bytes(abfd, sec, gap - contents, gap_size))
190075fd0b74Schristos 	goto error_return;
190175fd0b74Schristos 
190275fd0b74Schristos     } /* next relocation */
190375fd0b74Schristos 
190475fd0b74Schristos   free (free_relocs);
190575fd0b74Schristos   free_relocs = NULL;
190675fd0b74Schristos 
190775fd0b74Schristos   if (free_contents != NULL)
190875fd0b74Schristos     {
190975fd0b74Schristos       if (! link_info->keep_memory)
191075fd0b74Schristos 	free (free_contents);
191175fd0b74Schristos       /* Cache the section contents for elf_link_input_bfd.  */
191275fd0b74Schristos       else
191375fd0b74Schristos 	elf_section_data (sec)->this_hdr.contents = contents;
191475fd0b74Schristos 
191575fd0b74Schristos       free_contents = NULL;
191675fd0b74Schristos     }
191775fd0b74Schristos 
191875fd0b74Schristos   if (shndx_buf != NULL)
191975fd0b74Schristos     {
192075fd0b74Schristos       shndx_hdr->contents = NULL;
192175fd0b74Schristos       free (shndx_buf);
192275fd0b74Schristos     }
192375fd0b74Schristos 
192475fd0b74Schristos   if (free_intsyms != NULL)
192575fd0b74Schristos     {
192675fd0b74Schristos       if (! link_info->keep_memory)
192775fd0b74Schristos 	free (free_intsyms);
192875fd0b74Schristos       /* Cache the symbols for elf_link_input_bfd.  */
192975fd0b74Schristos       else
193075fd0b74Schristos 	{
193175fd0b74Schristos 	  symtab_hdr->contents = NULL /* (unsigned char *) intsyms*/;
193275fd0b74Schristos 	}
193375fd0b74Schristos 
193475fd0b74Schristos       free_intsyms = NULL;
193575fd0b74Schristos     }
193675fd0b74Schristos 
1937*e992f068Schristos   return true;
193875fd0b74Schristos 
193975fd0b74Schristos  error_return:
194075fd0b74Schristos   free (free_relocs);
194175fd0b74Schristos   free (free_contents);
194275fd0b74Schristos   if (shndx_buf != NULL)
194375fd0b74Schristos     {
194475fd0b74Schristos       shndx_hdr->contents = NULL;
194575fd0b74Schristos       free (shndx_buf);
194675fd0b74Schristos     }
194775fd0b74Schristos   free (free_intsyms);
1948*e992f068Schristos   return false;
194975fd0b74Schristos }
195075fd0b74Schristos 
195175fd0b74Schristos /* Delete some bytes from a section while relaxing.  */
195275fd0b74Schristos 
1953*e992f068Schristos static bool
m32c_elf_relax_delete_bytes(bfd * abfd,asection * sec,bfd_vma addr,int count)1954*e992f068Schristos m32c_elf_relax_delete_bytes (bfd *abfd,
195575fd0b74Schristos 			     asection *sec,
195675fd0b74Schristos 			     bfd_vma addr,
195775fd0b74Schristos 			     int count)
195875fd0b74Schristos {
195975fd0b74Schristos   Elf_Internal_Shdr *symtab_hdr;
196075fd0b74Schristos   Elf_Internal_Shdr *shndx_hdr;
196175fd0b74Schristos   int sec_shndx;
196275fd0b74Schristos   bfd_byte *contents;
196375fd0b74Schristos   Elf_Internal_Rela *irel;
196475fd0b74Schristos   Elf_Internal_Rela *irelend;
196575fd0b74Schristos   bfd_vma toaddr;
196675fd0b74Schristos   Elf_Internal_Sym *isym;
196775fd0b74Schristos   Elf_Internal_Sym *isymend;
196875fd0b74Schristos   Elf_Internal_Sym *intsyms;
196975fd0b74Schristos   Elf_External_Sym_Shndx *shndx_buf;
197075fd0b74Schristos   Elf_External_Sym_Shndx *shndx;
197175fd0b74Schristos   struct elf_link_hash_entry ** sym_hashes;
197275fd0b74Schristos   struct elf_link_hash_entry ** end_hashes;
197375fd0b74Schristos   unsigned int			symcount;
197475fd0b74Schristos 
197575fd0b74Schristos   contents   = elf_section_data (sec)->this_hdr.contents;
197675fd0b74Schristos 
197775fd0b74Schristos   toaddr = sec->size;
197875fd0b74Schristos 
197975fd0b74Schristos   irel = elf_section_data (sec)->relocs;
198075fd0b74Schristos   irelend = irel + sec->reloc_count;
198175fd0b74Schristos 
198275fd0b74Schristos   /* Actually delete the bytes.  */
198375fd0b74Schristos   memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
198475fd0b74Schristos   sec->size -= count;
198575fd0b74Schristos 
198675fd0b74Schristos   /* Adjust all the relocs.  */
198775fd0b74Schristos   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
198875fd0b74Schristos     {
198975fd0b74Schristos       /* Get the new reloc address.  */
199075fd0b74Schristos       if (irel->r_offset > addr && irel->r_offset < toaddr)
199175fd0b74Schristos 	irel->r_offset -= count;
199275fd0b74Schristos 
199375fd0b74Schristos       if (ELF32_R_TYPE(irel->r_info) == R_M32C_RL_JUMP
199475fd0b74Schristos 	  && irel->r_addend == 0x10 /* one byte insn, no relocs */
199575fd0b74Schristos 	  && irel->r_offset + 1 < addr
199675fd0b74Schristos 	  && irel->r_offset + 7 > addr)
199775fd0b74Schristos 	{
199875fd0b74Schristos 	  bfd_vma disp;
199975fd0b74Schristos 	  unsigned char *insn = &contents[irel->r_offset];
200075fd0b74Schristos 	  disp = *insn;
200175fd0b74Schristos 	  /* This is a JMP.S, which we have to manually update. */
200275fd0b74Schristos 	  if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
200375fd0b74Schristos 	    {
200475fd0b74Schristos 	      if ((*insn & 0xf8) != 0x60)
200575fd0b74Schristos 		continue;
200675fd0b74Schristos 	      disp = (disp & 7);
200775fd0b74Schristos 	    }
200875fd0b74Schristos 	  else
200975fd0b74Schristos 	    {
201075fd0b74Schristos 	      if ((*insn & 0xce) != 0x4a)
201175fd0b74Schristos 		continue;
201275fd0b74Schristos 	      disp = ((disp & 0x30) >> 3) | (disp & 1);
201375fd0b74Schristos 	    }
201475fd0b74Schristos 	  if (irel->r_offset + disp + 2 >= addr+count)
201575fd0b74Schristos 	    {
201675fd0b74Schristos 	      disp -= count;
201775fd0b74Schristos 	      if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
201875fd0b74Schristos 		{
201975fd0b74Schristos 		  *insn = (*insn & 0xf8) | disp;
202075fd0b74Schristos 		}
202175fd0b74Schristos 	      else
202275fd0b74Schristos 		{
202375fd0b74Schristos 		  *insn = (*insn & 0xce) | ((disp & 6) << 3) | (disp & 1);
202475fd0b74Schristos 		}
202575fd0b74Schristos 	    }
202675fd0b74Schristos 	}
202775fd0b74Schristos     }
202875fd0b74Schristos 
202975fd0b74Schristos   /* Adjust the local symbols defined in this section.  */
203075fd0b74Schristos   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
203175fd0b74Schristos   intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
203275fd0b74Schristos   isym = intsyms;
203375fd0b74Schristos   isymend = isym + symtab_hdr->sh_info;
203475fd0b74Schristos 
203575fd0b74Schristos   sec_shndx  = _bfd_elf_section_from_bfd_section (abfd, sec);
203675fd0b74Schristos   if (elf_symtab_shndx_list (abfd))
203775fd0b74Schristos     {
203875fd0b74Schristos       shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
203975fd0b74Schristos       shndx_buf  = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
204075fd0b74Schristos     }
204175fd0b74Schristos   else
204275fd0b74Schristos     {
204375fd0b74Schristos       shndx_hdr = NULL;
204475fd0b74Schristos       shndx_buf = NULL;
204575fd0b74Schristos     }
204675fd0b74Schristos   shndx = shndx_buf;
204775fd0b74Schristos 
204875fd0b74Schristos   for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
204975fd0b74Schristos     {
205075fd0b74Schristos       /* If the symbol is in the range of memory we just moved, we
205175fd0b74Schristos 	 have to adjust its value.  */
205275fd0b74Schristos       if ((int) isym->st_shndx == sec_shndx
205375fd0b74Schristos 	  && isym->st_value > addr
205475fd0b74Schristos 	  && isym->st_value < toaddr)
205575fd0b74Schristos 	{
205675fd0b74Schristos 	  isym->st_value -= count;
205775fd0b74Schristos 	}
205875fd0b74Schristos       /* If the symbol *spans* the bytes we just deleted (i.e. it's
205975fd0b74Schristos 	 *end* is in the moved bytes but it's *start* isn't), then we
206075fd0b74Schristos 	 must adjust its size.  */
206175fd0b74Schristos       if ((int) isym->st_shndx == sec_shndx
206275fd0b74Schristos 	    && isym->st_value < addr
206375fd0b74Schristos 	  && isym->st_value + isym->st_size > addr
206475fd0b74Schristos 	  && isym->st_value + isym->st_size < toaddr)
206575fd0b74Schristos 	{
206675fd0b74Schristos 	  isym->st_size -= count;
206775fd0b74Schristos 	}
206875fd0b74Schristos     }
206975fd0b74Schristos 
207075fd0b74Schristos   /* Now adjust the global symbols defined in this section.  */
207175fd0b74Schristos   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
207275fd0b74Schristos 	      - symtab_hdr->sh_info);
207375fd0b74Schristos   sym_hashes = elf_sym_hashes (abfd);
207475fd0b74Schristos   end_hashes = sym_hashes + symcount;
207575fd0b74Schristos 
207675fd0b74Schristos   for (; sym_hashes < end_hashes; sym_hashes ++)
207775fd0b74Schristos     {
207875fd0b74Schristos       struct elf_link_hash_entry * sym_hash = * sym_hashes;
207975fd0b74Schristos 
208075fd0b74Schristos       if (sym_hash &&
208175fd0b74Schristos 	  (sym_hash->root.type == bfd_link_hash_defined
208275fd0b74Schristos 	   || sym_hash->root.type == bfd_link_hash_defweak)
208375fd0b74Schristos 	  && sym_hash->root.u.def.section == sec)
208475fd0b74Schristos 	{
208575fd0b74Schristos 	  if (sym_hash->root.u.def.value > addr
208675fd0b74Schristos 	      && sym_hash->root.u.def.value < toaddr)
208775fd0b74Schristos 	    {
208875fd0b74Schristos 	      sym_hash->root.u.def.value -= count;
208975fd0b74Schristos 	    }
209075fd0b74Schristos 	  if (sym_hash->root.u.def.value < addr
209175fd0b74Schristos 	      && sym_hash->root.u.def.value + sym_hash->size > addr
209275fd0b74Schristos 	      && sym_hash->root.u.def.value + sym_hash->size < toaddr)
209375fd0b74Schristos 	    {
209475fd0b74Schristos 	      sym_hash->size -= count;
209575fd0b74Schristos 	    }
209675fd0b74Schristos 	}
209775fd0b74Schristos     }
209875fd0b74Schristos 
2099*e992f068Schristos   return true;
210075fd0b74Schristos }
210175fd0b74Schristos 
210275fd0b74Schristos /* This is for versions of gcc prior to 4.3.  */
210375fd0b74Schristos static unsigned int
_bfd_m32c_elf_eh_frame_address_size(bfd * abfd,const asection * sec ATTRIBUTE_UNUSED)2104ede78133Schristos _bfd_m32c_elf_eh_frame_address_size (bfd *abfd,
2105ede78133Schristos 				     const asection *sec ATTRIBUTE_UNUSED)
210675fd0b74Schristos {
210775fd0b74Schristos   if ((elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK) == EF_M32C_CPU_M16C)
210875fd0b74Schristos     return 2;
210975fd0b74Schristos   return 4;
211075fd0b74Schristos }
211175fd0b74Schristos 
211275fd0b74Schristos 
211375fd0b74Schristos 
211475fd0b74Schristos #define ELF_ARCH		bfd_arch_m32c
211575fd0b74Schristos #define ELF_MACHINE_CODE	EM_M32C
211675fd0b74Schristos #define ELF_MACHINE_ALT1	EM_M32C_OLD
211775fd0b74Schristos #define ELF_MAXPAGESIZE		0x100
211875fd0b74Schristos 
211975fd0b74Schristos #if 0
212075fd0b74Schristos #define TARGET_BIG_SYM		m32c_elf32_vec
212175fd0b74Schristos #define TARGET_BIG_NAME		"elf32-m32c"
212275fd0b74Schristos #else
212375fd0b74Schristos #define TARGET_LITTLE_SYM		m32c_elf32_vec
212475fd0b74Schristos #define TARGET_LITTLE_NAME		"elf32-m32c"
212575fd0b74Schristos #endif
212675fd0b74Schristos 
212775fd0b74Schristos #define elf_info_to_howto_rel			NULL
212875fd0b74Schristos #define elf_info_to_howto			m32c_info_to_howto_rela
212975fd0b74Schristos #define elf_backend_object_p			m32c_elf_object_p
213075fd0b74Schristos #define elf_backend_relocate_section		m32c_elf_relocate_section
213175fd0b74Schristos #define elf_backend_check_relocs		m32c_elf_check_relocs
213275fd0b74Schristos #define elf_backend_object_p			m32c_elf_object_p
213375fd0b74Schristos #define elf_symbol_leading_char			('_')
213475fd0b74Schristos #define elf_backend_always_size_sections \
213575fd0b74Schristos   m32c_elf_always_size_sections
213675fd0b74Schristos #define elf_backend_finish_dynamic_sections \
213775fd0b74Schristos   m32c_elf_finish_dynamic_sections
213875fd0b74Schristos 
213975fd0b74Schristos #define elf_backend_can_gc_sections		1
214075fd0b74Schristos #define elf_backend_eh_frame_address_size _bfd_m32c_elf_eh_frame_address_size
214175fd0b74Schristos 
214275fd0b74Schristos #define bfd_elf32_bfd_reloc_type_lookup		m32c_reloc_type_lookup
214375fd0b74Schristos #define bfd_elf32_bfd_reloc_name_lookup	m32c_reloc_name_lookup
214475fd0b74Schristos #define bfd_elf32_bfd_relax_section		m32c_elf_relax_section
214575fd0b74Schristos #define bfd_elf32_bfd_set_private_flags		m32c_elf_set_private_flags
214675fd0b74Schristos #define bfd_elf32_bfd_merge_private_bfd_data	m32c_elf_merge_private_bfd_data
214775fd0b74Schristos #define bfd_elf32_bfd_print_private_bfd_data	m32c_elf_print_private_bfd_data
214875fd0b74Schristos 
214975fd0b74Schristos #include "elf32-target.h"
2150