xref: /openbsd-src/gnu/usr.bin/binutils/bfd/elf-m10200.c (revision cf2f2c5620d6d9a4fd01930983c4b9a1f76d7aa3)
1fddef416Sniklas /* Matsushita 10200 specific support for 32-bit ELF
2*cf2f2c56Smiod    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
35f210c2aSfgsch    Free Software Foundation, Inc.
4fddef416Sniklas 
5fddef416Sniklas This file is part of BFD, the Binary File Descriptor library.
6fddef416Sniklas 
7fddef416Sniklas This program is free software; you can redistribute it and/or modify
8fddef416Sniklas it under the terms of the GNU General Public License as published by
9fddef416Sniklas the Free Software Foundation; either version 2 of the License, or
10fddef416Sniklas (at your option) any later version.
11fddef416Sniklas 
12fddef416Sniklas This program is distributed in the hope that it will be useful,
13fddef416Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
14fddef416Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15fddef416Sniklas GNU General Public License for more details.
16fddef416Sniklas 
17fddef416Sniklas You should have received a copy of the GNU General Public License
18fddef416Sniklas along with this program; if not, write to the Free Software
19fddef416Sniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20fddef416Sniklas 
21fddef416Sniklas #include "bfd.h"
22fddef416Sniklas #include "sysdep.h"
23fddef416Sniklas #include "libbfd.h"
24fddef416Sniklas #include "elf-bfd.h"
25fddef416Sniklas 
26fddef416Sniklas static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
27fddef416Sniklas   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
28fddef416Sniklas static void mn10200_info_to_howto
29d2201f2fSdrahn   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
30d2201f2fSdrahn static bfd_boolean mn10200_elf_relax_delete_bytes
31fddef416Sniklas   PARAMS ((bfd *, asection *, bfd_vma, int));
32d2201f2fSdrahn static bfd_boolean mn10200_elf_symbol_address_p
33d2201f2fSdrahn   PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
34d2201f2fSdrahn static bfd_reloc_status_type mn10200_elf_final_link_relocate
35d2201f2fSdrahn   PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
36d2201f2fSdrahn 	   bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
37d2201f2fSdrahn 	   struct bfd_link_info *, asection *, int));
38d2201f2fSdrahn static bfd_boolean mn10200_elf_relocate_section
39d2201f2fSdrahn   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
40d2201f2fSdrahn 	   bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
41d2201f2fSdrahn 	   asection **));
42d2201f2fSdrahn static bfd_boolean mn10200_elf_relax_section
43d2201f2fSdrahn   PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
44d2201f2fSdrahn static bfd_byte * mn10200_elf_get_relocated_section_contents
45d2201f2fSdrahn   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
46d2201f2fSdrahn 	   bfd_byte *, bfd_boolean, asymbol **));
47fddef416Sniklas 
485f210c2aSfgsch enum reloc_type {
49fddef416Sniklas   R_MN10200_NONE = 0,
50fddef416Sniklas   R_MN10200_32,
51fddef416Sniklas   R_MN10200_16,
52fddef416Sniklas   R_MN10200_8,
53fddef416Sniklas   R_MN10200_24,
54fddef416Sniklas   R_MN10200_PCREL8,
55fddef416Sniklas   R_MN10200_PCREL16,
56fddef416Sniklas   R_MN10200_PCREL24,
57fddef416Sniklas   R_MN10200_MAX
58fddef416Sniklas };
59fddef416Sniklas 
605f210c2aSfgsch static reloc_howto_type elf_mn10200_howto_table[] = {
61fddef416Sniklas   /* Dummy relocation.  Does nothing.  */
62fddef416Sniklas   HOWTO (R_MN10200_NONE,
63fddef416Sniklas 	 0,
64fddef416Sniklas 	 2,
65fddef416Sniklas 	 16,
66d2201f2fSdrahn 	 FALSE,
67fddef416Sniklas 	 0,
68fddef416Sniklas 	 complain_overflow_bitfield,
69fddef416Sniklas 	 bfd_elf_generic_reloc,
70fddef416Sniklas 	 "R_MN10200_NONE",
71d2201f2fSdrahn 	 FALSE,
72fddef416Sniklas 	 0,
73fddef416Sniklas 	 0,
74d2201f2fSdrahn 	 FALSE),
75fddef416Sniklas   /* Standard 32 bit reloc.  */
76fddef416Sniklas   HOWTO (R_MN10200_32,
77fddef416Sniklas 	 0,
78fddef416Sniklas 	 2,
79fddef416Sniklas 	 32,
80d2201f2fSdrahn 	 FALSE,
81fddef416Sniklas 	 0,
82fddef416Sniklas 	 complain_overflow_bitfield,
83fddef416Sniklas 	 bfd_elf_generic_reloc,
84fddef416Sniklas 	 "R_MN10200_32",
85d2201f2fSdrahn 	 FALSE,
86fddef416Sniklas 	 0xffffffff,
87fddef416Sniklas 	 0xffffffff,
88d2201f2fSdrahn 	 FALSE),
89fddef416Sniklas   /* Standard 16 bit reloc.  */
90fddef416Sniklas   HOWTO (R_MN10200_16,
91fddef416Sniklas 	 0,
92fddef416Sniklas 	 1,
93fddef416Sniklas 	 16,
94d2201f2fSdrahn 	 FALSE,
95fddef416Sniklas 	 0,
96fddef416Sniklas 	 complain_overflow_bitfield,
97fddef416Sniklas 	 bfd_elf_generic_reloc,
98fddef416Sniklas 	 "R_MN10200_16",
99d2201f2fSdrahn 	 FALSE,
100fddef416Sniklas 	 0xffff,
101fddef416Sniklas 	 0xffff,
102d2201f2fSdrahn 	 FALSE),
103fddef416Sniklas   /* Standard 8 bit reloc.  */
104fddef416Sniklas   HOWTO (R_MN10200_8,
105fddef416Sniklas 	 0,
106fddef416Sniklas 	 0,
107fddef416Sniklas 	 8,
108d2201f2fSdrahn 	 FALSE,
109fddef416Sniklas 	 0,
110fddef416Sniklas 	 complain_overflow_bitfield,
111fddef416Sniklas 	 bfd_elf_generic_reloc,
112fddef416Sniklas 	 "R_MN10200_8",
113d2201f2fSdrahn 	 FALSE,
114fddef416Sniklas 	 0xff,
115fddef416Sniklas 	 0xff,
116d2201f2fSdrahn 	 FALSE),
117fddef416Sniklas   /* Standard 24 bit reloc.  */
118fddef416Sniklas   HOWTO (R_MN10200_24,
119fddef416Sniklas 	 0,
120fddef416Sniklas 	 2,
121fddef416Sniklas 	 24,
122d2201f2fSdrahn 	 FALSE,
123fddef416Sniklas 	 0,
124fddef416Sniklas 	 complain_overflow_bitfield,
125fddef416Sniklas 	 bfd_elf_generic_reloc,
126fddef416Sniklas 	 "R_MN10200_24",
127d2201f2fSdrahn 	 FALSE,
128fddef416Sniklas 	 0xffffff,
129fddef416Sniklas 	 0xffffff,
130d2201f2fSdrahn 	 FALSE),
131fddef416Sniklas   /* Simple 8 pc-relative reloc.  */
132fddef416Sniklas   HOWTO (R_MN10200_PCREL8,
133fddef416Sniklas 	 0,
134fddef416Sniklas 	 0,
135fddef416Sniklas 	 8,
136d2201f2fSdrahn 	 TRUE,
137fddef416Sniklas 	 0,
138fddef416Sniklas 	 complain_overflow_bitfield,
139fddef416Sniklas 	 bfd_elf_generic_reloc,
140fddef416Sniklas 	 "R_MN10200_PCREL8",
141d2201f2fSdrahn 	 FALSE,
142fddef416Sniklas 	 0xff,
143fddef416Sniklas 	 0xff,
144d2201f2fSdrahn 	 TRUE),
145fddef416Sniklas   /* Simple 16 pc-relative reloc.  */
146fddef416Sniklas   HOWTO (R_MN10200_PCREL16,
147fddef416Sniklas 	 0,
148fddef416Sniklas 	 1,
149fddef416Sniklas 	 16,
150d2201f2fSdrahn 	 TRUE,
151fddef416Sniklas 	 0,
152fddef416Sniklas 	 complain_overflow_bitfield,
153fddef416Sniklas 	 bfd_elf_generic_reloc,
154fddef416Sniklas 	 "R_MN10200_PCREL16",
155d2201f2fSdrahn 	 FALSE,
156fddef416Sniklas 	 0xffff,
157fddef416Sniklas 	 0xffff,
158d2201f2fSdrahn 	 TRUE),
159fddef416Sniklas   /* Simple 32bit pc-relative reloc with a 1 byte adjustment
160fddef416Sniklas      to get the pc-relative offset correct.  */
161fddef416Sniklas   HOWTO (R_MN10200_PCREL24,
162fddef416Sniklas 	 0,
163fddef416Sniklas 	 2,
164fddef416Sniklas 	 24,
165d2201f2fSdrahn 	 TRUE,
166fddef416Sniklas 	 0,
167fddef416Sniklas 	 complain_overflow_bitfield,
168fddef416Sniklas 	 bfd_elf_generic_reloc,
169fddef416Sniklas 	 "R_MN10200_PCREL24",
170d2201f2fSdrahn 	 FALSE,
171fddef416Sniklas 	 0xffffff,
172fddef416Sniklas 	 0xffffff,
173d2201f2fSdrahn 	 TRUE),
174fddef416Sniklas };
175fddef416Sniklas 
1765f210c2aSfgsch struct mn10200_reloc_map {
177f7cc78ecSespie   bfd_reloc_code_real_type bfd_reloc_val;
178fddef416Sniklas   unsigned char elf_reloc_val;
179fddef416Sniklas };
180fddef416Sniklas 
1815f210c2aSfgsch static const struct mn10200_reloc_map mn10200_reloc_map[] = {
182fddef416Sniklas   { BFD_RELOC_NONE    , R_MN10200_NONE   , },
183fddef416Sniklas   { BFD_RELOC_32      , R_MN10200_32     , },
184fddef416Sniklas   { BFD_RELOC_16      , R_MN10200_16     , },
185fddef416Sniklas   { BFD_RELOC_8       , R_MN10200_8      , },
186fddef416Sniklas   { BFD_RELOC_24      , R_MN10200_24     , },
187fddef416Sniklas   { BFD_RELOC_8_PCREL , R_MN10200_PCREL8 , },
188fddef416Sniklas   { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
189fddef416Sniklas   { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
190fddef416Sniklas };
191fddef416Sniklas 
192fddef416Sniklas static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup(abfd,code)193fddef416Sniklas bfd_elf32_bfd_reloc_type_lookup (abfd, code)
194f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
195fddef416Sniklas      bfd_reloc_code_real_type code;
196fddef416Sniklas {
197fddef416Sniklas   unsigned int i;
198fddef416Sniklas 
199fddef416Sniklas   for (i = 0;
200fddef416Sniklas        i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
201fddef416Sniklas        i++)
202fddef416Sniklas     {
203fddef416Sniklas       if (mn10200_reloc_map[i].bfd_reloc_val == code)
204fddef416Sniklas 	return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
205fddef416Sniklas     }
206fddef416Sniklas 
207fddef416Sniklas   return NULL;
208fddef416Sniklas }
209fddef416Sniklas 
210fddef416Sniklas /* Set the howto pointer for an MN10200 ELF reloc.  */
211fddef416Sniklas 
212fddef416Sniklas static void
mn10200_info_to_howto(abfd,cache_ptr,dst)213fddef416Sniklas mn10200_info_to_howto (abfd, cache_ptr, dst)
214f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
215fddef416Sniklas      arelent *cache_ptr;
216d2201f2fSdrahn      Elf_Internal_Rela *dst;
217fddef416Sniklas {
218fddef416Sniklas   unsigned int r_type;
219fddef416Sniklas 
220fddef416Sniklas   r_type = ELF32_R_TYPE (dst->r_info);
221fddef416Sniklas   BFD_ASSERT (r_type < (unsigned int) R_MN10200_MAX);
222fddef416Sniklas   cache_ptr->howto = &elf_mn10200_howto_table[r_type];
223fddef416Sniklas }
224fddef416Sniklas 
225fddef416Sniklas /* Perform a relocation as part of a final link.  */
226d2201f2fSdrahn 
227fddef416Sniklas static bfd_reloc_status_type
mn10200_elf_final_link_relocate(howto,input_bfd,output_bfd,input_section,contents,offset,value,addend,info,sym_sec,is_local)228fddef416Sniklas mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
229fddef416Sniklas 				 input_section, contents, offset, value,
230fddef416Sniklas 				 addend, info, sym_sec, is_local)
231fddef416Sniklas      reloc_howto_type *howto;
232fddef416Sniklas      bfd *input_bfd;
233f7cc78ecSespie      bfd *output_bfd ATTRIBUTE_UNUSED;
234fddef416Sniklas      asection *input_section;
235fddef416Sniklas      bfd_byte *contents;
236fddef416Sniklas      bfd_vma offset;
237fddef416Sniklas      bfd_vma value;
238fddef416Sniklas      bfd_vma addend;
239f7cc78ecSespie      struct bfd_link_info *info ATTRIBUTE_UNUSED;
240f7cc78ecSespie      asection *sym_sec ATTRIBUTE_UNUSED;
241f7cc78ecSespie      int is_local ATTRIBUTE_UNUSED;
242fddef416Sniklas {
243fddef416Sniklas   unsigned long r_type = howto->type;
244fddef416Sniklas   bfd_byte *hit_data = contents + offset;
245fddef416Sniklas 
246fddef416Sniklas   switch (r_type)
247fddef416Sniklas     {
248fddef416Sniklas 
249fddef416Sniklas     case R_MN10200_NONE:
250fddef416Sniklas       return bfd_reloc_ok;
251fddef416Sniklas 
252fddef416Sniklas     case R_MN10200_32:
253fddef416Sniklas       value += addend;
254fddef416Sniklas       bfd_put_32 (input_bfd, value, hit_data);
255fddef416Sniklas       return bfd_reloc_ok;
256fddef416Sniklas 
257fddef416Sniklas     case R_MN10200_16:
258fddef416Sniklas       value += addend;
259fddef416Sniklas 
260fddef416Sniklas       if ((long) value > 0x7fff || (long) value < -0x8000)
261fddef416Sniklas 	return bfd_reloc_overflow;
262fddef416Sniklas 
263fddef416Sniklas       bfd_put_16 (input_bfd, value, hit_data);
264fddef416Sniklas       return bfd_reloc_ok;
265fddef416Sniklas 
266fddef416Sniklas     case R_MN10200_8:
267fddef416Sniklas       value += addend;
268fddef416Sniklas 
269f7cc78ecSespie       if ((long) value > 0x7f || (long) value < -0x80)
270fddef416Sniklas 	return bfd_reloc_overflow;
271fddef416Sniklas 
272fddef416Sniklas       bfd_put_8 (input_bfd, value, hit_data);
273fddef416Sniklas       return bfd_reloc_ok;
274fddef416Sniklas 
275fddef416Sniklas     case R_MN10200_24:
276fddef416Sniklas       value += addend;
277fddef416Sniklas 
278fddef416Sniklas       if ((long) value > 0x7fffff || (long) value < -0x800000)
279fddef416Sniklas 	return bfd_reloc_overflow;
280fddef416Sniklas 
281fddef416Sniklas       value &= 0xffffff;
282fddef416Sniklas       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
283fddef416Sniklas       bfd_put_32 (input_bfd, value, hit_data);
284fddef416Sniklas       return bfd_reloc_ok;
285fddef416Sniklas 
286fddef416Sniklas     case R_MN10200_PCREL8:
287fddef416Sniklas       value -= (input_section->output_section->vma
288fddef416Sniklas 		+ input_section->output_offset);
289f7cc78ecSespie       value -= (offset + 1);
290fddef416Sniklas       value += addend;
291fddef416Sniklas 
292fddef416Sniklas       if ((long) value > 0xff || (long) value < -0x100)
293fddef416Sniklas 	return bfd_reloc_overflow;
294fddef416Sniklas 
295fddef416Sniklas       bfd_put_8 (input_bfd, value, hit_data);
296fddef416Sniklas       return bfd_reloc_ok;
297fddef416Sniklas 
298fddef416Sniklas     case R_MN10200_PCREL16:
299fddef416Sniklas       value -= (input_section->output_section->vma
300fddef416Sniklas 		+ input_section->output_offset);
301f7cc78ecSespie       value -= (offset + 2);
302fddef416Sniklas       value += addend;
303fddef416Sniklas 
304fddef416Sniklas       if ((long) value > 0xffff || (long) value < -0x10000)
305fddef416Sniklas 	return bfd_reloc_overflow;
306fddef416Sniklas 
307fddef416Sniklas       bfd_put_16 (input_bfd, value, hit_data);
308fddef416Sniklas       return bfd_reloc_ok;
309fddef416Sniklas 
310fddef416Sniklas     case R_MN10200_PCREL24:
311fddef416Sniklas       value -= (input_section->output_section->vma
312fddef416Sniklas 		+ input_section->output_offset);
313f7cc78ecSespie       value -= (offset + 3);
314fddef416Sniklas       value += addend;
315fddef416Sniklas 
316fddef416Sniklas       if ((long) value > 0xffffff || (long) value < -0x1000000)
317fddef416Sniklas 	return bfd_reloc_overflow;
318fddef416Sniklas 
319fddef416Sniklas       value &= 0xffffff;
320fddef416Sniklas       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
321fddef416Sniklas       bfd_put_32 (input_bfd, value, hit_data);
322fddef416Sniklas       return bfd_reloc_ok;
323fddef416Sniklas 
324fddef416Sniklas     default:
325fddef416Sniklas       return bfd_reloc_notsupported;
326fddef416Sniklas     }
327fddef416Sniklas }
328fddef416Sniklas 
329fddef416Sniklas /* Relocate an MN10200 ELF section.  */
330d2201f2fSdrahn static bfd_boolean
mn10200_elf_relocate_section(output_bfd,info,input_bfd,input_section,contents,relocs,local_syms,local_sections)331fddef416Sniklas mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
332fddef416Sniklas 			      contents, relocs, local_syms, local_sections)
333fddef416Sniklas      bfd *output_bfd;
334fddef416Sniklas      struct bfd_link_info *info;
335fddef416Sniklas      bfd *input_bfd;
336fddef416Sniklas      asection *input_section;
337fddef416Sniklas      bfd_byte *contents;
338fddef416Sniklas      Elf_Internal_Rela *relocs;
339fddef416Sniklas      Elf_Internal_Sym *local_syms;
340fddef416Sniklas      asection **local_sections;
341fddef416Sniklas {
342fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
343fddef416Sniklas   struct elf_link_hash_entry **sym_hashes;
344fddef416Sniklas   Elf_Internal_Rela *rel, *relend;
345fddef416Sniklas 
346*cf2f2c56Smiod   if (info->relocatable)
347d2201f2fSdrahn     return TRUE;
348d2201f2fSdrahn 
349fddef416Sniklas   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
350fddef416Sniklas   sym_hashes = elf_sym_hashes (input_bfd);
351fddef416Sniklas 
352fddef416Sniklas   rel = relocs;
353fddef416Sniklas   relend = relocs + input_section->reloc_count;
354fddef416Sniklas   for (; rel < relend; rel++)
355fddef416Sniklas     {
356fddef416Sniklas       int r_type;
357fddef416Sniklas       reloc_howto_type *howto;
358fddef416Sniklas       unsigned long r_symndx;
359fddef416Sniklas       Elf_Internal_Sym *sym;
360fddef416Sniklas       asection *sec;
361fddef416Sniklas       struct elf_link_hash_entry *h;
362fddef416Sniklas       bfd_vma relocation;
363fddef416Sniklas       bfd_reloc_status_type r;
364fddef416Sniklas 
365fddef416Sniklas       r_symndx = ELF32_R_SYM (rel->r_info);
366fddef416Sniklas       r_type = ELF32_R_TYPE (rel->r_info);
367fddef416Sniklas       howto = elf_mn10200_howto_table + r_type;
368fddef416Sniklas 
369fddef416Sniklas       h = NULL;
370fddef416Sniklas       sym = NULL;
371fddef416Sniklas       sec = NULL;
372fddef416Sniklas       if (r_symndx < symtab_hdr->sh_info)
373fddef416Sniklas 	{
374fddef416Sniklas 	  sym = local_syms + r_symndx;
375fddef416Sniklas 	  sec = local_sections[r_symndx];
376*cf2f2c56Smiod 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
377fddef416Sniklas 	}
378fddef416Sniklas       else
379fddef416Sniklas 	{
380*cf2f2c56Smiod 	  bfd_boolean unresolved_reloc, warned;
381*cf2f2c56Smiod 
382*cf2f2c56Smiod 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
383*cf2f2c56Smiod 				   r_symndx, symtab_hdr, sym_hashes,
384*cf2f2c56Smiod 				   h, sec, relocation,
385*cf2f2c56Smiod 				   unresolved_reloc, warned);
386fddef416Sniklas 	}
387fddef416Sniklas 
388fddef416Sniklas       r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
389fddef416Sniklas 					   input_section,
390fddef416Sniklas 					   contents, rel->r_offset,
391fddef416Sniklas 					   relocation, rel->r_addend,
392fddef416Sniklas 					   info, sec, h == NULL);
393fddef416Sniklas 
394fddef416Sniklas       if (r != bfd_reloc_ok)
395fddef416Sniklas 	{
396fddef416Sniklas 	  const char *name;
397fddef416Sniklas 	  const char *msg = (const char *) 0;
398fddef416Sniklas 
399fddef416Sniklas 	  if (h != NULL)
400fddef416Sniklas 	    name = h->root.root.string;
401fddef416Sniklas 	  else
402fddef416Sniklas 	    {
403fddef416Sniklas 	      name = (bfd_elf_string_from_elf_section
404fddef416Sniklas 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
405fddef416Sniklas 	      if (name == NULL || *name == '\0')
406fddef416Sniklas 		name = bfd_section_name (input_bfd, sec);
407fddef416Sniklas 	    }
408fddef416Sniklas 
409fddef416Sniklas 	  switch (r)
410fddef416Sniklas 	    {
411fddef416Sniklas 	    case bfd_reloc_overflow:
412fddef416Sniklas 	      if (! ((*info->callbacks->reloc_overflow)
413fddef416Sniklas 		     (info, name, howto->name, (bfd_vma) 0,
414fddef416Sniklas 		      input_bfd, input_section, rel->r_offset)))
415d2201f2fSdrahn 		return FALSE;
416fddef416Sniklas 	      break;
417fddef416Sniklas 
418fddef416Sniklas 	    case bfd_reloc_undefined:
419fddef416Sniklas 	      if (! ((*info->callbacks->undefined_symbol)
420fddef416Sniklas 		     (info, name, input_bfd, input_section,
421d2201f2fSdrahn 		      rel->r_offset, TRUE)))
422d2201f2fSdrahn 		return FALSE;
423fddef416Sniklas 	      break;
424fddef416Sniklas 
425fddef416Sniklas 	    case bfd_reloc_outofrange:
426f7cc78ecSespie 	      msg = _("internal error: out of range error");
427fddef416Sniklas 	      goto common_error;
428fddef416Sniklas 
429fddef416Sniklas 	    case bfd_reloc_notsupported:
430f7cc78ecSespie 	      msg = _("internal error: unsupported relocation error");
431fddef416Sniklas 	      goto common_error;
432fddef416Sniklas 
433fddef416Sniklas 	    case bfd_reloc_dangerous:
434f7cc78ecSespie 	      msg = _("internal error: dangerous error");
435fddef416Sniklas 	      goto common_error;
436fddef416Sniklas 
437fddef416Sniklas 	    default:
438f7cc78ecSespie 	      msg = _("internal error: unknown error");
439fddef416Sniklas 	      /* fall through */
440fddef416Sniklas 
441fddef416Sniklas 	    common_error:
442fddef416Sniklas 	      if (!((*info->callbacks->warning)
443fddef416Sniklas 		    (info, msg, name, input_bfd, input_section,
444fddef416Sniklas 		     rel->r_offset)))
445d2201f2fSdrahn 		return FALSE;
446fddef416Sniklas 	      break;
447fddef416Sniklas 	    }
448fddef416Sniklas 	}
449fddef416Sniklas     }
450fddef416Sniklas 
451d2201f2fSdrahn   return TRUE;
452fddef416Sniklas }
453fddef416Sniklas 
454fddef416Sniklas /* This function handles relaxing for the mn10200.
455fddef416Sniklas 
456*cf2f2c56Smiod    There are quite a few relaxing opportunities available on the mn10200:
457fddef416Sniklas 
458fddef416Sniklas 	* jsr:24 -> jsr:16 					   2 bytes
459fddef416Sniklas 
460fddef416Sniklas 	* jmp:24 -> jmp:16					   2 bytes
461fddef416Sniklas 	* jmp:16 -> bra:8					   1 byte
462fddef416Sniklas 
463fddef416Sniklas 		* If the previous instruction is a conditional branch
464fddef416Sniklas 		around the jump/bra, we may be able to reverse its condition
465fddef416Sniklas 		and change its target to the jump's target.  The jump/bra
466fddef416Sniklas 		can then be deleted.				   2 bytes
467fddef416Sniklas 
468fddef416Sniklas 	* mov abs24 -> mov abs16	2 byte savings
469fddef416Sniklas 
470fddef416Sniklas 	* Most instructions which accept imm24 can relax to imm16  2 bytes
471fddef416Sniklas 	- Most instructions which accept imm16 can relax to imm8   1 byte
472fddef416Sniklas 
473fddef416Sniklas 	* Most instructions which accept d24 can relax to d16	   2 bytes
474fddef416Sniklas 	- Most instructions which accept d16 can relax to d8	   1 byte
475fddef416Sniklas 
476fddef416Sniklas 	abs24, imm24, d24 all look the same at the reloc level.  It
477fddef416Sniklas 	might make the code simpler if we had different relocs for
478fddef416Sniklas 	the various relaxable operand types.
479fddef416Sniklas 
480fddef416Sniklas 	We don't handle imm16->imm8 or d16->d8 as they're very rare
481fddef416Sniklas 	and somewhat more difficult to support.  */
482fddef416Sniklas 
483d2201f2fSdrahn static bfd_boolean
mn10200_elf_relax_section(abfd,sec,link_info,again)484fddef416Sniklas mn10200_elf_relax_section (abfd, sec, link_info, again)
485fddef416Sniklas      bfd *abfd;
486fddef416Sniklas      asection *sec;
487fddef416Sniklas      struct bfd_link_info *link_info;
488d2201f2fSdrahn      bfd_boolean *again;
489fddef416Sniklas {
490fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
491fddef416Sniklas   Elf_Internal_Rela *internal_relocs;
492fddef416Sniklas   Elf_Internal_Rela *irel, *irelend;
493fddef416Sniklas   bfd_byte *contents = NULL;
494d2201f2fSdrahn   Elf_Internal_Sym *isymbuf = NULL;
495fddef416Sniklas 
496fddef416Sniklas   /* Assume nothing changes.  */
497d2201f2fSdrahn   *again = FALSE;
498fddef416Sniklas 
499*cf2f2c56Smiod   /* We don't have to do anything for a relocatable link, if
500fddef416Sniklas      this section does not have relocs, or if this is not a
501fddef416Sniklas      code section.  */
502*cf2f2c56Smiod   if (link_info->relocatable
503fddef416Sniklas       || (sec->flags & SEC_RELOC) == 0
504fddef416Sniklas       || sec->reloc_count == 0
505fddef416Sniklas       || (sec->flags & SEC_CODE) == 0)
506d2201f2fSdrahn     return TRUE;
507fddef416Sniklas 
508fddef416Sniklas   /* If this is the first time we have been called for this section,
509fddef416Sniklas      initialize the cooked size.  */
510fddef416Sniklas   if (sec->_cooked_size == 0)
511fddef416Sniklas     sec->_cooked_size = sec->_raw_size;
512fddef416Sniklas 
513fddef416Sniklas   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
514fddef416Sniklas 
515fddef416Sniklas   /* Get a copy of the native relocations.  */
516*cf2f2c56Smiod   internal_relocs = (_bfd_elf_link_read_relocs
517fddef416Sniklas 		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
518fddef416Sniklas 		      link_info->keep_memory));
519fddef416Sniklas   if (internal_relocs == NULL)
520fddef416Sniklas     goto error_return;
521fddef416Sniklas 
522fddef416Sniklas   /* Walk through them looking for relaxing opportunities.  */
523fddef416Sniklas   irelend = internal_relocs + sec->reloc_count;
524fddef416Sniklas   for (irel = internal_relocs; irel < irelend; irel++)
525fddef416Sniklas     {
526fddef416Sniklas       bfd_vma symval;
527fddef416Sniklas 
528fddef416Sniklas       /* If this isn't something that can be relaxed, then ignore
529fddef416Sniklas 	 this reloc.  */
530fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
531fddef416Sniklas 	  || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
532fddef416Sniklas 	  || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
533fddef416Sniklas 	continue;
534fddef416Sniklas 
535fddef416Sniklas       /* Get the section contents if we haven't done so already.  */
536fddef416Sniklas       if (contents == NULL)
537fddef416Sniklas 	{
538fddef416Sniklas 	  /* Get cached copy if it exists.  */
539fddef416Sniklas 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
540fddef416Sniklas 	    contents = elf_section_data (sec)->this_hdr.contents;
541fddef416Sniklas 	  else
542fddef416Sniklas 	    {
543fddef416Sniklas 	      /* Go get them off disk.  */
544fddef416Sniklas 	      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
545fddef416Sniklas 	      if (contents == NULL)
546fddef416Sniklas 		goto error_return;
547fddef416Sniklas 
548fddef416Sniklas 	      if (! bfd_get_section_contents (abfd, sec, contents,
549fddef416Sniklas 					      (file_ptr) 0, sec->_raw_size))
550fddef416Sniklas 		goto error_return;
551fddef416Sniklas 	    }
552fddef416Sniklas 	}
553fddef416Sniklas 
554d2201f2fSdrahn       /* Read this BFD's local symbols if we haven't done so already.  */
555d2201f2fSdrahn       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
556fddef416Sniklas 	{
557d2201f2fSdrahn 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
558d2201f2fSdrahn 	  if (isymbuf == NULL)
559d2201f2fSdrahn 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
560d2201f2fSdrahn 					    symtab_hdr->sh_info, 0,
561d2201f2fSdrahn 					    NULL, NULL, NULL);
562d2201f2fSdrahn 	  if (isymbuf == NULL)
563fddef416Sniklas 	    goto error_return;
564fddef416Sniklas 	}
565fddef416Sniklas 
566fddef416Sniklas       /* Get the value of the symbol referred to by the reloc.  */
567fddef416Sniklas       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
568fddef416Sniklas 	{
569d2201f2fSdrahn 	  /* A local symbol.  */
570d2201f2fSdrahn 	  Elf_Internal_Sym *isym;
571fddef416Sniklas 	  asection *sym_sec;
572fddef416Sniklas 
573d2201f2fSdrahn 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
574d2201f2fSdrahn 	  if (isym->st_shndx == SHN_UNDEF)
575d2201f2fSdrahn 	    sym_sec = bfd_und_section_ptr;
576d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_ABS)
577d2201f2fSdrahn 	    sym_sec = bfd_abs_section_ptr;
578d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_COMMON)
579d2201f2fSdrahn 	    sym_sec = bfd_com_section_ptr;
580d2201f2fSdrahn 	  else
581d2201f2fSdrahn 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
582d2201f2fSdrahn 	  symval = (isym->st_value
583fddef416Sniklas 		    + sym_sec->output_section->vma
584fddef416Sniklas 		    + sym_sec->output_offset);
585fddef416Sniklas 	}
586fddef416Sniklas       else
587fddef416Sniklas 	{
588fddef416Sniklas 	  unsigned long indx;
589fddef416Sniklas 	  struct elf_link_hash_entry *h;
590fddef416Sniklas 
591fddef416Sniklas 	  /* An external symbol.  */
592fddef416Sniklas 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
593fddef416Sniklas 	  h = elf_sym_hashes (abfd)[indx];
594fddef416Sniklas 	  BFD_ASSERT (h != NULL);
595fddef416Sniklas 	  if (h->root.type != bfd_link_hash_defined
596fddef416Sniklas 	      && h->root.type != bfd_link_hash_defweak)
597fddef416Sniklas 	    {
598fddef416Sniklas 	      /* This appears to be a reference to an undefined
599fddef416Sniklas                  symbol.  Just ignore it--it will be caught by the
600fddef416Sniklas                  regular reloc processing.  */
601fddef416Sniklas 	      continue;
602fddef416Sniklas 	    }
603fddef416Sniklas 
604fddef416Sniklas 	  symval = (h->root.u.def.value
605fddef416Sniklas 		    + h->root.u.def.section->output_section->vma
606fddef416Sniklas 		    + h->root.u.def.section->output_offset);
607fddef416Sniklas 	}
608fddef416Sniklas 
609fddef416Sniklas       /* For simplicity of coding, we are going to modify the section
610fddef416Sniklas 	 contents, the section relocs, and the BFD symbol table.  We
611fddef416Sniklas 	 must tell the rest of the code not to free up this
612fddef416Sniklas 	 information.  It would be possible to instead create a table
613fddef416Sniklas 	 of changes which have to be made, as is done in coff-mips.c;
614fddef416Sniklas 	 that would be more work, but would require less memory when
615fddef416Sniklas 	 the linker is run.  */
616fddef416Sniklas 
617fddef416Sniklas       /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
618fddef416Sniklas 	 branch/call.  */
619fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
620fddef416Sniklas 	{
621fddef416Sniklas 	  bfd_vma value = symval;
622fddef416Sniklas 
623fddef416Sniklas 	  /* Deal with pc-relative gunk.  */
624fddef416Sniklas 	  value -= (sec->output_section->vma + sec->output_offset);
625f7cc78ecSespie 	  value -= (irel->r_offset + 3);
626fddef416Sniklas 	  value += irel->r_addend;
627fddef416Sniklas 
628fddef416Sniklas 	  /* See if the value will fit in 16 bits, note the high value is
629fddef416Sniklas 	     0x7fff + 2 as the target will be two bytes closer if we are
630fddef416Sniklas 	     able to relax.  */
631fddef416Sniklas 	  if ((long) value < 0x8001 && (long) value > -0x8000)
632fddef416Sniklas 	    {
633fddef416Sniklas 	      unsigned char code;
634fddef416Sniklas 
635fddef416Sniklas 	      /* Get the opcode.  */
636fddef416Sniklas 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
637fddef416Sniklas 
638fddef416Sniklas 	      if (code != 0xe0 && code != 0xe1)
639fddef416Sniklas 		continue;
640fddef416Sniklas 
641fddef416Sniklas 	      /* Note that we've changed the relocs, section contents, etc.  */
642fddef416Sniklas 	      elf_section_data (sec)->relocs = internal_relocs;
643fddef416Sniklas 	      elf_section_data (sec)->this_hdr.contents = contents;
644d2201f2fSdrahn 	      symtab_hdr->contents = (unsigned char *) isymbuf;
645fddef416Sniklas 
646fddef416Sniklas 	      /* Fix the opcode.  */
647fddef416Sniklas 	      if (code == 0xe0)
648fddef416Sniklas 		bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
649fddef416Sniklas 	      else if (code == 0xe1)
650fddef416Sniklas 		bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
651fddef416Sniklas 
652fddef416Sniklas 	      /* Fix the relocation's type.  */
653fddef416Sniklas 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
654fddef416Sniklas 					   R_MN10200_PCREL16);
655fddef416Sniklas 
656f7cc78ecSespie 	      /* The opcode got shorter too, so we have to fix the offset.  */
657fddef416Sniklas 	      irel->r_offset -= 1;
658fddef416Sniklas 
659fddef416Sniklas 	      /* Delete two bytes of data.  */
660fddef416Sniklas 	      if (!mn10200_elf_relax_delete_bytes (abfd, sec,
661fddef416Sniklas 						   irel->r_offset + 1, 2))
662fddef416Sniklas 		goto error_return;
663fddef416Sniklas 
664fddef416Sniklas 	      /* That will change things, so, we should relax again.
665fddef416Sniklas 		 Note that this is not required, and it may be slow.  */
666d2201f2fSdrahn 	      *again = TRUE;
667fddef416Sniklas 	    }
668fddef416Sniklas 	}
669fddef416Sniklas 
670fddef416Sniklas       /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
671fddef416Sniklas 	 branch.  */
672fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
673fddef416Sniklas 	{
674fddef416Sniklas 	  bfd_vma value = symval;
675fddef416Sniklas 
676fddef416Sniklas 	  /* Deal with pc-relative gunk.  */
677fddef416Sniklas 	  value -= (sec->output_section->vma + sec->output_offset);
678f7cc78ecSespie 	  value -= (irel->r_offset + 2);
679fddef416Sniklas 	  value += irel->r_addend;
680fddef416Sniklas 
681fddef416Sniklas 	  /* See if the value will fit in 8 bits, note the high value is
682fddef416Sniklas 	     0x7f + 1 as the target will be one bytes closer if we are
683fddef416Sniklas 	     able to relax.  */
684fddef416Sniklas 	  if ((long) value < 0x80 && (long) value > -0x80)
685fddef416Sniklas 	    {
686fddef416Sniklas 	      unsigned char code;
687fddef416Sniklas 
688fddef416Sniklas 	      /* Get the opcode.  */
689fddef416Sniklas 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
690fddef416Sniklas 
691fddef416Sniklas 	      if (code != 0xfc)
692fddef416Sniklas 		continue;
693fddef416Sniklas 
694fddef416Sniklas 	      /* Note that we've changed the relocs, section contents, etc.  */
695fddef416Sniklas 	      elf_section_data (sec)->relocs = internal_relocs;
696fddef416Sniklas 	      elf_section_data (sec)->this_hdr.contents = contents;
697d2201f2fSdrahn 	      symtab_hdr->contents = (unsigned char *) isymbuf;
698fddef416Sniklas 
699fddef416Sniklas 	      /* Fix the opcode.  */
700fddef416Sniklas 	      bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
701fddef416Sniklas 
702fddef416Sniklas 	      /* Fix the relocation's type.  */
703fddef416Sniklas 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
704fddef416Sniklas 					   R_MN10200_PCREL8);
705fddef416Sniklas 
706fddef416Sniklas 	      /* Delete one byte of data.  */
707fddef416Sniklas 	      if (!mn10200_elf_relax_delete_bytes (abfd, sec,
708fddef416Sniklas 						   irel->r_offset + 1, 1))
709fddef416Sniklas 		goto error_return;
710fddef416Sniklas 
711fddef416Sniklas 	      /* That will change things, so, we should relax again.
712fddef416Sniklas 		 Note that this is not required, and it may be slow.  */
713d2201f2fSdrahn 	      *again = TRUE;
714fddef416Sniklas 	    }
715fddef416Sniklas 	}
716fddef416Sniklas 
717fddef416Sniklas       /* Try to eliminate an unconditional 8 bit pc-relative branch
718fddef416Sniklas 	 which immediately follows a conditional 8 bit pc-relative
719fddef416Sniklas 	 branch around the unconditional branch.
720fddef416Sniklas 
721fddef416Sniklas 	    original:		new:
722fddef416Sniklas 	    bCC lab1		bCC' lab2
723fddef416Sniklas 	    bra lab2
724fddef416Sniklas 	   lab1:	       lab1:
725fddef416Sniklas 
726fddef416Sniklas 	 This happens when the bCC can't reach lab2 at assembly time,
727fddef416Sniklas 	 but due to other relaxations it can reach at link time.  */
728fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
729fddef416Sniklas 	{
730fddef416Sniklas 	  Elf_Internal_Rela *nrel;
731fddef416Sniklas 	  bfd_vma value = symval;
732fddef416Sniklas 	  unsigned char code;
733fddef416Sniklas 
734fddef416Sniklas 	  /* Deal with pc-relative gunk.  */
735fddef416Sniklas 	  value -= (sec->output_section->vma + sec->output_offset);
736f7cc78ecSespie 	  value -= (irel->r_offset + 1);
737fddef416Sniklas 	  value += irel->r_addend;
738fddef416Sniklas 
739fddef416Sniklas 	  /* Do nothing if this reloc is the last byte in the section.  */
740fddef416Sniklas 	  if (irel->r_offset == sec->_cooked_size)
741fddef416Sniklas 	    continue;
742fddef416Sniklas 
743fddef416Sniklas 	  /* See if the next instruction is an unconditional pc-relative
744fddef416Sniklas 	     branch, more often than not this test will fail, so we
745fddef416Sniklas 	     test it first to speed things up.  */
746fddef416Sniklas 	  code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
747fddef416Sniklas 	  if (code != 0xea)
748fddef416Sniklas 	    continue;
749fddef416Sniklas 
750fddef416Sniklas 	  /* Also make sure the next relocation applies to the next
751fddef416Sniklas 	     instruction and that it's a pc-relative 8 bit branch.  */
752fddef416Sniklas 	  nrel = irel + 1;
753fddef416Sniklas 	  if (nrel == irelend
754fddef416Sniklas 	      || irel->r_offset + 2 != nrel->r_offset
755fddef416Sniklas 	      || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
756fddef416Sniklas 	    continue;
757fddef416Sniklas 
758fddef416Sniklas 	  /* Make sure our destination immediately follows the
759fddef416Sniklas 	     unconditional branch.  */
760fddef416Sniklas 	  if (symval != (sec->output_section->vma + sec->output_offset
761fddef416Sniklas 			 + irel->r_offset + 3))
762fddef416Sniklas 	    continue;
763fddef416Sniklas 
764fddef416Sniklas 	  /* Now make sure we are a conditional branch.  This may not
765fddef416Sniklas 	     be necessary, but why take the chance.
766fddef416Sniklas 
767fddef416Sniklas 	     Note these checks assume that R_MN10200_PCREL8 relocs
768fddef416Sniklas 	     only occur on bCC and bCCx insns.  If they occured
769fddef416Sniklas 	     elsewhere, we'd need to know the start of this insn
770fddef416Sniklas 	     for this check to be accurate.  */
771fddef416Sniklas 	  code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
772fddef416Sniklas 	  if (code != 0xe0 && code != 0xe1 && code != 0xe2
773fddef416Sniklas 	      && code != 0xe3 && code != 0xe4 && code != 0xe5
774fddef416Sniklas 	      && code != 0xe6 && code != 0xe7 && code != 0xe8
775fddef416Sniklas 	      && code != 0xe9 && code != 0xec && code != 0xed
776fddef416Sniklas 	      && code != 0xee && code != 0xef && code != 0xfc
777fddef416Sniklas 	      && code != 0xfd && code != 0xfe && code != 0xff)
778fddef416Sniklas 	    continue;
779fddef416Sniklas 
780fddef416Sniklas 	  /* We also have to be sure there is no symbol/label
781fddef416Sniklas 	     at the unconditional branch.  */
782d2201f2fSdrahn 	  if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
783fddef416Sniklas 					    irel->r_offset + 1))
784fddef416Sniklas 	    continue;
785fddef416Sniklas 
786fddef416Sniklas 	  /* Note that we've changed the relocs, section contents, etc.  */
787fddef416Sniklas 	  elf_section_data (sec)->relocs = internal_relocs;
788fddef416Sniklas 	  elf_section_data (sec)->this_hdr.contents = contents;
789d2201f2fSdrahn 	  symtab_hdr->contents = (unsigned char *) isymbuf;
790fddef416Sniklas 
791fddef416Sniklas 	  /* Reverse the condition of the first branch.  */
792fddef416Sniklas 	  switch (code)
793fddef416Sniklas 	    {
794fddef416Sniklas 	    case 0xfc:
795fddef416Sniklas 	      code = 0xfd;
796fddef416Sniklas 	      break;
797fddef416Sniklas 	    case 0xfd:
798fddef416Sniklas 	      code = 0xfc;
799fddef416Sniklas 	      break;
800fddef416Sniklas 	    case 0xfe:
801fddef416Sniklas 	      code = 0xff;
802fddef416Sniklas 	      break;
803fddef416Sniklas 	    case 0xff:
804fddef416Sniklas 	      code = 0xfe;
805fddef416Sniklas 	      break;
806fddef416Sniklas 	    case 0xe8:
807fddef416Sniklas 	      code = 0xe9;
808fddef416Sniklas 	      break;
809fddef416Sniklas 	    case 0xe9:
810fddef416Sniklas 	      code = 0xe8;
811fddef416Sniklas 	      break;
812fddef416Sniklas 	    case 0xe0:
813fddef416Sniklas 	      code = 0xe2;
814fddef416Sniklas 	      break;
815fddef416Sniklas 	    case 0xe2:
816fddef416Sniklas 	      code = 0xe0;
817fddef416Sniklas 	      break;
818fddef416Sniklas 	    case 0xe3:
819fddef416Sniklas 	      code = 0xe1;
820fddef416Sniklas 	      break;
821fddef416Sniklas 	    case 0xe1:
822fddef416Sniklas 	      code = 0xe3;
823fddef416Sniklas 	      break;
824fddef416Sniklas 	    case 0xe4:
825fddef416Sniklas 	      code = 0xe6;
826fddef416Sniklas 	      break;
827fddef416Sniklas 	    case 0xe6:
828fddef416Sniklas 	      code = 0xe4;
829fddef416Sniklas 	      break;
830fddef416Sniklas 	    case 0xe7:
831fddef416Sniklas 	      code = 0xe5;
832fddef416Sniklas 	      break;
833fddef416Sniklas 	    case 0xe5:
834fddef416Sniklas 	      code = 0xe7;
835fddef416Sniklas 	      break;
836fddef416Sniklas 	    case 0xec:
837fddef416Sniklas 	      code = 0xed;
838fddef416Sniklas 	      break;
839fddef416Sniklas 	    case 0xed:
840fddef416Sniklas 	      code = 0xec;
841fddef416Sniklas 	      break;
842fddef416Sniklas 	    case 0xee:
843fddef416Sniklas 	      code = 0xef;
844fddef416Sniklas 	      break;
845fddef416Sniklas 	    case 0xef:
846fddef416Sniklas 	      code = 0xee;
847fddef416Sniklas 	      break;
848fddef416Sniklas 	    }
849fddef416Sniklas 	  bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
850fddef416Sniklas 
851fddef416Sniklas 	  /* Set the reloc type and symbol for the first branch
852fddef416Sniklas 	     from the second branch.  */
853fddef416Sniklas 	  irel->r_info = nrel->r_info;
854fddef416Sniklas 
855fddef416Sniklas 	  /* Make the reloc for the second branch a null reloc.  */
856fddef416Sniklas 	  nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
857fddef416Sniklas 				       R_MN10200_NONE);
858fddef416Sniklas 
859fddef416Sniklas 	  /* Delete two bytes of data.  */
860fddef416Sniklas 	  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
861fddef416Sniklas 					       irel->r_offset + 1, 2))
862fddef416Sniklas 	    goto error_return;
863fddef416Sniklas 
864fddef416Sniklas 	  /* That will change things, so, we should relax again.
865fddef416Sniklas 	     Note that this is not required, and it may be slow.  */
866d2201f2fSdrahn 	  *again = TRUE;
867fddef416Sniklas 	}
868fddef416Sniklas 
869fddef416Sniklas       /* Try to turn a 24bit immediate, displacement or absolute address
870fddef416Sniklas 	 into a 16bit immediate, displacement or absolute address.  */
871fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
872fddef416Sniklas 	{
873fddef416Sniklas 	  bfd_vma value = symval;
874fddef416Sniklas 
875fddef416Sniklas 	  /* See if the value will fit in 16 bits.
876fddef416Sniklas 	     We allow any 16bit match here.  We prune those we can't
877fddef416Sniklas 	     handle below.  */
878fddef416Sniklas 	  if ((long) value < 0x7fff && (long) value > -0x8000)
879fddef416Sniklas 	    {
880fddef416Sniklas 	      unsigned char code;
881fddef416Sniklas 
882fddef416Sniklas 	      /* All insns which have 24bit operands are 5 bytes long,
883fddef416Sniklas 		 the first byte will always be 0xf4, but we double check
884fddef416Sniklas 		 it just in case.  */
885fddef416Sniklas 
886fddef416Sniklas 	      /* Get the first opcode.  */
887fddef416Sniklas 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
888fddef416Sniklas 
889fddef416Sniklas 	      if (code != 0xf4)
890fddef416Sniklas 		continue;
891fddef416Sniklas 
892fddef416Sniklas 	      /* Get the second opcode.  */
893fddef416Sniklas 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
894fddef416Sniklas 
895fddef416Sniklas 	      switch (code & 0xfc)
896fddef416Sniklas 		{
897fddef416Sniklas 		/* mov imm24,dn -> mov imm16,dn */
898fddef416Sniklas 		case 0x70:
899fddef416Sniklas 		  /* Not safe if the high bit is on as relaxing may
900fddef416Sniklas 		     move the value out of high mem and thus not fit
901fddef416Sniklas 		     in a signed 16bit value.  */
902fddef416Sniklas 		  if (value & 0x8000)
903fddef416Sniklas 		    continue;
904fddef416Sniklas 
905*cf2f2c56Smiod 		  /* Note that we've changed the relocation contents, etc.  */
906fddef416Sniklas 		  elf_section_data (sec)->relocs = internal_relocs;
907fddef416Sniklas 		  elf_section_data (sec)->this_hdr.contents = contents;
908d2201f2fSdrahn 		  symtab_hdr->contents = (unsigned char *) isymbuf;
909fddef416Sniklas 
910fddef416Sniklas 		  /* Fix the opcode.  */
911fddef416Sniklas 		  bfd_put_8 (abfd, 0xf8 + (code & 0x03),
912fddef416Sniklas 			     contents + irel->r_offset - 2);
913fddef416Sniklas 
914fddef416Sniklas 		  /* Fix the relocation's type.  */
915fddef416Sniklas 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
916fddef416Sniklas 					       R_MN10200_16);
917fddef416Sniklas 
918fddef416Sniklas 		  /* The opcode got shorter too, so we have to fix the
919f7cc78ecSespie 		     offset.  */
920fddef416Sniklas 		  irel->r_offset -= 1;
921fddef416Sniklas 
922fddef416Sniklas 		  /* Delete two bytes of data.  */
923fddef416Sniklas 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
924fddef416Sniklas 						       irel->r_offset + 1, 2))
925fddef416Sniklas 		    goto error_return;
926fddef416Sniklas 
927fddef416Sniklas 		  /* That will change things, so, we should relax again.
928fddef416Sniklas 		     Note that this is not required, and it may be slow.  */
929d2201f2fSdrahn 		  *again = TRUE;
930fddef416Sniklas 		  break;
931fddef416Sniklas 
932fddef416Sniklas 		/* mov imm24,an -> mov imm16,an
933fddef416Sniklas 		   cmp imm24,an -> cmp imm16,an
934fddef416Sniklas 		   mov (abs24),dn -> mov (abs16),dn
935fddef416Sniklas 		   mov dn,(abs24) -> mov dn,(abs16)
936fddef416Sniklas 		   movb dn,(abs24) -> movb dn,(abs16)
937fddef416Sniklas 		   movbu (abs24),dn -> movbu (abs16),dn */
938fddef416Sniklas 		case 0x74:
939fddef416Sniklas 		case 0x7c:
940fddef416Sniklas 		case 0xc0:
941fddef416Sniklas 		case 0x40:
942fddef416Sniklas 		case 0x44:
943fddef416Sniklas 		case 0xc8:
944*cf2f2c56Smiod 		  /* Note that we've changed the relocation contents, etc.  */
945fddef416Sniklas 		  elf_section_data (sec)->relocs = internal_relocs;
946fddef416Sniklas 		  elf_section_data (sec)->this_hdr.contents = contents;
947d2201f2fSdrahn 		  symtab_hdr->contents = (unsigned char *) isymbuf;
948fddef416Sniklas 
949fddef416Sniklas 		  if ((code & 0xfc) == 0x74)
950fddef416Sniklas 		    code = 0xdc + (code & 0x03);
951fddef416Sniklas 		  else if ((code & 0xfc) == 0x7c)
952fddef416Sniklas 		    code = 0xec + (code & 0x03);
953fddef416Sniklas 		  else if ((code & 0xfc) == 0xc0)
954fddef416Sniklas 		    code = 0xc8 + (code & 0x03);
955fddef416Sniklas 		  else if ((code & 0xfc) == 0x40)
956fddef416Sniklas 		    code = 0xc0 + (code & 0x03);
957fddef416Sniklas 		  else if ((code & 0xfc) == 0x44)
958fddef416Sniklas 		    code = 0xc4 + (code & 0x03);
959fddef416Sniklas 		  else if ((code & 0xfc) == 0xc8)
960fddef416Sniklas 		    code = 0xcc + (code & 0x03);
961fddef416Sniklas 
962fddef416Sniklas 		  /* Fix the opcode.  */
963fddef416Sniklas 		  bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
964fddef416Sniklas 
965fddef416Sniklas 		  /* Fix the relocation's type.  */
966fddef416Sniklas 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
967fddef416Sniklas 					       R_MN10200_16);
968fddef416Sniklas 
969fddef416Sniklas 		  /* The opcode got shorter too, so we have to fix the
970f7cc78ecSespie 		     offset.  */
971fddef416Sniklas 		  irel->r_offset -= 1;
972fddef416Sniklas 
973fddef416Sniklas 		  /* Delete two bytes of data.  */
974fddef416Sniklas 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
975fddef416Sniklas 						       irel->r_offset + 1, 2))
976fddef416Sniklas 		    goto error_return;
977fddef416Sniklas 
978fddef416Sniklas 		  /* That will change things, so, we should relax again.
979fddef416Sniklas 		     Note that this is not required, and it may be slow.  */
980d2201f2fSdrahn 		  *again = TRUE;
981fddef416Sniklas 		  break;
982fddef416Sniklas 
983fddef416Sniklas 		/* cmp imm24,dn -> cmp imm16,dn
984fddef416Sniklas 		   mov (abs24),an -> mov (abs16),an
985fddef416Sniklas 		   mov an,(abs24) -> mov an,(abs16)
986fddef416Sniklas 		   add imm24,dn -> add imm16,dn
987fddef416Sniklas 		   add imm24,an -> add imm16,an
988fddef416Sniklas 		   sub imm24,dn -> sub imm16,dn
989fddef416Sniklas 		   sub imm24,an -> sub imm16,an
990fddef416Sniklas 		   And all d24->d16 in memory ops.  */
991fddef416Sniklas 		case 0x78:
992fddef416Sniklas 		case 0xd0:
993fddef416Sniklas 		case 0x50:
994fddef416Sniklas 		case 0x60:
995fddef416Sniklas 		case 0x64:
996fddef416Sniklas 		case 0x68:
997fddef416Sniklas 		case 0x6c:
998fddef416Sniklas 		case 0x80:
999fddef416Sniklas 		case 0xf0:
1000fddef416Sniklas 		case 0x00:
1001fddef416Sniklas 		case 0x10:
1002fddef416Sniklas 		case 0xb0:
1003fddef416Sniklas 		case 0x30:
1004fddef416Sniklas 		case 0xa0:
1005fddef416Sniklas 		case 0x20:
1006fddef416Sniklas 		case 0x90:
1007fddef416Sniklas 		  /* Not safe if the high bit is on as relaxing may
1008fddef416Sniklas 		     move the value out of high mem and thus not fit
1009fddef416Sniklas 		     in a signed 16bit value.  */
1010fddef416Sniklas 		  if (((code & 0xfc) == 0x78
1011fddef416Sniklas 		       || (code & 0xfc) == 0x60
1012fddef416Sniklas 		       || (code & 0xfc) == 0x64
1013fddef416Sniklas 		       || (code & 0xfc) == 0x68
1014fddef416Sniklas 		       || (code & 0xfc) == 0x6c
1015fddef416Sniklas 		       || (code & 0xfc) == 0x80
1016fddef416Sniklas 		       || (code & 0xfc) == 0xf0
1017fddef416Sniklas 		       || (code & 0xfc) == 0x00
1018fddef416Sniklas 		       || (code & 0xfc) == 0x10
1019fddef416Sniklas 		       || (code & 0xfc) == 0xb0
1020fddef416Sniklas 		       || (code & 0xfc) == 0x30
1021fddef416Sniklas 		       || (code & 0xfc) == 0xa0
1022fddef416Sniklas 		       || (code & 0xfc) == 0x20
1023fddef416Sniklas 		       || (code & 0xfc) == 0x90)
1024fddef416Sniklas 		      && (value & 0x8000) != 0)
1025fddef416Sniklas 		    continue;
1026fddef416Sniklas 
1027*cf2f2c56Smiod 		  /* Note that we've changed the relocation contents, etc.  */
1028fddef416Sniklas 		  elf_section_data (sec)->relocs = internal_relocs;
1029fddef416Sniklas 		  elf_section_data (sec)->this_hdr.contents = contents;
1030d2201f2fSdrahn 		  symtab_hdr->contents = (unsigned char *) isymbuf;
1031fddef416Sniklas 
1032fddef416Sniklas 		  /* Fix the opcode.  */
1033fddef416Sniklas 		  bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
1034fddef416Sniklas 
1035fddef416Sniklas 		  if ((code & 0xfc) == 0x78)
1036fddef416Sniklas 		    code = 0x48 + (code & 0x03);
1037fddef416Sniklas 		  else if ((code & 0xfc) == 0xd0)
1038fddef416Sniklas 		    code = 0x30 + (code & 0x03);
1039fddef416Sniklas 		  else if ((code & 0xfc) == 0x50)
1040fddef416Sniklas 		    code = 0x20 + (code & 0x03);
1041fddef416Sniklas 		  else if ((code & 0xfc) == 0x60)
1042fddef416Sniklas 		    code = 0x18 + (code & 0x03);
1043fddef416Sniklas 		  else if ((code & 0xfc) == 0x64)
1044fddef416Sniklas 		    code = 0x08 + (code & 0x03);
1045fddef416Sniklas 		  else if ((code & 0xfc) == 0x68)
1046fddef416Sniklas 		    code = 0x1c + (code & 0x03);
1047fddef416Sniklas 		  else if ((code & 0xfc) == 0x6c)
1048fddef416Sniklas 		    code = 0x0c + (code & 0x03);
1049fddef416Sniklas 		  else if ((code & 0xfc) == 0x80)
1050fddef416Sniklas 		    code = 0xc0 + (code & 0x07);
1051fddef416Sniklas 		  else if ((code & 0xfc) == 0xf0)
1052fddef416Sniklas 		    code = 0xb0 + (code & 0x07);
1053fddef416Sniklas 		  else if ((code & 0xfc) == 0x00)
1054fddef416Sniklas 		    code = 0x80 + (code & 0x07);
1055fddef416Sniklas 		  else if ((code & 0xfc) == 0x10)
1056fddef416Sniklas 		    code = 0xa0 + (code & 0x07);
1057fddef416Sniklas 		  else if ((code & 0xfc) == 0xb0)
1058fddef416Sniklas 		    code = 0x70 + (code & 0x07);
1059fddef416Sniklas 		  else if ((code & 0xfc) == 0x30)
1060fddef416Sniklas 		    code = 0x60 + (code & 0x07);
1061fddef416Sniklas 		  else if ((code & 0xfc) == 0xa0)
1062fddef416Sniklas 		    code = 0xd0 + (code & 0x07);
1063fddef416Sniklas 		  else if ((code & 0xfc) == 0x20)
1064fddef416Sniklas 		    code = 0x90 + (code & 0x07);
1065fddef416Sniklas 		  else if ((code & 0xfc) == 0x90)
1066fddef416Sniklas 		    code = 0x50 + (code & 0x07);
1067fddef416Sniklas 
1068fddef416Sniklas 		  bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1069fddef416Sniklas 
1070fddef416Sniklas 		  /* Fix the relocation's type.  */
1071fddef416Sniklas 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1072fddef416Sniklas 					       R_MN10200_16);
1073fddef416Sniklas 
1074fddef416Sniklas 		  /* Delete one bytes of data.  */
1075fddef416Sniklas 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1076fddef416Sniklas 						       irel->r_offset + 2, 1))
1077fddef416Sniklas 		    goto error_return;
1078fddef416Sniklas 
1079fddef416Sniklas 		  /* That will change things, so, we should relax again.
1080fddef416Sniklas 		     Note that this is not required, and it may be slow.  */
1081d2201f2fSdrahn 		  *again = TRUE;
1082fddef416Sniklas 		  break;
1083fddef416Sniklas 
1084fddef416Sniklas 		/* movb (abs24),dn ->movbu (abs16),dn extxb bn */
1085fddef416Sniklas 		case 0xc4:
1086fddef416Sniklas 		  /* Note that we've changed the reldection contents, etc.  */
1087fddef416Sniklas 		  elf_section_data (sec)->relocs = internal_relocs;
1088fddef416Sniklas 		  elf_section_data (sec)->this_hdr.contents = contents;
1089d2201f2fSdrahn 		  symtab_hdr->contents = (unsigned char *) isymbuf;
1090fddef416Sniklas 
1091fddef416Sniklas 		  bfd_put_8 (abfd, 0xcc + (code & 0x03),
1092fddef416Sniklas 			     contents + irel->r_offset - 2);
1093fddef416Sniklas 
1094fddef416Sniklas 		  bfd_put_8 (abfd, 0xb8 + (code & 0x03),
1095fddef416Sniklas 			     contents + irel->r_offset - 1);
1096fddef416Sniklas 
1097fddef416Sniklas 		  /* Fix the relocation's type.  */
1098fddef416Sniklas 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1099fddef416Sniklas 					       R_MN10200_16);
1100fddef416Sniklas 
1101fddef416Sniklas 		  /* The reloc will be applied one byte in front of its
1102fddef416Sniklas 		     current location.  */
1103fddef416Sniklas 		  irel->r_offset -= 1;
1104fddef416Sniklas 
1105fddef416Sniklas 		  /* Delete one bytes of data.  */
1106fddef416Sniklas 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1107fddef416Sniklas 						       irel->r_offset + 2, 1))
1108fddef416Sniklas 		    goto error_return;
1109fddef416Sniklas 
1110fddef416Sniklas 		  /* That will change things, so, we should relax again.
1111fddef416Sniklas 		     Note that this is not required, and it may be slow.  */
1112d2201f2fSdrahn 		  *again = TRUE;
1113fddef416Sniklas 		  break;
1114fddef416Sniklas 		}
1115fddef416Sniklas 	    }
1116fddef416Sniklas 	}
1117fddef416Sniklas     }
1118fddef416Sniklas 
1119d2201f2fSdrahn   if (isymbuf != NULL
1120d2201f2fSdrahn       && symtab_hdr->contents != (unsigned char *) isymbuf)
1121fddef416Sniklas     {
1122fddef416Sniklas       if (! link_info->keep_memory)
1123d2201f2fSdrahn 	free (isymbuf);
1124d2201f2fSdrahn       else
1125d2201f2fSdrahn 	{
1126d2201f2fSdrahn 	  /* Cache the symbols for elf_link_input_bfd.  */
1127d2201f2fSdrahn 	  symtab_hdr->contents = (unsigned char *) isymbuf;
1128d2201f2fSdrahn 	}
1129d2201f2fSdrahn     }
1130d2201f2fSdrahn 
1131d2201f2fSdrahn   if (contents != NULL
1132d2201f2fSdrahn       && elf_section_data (sec)->this_hdr.contents != contents)
1133d2201f2fSdrahn     {
1134d2201f2fSdrahn       if (! link_info->keep_memory)
1135d2201f2fSdrahn 	free (contents);
1136fddef416Sniklas       else
1137fddef416Sniklas 	{
1138fddef416Sniklas 	  /* Cache the section contents for elf_link_input_bfd.  */
1139fddef416Sniklas 	  elf_section_data (sec)->this_hdr.contents = contents;
1140fddef416Sniklas 	}
1141fddef416Sniklas     }
1142fddef416Sniklas 
1143d2201f2fSdrahn   if (internal_relocs != NULL
1144d2201f2fSdrahn       && elf_section_data (sec)->relocs != internal_relocs)
1145d2201f2fSdrahn     free (internal_relocs);
1146fddef416Sniklas 
1147d2201f2fSdrahn   return TRUE;
1148fddef416Sniklas 
1149fddef416Sniklas  error_return:
1150d2201f2fSdrahn   if (isymbuf != NULL
1151d2201f2fSdrahn       && symtab_hdr->contents != (unsigned char *) isymbuf)
1152d2201f2fSdrahn     free (isymbuf);
1153d2201f2fSdrahn   if (contents != NULL
1154d2201f2fSdrahn       && elf_section_data (sec)->this_hdr.contents != contents)
1155d2201f2fSdrahn     free (contents);
1156d2201f2fSdrahn   if (internal_relocs != NULL
1157d2201f2fSdrahn       && elf_section_data (sec)->relocs != internal_relocs)
1158d2201f2fSdrahn     free (internal_relocs);
1159d2201f2fSdrahn 
1160d2201f2fSdrahn   return FALSE;
1161fddef416Sniklas }
1162fddef416Sniklas 
1163fddef416Sniklas /* Delete some bytes from a section while relaxing.  */
1164fddef416Sniklas 
1165d2201f2fSdrahn static bfd_boolean
mn10200_elf_relax_delete_bytes(abfd,sec,addr,count)1166fddef416Sniklas mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
1167fddef416Sniklas      bfd *abfd;
1168fddef416Sniklas      asection *sec;
1169fddef416Sniklas      bfd_vma addr;
1170fddef416Sniklas      int count;
1171fddef416Sniklas {
1172fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
1173d2201f2fSdrahn   unsigned int sec_shndx;
1174fddef416Sniklas   bfd_byte *contents;
1175fddef416Sniklas   Elf_Internal_Rela *irel, *irelend;
1176fddef416Sniklas   Elf_Internal_Rela *irelalign;
1177fddef416Sniklas   bfd_vma toaddr;
1178d2201f2fSdrahn   Elf_Internal_Sym *isym;
1179d2201f2fSdrahn   Elf_Internal_Sym *isymend;
1180d2201f2fSdrahn   struct elf_link_hash_entry **sym_hashes;
1181d2201f2fSdrahn   struct elf_link_hash_entry **end_hashes;
1182d2201f2fSdrahn   unsigned int symcount;
1183fddef416Sniklas 
1184d2201f2fSdrahn   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1185fddef416Sniklas 
1186fddef416Sniklas   contents = elf_section_data (sec)->this_hdr.contents;
1187fddef416Sniklas 
1188fddef416Sniklas   /* The deletion must stop at the next ALIGN reloc for an aligment
1189fddef416Sniklas      power larger than the number of bytes we are deleting.  */
1190fddef416Sniklas 
1191fddef416Sniklas   irelalign = NULL;
1192fddef416Sniklas   toaddr = sec->_cooked_size;
1193fddef416Sniklas 
1194fddef416Sniklas   irel = elf_section_data (sec)->relocs;
1195fddef416Sniklas   irelend = irel + sec->reloc_count;
1196fddef416Sniklas 
1197fddef416Sniklas   /* Actually delete the bytes.  */
1198d2201f2fSdrahn   memmove (contents + addr, contents + addr + count,
1199d2201f2fSdrahn 	   (size_t) (toaddr - addr - count));
1200fddef416Sniklas   sec->_cooked_size -= count;
1201fddef416Sniklas 
1202fddef416Sniklas   /* Adjust all the relocs.  */
1203fddef416Sniklas   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1204fddef416Sniklas     {
1205fddef416Sniklas       /* Get the new reloc address.  */
1206fddef416Sniklas       if ((irel->r_offset > addr
1207fddef416Sniklas 	   && irel->r_offset < toaddr))
1208fddef416Sniklas 	irel->r_offset -= count;
1209fddef416Sniklas     }
1210fddef416Sniklas 
1211f7cc78ecSespie   /* Adjust the local symbols defined in this section.  */
1212d2201f2fSdrahn   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1213d2201f2fSdrahn   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1214d2201f2fSdrahn   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1215fddef416Sniklas     {
1216d2201f2fSdrahn       if (isym->st_shndx == sec_shndx
1217d2201f2fSdrahn 	  && isym->st_value > addr
1218d2201f2fSdrahn 	  && isym->st_value < toaddr)
1219d2201f2fSdrahn 	isym->st_value -= count;
1220fddef416Sniklas     }
1221fddef416Sniklas 
1222f7cc78ecSespie   /* Now adjust the global symbols defined in this section.  */
1223d2201f2fSdrahn   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1224d2201f2fSdrahn 	      - symtab_hdr->sh_info);
1225d2201f2fSdrahn   sym_hashes = elf_sym_hashes (abfd);
1226d2201f2fSdrahn   end_hashes = sym_hashes + symcount;
1227d2201f2fSdrahn   for (; sym_hashes < end_hashes; sym_hashes++)
1228fddef416Sniklas     {
1229d2201f2fSdrahn       struct elf_link_hash_entry *sym_hash = *sym_hashes;
1230d2201f2fSdrahn       if ((sym_hash->root.type == bfd_link_hash_defined
1231d2201f2fSdrahn 	   || sym_hash->root.type == bfd_link_hash_defweak)
1232d2201f2fSdrahn 	  && sym_hash->root.u.def.section == sec
1233d2201f2fSdrahn 	  && sym_hash->root.u.def.value > addr
1234d2201f2fSdrahn 	  && sym_hash->root.u.def.value < toaddr)
1235fddef416Sniklas 	{
1236d2201f2fSdrahn 	  sym_hash->root.u.def.value -= count;
1237fddef416Sniklas 	}
1238fddef416Sniklas     }
1239fddef416Sniklas 
1240d2201f2fSdrahn   return TRUE;
1241fddef416Sniklas }
1242fddef416Sniklas 
1243d2201f2fSdrahn /* Return TRUE if a symbol exists at the given address, else return
1244d2201f2fSdrahn    FALSE.  */
1245d2201f2fSdrahn static bfd_boolean
mn10200_elf_symbol_address_p(abfd,sec,isym,addr)1246d2201f2fSdrahn mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
1247fddef416Sniklas      bfd *abfd;
1248fddef416Sniklas      asection *sec;
1249d2201f2fSdrahn      Elf_Internal_Sym *isym;
1250fddef416Sniklas      bfd_vma addr;
1251fddef416Sniklas {
1252fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
1253d2201f2fSdrahn   unsigned int sec_shndx;
1254d2201f2fSdrahn   Elf_Internal_Sym *isymend;
1255d2201f2fSdrahn   struct elf_link_hash_entry **sym_hashes;
1256d2201f2fSdrahn   struct elf_link_hash_entry **end_hashes;
1257d2201f2fSdrahn   unsigned int symcount;
1258fddef416Sniklas 
1259d2201f2fSdrahn   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1260d2201f2fSdrahn 
1261d2201f2fSdrahn   /* Examine all the local symbols.  */
1262fddef416Sniklas   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1263d2201f2fSdrahn   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1264fddef416Sniklas     {
1265d2201f2fSdrahn       if (isym->st_shndx == sec_shndx
1266d2201f2fSdrahn 	  && isym->st_value == addr)
1267d2201f2fSdrahn 	return TRUE;
1268fddef416Sniklas     }
1269fddef416Sniklas 
1270d2201f2fSdrahn   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1271d2201f2fSdrahn 	      - symtab_hdr->sh_info);
1272d2201f2fSdrahn   sym_hashes = elf_sym_hashes (abfd);
1273d2201f2fSdrahn   end_hashes = sym_hashes + symcount;
1274d2201f2fSdrahn   for (; sym_hashes < end_hashes; sym_hashes++)
1275fddef416Sniklas     {
1276d2201f2fSdrahn       struct elf_link_hash_entry *sym_hash = *sym_hashes;
1277d2201f2fSdrahn       if ((sym_hash->root.type == bfd_link_hash_defined
1278d2201f2fSdrahn 	   || sym_hash->root.type == bfd_link_hash_defweak)
1279d2201f2fSdrahn 	  && sym_hash->root.u.def.section == sec
1280d2201f2fSdrahn 	  && sym_hash->root.u.def.value == addr)
1281d2201f2fSdrahn 	return TRUE;
1282fddef416Sniklas     }
1283d2201f2fSdrahn 
1284d2201f2fSdrahn   return FALSE;
1285fddef416Sniklas }
1286fddef416Sniklas 
1287fddef416Sniklas /* This is a version of bfd_generic_get_relocated_section_contents
1288fddef416Sniklas    which uses mn10200_elf_relocate_section.  */
1289fddef416Sniklas 
1290fddef416Sniklas static bfd_byte *
mn10200_elf_get_relocated_section_contents(output_bfd,link_info,link_order,data,relocatable,symbols)1291fddef416Sniklas mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
1292*cf2f2c56Smiod 					    data, relocatable, symbols)
1293fddef416Sniklas      bfd *output_bfd;
1294fddef416Sniklas      struct bfd_link_info *link_info;
1295fddef416Sniklas      struct bfd_link_order *link_order;
1296fddef416Sniklas      bfd_byte *data;
1297*cf2f2c56Smiod      bfd_boolean relocatable;
1298fddef416Sniklas      asymbol **symbols;
1299fddef416Sniklas {
1300fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
1301fddef416Sniklas   asection *input_section = link_order->u.indirect.section;
1302fddef416Sniklas   bfd *input_bfd = input_section->owner;
1303fddef416Sniklas   asection **sections = NULL;
1304fddef416Sniklas   Elf_Internal_Rela *internal_relocs = NULL;
1305d2201f2fSdrahn   Elf_Internal_Sym *isymbuf = NULL;
1306fddef416Sniklas 
1307fddef416Sniklas   /* We only need to handle the case of relaxing, or of having a
1308fddef416Sniklas      particular set of section contents, specially.  */
1309*cf2f2c56Smiod   if (relocatable
1310fddef416Sniklas       || elf_section_data (input_section)->this_hdr.contents == NULL)
1311fddef416Sniklas     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1312fddef416Sniklas 						       link_order, data,
1313*cf2f2c56Smiod 						       relocatable,
1314fddef416Sniklas 						       symbols);
1315fddef416Sniklas 
1316fddef416Sniklas   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1317fddef416Sniklas 
1318fddef416Sniklas   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1319d2201f2fSdrahn 	  (size_t) input_section->_raw_size);
1320fddef416Sniklas 
1321fddef416Sniklas   if ((input_section->flags & SEC_RELOC) != 0
1322fddef416Sniklas       && input_section->reloc_count > 0)
1323fddef416Sniklas     {
1324d2201f2fSdrahn       Elf_Internal_Sym *isym;
1325d2201f2fSdrahn       Elf_Internal_Sym *isymend;
1326fddef416Sniklas       asection **secpp;
1327d2201f2fSdrahn       bfd_size_type amt;
1328fddef416Sniklas 
1329*cf2f2c56Smiod       internal_relocs = (_bfd_elf_link_read_relocs
1330fddef416Sniklas 			 (input_bfd, input_section, (PTR) NULL,
1331d2201f2fSdrahn 			  (Elf_Internal_Rela *) NULL, FALSE));
1332fddef416Sniklas       if (internal_relocs == NULL)
1333fddef416Sniklas 	goto error_return;
1334fddef416Sniklas 
1335d2201f2fSdrahn       if (symtab_hdr->sh_info != 0)
1336d2201f2fSdrahn 	{
1337d2201f2fSdrahn 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1338d2201f2fSdrahn 	  if (isymbuf == NULL)
1339d2201f2fSdrahn 	    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1340d2201f2fSdrahn 					    symtab_hdr->sh_info, 0,
1341d2201f2fSdrahn 					    NULL, NULL, NULL);
1342d2201f2fSdrahn 	  if (isymbuf == NULL)
1343d2201f2fSdrahn 	    goto error_return;
1344d2201f2fSdrahn 	}
1345d2201f2fSdrahn 
1346d2201f2fSdrahn       amt = symtab_hdr->sh_info;
1347d2201f2fSdrahn       amt *= sizeof (asection *);
1348d2201f2fSdrahn       sections = (asection **) bfd_malloc (amt);
1349d2201f2fSdrahn       if (sections == NULL && amt != 0)
1350fddef416Sniklas 	goto error_return;
1351fddef416Sniklas 
1352d2201f2fSdrahn       isymend = isymbuf + symtab_hdr->sh_info;
1353d2201f2fSdrahn       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1354fddef416Sniklas 	{
1355fddef416Sniklas 	  asection *isec;
1356fddef416Sniklas 
1357d2201f2fSdrahn 	  if (isym->st_shndx == SHN_UNDEF)
1358fddef416Sniklas 	    isec = bfd_und_section_ptr;
1359d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_ABS)
1360fddef416Sniklas 	    isec = bfd_abs_section_ptr;
1361d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_COMMON)
1362fddef416Sniklas 	    isec = bfd_com_section_ptr;
1363fddef416Sniklas 	  else
1364d2201f2fSdrahn 	    isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1365fddef416Sniklas 
1366fddef416Sniklas 	  *secpp = isec;
1367fddef416Sniklas 	}
1368fddef416Sniklas 
1369fddef416Sniklas       if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
1370fddef416Sniklas 				     input_section, data, internal_relocs,
1371d2201f2fSdrahn 				     isymbuf, sections))
1372fddef416Sniklas 	goto error_return;
1373fddef416Sniklas 
1374fddef416Sniklas       if (sections != NULL)
1375fddef416Sniklas 	free (sections);
1376d2201f2fSdrahn       if (isymbuf != NULL
1377d2201f2fSdrahn 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
1378d2201f2fSdrahn 	free (isymbuf);
1379d2201f2fSdrahn       if (elf_section_data (input_section)->relocs != internal_relocs)
1380fddef416Sniklas 	free (internal_relocs);
1381fddef416Sniklas     }
1382fddef416Sniklas 
1383fddef416Sniklas   return data;
1384fddef416Sniklas 
1385fddef416Sniklas  error_return:
1386fddef416Sniklas   if (sections != NULL)
1387fddef416Sniklas     free (sections);
1388d2201f2fSdrahn   if (isymbuf != NULL
1389d2201f2fSdrahn       && symtab_hdr->contents != (unsigned char *) isymbuf)
1390d2201f2fSdrahn     free (isymbuf);
1391d2201f2fSdrahn   if (internal_relocs != NULL
1392d2201f2fSdrahn       && elf_section_data (input_section)->relocs != internal_relocs)
1393d2201f2fSdrahn     free (internal_relocs);
1394fddef416Sniklas   return NULL;
1395fddef416Sniklas }
1396fddef416Sniklas 
1397fddef416Sniklas #define TARGET_LITTLE_SYM	bfd_elf32_mn10200_vec
1398fddef416Sniklas #define TARGET_LITTLE_NAME	"elf32-mn10200"
1399fddef416Sniklas #define ELF_ARCH		bfd_arch_mn10200
1400d2201f2fSdrahn #define ELF_MACHINE_CODE	EM_MN10200
1401d2201f2fSdrahn #define ELF_MACHINE_ALT1	EM_CYGNUS_MN10200
1402fddef416Sniklas #define ELF_MAXPAGESIZE		0x1000
1403fddef416Sniklas 
1404d2201f2fSdrahn #define elf_backend_rela_normal 1
1405fddef416Sniklas #define elf_info_to_howto	mn10200_info_to_howto
1406fddef416Sniklas #define elf_info_to_howto_rel	0
1407fddef416Sniklas #define elf_backend_relocate_section mn10200_elf_relocate_section
1408fddef416Sniklas #define bfd_elf32_bfd_relax_section	mn10200_elf_relax_section
1409fddef416Sniklas #define bfd_elf32_bfd_get_relocated_section_contents \
1410fddef416Sniklas 				mn10200_elf_get_relocated_section_contents
1411fddef416Sniklas 
1412fddef416Sniklas #define elf_symbol_leading_char '_'
1413fddef416Sniklas 
1414fddef416Sniklas #include "elf32-target.h"
1415